diff --git a/.gitattributes b/.gitattributes index c3af0de1..313dfab5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ # Vite's generated runtime includes significant whitespace in a template literal. drowse/web/dist/assets/*.js whitespace=-trailing-space +browser-runtime/forks/*.patch whitespace=-blank-at-eol diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f43bf58d..0600aadd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -98,8 +98,10 @@ jobs: pip install dist/drowse_ai-*.whl python -c "import drowse; from importlib.metadata import version; assert version('drowse.ai') == drowse.__version__; print('version:', drowse.__version__)" - webui: + webui-build: runs-on: ubuntu-latest + env: + DROWSE_STORAGE_BROWSERS: chromium steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 @@ -114,17 +116,15 @@ jobs: run: pip install -e . - run: npm ci working-directory: webui + - name: Install the pinned Playwright browsers + run: npx playwright install --with-deps chromium webkit firefox + working-directory: webui - run: npm run check working-directory: webui - run: npm run check:hosted working-directory: webui - run: npm run test:hosted working-directory: webui - - name: Install the pinned Playwright browsers - run: npx playwright install --with-deps chromium webkit firefox - working-directory: webui - - run: npm run test:e2e - working-directory: webui - run: npm run build working-directory: webui - name: Verify default and hosted builds are isolated @@ -139,8 +139,91 @@ jobs: exit 1 fi - fitting-wasm: + webui-browser: + runs-on: ubuntu-latest + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + shard: [1, 2, 3, 4] + defaults: + run: + working-directory: webui + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version: "24" + cache: npm + cache-dependency-path: webui/package-lock.json + - run: npm ci + - name: Install the pinned Playwright browsers + run: npx playwright install --with-deps chromium webkit firefox + - run: npm run test:e2e -- --shard=${{ matrix.shard }}/4 --workers=1 + - name: Preserve browser failure diagnostics + if: failure() + uses: actions/upload-artifact@v7 + with: + name: browser-failures-${{ matrix.shard }} + path: /tmp/drowse-playwright-results + retention-days: 3 + + webui: runs-on: ubuntu-latest + needs: [webui-build, webui-browser] + if: always() + steps: + - name: Verify the dashboard build and browser matrix succeeded + run: | + if [ "${{ needs.webui-build.result }}" != "success" ] || [ "${{ needs.webui-browser.result }}" != "success" ]; then + echo "webui-build=${{ needs.webui-build.result }}, webui-browser=${{ needs.webui-browser.result }}" + exit 1 + fi + + webkit-storage: + runs-on: macos-15 + defaults: + run: + working-directory: webui + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version: "24" + cache: npm + cache-dependency-path: webui/package-lock.json + - run: npm ci + - run: npx playwright install chromium webkit + - run: node scripts/iphone-storage.test.mjs + + contact-worker: + runs-on: ubuntu-latest + defaults: + run: + working-directory: webui/contact-worker + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version: "24" + cache: npm + cache-dependency-path: | + webui/package-lock.json + webui/contact-worker/package-lock.json + - name: Install dependencies for shared contact validation + run: npm ci + working-directory: webui + - run: npm ci + - run: npm run check + - run: npm test + - run: npm run build + + fitting-wasm: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-15] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v7 - name: Install Rust components and WebAssembly target @@ -156,7 +239,11 @@ jobs: - name: Build optimized WebAssembly module run: cargo build --locked --release --target wasm32-unknown-unknown --manifest-path browser-runtime/fitting-wasm/Cargo.toml - name: Install the pinned wasm-bindgen packager + if: runner.os == 'macOS' run: cargo install wasm-bindgen-cli --version 0.2.127 --locked + # Compare on the same host architecture that produces the committed assets; + # Cargo's host-dependent metadata changes Wasm function ordering on Linux. - name: Verify committed browser bindings are reproducible + if: runner.os == 'macOS' run: npm run check:fitting-wasm working-directory: webui diff --git a/.gitignore b/.gitignore index ee75bb00..f57d0873 100644 --- a/.gitignore +++ b/.gitignore @@ -23,8 +23,10 @@ webui/dist-hosted/ browser-runtime/.v3-compile.*/ browser-runtime/.local-build/ browser-runtime/vendor/*.tgz -!browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.32.tgz !browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.34.tgz +!browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.36.tgz +!browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.37.tgz +!browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.38.tgz # Virtual environments .venv/ @@ -34,6 +36,7 @@ env/ # pytest / ruff .pytest_cache/ .ruff_cache/ +.coverage # OS .DS_Store @@ -58,3 +61,45 @@ scripts/out/ # Local research experiments (scripts + results live outside version control) scripts/experiments/ + +# Local audit reports, repair checklists, and historical validation notes. +*_AUDIT*.md +*-audit*.md +*_QA.md +*_REVIEW.md +*-review*.md +*_VALIDATION_*.md +*-validation-20??-??-??.md +*CHECKLIST*.md +*checklist*.md +*_FIXES*.md +*-fixes*.md +/browser-runtime/BASE_MODELS.md +/webui/GEO-SCHEMA-REPORT.md +/docs/cloudflare-configuration-20??-??-??.md +/docs/*-20??-??-??.md +/legacy/ + +# Ongoing local evidence and provenance records; schemas are source code. +*-evidence*.json +!*.schema.json +/browser-runtime/evidence/* +!/browser-runtime/evidence/README.md +PROVENANCE.md +provenance.json +# Required authored-source manifest, not a run or audit record. +!/browser-runtime/release-inputs/core-manifolds/welcoming.detached/provenance.json + +# Local research, benchmark reports, and generated verification output. +/DOMAIN_NAME_*.md +/domain-name-*.csv +/domain-name-*.json +/domain-registrar-*.json +/docs/research/ +/benchmarks/*_20??-??-??.md +playwright-report/ +test-results/ +blob-report/ +coverage/ +audit-reports/ +verification-results/ diff --git a/DOMAIN_NAME_RESEARCH.md b/DOMAIN_NAME_RESEARCH.md deleted file mode 100644 index a9643273..00000000 --- a/DOMAIN_NAME_RESEARCH.md +++ /dev/null @@ -1,40 +0,0 @@ -# One-word product-name domain research - -Checked 2026-08-27 with live Porkbun registration results. Every CSV row is an exact dictionary word, standard-price at check time, and rechecked on both .ai and .com. - -## Important price detail - -- .ai: $82.70/year, two-year minimum, so $165.40 at initial checkout. -- Standard .com: $11.08/year at the checked registrar. The CSV prefers .com whenever the exact word was available. -- Availability is not trademark clearance and can change at any moment. - -## Best pick - -**Borage** — **Behavior Observation and Representation Analysis for Guided Editing** - -- [borage.ai](https://borage.ai) was live, exact, and standard-price at the final check. -- It names both halves of the product cleanly: observing representations and editing model behavior. -- It is a short real word, easy to spell after hearing it once, and has a distinctive botanical identity. -- The exact PyPI and npm package names were unclaimed at check time. A quick web collision screen found no obvious active software or AI product called Borage. - -## Strongest alternatives after the collision screen - -| Name | Domain | Theme | Backronym | Caveat | -|---|---|---|---|---| -| Doline | [doline.ai](https://doline.ai) | land | Directional Observation of Latent Inference in Neural Embeddings | A karst depression; the physical meaning may feel downward or hollow. | -| Visile | [visile.ai](https://visile.ai) | mind | Vector Interpretation of Subspaces in Layerwise Embeddings | Rare word; an unrelated swimwear brand and chemical wholesaler use the name. | -| Dimity | [dimity.ai](https://dimity.ai) | craft | Directional Interpretation and Manifold Injection for Trait Yield | An active UK management consultancy uses the name. | -| Fernery | [fernery.ai](https://fernery.ai) | flora | Feature Exploration and Readout for Neural Embedding Representation, Yield-aware | Longer; also the name of a small open-source fractal-image project. | -| Muskeg | [muskeg.ai](https://muskeg.ai) | land | Manifold Understanding, Steering, Kernel Exploration, and Geometry | Strong sound, but closely associated with Muskeg Lake Cree Nation and Canadian geography. | - -## Collision screen - -Several excellent-sounding domain hits are poor product-name choices because an active adjacent brand already uses the exact word. I would not lead with **Monody, Pavane, Rundel, Cleome, Hyssop, Joyance, Argali, Digram, Smilax, Spathe, Albite, Tenter, Ogive, Achene,** or **Crewel**. Examples include [Monody](https://monody.app/terms), [Pavane Solutions](https://pavaneinc.com/), [Hyssop Labs](https://hyssoplabs.com/), [Albite ERP](https://albitee.com/ourcompany), [Tenter](https://tenter.framer.website/), [Achene](https://achene.app/about), and [Crewel Technologies](https://creweltechnologies.com/index.html). - -This is a pragmatic web and package-namespace screen, not trademark clearance. - -## Method - -A themed lexical pool spanning nature, feeling, motion, geometry, language, instruments, and interpretability was filtered for negative, medical, demonym, place-name, misspelling, and awkward-inflection meanings. Candidates were checked live for exact .ai availability and premium status, curated to 200, then rechecked alongside exact .com status. - -The complete 200-name inventory is in `domain-name-candidates.csv`. Its `rank` column reflects name/domain fit before the collision screen; use the shortlist above for the actual recommendation. diff --git a/DOMAIN_NAME_RESEARCH_ROUND_2.md b/DOMAIN_NAME_RESEARCH_ROUND_2.md deleted file mode 100644 index 63f84a49..00000000 --- a/DOMAIN_NAME_RESEARCH_ROUND_2.md +++ /dev/null @@ -1,48 +0,0 @@ -# Polythetic name research: round 2 - -Checked: 2026-08-27 - -This round is deliberately less obscure than the first. Every candidate is a familiar English word or an established psychology/cognitive-science term, with no invented suffixes. `Drowse` remains the strongest overall name; this sheet contains 200 additional candidates. - -## Best new candidates - -| Rank | Name | Live domain | Why it works | Backronym sketch | -|---:|---|---|---|---| -| 1 | Psyche | [psyche.tools](https://psyche.tools) | Directly signals mind and psychology; warm rather than clinical. | Probing Subspaces to Yield Cognitive Hidden-state Explanations | -| 2 | Affect | [affect.tools](https://affect.tools) | Canonical emotion term and a verb meaning to change. | Activation Feature Fitting for Explainable Concept Tuning | -| 3 | Slant | [slant.tools](https://slant.tools) | A directional bias or interpretive angle; short and tactile. | Subspace Lenses for Activation Navigation and Tuning | -| 4 | Drowsy | [drowsy.tools](https://drowsy.tools) | The closest new sibling to Drowse. | Directional Readout and Observation for Workspace Steering, Yield-aware | -| 5 | Pensive | [pensive.tools](https://pensive.tools) | Thoughtful, introspective, and emotionally colored. | Probing Embeddings and Neural Subspaces for Interpretable Vector Editing | -| 6 | Appraisal | [appraisal.tools](https://appraisal.tools) | A core emotion-theory term for how a system evaluates a situation. | Activation Probing and Projection for Representation Analysis, Interpretation, Steering, Alignment, and Layers | -| 7 | Affordance | [affordance.tools](https://affordance.tools) | Canonical cognitive-science term for possible actions and control. | Activation Feature Fitting for Output Representation, Direction, Analysis, Navigation, Control, and Editing | -| 8 | Arousal | [arousal.tools](https://arousal.tools) | A core affect dimension and a measurable activation state. | Activation Readout for Output Understanding, Steering, and Layers | -| 9 | Inward | [inward.tools](https://inward.tools) | Suggests opening a model and looking within. | Interpreting Neural Workspaces for Activation Readout and Direction | -| 10 | Heed | [heed.tools](https://heed.tools) | Attention and behavioral steering compressed into one verb. | Hidden-state Evaluation for Editing and Direction | -| 11 | Sentiment | [sentiment.tools](https://sentiment.tools) | Immediately legible as affect, evaluation, and model measurement. | Subspace Editing of Neural Traits through Interpretable Manifold Evaluation and Neural Tracking | -| 12 | Dreamy | [dreamy.tools](https://dreamy.tools) | Soft, stateful, and close to the tone that made Drowse work. | Directional Representation Editing and Manifold Analysis, Yield-aware | -| 13 | Attitude | [attitude.tools](https://attitude.tools) | Both a mental stance and an orientation in space. | Activation Traits Traced through Interpretable Tuning, Understanding, Direction, and Editing | -| 14 | Binding | [binding.tools](https://binding.tools) | A cognitive-science problem and a literal operation on representations. | Basis Interpretation for Neural Direction Injection and Navigation Geometry | -| 15 | Anchoring | [anchoring.tools](https://anchoring.tools) | A cognitive bias and a geometric control metaphor. | Activation Navigation and Concept Hidden-state Observation for Representation Injection and Neural Guidance | -| 16 | Polarity | [polarity.tools](https://polarity.tools) | Fits bipolar concepts, activation axes, and emotional valence. | Probing Output Layers for Activation Representation Interpretation, Tuning, and Yield | -| 17 | Mellow | [mellow.tools](https://mellow.tools) | Friendly affective tone with an implicit modulation metaphor. | Manifold Editing with Layerwise Lenses for Output Watching | -| 18 | Slumber | [slumber.tools](https://slumber.tools) | Drowse-adjacent, substantial, and easy to remember. | Subspace Lenses for Understanding Model Behavior, Editing, and Readout | -| 19 | Emergence | [emergence.tools](https://emergence.tools) | Names the phenomenon interpretability tries to make legible. | Editing Model Embeddings for Representation Geometry, Evaluation, Neural Control, and Explainability | -| 20 | Enaction | [enaction.tools](https://enaction.tools) | Connects cognition, embodiment, and action. | Editing Neural Activations for Concept Tuning, Interpretation, Output Navigation | - -The complete 200-name table, including domain, theme, rationale, a backronym sketch, live status, and pricing, is in [domain-name-candidates-round-2.csv](domain-name-candidates-round-2.csv). - -## Domain and pricing result - -I prioritized exact `.ai` and `.com` names, but credible familiar words in this theme were already registered or premium-priced. Exact `.tools` domains produced the strongest combination of name quality, product fit, and price. - -| TLD used | First year | Renewal | Count | -|---|---:|---:|---:| -| `.tools` | $9.78 | $29.35 | 196 | -| `.design` | $10.81 | $46.86 | 1 | -| `.wiki` | $2.06 | $26.26 | 1 | -| `.science` | $10.79 | $10.79 | 1 | -| `.software` | $15.96 | $33.47 | 1 | - -All 200 were returned as available at standard, non-premium pricing by Porkbun's live registrar search on the checked date. Availability can change at any time and this is not trademark clearance. - -Sources: [Porkbun domain search](https://porkbun.com/checkout/search), [Porkbun domain pricing](https://porkbun.com/products/domains), [Datamuse lexical API](https://www.datamuse.com/api/). diff --git a/DOMAIN_NAME_SHORTLIST_2026-09-05.md b/DOMAIN_NAME_SHORTLIST_2026-09-05.md deleted file mode 100644 index e6ccbb28..00000000 --- a/DOMAIN_NAME_SHORTLIST_2026-09-05.md +++ /dev/null @@ -1,80 +0,0 @@ -# Polythetic naming shortlist — 5 September 2026 - -The strongest choices are **Unknit** for semantic fit, **Billowy** for a soft and expressive identity, and **Borage** for a distinctive botanical identity. - -Inspected the current README, architecture description, and previous naming inventories. The project is a workbench for observing and steering model internals, with probes, manifolds, token readouts, and branching conversations. Names were selected around hidden structure, fine adjustment, geometry, craft, and nature. - -Checked 594 distinct exact .ai domains through Porkbun. All 20 finalists returned AVAILABLE, type registration, premium 0, and pending 0 in the final check at **2026-09-05 15:19:17 UTC / 11:19:17 EDT**. Independent Identity Digital RDAP lookups also returned 404 for every finalist. All names have 5–8 letters; 18 have 7 or fewer. - -Each finalist was quoted **US$82.70/year for registration and renewal**. The registry requires at least **two years** for registration and renewal. Budget approximately **US$165 upfront** before any tax. Twice the displayed annual rate is $165.40, an estimate rather than a completed checkout quote; checkout arithmetic may differ. Sources: [Porkbun .ai terms](https://porkbun.com/tld/ai), [Porkbun pricing](https://porkbun.com/products/domains). - -Names near the top balance fit, pronunciation, and the preliminary collision screen. Some lower-ranked options have stronger existing software uses; those are explicitly recorded below. Domain availability is time-sensitive and does not constitute trademark clearance. Package HTTP 404 means no current public listing was returned, not a guarantee that the package name can be claimed. - -| # | Name and registrar link | Pronunciation | Meaning and fit | -|---:|---|---|---| -| 1 | [Unknit — unknit.ai](https://porkbun.com/checkout/search?q=unknit.ai) | un-NIT | Undo intertwined strands; a clear metaphor for disentangling model representations. | -| 2 | [Billowy — billowy.ai](https://porkbun.com/checkout/search?q=billowy.ai) | BIL-oh-ee | Flowing, changing shapes; soft and memorable for exploring model behavior. | -| 3 | [Borage — borage.ai](https://porkbun.com/checkout/search?q=borage.ai) | BOR-ij | A blue, star-flowered herb; a distinctive botanical identity with room to grow. | -| 4 | [Drowse — drowse.ai](https://porkbun.com/checkout/search?q=drowse.ai) | DROWZ (rhymes with cows) | A liminal mental state; the strongest short, atmospheric option. | -| 5 | [Unpleat — unpleat.ai](https://porkbun.com/checkout/search?q=unpleat.ai) | un-PLEET | Unfold hidden structure; a compact metaphor for opening up model geometry. | -| 6 | [Toneme — toneme.ai](https://porkbun.com/checkout/search?q=toneme.ai) | TOH-neem | A meaningful tone unit in language; connects language with subtle behavioral differences. | -| 7 | [Tepal — tepal.ai](https://porkbun.com/checkout/search?q=tepal.ai) | TEE-puhl | A petal-like flower part; five letters and a compact, organic identity. | -| 8 | [Smidgen — smidgen.ai](https://porkbun.com/checkout/search?q=smidgen.ai) | SMID-jin | A tiny amount; a friendly metaphor for fine-grained steering adjustments. | -| 9 | [Unshown — unshown.ai](https://porkbun.com/checkout/search?q=unshown.ai) | un-SHOHN | The parts normally hidden; direct and relevant to model inspection. | -| 10 | [Doline — doline.ai](https://porkbun.com/checkout/search?q=doline.ai) | DOH-leen | A natural basin; an evocative name for exploring a model's internal landscape. | -| 11 | [Scumble — scumble.ai](https://porkbun.com/checkout/search?q=scumble.ai) | SKUM-buhl | A painting technique that softens color through layers; fits subtle trait modulation. | -| 12 | [Brayer — brayer.ai](https://porkbun.com/checkout/search?q=brayer.ai) | BRAY-er | A printmaker's ink roller; a tactile tool for applying controlled changes. | -| 13 | [Coving — coving.ai](https://porkbun.com/checkout/search?q=coving.ai) | KOH-ving | A curved transition between surfaces; a quiet geometric metaphor. | -| 14 | [Harebell — harebell.ai](https://porkbun.com/checkout/search?q=harebell.ai) | HAIR-bell | A delicate blue wildflower; an approachable visual identity with a clear image. | -| 15 | [Dimity — dimity.ai](https://porkbun.com/checkout/search?q=dimity.ai) | DIM-ih-tee | A woven fabric; a soft name for a workbench that combines many traits. | -| 16 | [Sculler — sculler.ai](https://porkbun.com/checkout/search?q=sculler.ai) | SKUL-er | Someone who rows with two oars; a concrete metaphor for directional control. | -| 17 | [Ruddle — ruddle.ai](https://porkbun.com/checkout/search?q=ruddle.ai) | RUD-uhl | Red ochre used for marking; fits highlighting and tracing hidden activity. | -| 18 | [Isobath — isobath.ai](https://porkbun.com/checkout/search?q=isobath.ai) | EYE-so-bath | A line connecting equal depths; a precise metaphor for mapping internal geometry. | -| 19 | [Mordent — mordent.ai](https://porkbun.com/checkout/search?q=mordent.ai) | MOR-dunt | A quick musical turn around a note; suggests small, deliberate changes in output. | -| 20 | [Shimmery — shimmery.ai](https://porkbun.com/checkout/search?q=shimmery.ai) | SHIM-er-ee | Subtle changes in light; suited to a visual, exploratory product identity. | - -## Existing-use screen - -| Name | Findings | -|---|---| -| Unknit | No obvious exact-name AI product found; PyPI and npm lookups returned 404. [Source 1](https://www.merriam-webster.com/dictionary/unknit) | -| Billowy | A footwear retailer and other unrelated businesses use the word; no obvious exact-name AI product found. [Source 1](https://billowyshop.com/policies/legal-notice) | -| Borage | No obvious exact-name AI/software product found; PyPI and npm lookups returned 404. | -| Drowse | Existing Drowse sleep-sound apps and a PyPI REST client. Excellent sound, but not an unused software name. [Source 1](https://apps.apple.com/us/app/drowse-sleep-sounds-mixer/id6760371927) [Source 2](https://play.google.com/store/apps/details?id=be.studio3020.drowse) [Source 3](https://pypi.org/project/drowse/) | -| Unpleat | No obvious exact-name AI/software product found; a real but less common verb. [Source 1](https://en.wiktionary.org/wiki/unpleat) | -| Toneme | An unrelated ToneMe GitHub repository surfaced; the exact PyPI and npm lookups returned 404. [Source 1](https://www.merriam-webster.com/dictionary/toneme) [Source 2](https://github.com/leihuayi/ToneMe/releases) | -| Tepal | No obvious exact-name AI/software product found. The botanical word also permits TEP-uhl. [Source 1](https://www.dictionary.com/browse/tepal) | -| Smidgen | Existing npm IOTA CLI, Go text-editor component, and inventory-management project. Not an unused software name. [Source 1](https://github.com/bitfinexcom/smidgen) [Source 2](https://pkg.go.dev/github.com/sedwards2009/smidgen) [Source 3](https://github.com/Smidgen-Inventory-Management) | -| Unshown | An unrelated UnShown game exists; no obvious exact-name AI workbench found. [Source 1](https://www.collinsdictionary.com/dictionary/english/unshown) [Source 2](https://pix3ldev.itch.io/un-shown) | -| Doline | A less familiar geological word, with a sinkhole association. No obvious exact-name AI/software product found. [Source 1](https://www.collinsdictionary.com/dictionary/english/doline) | -| Scumble | Also a novel title, a Discworld drink, and an established multilabel-learning metric acronym. Distinctive, but the opening sound may be polarizing. [Source 1](https://arxiv.org/abs/1802.05033) [Source 2](https://en.wikipedia.org/wiki/Scumble) | -| Brayer | The exact PyPI name is already a Pydantic desktop-form library. Brayer is also used by an appliance brand and as a surname. [Source 1](https://pypi.org/project/brayer/) [Source 2](https://brayer.ru/) | -| Coving | A common architectural and graphics term; no obvious exact-name AI product found. [Source 1](https://www.sidefx.com/media/uploads/tutorial/H12_%20lessons/Light%20Shade%20Rendering/lsr_m07.pdf) | -| Harebell | No obvious exact-name AI/software product found. Eight letters, but only two familiar syllables. [Source 1](https://www.oxfordlearnersdictionaries.com/definition/english/harebell) | -| Dimity | Existing activity-and-mood diary app and UK consultancy. Exact PyPI and npm lookups returned 404. [Source 1](https://apps.apple.com/au/app/dimity-activity-mood-diary/id6791005508) [Source 2](https://find-and-update.company-information.service.gov.uk/company/15070128) | -| Sculler | Digital Sculler is a content/AI tutorial brand; no obvious exact-name AI workbench found. Sounds like skull-er. [Source 1](https://digitalsculler.com/) | -| Ruddle | An npm SVG-icon collection already uses the exact name. Surname uses also appear. [Source 1](https://www.npmjs.com/package/ruddle) | -| Isobath | The exact PyPI name is already a bathymetry GUI. More technical than the leading names. [Source 1](https://pypi.org/project/isobath/) | -| Mordent | An older music-score authoring tool uses the name. The exact PyPI and npm lookups returned 404. [Source 1](https://dcgi.fel.cvut.cz/en/theses/2013/rejthedv/) | -| Shimmery | No obvious exact-name AI/software product found. Eight letters and less technical than the other choices. | - -## Rejected despite attractive names - -- **Lenslet** — an existing image-inspection Python product occupies the same general developer-tool space. -- **Coaxer** — an existing prompt-generation Python package is too close to this project. -- **Sidelong** — an active AI research and writing product. -- **Chervil** — an active agentic browser. -- **Frisket** — existing AI spreadsheet, SQL verification, and macOS software uses. -- **Unbraid** — a software and AI consultancy. -- **Unshade** — existing AI and software products. -- **Dappled** — a game-software brand and a trademark-record hit; excluded without making a legal judgment. -- **Dunlin** — an established AI accounting brand; excluded even though the registrar scan returned AVAILABLE. -- **Dittany** — an existing dynamic information-flow analysis tool, an unnecessarily close conceptual overlap. - -## Evidence files - -- [Final 20 with price, time, registry and package results](domain-name-shortlist-2026-09-05.csv) -- [All 594 unique exact-domain checks](domain-name-screening-2026-09-05.csv) -- [Raw final registrar response plus independent checks](domain-registrar-evidence-2026-09-05.json) - -Availability came from live registrar results, not search-engine absence, DNS absence, or older research. No pending result was counted as available. The public search links rerun the search and may show a changed status later. diff --git a/DOMAIN_NAME_SHORTLIST_2026-09-05_COGNITION.md b/DOMAIN_NAME_SHORTLIST_2026-09-05_COGNITION.md deleted file mode 100644 index 06bd63ec..00000000 --- a/DOMAIN_NAME_SHORTLIST_2026-09-05_COGNITION.md +++ /dev/null @@ -1,90 +0,0 @@ -# 20 short names for the model-internals workbench - -My strongest choices are **Nitore**, **Sisin**, **Asomar**, and **Unskein**. Nitore has the best balance of sound and purpose; Sisin is the shortest and most literal; Asomar is the warmest visual metaphor; Unskein is the strongest English metaphor. - -The naming brief was grounded in the current README and architecture: local model exploration, activation steering, concept poles, manifolds, per-token readouts, and branching conversations. The ranking favors pronounceability, meaning, visual simplicity, and distinctiveness. All 20 are existing words, five to eight letters long, with no hyphens or added suffixes. They do not repeat any of the 90 names in the three earlier September 5 shortlists. None occur in the two older broad candidate CSV inventories either. - -Checked 639 unique exact .ai domains in this pass. All 639 reached a resolved registrar status; 190 were AVAILABLE. The final 20 were then checked again together at **2026-09-05T22:21:02.871842+00:00**, or **6:21 p.m. EDT on September 5, 2026**. Every final domain returned **AVAILABLE**, registration type, **premium=0**, with no pending result. Each was independently corroborated by an HTTP 404 from the .ai registry RDAP service. - -Every final quote was **US$82.70 per year for registration and renewal**. The mandatory two-year initial term therefore gives **US$165.40 before tax**, calculated from the annual quote. Renewals also require at least two years, currently the same calculated amount. No checkout total was obtained. [Porkbun .ai minimum term and pricing](https://porkbun.com/tld/ai). Availability and quotes can change. - -Pronunciations are approximate English reading guides; they do not capture every sound distinction in the source languages. The meanings are sourced; connections to model internals are editorial metaphors. - -| # | Name / purchase search | Pronunciation | Origin and meaning | Why it fits | -|---:|---|---|---|---| -| 1 | [Nitore — nitore.ai](https://porkbun.com/checkout/search?q=nitore.ai) | nee-TOH-reh | Italian: [Clarity, brilliance, polish.](https://www.treccani.it/vocabolario/nitore/) | A precise, elegant name for making model internals intelligible. | -| 2 | [Sisin — sisin.ai](https://porkbun.com/checkout/search?q=sisin.ai) | SEE-sin | Finnish: [Innermost.](https://en.wiktionary.org/wiki/sisin) | The shortest, most direct expression of looking inside a model. | -| 3 | [Asomar — asomar.ai](https://porkbun.com/checkout/search?q=asomar.ai) | ah-soh-MAR | Spanish: [To appear or come into view.](https://www.larousse.com/en/dictionaries/spanish-english/asomar/3441) | Hidden patterns becoming visible through probes and readouts. | -| 4 | [Unskein — unskein.ai](https://porkbun.com/checkout/search?q=unskein.ai) | un-SKAYN | English: [To unwind a skein; to unfurl.](https://en.wiktionary.org/wiki/unskein) | Untangling distributed representations into understandable threads. | -| 5 | [Merism — merism.ai](https://porkbun.com/checkout/search?q=merism.ai) | MAIR-iz-um | English, from Greek: [A whole expressed through contrasting parts, such as high and low.](https://en.wiktionary.org/wiki/merism) | An unusually close match to concept poles and the space between them. | -| 6 | [Svelare — svelare.ai](https://porkbun.com/checkout/search?q=svelare.ai) | zveh-LAH-reh | Italian: [To reveal or unveil.](https://dictionary.cambridge.org/dictionary/italian-english/svelare) | A direct statement of the interpretability mission. | -| 7 | [Ricalco — ricalco.ai](https://porkbun.com/checkout/search?q=ricalco.ai) | ree-KAHL-koh | Italian: [Tracing or a copy produced by tracing.](https://www.treccani.it/vocabolario/ricalco/) | Following the outlines and paths of internal model behavior. | -| 8 | [Deuten — deuten.ai](https://porkbun.com/checkout/search?q=deuten.ai) | DOY-tuhn | German: [To interpret or read signs.](https://dictionary.cambridge.org/dictionary/german-english/deuten) | Turning hidden measurements into something understandable. | -| 9 | [Falte — falte.ai](https://porkbun.com/checkout/search?q=falte.ai) | FAHL-tuh | German: [A fold, crease, or wrinkle.](https://www.collinsdictionary.com/dictionary/german-english/falte) | A simple geometric image for folded representation spaces. | -| 10 | [Punoa — punoa.ai](https://porkbun.com/checkout/search?q=punoa.ai) | POO-noh-ah | Finnish: [To weave or plait.](https://livingdictionaries.app/finnish/entry/80b77ce8-860d-42b3-8d8c-6b1080623ea2) | Composing steering directions and following the model's intertwined features. | -| 11 | [Havaita — havaita.ai](https://porkbun.com/checkout/search?q=havaita.ai) | HAH-vy-tah | Finnish: [To perceive, observe, detect, or notice.](https://en.wiktionary.org/wiki/havaita) | Almost a definition of what the probing instruments let you do. | -| 12 | [Udito — udito.ai](https://porkbun.com/checkout/search?q=udito.ai) | oo-DEE-toh | Italian: [Hearing; the sense of hearing.](https://www.collinsdictionary.com/dictionary/italian-english/udito) | A metaphor for listening to otherwise inaccessible internal signals. | -| 13 | [Skimte — skimte.ai](https://porkbun.com/checkout/search?q=skimte.ai) | SHIM-teh | Norwegian: [To glimpse or discern faintly.](https://dictionary.cambridge.org/dictionary/norwegian-english/skimte) | Catching a glimpse of the hidden activity behind an answer. | -| 14 | [Ordire — ordire.ai](https://porkbun.com/checkout/search?q=ordire.ai) | or-DEE-reh | Italian: [To set up the warp of a fabric; also to weave or plot.](https://www.treccani.it/vocabolario/ordire/) | Preparing the threads from which model behavior is composed. | -| 15 | [Risvolto — risvolto.ai](https://porkbun.com/checkout/search?q=risvolto.ai) | reez-VOHL-toh | Italian: [A turned-back fold; figuratively, a less visible aspect or implication.](https://www.treccani.it/vocabolario/risvolto_%28Sinonimi-e-Contrari%29/) | Revealing the other side of a model response. | -| 16 | [Rimple — rimple.ai](https://porkbun.com/checkout/search?q=rimple.ai) | RIM-puhl | English: [A fold, wrinkle, or ripple.](https://www.merriam-webster.com/dictionary/rimple) | Small changes moving through a curved internal landscape. | -| 17 | [Retazo — retazo.ai](https://porkbun.com/checkout/search?q=retazo.ai) | reh-TAH-soh | Spanish: [A fragment, remnant, or snippet.](https://www.spanishdict.com/translate/el%20retazo?langFrom=es) | Small pieces of activity used to understand a larger representation. | -| 18 | [Venula — venula.ai](https://porkbun.com/checkout/search?q=venula.ai) | VEN-yoo-lah | Latin-derived anatomical word: [A small vein.](https://en.wiktionary.org/wiki/venula) | An organic metaphor for pathways and flows inside a complex system. | -| 19 | [Wispish — wispish.ai](https://porkbun.com/checkout/search?q=wispish.ai) | WIS-pish | English: [Resembling a wisp; wispy.](https://www.merriam-webster.com/dictionary/wispish) | Faint, fleeting patterns becoming visible in a live model. | -| 20 | [Purling — purling.ai](https://porkbun.com/checkout/search?q=purling.ai) | PUR-ling | English: [Knitting in purl stitch; also softly murmuring or flowing.](https://www.merriam-webster.com/dictionary/purl) | Connects the project's threads with its continuous stream of activations. | - -## How I would choose - -- **Nitore:** the most polished general product name; suggests clarity without binding the project to one mechanism. -- **Sisin:** a compact identity built around the innermost layer. Particularly good for a tool centered on hidden states. -- **Asomar:** a welcoming name for the visual interface and the act of discovery. -- **Unskein:** a concrete English verb for teasing apart intertwined representations. Less familiar spelling is its main tradeoff. -- **Merism:** the strongest conceptual match to bipolar concept geometry, with a more scholarly tone. - -## Existing-use screen and tradeoffs - -This is a bounded web/package screen, not trademark clearance. All final exact PyPI lookups returned 404. Nineteen exact npm lookups returned 404; Rimple already has an npm package. Domain availability does not establish exclusive name rights. - -| Name | Naming tradeoff | Existing-use observation | -|---|---|---| -| Nitore | Best overall balance of sound, brevity, and purpose. | No obvious exact-name AI/software product surfaced in the bounded web screen. Surname and account-name uses exist. | -| Sisin | Five letters, two syllables, and an unusually exact thematic fit. | SISIN also appears as an acronym for a Bolivian public-investment information system; no exact-name AI workbench surfaced. [Source](https://www.contraloria.gob.bo/wp-content/uploads/2025/03/GATIC-AUD-2024-001.pdf) | -| Asomar | Warm and spacious; especially suited to a visual exploration product. | Existing communications consultancy and maritime-association uses. No exact-name AI workbench surfaced. [Source](https://asomar.es/en/elementor-1425/) | -| Unskein | Strongest English metaphor; spelling is less familiar than its sound. | No obvious exact-name software product surfaced; literary uses exist. | -| Merism | Most conceptually specific; a little more academic than the first four. | A community-oriented landing page and company-directory entries use Merism. No exact-name AI workbench surfaced. [Source](https://merism.org/) | -| Svelare | Elegant and active; the initial sv sound needs one introduction for English speakers. | No obvious exact-name AI/software product surfaced in the bounded web screen. | -| Ricalco | Crisp, rhythmic, and more instrument-like in tone. | Ricalco appears descriptively in drawing-software titles; no clear standalone exact-name AI brand surfaced. [Source](https://apps.apple.com/it/app/ar-drawing-schizzo-ricalco/id6760111809) | -| Deuten | Compact and serious; eu is pronounced oy in German. | No obvious exact-name AI/software product surfaced in the bounded web screen. | -| Falte | Five letters and two syllables; a strong geometric identity. | Common word and surname uses; no exact-name AI/software brand surfaced in the bounded screen. | -| Punoa | Soft, distinctive, and only five letters. | Also a place name and surname; no obvious exact-name AI/software product surfaced. [Source](https://en.wikipedia.org/wiki/Punoa) | -| Havaita | A precise perception word with a clear three-syllable rhythm. | No obvious exact-name AI/software product surfaced in the bounded web screen. | -| Udito | Short, warm, and immediately speakable. | An unrelated hearing-care clinic uses Udito. [Source](https://www.udito.pl/) | -| Skimte | Compact and distinctive; Norwegian ski here sounds like shi. | No obvious exact-name AI/software product surfaced in the bounded web screen. | -| Ordire | Memorable and purposeful; the plotting sense is a tonal consideration. | No obvious exact-name AI/software product surfaced; the ordinary word also means to hatch a plot. | -| Risvolto | The longest option at eight letters, but a strong three-syllable word. | Existing fashion/boutique usage; no obvious exact-name AI/software product surfaced. [Source](https://it.wikipedia.org/wiki/Risvolto) | -| Rimple | One of the easiest to say; playful and tactile. | The exact npm name is already a JavaScript library. Kept as a domain-available option, with a developer-namespace collision. [Source](https://github.com/xiechao06/rimple) | -| Retazo | Strong consonants and a clear three-syllable rhythm; guide uses Latin American pronunciation. | Existing design/retail uses and Retazo Digital, a web/app-services brand. [Source](https://bucle.io/servicios/) | -| Venula | Soft and biological; less literal about AI than the leading names. | Personal-name uses surfaced; no obvious exact-name AI/software product. | -| Wispish | Light and memorable; more atmospheric than technical. | No obvious exact-name AI/software product surfaced in the bounded web screen. | -| Purling | Gentle, tactile, and familiar to say. | Purling is an established luxury chess/art-games brand; no exact-name AI workbench surfaced. [Source](https://www.purlingartgames.com/our-story) | - -## Available domains excluded after the existing-use screen - -- **Kuulto:** an existing AI terminal and developer-tools brand. [Source](https://kuulto.app/company). -- **Katse:** already used for AI-based advertising attention measurement. [Source](https://www.karkimedia.fi/en/display-advertising-reporting/). -- **Ajatus:** an established software/AI services company. [Source](https://www.ajatus.in/about-us/). -- **Plica:** existing AI and software products. [Source](https://plica.studio/). -- **Latebra:** an existing MCP tool for AI agents. [Source](https://github.com/evandrodevbr/latebra). -- **Lucarne:** an existing browser-control developer tool. [Source](https://pypi.org/project/lucarne/). -- **Sutil:** an existing F# frontend framework. [Source](https://sutil.dev/). -- **Portato:** an existing tool for inspecting local servers started by coding agents. [Source](https://github.com/kwakseongjae/portato). -- **Filose:** existing language/NLP services. [Source](https://www.filose.com/natural-language-processing-services/). -- **Atinar:** an existing AI consultancy. [Source](https://atinargroup.com/about). - -## Evidence - -- [Final 20 with prices, sources, and purchase links](domain-name-shortlist-2026-09-05-cognition.csv) -- [Raw final registrar response and independent checks](domain-registrar-evidence-2026-09-05-cognition.json) -- [All 639 resolved registrar checks](domain-name-screening-2026-09-05-cognition.csv) - -No domains were purchased or added to a shopping cart. diff --git a/DOMAIN_NAME_SHORTLIST_2026-09-05_ROUND_2.md b/DOMAIN_NAME_SHORTLIST_2026-09-05_ROUND_2.md deleted file mode 100644 index 46d8cd99..00000000 --- a/DOMAIN_NAME_SHORTLIST_2026-09-05_ROUND_2.md +++ /dev/null @@ -1,55 +0,0 @@ -# 20 more real-word .ai names — 5 September 2026 - -My strongest choices are **Puckish**, **Underlit**, **Unmuffle**, and **Retint**. The first has the most personality; the others connect more directly to interpreting and steering model behavior. - -Screened **799 new exact .ai domains** across conversational language, texture/light, food, temperament, animals, revealing/tuning, cognition, and nature. Of those, 144 returned AVAILABLE; the final 20 were selected for sound, spelling, meaning, and project fit. Each is six to eight letters, a real dictionary word (including ordinary inflected words), and absent from the previous 20-name shortlist. - -All 20 returned **AVAILABLE**, **registration**, **premium: 0**, with **pending: 0**, in the final Porkbun check at **2026-09-05 15:45:52 UTC (11:45:52 a.m. EDT)**. Each also returned HTTP 404 from the official .ai RDAP service and from its exact PyPI and npm package endpoint. These are observations at check time, not reservations or guaranteed namespace availability. - -Porkbun showed **US$82.70/year** for both registration and renewal. .ai requires a **two-year minimum** for both: budget **about US$165 upfront before tax**. Twice the displayed annual price is $165.40; actual checkout rounding/fees may differ. The $165.09 transfer price is not treated as a confirmed registration checkout total. [Registrar pricing and term](https://porkbun.com/tld/ai). - -| # | Name / exact domain | Pronunciation | Brand appeal | -|---|---|---|---| -| 1 | [puckish.ai](https://porkbun.com/checkout/search?q=puckish.ai) | PUCK-ish | Mischievous and playful; a strong match for experimenting with model personalities. | -| 2 | [underlit.ai](https://porkbun.com/checkout/search?q=underlit.ai) | UN-der-lit | Light beneath the surface; an evocative metaphor for inspecting model internals. | -| 3 | [unmuffle.ai](https://porkbun.com/checkout/search?q=unmuffle.ai) | un-MUFF-ul | Free hidden signals from what obscures them; the clearest interpretability metaphor. | -| 4 | [retint.ai](https://porkbun.com/checkout/search?q=retint.ai) | ree-TINT | Change the shade of something; a compact metaphor for steering model behavior. | -| 5 | [uncoiled.ai](https://porkbun.com/checkout/search?q=uncoiled.ai) | un-KOYLD | Complex structure opened out so it can be explored. | -| 6 | [intoned.ai](https://porkbun.com/checkout/search?q=intoned.ai) | in-TOHND | Voice, tone, and expression; a natural association with language. | -| 7 | [unlaced.ai](https://porkbun.com/checkout/search?q=unlaced.ai) | un-LAYST | Opened and loosened; tactile, memorable, and easy to spell. | -| 8 | [fancied.ai](https://porkbun.com/checkout/search?q=fancied.ai) | FAN-seed | Imagined possibilities; creative and slightly whimsical. | -| 9 | [honeyed.ai](https://porkbun.com/checkout/search?q=honeyed.ai) | HUN-eed | A warm, pleasant voice; particularly apt for tone and persona steering. | -| 10 | [brambly.ai](https://porkbun.com/checkout/search?q=brambly.ai) | BRAM-blee | Tangled, branching growth; a visual identity for exploring branching conversations. | -| 11 | [fernery.ai](https://porkbun.com/checkout/search?q=fernery.ai) | FUR-nuh-ree | A place where ferns grow; a quiet, organic name with strong visual possibilities. | -| 12 | [hazily.ai](https://porkbun.com/checkout/search?q=hazily.ai) | HAY-zih-lee | Half-visible patterns and uncertain impressions; soft and atmospheric. | -| 13 | [dozing.ai](https://porkbun.com/checkout/search?q=dozing.ai) | DOH-zing | Dormant potential and dreamlike states; gentle and easy to remember. | -| 14 | [riverlet.ai](https://porkbun.com/checkout/search?q=riverlet.ai) | RIV-er-let | A little river; a natural metaphor for branching streams of generation. | -| 15 | [dimpled.ai](https://porkbun.com/checkout/search?q=dimpled.ai) | DIM-puld | Small contours in a surface; friendly, tactile, and suggestive of geometry. | -| 16 | [wafting.ai](https://porkbun.com/checkout/search?q=wafting.ai) | WAF-ting | Gentle movement in a direction; a soft metaphor for activation steering. | -| 17 | [satiny.ai](https://porkbun.com/checkout/search?q=satiny.ai) | SAT-in-ee | Smooth and tactile; a polished, approachable brand. | -| 18 | [wittily.ai](https://porkbun.com/checkout/search?q=wittily.ai) | WIT-ih-lee | Clever expression; an upbeat name for a language-focused tool. | -| 19 | [giddily.ai](https://porkbun.com/checkout/search?q=giddily.ai) | GID-ih-lee | Excitement and discovery; playful and buoyant. | -| 20 | [blithely.ai](https://porkbun.com/checkout/search?q=blithely.ai) | BLYTHE-lee | Carefree and cheerful; a light, literary personality. | - -## Existing uses and meaning tradeoffs - -The associations in the table are naming judgments, not technical claims or dictionary definitions. The CSV links to dictionary entries. Domain availability is not trademark clearance. - -- **Underlit:** Exact title of a small 2024 game-jam game. This is an existing software use. [Source 1](https://mathix94.itch.io/underlit) -- **Uncoiled:** Also used as a music release title and in mathematical terminology; no exact software brand surfaced in the limited search. [Source 1](https://arxiv.org/abs/2302.12782) -- **Honeyed:** Existing creative studio name and adjective in the app title Honeyed Legends Myths. Its literal meaning can also imply insincere sweetness. [Source 1](https://thehoneyedcollective.com/honeyed-studios/) [Source 2](https://apps.apple.com/hk/app/honeyed-legends-myths/id6761210848) -- **Brambly:** Strong association with Brambly Hedge, a children's book series. No exact standalone software brand surfaced in the limited search. -- **Hazily:** Has a deliberate ambiguity/uncertainty connotation. No exact software brand surfaced in the limited search. [Source 1](https://www.oxfordlearnersdictionaries.com/us/definition/english/hazily) -- **Dimpled:** Existing technical phrase Dimpled Manifold Model in ML research; this is not an exact standalone product-name match. [Source 1](https://arxiv.org/abs/2106.10151) -- **Blithely:** Can mean cheerfully or carelessly; pronunciation has a voiced th. No exact software brand surfaced in the limited search. [Source 1](https://www.oxfordlearnersdictionaries.com/us/definition/english/blithely) - -I excluded several otherwise attractive available domains after the software-use screen: **Starglow** (stargazing app and AI/music platform), **Airily** (software company), **Detune** (music-software company), **Cutwork** (AI video platform and embroidery software), **Nearish** (several apps), **Spiffing** (PyPI/npm packages and software services), **Waggish** (npm package), **Semolina** (Python data-warehouse package), **Offcuts** (cut-planning software), and **Coyly** (beauty brand with an AI diagnostic product). This is a lightweight screen, not a comprehensive brand or legal search. - -## Evidence files - -- [Shortlist CSV](domain-name-shortlist-2026-09-05-round-2.csv) -- [799-domain screening CSV](domain-name-screening-2026-09-05-round-2.csv) -- [Raw registrar responses and registry/package observations](domain-registrar-evidence-2026-09-05-round-2.json) - -No domains were added to a cart or purchased. - diff --git a/DOMAIN_NAME_SHORTLIST_2026-09-05_ROUND_3.md b/DOMAIN_NAME_SHORTLIST_2026-09-05_ROUND_3.md deleted file mode 100644 index 79c4f167..00000000 --- a/DOMAIN_NAME_SHORTLIST_2026-09-05_ROUND_3.md +++ /dev/null @@ -1,100 +0,0 @@ -# Naming shortlist: round 3 - -My strongest five: Lunomi, Nimela, Quiet Tide, Inner Vale, and Domaso. - -All 50 exact .ai domains returned AVAILABLE for new registration, with premium=0 and pending=0, in the final Porkbun check retrieved at 2026-09-05T22:04:16.175Z. All 50 also returned HTTP 404 from the .ai registry RDAP endpoint and the exact-name PyPI and npm package endpoints. RDAP is corroboration; the registrar result is the availability evidence. - -Each quoted registration and renewal price was US$82.70 per year. Porkbun requires a two-year minimum, so US$165.40 is the two-year amount calculated from the annual quote, before tax or checkout adjustments. No checkout total was obtained. [Porkbun .ai pricing and minimum term](https://porkbun.com/tld/ai). - -The ranking is an editorial judgment for this project: easy speech, visual potential, and a warm name for a language-model exploration and steering tool. The list includes 12 sound-led names, 10 place names, and 28 English compounds. Sound-led names are not claimed as first-ever coinages, and no foreign-language translations are invented. Pronunciations are approximate English reading guides. - -## The 50 names - -| # | Name / domain check | Say it roughly | Why I would consider it | -|---:|---|---|---| -| 1 | [Lunomi](https://porkbun.com/checkout/search?q=lunomi.ai) | loo-NOH-mee | Soft, memorable, and slightly lunar; my strongest overall pick. | -| 2 | [Nimela](https://porkbun.com/checkout/search?q=nimela.ai) | nih-MEL-ah | Gentle and compact; works equally well for an app or a library. | -| 3 | [Quiet Tide](https://porkbun.com/checkout/search?q=quiettide.ai) | quiet tide | A natural metaphor for subtly steering a model’s behavior. | -| 4 | [Inner Vale](https://porkbun.com/checkout/search?q=innervale.ai) | inner vale | Suggests an interior landscape waiting to be explored. | -| 5 | [Domaso](https://porkbun.com/checkout/search?q=domaso.ai) | DOH-mah-zoh | A Lake Como village name with a warm, unhurried sound. [Origin](https://www.northlakecomo.net/uploads/EnTravelguide-upload.pdf). | -| 6 | [Somori](https://porkbun.com/checkout/search?q=somori.ai) | soh-MOR-ee | Rounded and restful; has the feel of a small creative studio. | -| 7 | [Open Fern](https://porkbun.com/checkout/search?q=openfern.ai) | open fern | Unfolding structure; a good image for making hidden things visible. | -| 8 | [Paper Tide](https://porkbun.com/checkout/search?q=papertide.ai) | paper tide | Language in motion; literary without sounding academic. | -| 9 | [Lumella](https://porkbun.com/checkout/search?q=lumella.ai) | loo-MEL-ah | Luminous and melodic; especially strong as a visual identity. | -| 10 | [Silver Moss](https://porkbun.com/checkout/search?q=silvermoss.ai) | silver moss | Soft nature imagery with a slight metallic, technical edge. | -| 11 | [Norali](https://porkbun.com/checkout/search?q=norali.ai) | nor-AH-lee | Airy, balanced, and easy to use in ordinary conversation. | -| 12 | [Ostuni](https://porkbun.com/checkout/search?q=ostuni.ai) | os-TOO-nee | An Italian town name; crisp, sunny, and distinctive. [Origin](https://www.italia.it/en/puglia/brindisi/ostuni). | -| 13 | [Kind Muse](https://porkbun.com/checkout/search?q=kindmuse.ai) | kind muse | Warm and creative; a good fit for shaping model personality. | -| 14 | [Soft Current](https://porkbun.com/checkout/search?q=softcurrent.ai) | soft current | Subtle influence and continuous flow; closely fits steering. | -| 15 | [Moon Cove](https://porkbun.com/checkout/search?q=mooncove.ai) | moon cove | A quiet place to explore; compact and visually evocative. | -| 16 | [Nolemi](https://porkbun.com/checkout/search?q=nolemi.ai) | noh-LEM-ee | Friendly and fluid; could support a personable little mascot. | -| 17 | [Clear Meadow](https://porkbun.com/checkout/search?q=clearmeadow.ai) | clear meadow | Open terrain and visibility; a gentle interpretability metaphor. | -| 18 | [Siluna](https://porkbun.com/checkout/search?q=siluna.ai) | sih-LOO-nah | Smooth and moonlike; graceful when spoken aloud. | -| 19 | [Light Grove](https://porkbun.com/checkout/search?q=lightgrove.ai) | light grove | A branching space illuminated from within. | -| 20 | [Roseto](https://porkbun.com/checkout/search?q=roseto.ai) | roh-ZEH-toh | From Roseto degli Abruzzi; rounded, warm, and elegant. [Origin](https://www.visitroseto.it/en/discover/). | -| 21 | [Soft Moss](https://porkbun.com/checkout/search?q=softmoss.ai) | soft moss | Tactile and welcoming; easy to remember after hearing once. | -| 22 | [Gold Fern](https://porkbun.com/checkout/search?q=goldfern.ai) | gold fern | Simple, bright, and easy to turn into a recognizable symbol. | -| 23 | [Enoli](https://porkbun.com/checkout/search?q=enoli.ai) | eh-NOH-lee | Short, flowing, and adaptable beyond the initial product. | -| 24 | [Blue Hollow](https://porkbun.com/checkout/search?q=bluehollow.ai) | blue hollow | Hidden depth; a strong fit for an exploratory visual interface. | -| 25 | [Fable Cove](https://porkbun.com/checkout/search?q=fablecove.ai) | fable cove | A small home for language, stories, and different voices. | -| 26 | [Bormio](https://porkbun.com/checkout/search?q=bormio.ai) | BOR-myoh | An Italian Alpine town name; compact and sturdy. [Origin](https://www.bormio.eu/en). | -| 27 | [Amber Muse](https://porkbun.com/checkout/search?q=ambermuse.ai) | amber muse | Warm color and creative influence; polished without being cold. | -| 28 | [Sorumi](https://porkbun.com/checkout/search?q=sorumi.ai) | soh-ROO-mee | A soft, rhythmic name with a friendly character. | -| 29 | [Ponza](https://porkbun.com/checkout/search?q=ponza.ai) | PON-tsah | An Italian island name; short, lively, and distinctive. [Origin](https://www.visitponza.it/en/discover-ponza-2/). | -| 30 | [Mellow Tide](https://porkbun.com/checkout/search?q=mellowtide.ai) | mellow tide | Relaxed movement; approachable and pleasant to say. | -| 31 | [Moon Moss](https://porkbun.com/checkout/search?q=moonmoss.ai) | moon moss | A slightly strange natural image with strong visual potential. | -| 32 | [Tameli](https://porkbun.com/checkout/search?q=tameli.ai) | tah-MEL-ee | Gentle consonants and a clear three-syllable rhythm. | -| 33 | [Still Cove](https://porkbun.com/checkout/search?q=stillcove.ai) | still cove | A calm workspace; quiet and self-contained. | -| 34 | [Light Moss](https://porkbun.com/checkout/search?q=lightmoss.ai) | light moss | Small points of illumination; delicate and unusual. | -| 35 | [Tropea](https://porkbun.com/checkout/search?q=tropea.ai) | troh-PEH-ah | A Calabrian town name; flowing and sunlit. [Origin](https://calabriastraordinaria.it/en/destinations/tropea-the-pearl-of-the-tyrrhenian-sea). | -| 36 | [Fable Fern](https://porkbun.com/checkout/search?q=fablefern.ai) | fable fern | Language and unfolding forms; playful alliteration. | -| 37 | [Norumi](https://porkbun.com/checkout/search?q=norumi.ai) | noh-ROO-mee | Rounded and companionable; good for a personable product. | -| 38 | [Silver Glow](https://porkbun.com/checkout/search?q=silverglow.ai) | silver glow | Illumination with a restrained, slightly futuristic feel. | -| 39 | [Bloom Cove](https://porkbun.com/checkout/search?q=bloomcove.ai) | bloom cove | A sheltered place for ideas and personalities to develop. | -| 40 | [Locarno](https://porkbun.com/checkout/search?q=locarno.ai) | loh-KAR-noh | A Swiss lakeside city name; established and substantial. [Origin](https://www.ascona-locarno.com/en/explore/locarno). | -| 41 | [Gentle Tide](https://porkbun.com/checkout/search?q=gentletide.ai) | gentle tide | Small, deliberate changes; an intuitive steering association. | -| 42 | [Moss Lane](https://porkbun.com/checkout/search?q=mosslane.ai) | moss lane | A path through something living; grounded and approachable. | -| 43 | [Ikumi](https://porkbun.com/checkout/search?q=ikumi.ai) | ee-KOO-mee | Compact and rhythmic; friendly enough for everyday use. | -| 44 | [Fable Moon](https://porkbun.com/checkout/search?q=fablemoon.ai) | fable moon | Dreamlike and literary; broad room for a visual identity. | -| 45 | [Varallo](https://porkbun.com/checkout/search?q=varallo.ai) | vah-RAHL-loh | A Piedmont town name; melodic, with a confident ending. [Origin](https://www.italia.it/en/piedmont/varallo). | -| 46 | [Mist Lake](https://porkbun.com/checkout/search?q=mistlake.ai) | mist lake | Hidden depth gradually becoming visible. | -| 47 | [Bright Muse](https://porkbun.com/checkout/search?q=brightmuse.ai) | bright muse | Clear, optimistic, and immediately easy to understand. | -| 48 | [Posada](https://porkbun.com/checkout/search?q=posada.ai) | poh-SAH-dah | A Sardinian village name; welcoming and easy to say. [Origin](https://www.sardegnaturismo.it/en/explore/posada?language=en-gb). | -| 49 | [Merry Bloom](https://porkbun.com/checkout/search?q=merrybloom.ai) | merry bloom | Cheerful and playful; suited to a less formal product voice. | -| 50 | [Sulmona](https://porkbun.com/checkout/search?q=sulmona.ai) | sool-MOH-nah | An Abruzzo town name; sonorous and distinctive. [Origin](https://turismo.comune.sulmona.aq.it/). | - -## Existing-use notes - -Availability does not establish exclusive rights to a name. Searches screened for obvious AI/software product collisions, but were bounded, and the shortlist includes existing words, place names, personal names, and unrelated commercial uses. The following observations identify remaining naming considerations; no legal trademark assessment was performed. - -| Name | Observation | -|---|---| -| Lunomi | Existing musician/creator use and an unrelated Polish trading company. [Source](https://ko-fi.com/lunomi/). | -| Inner Vale | Existing fictional-place uses and company names. [Source](https://www.innervale.com/). | -| Open Fern | Existing company-directory use. [Source](https://www.lgr.co.uk/Directory/?letter=F). | -| Paper Tide | Name appears as a customer/example business on an AI-email-marketing site; existence of a separate active company not established. [Source](https://hiremara.com/). | -| Lumella | Existing beauty-store and diagnostic-brand uses; domain availability does not establish exclusive name rights. [Source](https://lumella.net/). | -| Moon Cove | Existing Minecraft-server and production-company uses. [Source](https://rsq.productions/privacy-policy/). | -| Nolemi | Appears as a user-created character name on an AI platform, not as the platform brand. [Source](https://shapes.inc/nolemi). | -| Siluna | Existing music and lighting-product uses; siluna.world also has a landing page. [Source](https://siluna.world/). | -| Light Grove | Existing fictional location in Enderal. [Source](https://wiki.en.sureai.net/Enderal%3ALightgrove). | -| Gold Fern | Existing real-estate and mining-consulting uses. [Source](https://www.goldfern.com.au/). | -| Enoli | Existing corporate-services organization and personal-name uses. [Source](https://enoli.net/). | -| Amber Muse | Existing jewelry brand. [Source](https://ambermuse.lt/). | -| Mellow Tide | Existing musician use and trademark-journal mentions; legal scope not assessed. [Source](https://music.apple.com/us/artist/mellowtide/1768055740). | -| Moon Moss | Food-product trademark use surfaced; legal status/scope not assessed. [Source](https://ttabvue.uspto.gov/ttabvue-92091396-CAN-1.pdf). | -| Still Cove | An exact-name trademark application surfaced for an e-commerce company; legal scope not assessed. [Source](https://trademarks.justia.com/983/52/stillcove-98352747.html). | -| Fable Fern | Existing bookshop and invitation-studio uses. [Source](https://www.fablefernbookshop.com/pages/contact-us). | -| Norumi | Existing cat-related shop use. [Source](https://heynorumi.com/). | -| Silver Glow | Existing typeface and music uses. [Source](https://www.myfonts.com/collections/silverglow-font-balpirick/). | -| Bloom Cove | Existing online-store uses. [Source](https://www.merchantgenius.io/shop/url/bloomcove.shop). | -| Gentle Tide | Existing retreat-business use. [Source](https://linktr.ee/gentletide). | -| Mist Lake | Existing Codex color-theme name. [Source](https://www.dexthemes.com/mistlake/dark). | -| Bright Muse | Japanese company name surfaced in a commercial-disclosure page; business type not resolved. [Source](https://utage-system.com/p/kMKZthBOukj5). | - -## Evidence files - -- [Spreadsheet-friendly shortlist](domain-name-shortlist-2026-09-05-round-3.csv) -- [Raw final registrar response](domain-registrar-evidence-2026-09-05-round-3.json) -- [RDAP, PyPI, and npm checks](domain-name-registry-checks-2026-09-05-round-3.json) -- [Ranked recommendations and origin sources](domain-name-recommendations-2026-09-05-round-3.json) diff --git a/README.md b/README.md index 8372e513..f1805285 100644 --- a/README.md +++ b/README.md @@ -36,16 +36,34 @@ drowse serve google/gemma-3-4b-it --device cuda ## Hosted browser edition status The repository includes an isolated Svelte PWA for the on-device WebGPU -edition. This Drowse checkout is a preview: its renamed runtime and distribution -locks remain `feasibility-required`, so one-click model installation is not enabled. +edition. The runtime and distribution locks are `verified`, enabling installation +from the signed catalog after the browser's device checks pass. These release +checks do not guarantee that every GPU remains stable under model load. The [published model files](https://huggingface.co/logitsml/drowse-web-catalog) -are available separately; their upload does not establish compatibility with -this preview. Base-model file links appear on the home page without a beta badge. +are available separately; their upload alone does not establish compatibility. +Base-model file links appear on the home page without a beta badge. Gemma PT still has a matched-weight numerical discrepancy; Qwen 3.5 still needs matched-quantization validation. Matching core packs and a signed installation catalog also remain required. J-lens and SAE are optional for base-model setup. The development fixture is deterministic test data, not real inference. +The device check shows the selected GPU vendor and architecture when the browser +exposes them. Its short compute test is not a full model-load stress test. On +Windows, an Intel adapter gets conditional guidance for selecting a dedicated +GPU through the browser's Windows Graphics settings. Two recorded device losses +since the last successful load block further loads on that device profile; +changing models or context length does not bypass that block. Software fallback +adapters remain unsupported, including in remote sessions without hardware WebGPU. + +Windows Chromium on an identified Intel `gen-9` adapter is conservatively blocked +before model loading following a reported GPU-process watchdog hang during +initialization. Other Intel generations retain a warning. Chrome on Windows +ignores WebGPU's `powerPreference`; Drowse cannot enumerate or select a hidden +dedicated GPU. On dual-GPU laptops, copy +`chrome://flags/#force-high-performance-gpu` into Chrome's address bar, enable it, +restart Chrome, and run the device check again. Confirm that the selected adapter +is the dedicated GPU. This changes GPU routing, not the GPU's memory capacity. + The hosted edition keeps prompts, conversations, activations, and fitted artifacts on the device. WebGPU is mandatory for inference; it does not fall back to cloud inference or CPU-only inference. The existing Python server @@ -250,6 +268,11 @@ uv pip install -e ".[dev]" drowse serve MODEL [options] ``` +Repository Python is disabled by default. For a trusted model that requires custom +code, use `DROWSE_TRUST_REMOTE_CODE=1 drowse serve MODEL`; Python callers can +pass `trust_remote_code=True` to `DrowseSession.from_pretrained`. This grants +the model repository permission to execute Python locally. + Common options: | Option | Default | Purpose | @@ -257,7 +280,7 @@ Common options: | `-d`, `--device` | `auto` | `cuda`, `mps`, `cpu`, or automatic selection | | `-q`, `--quantize` | none | `4bit` or `8bit` bitsandbytes quantization on CUDA | | `-p`, `--probes` | `all` | Bundled probe categories, `all`, or `none` | -| `-H`, `--host` | `0.0.0.0` | Bind address | +| `-H`, `--host` | `127.0.0.1` | Bind address; non-loopback requires an API key | | `-P`, `--port` | `8000` | Bind port | | `-S`, `--steer` | none | Default steering expression | | `--top-k-alts` | `0` | Alternative tokens captured at each decode step | @@ -538,7 +561,11 @@ the verbalizable-workspace method of If you use Drowse in published research, please cite the relevant upstream methods alongside the Drowse version and exact model checkpoint you used. -## Issues and security +## Contact, issues, and security + +For questions, feedback, or research inquiries, email +[contact@drowse.ai](mailto:contact@drowse.ai) or use the +[contact form](https://drowse.ai/contact). Please update to the latest Drowse release before filing a bug. Include the model ID, device, dtype or quantization mode, Drowse version, and a minimal reproduction diff --git a/SECURITY.md b/SECURITY.md index 58e344e2..6f350d48 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,6 +5,7 @@ If you've found a security issue in drowse, please report it privately rather than filing a public issue. - **GitHub:** use [private security advisories](https://github.com/a9lim/polythetic/security/advisories/new) +- **Email:** [contact@drowse.ai](mailto:contact@drowse.ai) Please include a description, reproduction steps, affected version, model ID, and whether the server was reachable beyond localhost. Do not include API keys, @@ -15,6 +16,16 @@ private prompts, or credentials in the report. Only the latest release on PyPI receives security fixes. Upgrade before reporting an issue that may already be fixed. +## Known dependency advisory + +As of September 7, 2026, NLTK 3.10.3 has no published fix for +[CVE-2026-81726](https://github.com/advisories/GHSA-8mgp-746c-j5xp). +SAE Lens requires NLTK, so it remains in the Python dependency set. Drowse does +not call the affected NLTK model import/export APIs or use NLTK's `pathsec` as a +sandbox. This limits Drowse's exposure but does not fix the dependency itself. +Do not pass untrusted model-file paths to NLTK APIs in applications embedding +Drowse. Upgrade when a patched NLTK release becomes available. + ## Threat model for `drowse serve` The HTTP server (`drowse serve`) is designed for a single trusted user on a local @@ -23,11 +34,44 @@ should not be exposed directly to the public internet. What it does: -- Optional bearer auth via `--api-key` or `$DROWSE_API_KEY`. If unset, every HTTP - and WebSocket route is open. +- CLI binding defaults to `127.0.0.1`. Non-loopback binds require bearer auth + via `--api-key` or `$DROWSE_API_KEY`. Without a key, HTTP/WS also reject + non-loopback TCP peers, including programmatic `create_app` deployments; + changing the Host header cannot bypass this check. +- Browser API requests and WebSockets must have a valid same origin or an explicit `--cors` + origin, even with a valid key. `--cors '*'` does not authorize arbitrary + API or WebSocket origins. Clients without an Origin header still use normal auth. + Without a key, API Host headers must identify loopback or the ASGI server + address, preventing arbitrary DNS rebinding hosts from gaining access. +- API authentication runs before request-body parsing. HTTP bodies are limited + to 64 MiB, counting received bytes even without Content-Length. Set + `DROWSE_MAX_REQUEST_BYTES` or `create_app(max_request_bytes=...)` to change the + limit; the explicit argument wins. +- The browser dashboard sends its WebSocket credential in the handshake's + `Sec-WebSocket-Protocol` header and negotiates only `drowse.v1` back. Legacy + `?token=` clients remain supported, with tokens removed from the ASGI query + before Uvicorn logs the handshake. Proxies can still log a legacy client's + original URL; use header authentication or redact those query parameters. +- API responses use `Cache-Control: no-store`. The Python dashboard has a + Content Security Policy, blocks framing, omits referrers, disables MIME + sniffing, and denies unused sensitive browser permissions. +- HTTP filesystem failures and wrapped Hugging Face transport errors keep + paths and signed download URLs out of client responses. Full diagnostic + exceptions remain available in local server logs. +- Native WebSocket inputs have a 1 MiB frame limit and a pending budget of 16 + messages / 4 MiB. Stop and disconnect controls do not consume that budget. + Each outbound token/tree queue holds at most 256 events, including pending + thread callbacks; slow consumers are disconnected. Sends time out after + 30 seconds. These limits do not cap model memory or individual output size. - A bounded async session lock serializes generation-facing OpenAI, Ollama, and native requests before they enter the engine; the synchronous session also - rejects generation re-entry. + rejects generation re-entry. HTTP streams start their engine worker only after + acquiring that lock. Blocking inference, token reads, and worker joins run off + the ASGI event loop. Cancellation and send failures retain ownership until + the worker exits; background artifact jobs follow the same rule. +- Native progress streams and JSON progress histories retain at most 256 + recent messages. Thread callbacks are coalesced and completion/error frames + remain deliverable without waiting for a disconnected consumer. - Pydantic validates protocol request bodies; native request models reject unknown fields. - Installed manifold payloads and Drowse-owned fitted artifacts are checked @@ -41,24 +85,62 @@ What it does not do: fitting jobs, or repeated downloads - TLS; use a correctly configured reverse proxy if HTTPS is required - Sandboxing for model code, tokenizers, checkpoints, or downloaded artifacts -- Protection against a bearer token appearing in browser WebSocket query strings - and intermediary logs (the bundled dashboard uses `?token=` because browser - WebSocket APIs cannot set an `Authorization` header) -If untrusted callers need access, add authentication, TLS, request/body limits, +If untrusted callers need access, add authentication, TLS, deployment-specific request limits, rate limits, and process-level isolation outside Drowse. A reverse proxy alone is not a complete isolation boundary. ## Model and checkpoint trust -Drowse resolves Hugging Face configuration and tokenizer metadata with remote-code -support enabled, then avoids custom model code when the architecture is supported -natively by Transformers. Repositories that are not natively supported may execute -their model implementation as well. Treat every model repository as executable -code and load only revisions and publishers you trust. +Model loading disables repository Python by default, including configuration +and tokenizer modules declared through `auto_map`. Models requiring custom +Python must be explicitly trusted: pass `trust_remote_code=True` to +`DrowseSession.from_pretrained` / `load_model`, or set +`DROWSE_TRUST_REMOTE_CODE=1` for a CLI invocation. The environment also accepts +`true`, `yes`, and `on`; an explicit Python `False` overrides it. This opt-in +allows arbitrary Python execution with the process's permissions. Use only +publishers and revisions you trust. Native model implementations remain +preferred when Transformers supports the architecture. + +Metadata-only lens fetches, model-shape/source checks, and offline cache checks +always use `trust_remote_code=False`, regardless of that environment opt-in. An unsupported custom configuration fails closed +on these paths; fetching metadata must not execute repository Python. `drowse pack install /` verifies files declared by the manifold's `manifold.json` integrity map, but integrity is not authorship or safety. Manifold metadata and corpora remain untrusted input; install only from publishers you trust. Provider-owned J-lens and SAE payloads remain in their provider cache and are pinned through local bindings. + +## Local state and conversation imports + +State written through Drowse's atomic JSON/byte helpers uses exclusive, unique +temporary files and publishes with owner-only permissions on POSIX (0600). +Payload data is synced before replacement, followed by a best-effort directory +sync. This prevents predictable staging-file symlink attacks and staging +collisions between writers. It does not encrypt the contents or change the +permissions of untouched older files, parent directories, or external backups. + +`LoomTree.load` accepts at most 64 MiB of main JSON and 256 MiB of decompressed +token-sidecar JSON by default. Both limits apply before parsing; a positive +integer `max_bytes=` explicitly changes both for trusted large exports. +These limits constrain input expansion, not total process memory or compute. +Tree JSON and token sidecars are individually replaced but are not a single +crash-atomic transaction; interrupted overwrites can leave a mismatched pair. + +## Browser data + +Hosted conversations, fitted artifacts, and model downloads are stored locally +in browser storage. They are not encrypted by Drowse. The service worker caches +application assets; it does not cache conversation API responses. Published SAE +descriptions for the verified Gemma Scope 2 packs ship as application assets. +Missing descriptions fall back to Neuronpedia, sending only the public +dictionary/feature identity without cookies, referrers, activation values, or +conversation text. + +"Clear all local data" stops persistence and clears the application's saved +sessions, artifacts, and preferences, including legacy Polythetic/Saklas +databases and files that migration could otherwise restore on reload. Legacy +directory handles remain usable after their contents are removed. A failed deletion is reported and can be +retried; it must not silently report success. Browser profiles, extensions, OS +accounts, and external backups remain outside this deletion boundary. diff --git a/benchmarks/FITTING_SWEEP_2026-07-09.md b/benchmarks/FITTING_SWEEP_2026-07-09.md deleted file mode 100644 index e3b9ae85..00000000 --- a/benchmarks/FITTING_SWEEP_2026-07-09.md +++ /dev/null @@ -1,67 +0,0 @@ -# Fitting optimization sweep evidence — 2026-07-09 - -Comparison base: `1a39e1d` (`perf: optimize manifold and j-lens fitting`). -Candidate: the subsequent fitting sweep that ships this record. Commands used -the repository's Python 3.11 virtualenv. - -Environment: Apple M5 Max, 128 GB unified memory, macOS 27.0, MPS; PyTorch -2.12.1 and Transformers 5.12.1. Process RSS is the OS process-lifetime -high-water mark, so it is reported for the force-fit process only and is not -misrepresented as phase-local cache RSS. - -## Representative J-lens fit - -Workload: cached `google/gemma-3-4b-it`, two 24-token-truncated English corpus -prompts, workspace-band source layers, `dim_batch=8`. The base used its default -one-prompt graph; the candidate used `prompt_batch=2`. Both runs started with a -fresh temporary `DROWSE_HOME` and included durable final artifact writing. - -| tree | wall time | model forwards | process peak RSS | -|---|---:|---:|---:| -| `1a39e1d` | 84.293 s | 2 | 4,161,568,768 B | -| candidate | 49.080 s | 1 | 4,161,404,928 B | - -The candidate is 1.72x faster (41.8% lower wall time), halves model forwards, -and does not increase the process RSS high-water mark. Its immediate exact -repeat took 0.244 s and issued zero model forwards; that repeat includes -token-ID revalidation plus the v2 artifact digest check. - -Reproduction command for the candidate: - -```bash -python scripts/benchmark_fitting.py jlens google/gemma-3-4b-it \ - --corpus benchmarks/fixtures/jlens_prompts.txt --prompts 2 \ - --layers workspace --seq-len 24 --dim-batch 8 --prompt-batch 2 -``` - -## Manifold capture/cache work - -A 20-iteration geometry-only refit microbenchmark used the deterministic -five-node, four-layer extraction fixture. Geometry alternated while corpus, -token IDs, node partition, and loaded weights stayed fixed. - -| tree | wall time | residual-capture forwards | -|---|---:|---:| -| `1a39e1d` | 0.112 s | 20 | -| candidate | 0.111 s | 0 | - -The synthetic wall time is dominated by tiny CPU fit/JSON work and is not a -model-speed proxy; the useful result is the eliminated model work. Regression -tests additionally pin these work contracts: - -- full capture to subset fit: zero forwards and only requested row layers read; -- partial `[1,3]` to full fit: only missing layers `[0,2]` captured; -- geometry-only refit: zero forwards via token-exact activation reuse; -- known-bad OOM batch widths are not retried; -- reusable capture hooks register once per selected layer across forwards; -- auto-curved topology reuses its Fisher bases and retained activation rows. - -The real-model harness also supports forced manifold fits and exact repeats: - -```bash -python scripts/benchmark_fitting.py manifold MODEL MANIFOLD_FOLDER \ - --layers workspace -``` - -Correctness gates for this sweep are recorded in the commit handoff, including -the full non-GPU suite and focused fallback/resume/cache-integrity tests. diff --git a/browser-runtime/BASE_COMPLETION_POLISH_REVIEW.md b/browser-runtime/BASE_COMPLETION_POLISH_REVIEW.md deleted file mode 100644 index 02f8fae0..00000000 --- a/browser-runtime/BASE_COMPLETION_POLISH_REVIEW.md +++ /dev/null @@ -1,69 +0,0 @@ -# Base completion interface polish - -Reviewed 2026-09-05 with `better-interface` (full) and `make-interfaces-feel-better`. This follow-up records only the current interface work; the earlier support and release review remains separate. - -## Scope and Coverage - -Svelte 5, plain CSS, existing semantic colors, Wix Madefor interface type, Martian Mono data type, shared buttons and segmented controls. Scope: the base completion editor, saving/discarding, generation/stopping, sampling controls, token inspection and replacement branches, and missing optional J-lens states. The real model picker’s unavailable-download state was inspected, but base-model installation and inference are outside this UI approval. - -Browser interactions used the development-only `layoutFixture=base` runtime. Its deterministic completion is not model inference. The desktop view and 320px/768px iframe previews were inspected. No deployment, model/compiler change, new comparison feature, dependency, or version bump was made. - -| Domain | Evidence inspected | Result | -| --- | --- | --- | -| Accessibility | Editor/label/error association, save/discard focus, streaming locks, keyboard token navigation, drawer focus return, sampling inputs | 2 resolved findings; screen-reader certification not claimed | -| Layout | Empty and long editors; save, generating and finished states; compact status/control geometry | 1 resolved finding | -| Writing | Save versus generate status, base/instruct control labels, inspection colors, optional J-lens messages, branch copy | 3 resolved findings | -| Typography | Monospace editor, numeric metrics, line wrapping and narrow input size | Clear; existing type tokens and tabular figures retained | -| Colors | Light/dark rendered editor and controls, token/focus styles, theme and contrast checks | Clear; no palette changes | -| UI | Stream-follow behavior, scroll-back escape, inspection availability, shared press treatment and loading glow | 1 resolved finding; existing reduced-motion policy inspected in source | - -## Findings - -All findings below were implemented. Locations point to the resulting source. - -| # | Severity | Domain | Location | Before | After | Why | -| --- | --- | --- | --- | --- | --- | --- | -| 1 | MEDIUM | UI | `webui/src/panels/RawBuffer.svelte:420` | Auto-scroll targeted the enclosing div, not the textarea. A long completion had textarea scrollTop=0 despite 898px of content in a 346px viewport; the empty outer surface also scrolled 5px. | Scroll the active text surface after rendering; respect manual scroll-back; offer Jump to latest text. A block textarea removes the inline baseline overflow. Verified textarea scrollTop=552, outer scrollTop=0, and zero remaining distance after Jump. | Keeps new output visible without taking away the ability to read earlier text. The jump control overlays the surface without resizing it. | -| 2 | MEDIUM | Accessibility | `webui/src/panels/RawBuffer.svelte:104`, `:228`, `:448` | Save/discard removed the focused action; browser focus fell to BODY. The visible title was not associated with the editor. | Return focus after completion when focus is still on the originating control or BODY; discard and Jump also return to the editor. Associate the visible label and expose an error’s invalid state. | Keyboard users can continue editing immediately; delayed saves do not steal focus from another selected control. Browser checks confirmed TEXTAREA focus after save and discard. | -| 3 | MEDIUM | Writing | `webui/src/panels/RawBuffer.svelte:510`; `webui/src/panels/StatusFooter.svelte:70`; `webui/src/panels/Chat.svelte:856` | Saving an authored edit displayed zero-token generation metrics and announced Completion finished. | Display/announce Edit saved. Distinguish a zero-token generated completion from an authored save. Unknown/error finishes say Ended, not Complete. | Saving text is not model generation. Tests cover save, cancellation, token limit, unknown finish and zero-token output. | -| 4 | MEDIUM | Writing | `webui/src/hosted/ui/JLensMissingState.svelte:9`; `webui/src/hosted/ui/JLensSourceSection.svelte:39` | Missing word insights told base-model users to download the model again. | Explain that J-lens is optional, this view needs a compatible pack, and text completion still works without it. Instruct-model wording is unchanged. | Avoids treating an intentionally omitted optional tool as a broken model download. The old and new messages were both observed in token inspection. | -| 5 | MEDIUM | Accessibility | `webui/src/panels/RawBuffer.svelte:322` | Inspect tokens could become enabled during generation even though it was intended for a settled buffer. | Include the active-generation guard and explain when inspection becomes available. Continue from inspection returns to the editable view. | Keeps availability consistent with the read-only generation state. Browser and rendered-component checks confirm the lock. | -| 6 | MEDIUM | Layout | `webui/src/panels/StatusFooter.svelte:94`, `:137` | Status used one nowrap, overflow-hidden row, with the finish reason after secondary metrics. Independent separators remained when metrics were hidden. | Put the terminal reason with the token count; wrap complete metric groups; remove loose separators. | Prioritizes the outcome over speed statistics. At 320px, the completed status measured 239px clientWidth and 239px scrollWidth; primary controls remained reachable. | -| 7 | LOW | Writing | `webui/src/App.svelte:485`; `webui/src/panels/ControlsPanel.svelte:17`; `webui/src/panels/InspectorPanel.svelte:66`; `webui/src/panels/SteeringRack.svelte:37`; `webui/src/panels/ProbeRack.svelte:38`; `webui/src/panels/Chat.svelte:1115`; `webui/src/drawers/TokenDrilldownDrawer.svelte:895` | Base controls called the output a response/reply; the color control did not identify the inspection view. | Completion-specific labels, help and branch copy; Inspection colors / Color inspected tokens by. Internal keys and instruct labels stay unchanged. | Matches a continuous-text workflow without renaming protocol fields or altering model behavior. | - -## Considered but Rejected - -| Location | Candidate | Rejected because | -| --- | --- | --- | -| `webui/src/lib/ui/Button.svelte`; `webui/src/lib/style/global.css` | Add a separate animation dependency, spinner, or token-by-token entrance effects | Shared 0.96 press feedback and the existing loading glow already cover discrete controls; streamed text should remain immediate. | -| `webui/src/lib/NumberInput.svelte` | Add separate keyboard stops for the mouse-only spinner pair | The native labeled spinbutton already provides arrow-key operation. Its duplicate steppers are aria-hidden and absent from tab order. Narrow layouts omit them. | -| `webui/src/panels/RawBuffer.svelte` | Give every inline token a 40px box | Inline token controls need to preserve text flow; the roving keyboard stop and shared drawer provide navigation. Main buttons already measured 40px on desktop and 44px in the responsive preview. | -| Loom map and generation recipe | Rename structural user/assistant roles or sampling/protocol keys to completion language | Those are provenance, not conversational instructions. Their identities must remain faithful to the saved tree. | - -## Verification - -Passed: - -- `cd webui && npm run check`: final run exits 0; Svelte reports 0 errors/0 warnings. Theme, contrast, runtime boundary, entry, interface policy, backups and base-mode checks pass. Log: `/tmp/polythetic-base-interface-final-check.log`. -- `cd webui && node scripts/base-model-ui.test.mjs`: original base/instruct mode checks plus rendered-component regressions for readonly generation, inspection guards, visible label association, stop/token-limit/unknown outcomes, authored saves, zero-token model output, completion wording and optional J-lens copy. This script is already included in `npm run check`. -- `cd webui && node scripts/sampling-store.test.mjs && node scripts/loom-store.test.mjs && node scripts/browser-loom.test.mjs`: sampling/queued edits, tree invalidation/streaming, and authoritative branch tests pass. -- `cd webui && npm run build`: native build and isolation pass. Log: `/tmp/polythetic-base-interface-native-build.log`. -- `cd webui && npm run build:hosted`: hosted build and isolation pass. Log: `/tmp/polythetic-base-interface-hosted-build.log`. Both builds retain the existing large-chunk advisory. -- Browser: save and discard return focus to the editor; save displays and announces Edit saved; Ctrl+Enter continues the text; inspection stays disabled while streaming; Stop displays Stopped and unlocks the controls. -- Browser: a 40-line prefix now follows new output. Manual scroll-back exposes Jump to latest text, and Jump returns the textarea to the end. Empty editor no longer has outer baseline overflow. -- Browser: Inspect tokens → ArrowRight → Enter opens the next token; Escape returns focus to the originating token. Replacement text `was ` creates a distinct Loom sibling while the original `is ` path remains visible. The resulting branch retains the `I love marmots because` prefix. -- Browser: 320px and 768px completion previews have no editor horizontal overflow. The 320px sampling sliders and number input measured 44px tall. Light/dark states, invalid logit-bias field feedback, optional J-lens guidance and the actual unavailable-download setup state were inspected. -- Browser: the final workbench error/warning log query returned no entries. -- `git diff --check` passes for tracked edited UI files. Pre-existing untracked components/tests were also inspected directly; no claim is made that Git diff covers those files. - -Not verified: - -- VoiceOver, physical mobile keyboards, 200% browser zoom, and an actual reduced-motion browser session. Reduced-motion source rules were retained, not reimplemented. -- A browser-injected asynchronous save/storage failure. The retained-draft/error path and invalid-state association were inspected; the unknown/error terminal label has rendered-component regression coverage. -- Production base-model installation, model accuracy, GPU capture/replay or release readiness. The development fixture proves UI behavior only; no downloads were enabled or published. - -The shared footer’s new `savedEdit` prop defaults to false; its chat-mode caller remains unchanged. The completion caller supplies the authored-save condition. Other changes are local focus/scroll state, presentation text, and CSS; no wire contract or generation algorithm changed. - -## Verdict - -Approve diff --git a/browser-runtime/BASE_MODELS.md b/browser-runtime/BASE_MODELS.md deleted file mode 100644 index bfe02c5b..00000000 --- a/browser-runtime/BASE_MODELS.md +++ /dev/null @@ -1,72 +0,0 @@ -# Small base-model artifact audit - -For the newer candidate compiler adapters, completion UI, tests, and remaining release work, see [Base-model integration status](BASE_MODEL_SUPPORT_QA.md). The audit below records the earlier artifact checks; it does not establish current public catalog availability. - -Checked 2026-09-04. This is an upstream-artifact shortlist, **not a list of tested browser releases**. No J-lens or SAE was fitted. No runtime locks or public repositories were changed. - -## Result - -Gemma 3 1B PT is the closest fit to the current browser runtime. GPT-2 small and Pythia 70M deduped provide genuinely smaller, different families, but require architecture support before browser installation. Qwen 3.5 2B Base has official pretrained SAEs and an existing J-lens, but needs both hybrid-attention and Top-K SAE support. None is currently published as a verified Polythetic base-model bundle. - -The live Polythetic catalog returned HTTP 200, sequence 6, with Gemma 3 IT and Qwen3 post-trained variants only. A missing “Instruct” suffix does not make Qwen3 1.7B or 4B a base model. - -## Shortlist and evidence - -All Neuronpedia J-lens paths below are pinned to revision `0731326edff4ae730ffc5356fe1a4728c748b3a6`. Each checked `config.yaml` names the specified base checkpoint, not its instruction-tuned sibling. These configs do not establish the exact source-model weight commit used for fitting; that provenance must be resolved before release. - -| Model | Existing J-lens | Existing SAE | Browser status | -| --- | --- | --- | --- | -| **Gemma 3 1B PT** | [Neuronpedia base lens](https://huggingface.co/neuronpedia/jacobian-lens/tree/0731326edff4ae730ffc5356fe1a4728c748b3a6/gemma-3-1b/jlens/Salesforce-wikitext), `google/gemma-3-1b-pt`; 25 matrices, 1152 × 1152 | [Google Gemma Scope 2 PT](https://huggingface.co/google/gemma-scope-2-1b-pt/tree/b738dc06961818c011fb2e44a316352ca0f4e873/resid_post/layer_13_width_16k_l0_medium), residual output layer 13, 16,384 features, JumpReLU | Supported architecture and SAE activation primitives; still needs a base-specific conversion, prompt/stop policy, runtime lock, packed instruments, and physical generation/readout validation. Official model access is gated. | -| **GPT-2 small, 124M** | [Neuronpedia GPT-2 lens](https://huggingface.co/neuronpedia/jacobian-lens/tree/0731326edff4ae730ffc5356fe1a4728c748b3a6/gpt2-small/jlens/Salesforce-wikitext), `openai-community/gpt2`; 11 matrices, 768 × 768 | [Bloom residual SAEs](https://huggingface.co/jbloom/GPT2-Small-SAEs-Reformatted/tree/57d08a4fd333fbf18caf3fbea63ceeb88e2f50d9/blocks.8.hook_resid_pre), 24,576 features | GPT-2 is not a supported production compiler target. Need LayerNorm/unembedding support and an explicit check of TransformerLens preprocessing and pre-block versus post-block capture coordinates. Matching dimensions alone does not prove compatibility. | -| **Pythia 70M deduped** | [Neuronpedia deduped lens](https://huggingface.co/neuronpedia/jacobian-lens/tree/0731326edff4ae730ffc5356fe1a4728c748b3a6/pythia-70m-deduped/jlens/Salesforce-wikitext), `EleutherAI/pythia-70m-deduped`; 5 matrices, 512 × 512 | [EleutherAI deduped SAEs](https://huggingface.co/EleutherAI/sae-pythia-70m-deduped-32k/tree/7a64bade597212176dfe0782f9d839b94f0addaf/layers.3), 32,768 features, Top-K **16** | GPT-NeoX and Top-K are not supported production paths. Do not substitute non-deduped weights, a different training step, or ReLU. The lens ran to 1000 prompts with final relative change 0.00951 versus requested 0.001; evaluate readout quality before recommending it. | -| **Qwen 3.5 2B Base** | [Neuronpedia base lens](https://huggingface.co/neuronpedia/jacobian-lens/tree/0731326edff4ae730ffc5356fe1a4728c748b3a6/qwen3.5-2b-pt/jlens/Salesforce-wikitext), `Qwen/Qwen3.5-2B-Base` | [Official Qwen SAE](https://huggingface.co/Qwen/SAE-Res-Qwen3.5-2B-Base-W32K-L0_50/tree/132ea3697b591df9ee46d738aa1d528e3c6082f7), residual post, width 32,768, Top-K **50**, hidden size 2048 | Not interchangeable with Qwen3. Its hybrid linear/full-attention architecture is not a production compiler target. SAE weights alone are roughly 537 MB per layer in FP32, so this is not a low-memory default. | - -Additional candidates checked: [Gemma 2 2B base](https://huggingface.co/google/gemma-scope-2b-pt-res/tree/fd571b47c1c64851e9b1989792367b9babb4af63) has Google SAEs and a Neuronpedia J-lens, but needs Gemma 2 compiler support and NPZ import verification. [Gemma 3 4B base](https://huggingface.co/google/gemma-scope-2-4b-pt/tree/a0ffd6132a985bc84077a66d1a1033e10b604fa8) also has both; it is a larger desktop candidate, not a compact-device fallback. Gemma 270M remains excluded from the app in accordance with the earlier removal request. Searches did not establish matching precomputed pairs for SmolLM2 or Pythia 160M; do not claim that no such artifacts can exist elsewhere. - -## Actual artifact checks - -Run from the repository root: - -```sh -.venv/bin/python browser-runtime/audit-base-model-artifacts.py -``` - -The script downloads approximately 233 MB into memory, verifies pinned SHA-256 and exact lengths, uses restricted `torch.load(weights_only=True)`, and checks every downloaded matrix for expected dimensions and finite values. It downloads no model weights, executes no repository code, trains nothing, writes no packs, and publishes nothing. - -Observed results: - -| Artifact | Download bytes | FP32 tensor storage | Result | -| --- | ---: | ---: | --- | -| Gemma 3 1B base J-lens, all fitted layers 0–24 | 66,363,652 | 132,710,400 | Passed | -| Gemma 3 1B base SAE, layer 13 | 151,131,000 | 151,130,624 | Passed; all five FP32 tensors, nonnegative JumpReLU thresholds | -| GPT-2 J-lens, layers 0–10 | 12,980,477 | 25,952,256 | Passed | -| Pythia 70M deduped J-lens, layers 0–4 | 2,624,492 | 5,242,880 | Passed | - -GPT-2 and Pythia SAE repository/config/file metadata were checked, not their complete tensor payloads. Qwen's config and lens provenance were checked, not its complete tensors. No base model has passed a generation, quantized-activation parity, or physical-phone test in this audit. - -## Memory and accuracy constraints - -- Parameter count and download size are not peak memory. Include model weights, KV cache, prefill/decode scratch buffers, instrument matrices, exact vocabulary readouts, CPU/GPU copies during loading, and browser overhead. -- Gemma 1B's full J-lens plus one SAE is about **284 MB of FP32 tensors before the model and working memory**. Avoid downloading the 815 MB `examples.safetensors` file for inference. It is not required by the encoder/decoder. -- Keep the provider's actual activation function, thresholds, bias convention, capture position, layer indexing, normalization, tokenizer, and unembedding. Do not approximate Top-K with ReLU or replace J-lens with R-lens/logit lens. -- Existing `import-provider-instruments.py` samples at most eight J-lens layers. A new release must not silently describe that as the full provider lens. For small models, preserve all fitted layers when the measured memory budget allows; otherwise explicitly disclose the selected-layer coverage. No fitting is necessary to retain existing matrices. -- The runtime currently admits ReLU and JumpReLU SAE packs, not Top-K. The production compiler explicitly accepts `qwen3`, `llama`, and `gemma3_text`, not GPT-2, GPT-NeoX, Gemma 2, or Qwen 3.5. -- Existing instruction-model binaries, fingerprints, core packs, lenses, or SAE manifests must not be relabeled as base-model releases. The current importer's manifest stamping is not proof of an upstream checkpoint match. - -## UI and release gate - -The picker now has a native, keyboard-accessible **Base Models** disclosure, closed initially. Its warning explains text completion versus instruction following. Empty catalogs say there are no verified base downloads; candidates are not presented as usable installs. - -An optional signed `modelType: "base"` field separates explicitly classified base models. Older catalogs without it retain their existing chat behavior. As of the 2026-09-05 implementation pass, base-model generation requires a validated model/core closure but not a J-lens or SAE. These tools are optional and unselected on a fresh install; selecting them still enforces compatibility and their combined instrument budget. Base models remain excluded from automatic recommendations and first-run default selection. Explicitly reopening an already selected base model remains possible and reveals its section. - -Before publishing entries: resolve exact checkpoint provenance and redistribution/access prerequisites, create base-specific immutable artifacts, implement and test raw-completion prompting/stopping, validate model generation and instrument readouts on physical hardware, measure context/memory limits, and sign the catalog. Deploy the reader that understands `modelType` before publishing that field: older strict-schema clients will reject it. Existing signature verification and runtime identity checks remain enabled. - -## Local application verification - -The following records the earlier compulsory-tool setup tests, superseded by the optional-instrument tests in [Base-model integration status](BASE_MODEL_SUPPORT_QA.md). - -- 65 runtime-foundation tests passed, including strict signed-catalog admission and the new requirement that both instruments cover every base-model context. -- 43 shell-controller tests passed, including compulsory base-model instrument downloads on mobile, missing-SAE rejection, and combined-memory-budget rejection. -- Catalog-builder and entry-selection tests passed. Invalid model types and incomplete base-model tool coverage are rejected; a hidden base model is never implicitly selected. -- Three browser regressions passed in Chromium/WebKit: keyboard disclosure/selection, required SAE labeling, the empty-catalog state, light/dark layouts at 320, 390, and 1440 pixels, and an accessibility scan of the disclosure. Screenshots were inspected. These are UI fixtures, not real-model inference tests or physical iPhone measurements. -- Svelte check reported zero errors and warnings; theme, runtime-boundary, color, interface-policy, and hosted build checks passed. The existing large-chunk build advisory remains. diff --git a/browser-runtime/BASE_MODEL_INTERFACE_REVIEW.md b/browser-runtime/BASE_MODEL_INTERFACE_REVIEW.md deleted file mode 100644 index 0fc143a9..00000000 --- a/browser-runtime/BASE_MODEL_INTERFACE_REVIEW.md +++ /dev/null @@ -1,71 +0,0 @@ -# Base completion interface review - -Reviewed 2026-09-05. Runtime repairs and interface improvements are implemented locally; this is **not a model-release approval**. - -## Scope and Coverage - -Full `better-interface` review with `make-interfaces-feel-better`, covering the base-model picker/session identity, completion editor, generation controls, token inspection, Loom edits, and backup confirmation. Svelte 5, existing CSS tokens, shared controls and motion conventions. Unrelated pages were not redesigned. - -Browser interactions used the development-only `layoutFixture=base` runtime. Its deterministic output proves interface behavior, not Pythia inference. Desktop interactions and a 320px iframe layout were inspected; iframe keyboard interactions and physical mobile devices were not tested. - -| Domain | Evidence inspected | Result | -| --- | --- | --- | -| Accessibility | Editor label and error association; token arrow/Enter navigation; drawer Escape/focus return; terminal announcements; counter DOM | Focus and status fixes; no assistive-technology certification | -| Layout | Empty, populated, editing, generating and stopped buffers; action grouping; narrow-width preview | Header/actions wrap; separate edit and generation groups | -| Writing | Editor hints, Continue/Save/Discard, inspection, completion identity, stopped/completed announcements | Completion-specific copy replaces misleading chat language | -| Typography | Editor/inspection text, hint wrapping, counters, narrow input size | Existing type system retained; mobile editor minimum 16px | -| Colors | Light/dark rendered states; shared neutral controls, accent and focus tokens; contrast script | Shared theme retained; checks pass | -| UI | Pending/committing controls, loading surface, draft retention, inspection and download interaction | Quiet card glow; no rotating decoration or new animation dependency | - -## Findings - -Implemented findings below are resolved unless explicitly marked outstanding. Locations refer to the resulting code. - -| # | Severity | Domain | Location | Before | After | Why | -| --- | --- | --- | --- | --- | --- | --- | -| 1 | HIGH | UI | `webui/src/panels/RawBuffer.svelte:432` | A tinted mirror sat behind an independently scrolling textarea | One editable text surface; token coloring lives in Inspect tokens | Removes competing text layers and their scrolling/selection alignment risk | -| 2 | HIGH | Accessibility | `webui/src/hosted/runtime/browserLoom.ts:682`; `webui/src/panels/Chat.svelte:858` | An external-stop result could retain a successful finish reason | External stops store cancellation and announce Generation stopped | A partial completion must not be presented as finished; reproduced and retested in browser | -| 3 | MEDIUM | UI | `webui/src/panels/RawBuffer.svelte:197` | Boundary navigation failures escaped the edit error path; pending edits could overlap input | Busy guard, retained draft, persistent inline alert and boundary error handling | Keeps the recovery action next to the affected text; error branch checked in code, not browser-injected | -| 4 | MEDIUM | Accessibility | `webui/src/panels/RawBuffer.svelte:475` | Commit state did not lock the editing surface; token/editor focus lacked a dedicated keyboard outline | Read-only during commit/generation; explicit keyboard focus treatment | Prevents accidental overlapping edits and makes keyboard position visible | -| 5 | MEDIUM | Layout | `webui/src/panels/RawBuffer.svelte:484` | Editing and generation actions shared one undifferentiated row | Two wrapping groups; keyboard hint hidden on narrow screens | Preserves grouping without squeezing the input or primary action | -| 6 | MEDIUM | Writing | `webui/src/panels/Chat.svelte:858`; `webui/src/drawers/TokenDrilldownDrawer.svelte:783` | Response/chat language appeared within base completion tasks | Completion-specific announcements and token identity; Edit text / Inspect tokens hints | Clarifies that a base model continues a passage, rather than answering a chat message | -| 7 | MEDIUM | UI | `webui/src/panels/RawBuffer.svelte:450` | Assistant text without captured token rows could disappear in inspection | Preserve it as plain text, without inventing measurements | The inspection view must not silently omit saved content | -| 8 | LOW | Accessibility | `webui/src/lib/ui/RollingNumber.svelte:37` | Number accessibility relied on animation-library generated markup | Stable formatted text plus an aria-hidden visual animation subtree | Separates accessible content from animated digits; inspected DOM, not a screen-reader run | -| 9 | LOW | UI | `webui/src/panels/RawBuffer.svelte:432` | The completion input had no matching generating-state surface treatment | Existing loading-pulse surface style while generation is active | Gives a restrained activity cue consistent with the app; existing reduced-motion rule retained | -| 10 | LOW | Typography | `webui/src/panels/RawBuffer.svelte:631` | Input size followed only the global type scale | At least 16px for narrow input and inspection text | Keeps completion text readable at the tested narrow width | -| 11 | HIGH | UI | `browser-runtime/BASE_MODEL_SUPPORT_QA.md`, latest status section | Requested base families are not installable; public pinned artifact endpoints return 401 | **Outstanding:** exact runtime/pack validation and accessible published artifacts | Users still cannot complete the real download-to-generation task; do not enable a misleading Install action | - -## Considered but Rejected - -| Location | Candidate | Rejected because | -| --- | --- | --- | -| Completion editor | Keep animated token colors behind the textarea | One editable layer is more reliable; inspection already provides the token-color view | -| Completion editor | Add an animation library and a rotating generating icon | Shared surface motion already conveys activity with less distraction and no new runtime dependency | -| Completion input | Remove the keyboard outline to achieve an entirely soft glow | The soft focus shadow can coexist with a clear keyboard outline; visual restraint should not hide focus | -| Base model cards | Enable Install as soon as compiler code generation passes | Code generation is not successful checkpoint inference or a validated downloadable package | - -## Verification - -Passed checks: - -- `cd webui && npm run check`: Svelte 0 errors/0 warnings, theme/contrast/boundary/interface policies, backup round trips, base-mode enforcement and instruct compatibility. -- `cd webui && npm run build:hosted`: build and hosted isolation pass; existing large-chunk advisory remains. The development preview is not a production build entry. -- `node scripts/qwen-hybrid-contract.test.mjs`: 53 checks pass against the **installed bundle**, using fake device objects. It is now part of `test:runtime`. -- `node scripts/browser-loom.test.mjs`: external-stop regression and authoritative Loom checks pass. -- `npm run test:runtime`: final sequential run passes all 44 scripts after isolating the two test harnesses from unnecessary dependency discovery. Log: `/tmp/polythetic-final-runtime-no-discovery.log`. -- `node scripts/worker-runtime.test.mjs`: 113 orchestration checks pass, including artifact routing after adding the missing fake-runtime method. -- `npm run test:fork-overlays` and `node scripts/check-runtime-lock.mjs`: regenerated overlay and packaged runtime identity checks pass. These are structural checks, not new GPU attestations. -- Browser: enter multiline text; Ctrl+Enter continues; Inspect tokens → ArrowRight → Enter opens token details; Escape closes and returns focus; edit/save creates a new Loom branch without deleting the original; saved model has `[BASE]`; download confirmation shows an editable filename and byte size; stop retains partial text and displays stopped status. -- Browser: Light/Dark switch, busy/read-only editor, disabled Continue/enabled Stop, and a rendered 320px iframe preview. DOM inspection confirms the counter's visual subtree is aria-hidden. - -Verification limits: - -- Fake-runtime browser output is **not** actual base-model generation, capture, replay or SAE execution. -- No VoiceOver, physical mobile keyboard, 200% browser zoom, or injected browser save-error run. Error retention is covered by the code path and underlying storage/backup tests, not a manually forced UI failure. -- Intermediate runtime runs hit native Node/Rolldown SIGSEGV/SIGBUS failures, including one after conversation-library assertions passed. After disabling unnecessary dependency discovery in the affected harnesses, five consecutive conversation-library runs and the complete 44-script chain exited successfully. The failed intermediate runs remain recorded in the QA log; they are not counted as passing runs. -- Release-mode lock checking requires a release revision; no release candidate, deployment or fresh GPU attestation was produced. -- All five anonymous pinned artifact-manifest requests returned HTTP 401. This does not establish whether the repositories are private, missing, or otherwise access-controlled. - -## Verdict - -Block diff --git a/browser-runtime/BASE_MODEL_SUPPORT_QA.md b/browser-runtime/BASE_MODEL_SUPPORT_QA.md deleted file mode 100644 index 2bba7dba..00000000 --- a/browser-runtime/BASE_MODEL_SUPPORT_QA.md +++ /dev/null @@ -1,614 +0,0 @@ -# Base-model integration status - -**Latest status (2026-09-06, 16:06 UTC recheck):** All four base models pass signed installation, ordinary and core-steered generation, full-page saved-session reopening, and further generation at the original local app origin. Catalog sequence 7 fixes the existing-client rollback rejection. Additional fixes cover model reload approval, zero-probability replay persistence, and cross-model conversation isolation. The app is rebuilt locally, not deployed to a production website. The historical blocked recheck below is superseded by the final section. - -The sections before “Signed base installs and long-context validation” record candidate work on 2026-09-05; their not-published statements do not describe the current release. - -## Implemented - -- GPT-2 and GPT-NeoX adapters use the upstream decoder blocks and preserve their checkpoint parameter paths. GPT-2 adds learned absolute positions using the cache's query positions before the first block. GPT-NeoX retains the upstream parallel-residual and partial-RoPE implementation. Both retain LayerNorm rather than substituting RMSNorm. -- Qwen 3.5's candidate adapter threads recurrent state through each native hybrid decoder layer and returns it alongside KV cache before instrumentation outputs. The candidate recurrent-state gather/scatter kernels avoid the pinned compiler's undefined local-buffer error in the upstream state kernels. -- An opt-in compiler entrypoint registers candidate implementations and their quantizers while preserving the upstream checkpoint loaders. Qwen requires the explicit `--hybrid-state-abi` flag; current production instrumentation consumers do **not** support its output layout yet. -- Base sessions always use raw text, including continuation and token replay. Chat-message arrays are rejected before generation. An old UI preference cannot turn a base session into a templated chat. -- The completion workspace offers multiline editing, Continue text, Save edit, Discard edit, and token inspection. Enter inserts a newline; Cmd/Ctrl+Enter continues text. Saving a boundary deletion selects the shorter Loom path. Editing below a shared parent creates a new node instead of modifying the original branch. Failed submissions retain the draft. -- `[BASE]` appears beside model names in the model picker, saved-chat selector, and workbench model card. Optional model-type metadata survives autosave and `.polytheticchat` export/import; legacy records remain accepted without guessing their type. - -The UI and writing skill guidance informed the completion terminology, control grouping, and reuse of existing theme tokens rather than a separate visual theme for base models. - -## Verification - -| Check | GPT-2 | GPT-NeoX / Pythia | Qwen 3.5 | -| --- | --- | --- | --- | -| Native parameter names, shapes, dtypes preserved | Passed | Passed | Passed | -| All 25 instrumentation entry points export to TVM IR, FP32 | Passed | Passed | Passed | -| All 25 entry points export after q4f16_1 quantization | Passed | Passed | Passed | -| Compiled FP32 LayerNorm J-lens probabilities and directions versus NumPy | Passed | Passed | Not tested | -| Compiled recurrent-state gather/scatter versus NumPy | N/A | N/A | Passed | -| Real checkpoint generation / WebGPU parity | Not tested | Not tested | Not tested | - -The recurrent-state test covers 1D, 2D, and 3D state tensors, noncontiguous sequence slots, history-ring wraparound, and preservation of untouched slots. The J-lens CPU test serializes GPU thread bindings to exercise arithmetic; it does not certify GPU scheduling. These tests use small synthetic configurations and deterministic tensors, not downloaded model checkpoints. - -Browser testing used the development-only `?layoutFixture=base` route. Verified raw completion, saving a shortened path, continued generation, multiline Enter behavior, token-detail access, light/dark appearance, and the `[BASE]` badge in the saved-chat drawer. Its output is a deterministic fixture, not real Pythia inference. - -Svelte checks, browser-Loom tests, engine-adapter tests, conversation-library tests, backup round trips, base-mode enforcement tests, theme/contrast/interface checks, and hosted/native builds passed. Builds retain the existing large-chunk warning. - -## Reproduce compiler checks - -Use the project's patched MLC/TVM compiler environment. `--mlc-repository` points to its MLC source tree; the adapters require the current `polythetic_*` hook names, not an older `saklas_*` overlay. - -```sh -python browser-runtime/forks/verify-base-model-adapters.py --mlc-repository /path/to/mlc-llm --architecture gpt2 --readout-golden -python browser-runtime/forks/verify-base-model-adapters.py --mlc-repository /path/to/mlc-llm --architecture gpt_neox --readout-golden -python browser-runtime/forks/verify-base-model-adapters.py --mlc-repository /path/to/mlc-llm --architecture qwen3_5 -``` - -Repeat for each architecture with `--quantization q4f16_1` (without `--readout-golden`). The script prints hashes of the adapter files and explicitly reports `real_model_inference: false`. - -`forks/compile-base-candidate.py` accepts the normal MLC `compile`, `convert_weight`, and `gen_config` arguments. Qwen's local candidate registration additionally requires `--hybrid-state-abi`. This wrapper does not bypass production attestation or publish artifacts. - -## Remaining before usable downloads - -1. Compile actual WebGPU/WASM libraries and convert exact, pinned model checkpoints. Validate quantized prefill/decode logits, captures, EOS behavior, context overflow, and checkpoint-to-instrument coordinates. GPT-2's actual position limit is 1024, so the existing production builder's 2048/4096-only context choices need extending. -2. Complete the WebLLM hybrid instrumentation consumer: pass both states to capture and rank-one-capture calls; read measurements/captures after both returned states; test reset, cancellation, repeated prefill, branching, and replay. Ordinary hybrid generation support alone does not cover these calls. -3. Implement exact Top-K SAE encoding for the selected Pythia and Qwen packs, including global selection across chunks. ReLU is not a valid replacement. Resolve GPT-2 SAE preprocessing and capture-coordinate provenance before treating its dictionary as compatible. -4. Package and validate matching core/J-lens/SAE artifacts, measure browser memory/performance, then produce new release attestations and signed catalog entries. Existing instruction-model binaries and fingerprints must not be relabeled as base models. - -The app deliberately continues to withhold unverified base downloads. This task has not established end-to-end production support for these three model families. - -## Extended validation — 2026-09-05 - -This pass adds executable failure reproductions and target code generation. **No real checkpoint was generated with in a browser.** Compiler success is not a generation-parity result, and the CPU state tests do not validate the full GatedDeltaNet computation. - -### Results - -- All three candidate architectures pass FP32 and q4f16_1 WebGPU/wasm-target code generation through the MLC compiler pipeline, including all 25 instrumentation exports. These executables were not linked to a browser runtime or executed on a GPU. GPT-2 and NeoX use 256-wide synthetic configurations for this check; the smaller 8-wide attention heads used for their IR tests exceed a WebGPU decode-kernel thread limit and are not suitable GPU fixtures. -- GPT-2 and NeoX FP32 J-lens CPU probability/direction goldens pass again. -- Qwen state gather/scatter passes **72 scenarios**: FP32/FP16; 1D, 2D and 3D state; ring capacities 1, 2, 3 and 7; singleton, partial and full batches; reordered/noncontiguous sequence slots; more than two full ring cycles; exact preservation of all untouched storage. These compare compiled CPU kernels to NumPy after every update. -- The core-pack suite passes **67 tests**, including new rejection checks for `topk`, `top_k` and `batch_topk` SAE manifests. This verifies safe rejection, **not Top-K support**. There is still no K=16/K=50 global encoder to test, nor coverage for Top-K chunk merging, ties, normalization or steering through those dictionaries. -- The new Qwen consumer-contract suite runs actual methods extracted from the attested `llm_chat.ts` source with fake device objects: **40 pass, 6 fail**. Four failures reproduce omitted recurrent state in ordinary/rank-one capture, for both prefill and decode. Two reproduce capture/measurement reads at the wrong return offset. Single/batch KV-only and RNN-only controls and plain/steered hybrid forwarding pass. Injected capture failures balance both state-forward scopes without advancing the recorded cache length. -- The consumer source SHA-256 is `9f9ea3b62c96f5755fe591f22b06cf1b18574c7988fffb82d4f47eea921caa5f`, matching `forks/manifest.json`. The test is intentionally red while these production-consumer contracts remain broken; it is not added to the default passing suite. -- All **43 runtime scripts** were run independently to avoid fail-fast masking. Initially 41 passed. The streaming-generation script's manually initialized runtime lacked its capability record, so its concurrency test never reached generation. Supplying the fixture's existing capabilities fixes that test, bringing the result to **42/43**. The remaining worker-runtime failure is `missing fixture method manifolds.inspectSurface`; later tests within that script remain unverified. -- Additional full-runtime contract tests (12), hosted-SAE tooling and residual-capture tooling pass. Svelte/checks and the hosted build pass, with the existing large-chunk advisory. The full-runtime contract tests validate the harness, not a real browser inference run. - -### Reproduce the added checks - -```sh -# Run each architecture separately in the patched compiler environment. -python browser-runtime/forks/verify-base-model-adapters.py \ - --mlc-repository /path/to/mlc-llm --architecture gpt2 \ - --quantization q4f16_1 --webgpu-codegen -# Repeat with gpt_neox and qwen3_5. Omit --webgpu-codegen for IR/state tests. - -cd webui -node scripts/browser-core-pack.test.mjs -node scripts/web-llm-generation.test.mjs -node scripts/qwen-hybrid-contract.test.mjs /path/to/web-llm/src/llm_chat.ts -``` - -`--readout-golden` and `--webgpu-codegen` are mutually exclusive. The latter runs code generation only and does not attest a toolchain, link a runnable browser library, publish files or modify production locks. The Qwen contract suite's nonzero exit is an expected **readiness failure**, not a passing integration result. - -### Still required for the requested end-to-end validation - -Implement global Top-K SAE encoding and hybrid capture/output handling first. Then link candidate WebGPU libraries, convert pinned checkpoints, load them through the actual browser consumer, and compare prefill/decode logits and captures against a reference. Real browser checks must cover EOS/context limits, cancellation, reset, repeated generation, Loom branching and forced replay without stale recurrent state. None of those real-model browser outcomes is established by this pass. - -## Runtime repair and completion interface pass — 2026-09-05 - -This section supersedes the earlier red consumer-contract and missing fixture-method results. No public release or real-checkpoint browser inference is claimed. - -### Implemented and packaged - -- Hybrid capture and rank-one capture now pass both KV and recurrent state. Instrument outputs are read after the complete returned-state prefix, rather than assuming a single state. Ordinary instrumented generation uses the same offset convention. -- State-forward scopes and TVM scopes are closed after embedding, forward, and partial state-begin failures. The regression covers the case where the second state cannot begin without attempting to end a state that never began. -- The rebuilt runtime is `@polythetic/web-llm@0.2.84-polythetic.33`; the web app installs the new vendor tarball. The previous `.32` tarball was not overwritten. Fork overlay, manifest, package lock and runtime identity were regenerated together; no old GPU evidence was relabeled as validating the new runtime. -- Runtime package SHA-256: `f0c6cb71ea4bff6ce7a3fc7d55166658c217f24f106addcd7d74820e2fc63b2b`. -- Fork manifest SHA-256: `97ff7b31f5bd4f561a492748da9e2ffd43101fd3df7e03d9b6c8f445b37dff0f`. -- Runtime identity: `72d368fc8b9100c6773e519366ec57b505e8d29597ec9e66ac0ad9f7b2cbe446`. -- Fake artifact routing now exposes `manifolds.inspectSurface`; all 113 worker orchestration checks pass. -- Browser Loom treats `terminalReason: external_stop` as cancellation even when its own stop flag was not set. The stored node and UI preserve partial text and report stopped rather than complete. -- Base interface fixture sessions use unique roots to avoid test-run autosave collisions. The visible streaming delay is a fixture-only interaction aid, not a performance measurement. - -### Verification and provenance - -- Rebuilt WebLLM source: `npm run build` passes; Jest passes 20 suites / 300 tests. Logs: `/tmp/polythetic-hybrid-runtime-build.log`, `/tmp/polythetic-hybrid-runtime-jest.log`. -- `cd webui && node scripts/qwen-hybrid-contract.test.mjs`: **53/53** against the installed bundle. An optional path still allows the same tests against `src/llm_chat.ts`, which also passes. The harness extracts the actual consumer methods and compiled async helper; its TVM/device objects are fakes. It validates the calling contract and cleanup, **not GPU numerical correctness**. Log: `/tmp/polythetic-qwen-bundled-contract.log`. -- `npm run test:fork-overlays` and `node scripts/check-runtime-lock.mjs` pass. Release checking was not completed: `--release` requires an explicit release revision. No fresh release attestation was produced. -- `npm run check` passes, including Svelte with zero errors/warnings, contrast and theme policies, backup round trips, and base/instruct mode enforcement. `npm run build:hosted` passes, including 291-file isolation; the existing chunk-size advisory remains. -- Earlier full-chain runtime verification passed all 43 scripts. After adding the Qwen contract test, the first independent 44-script pass returned 43 successes plus a native SIGSEGV after conversation-library assertions completed. Other chained runs also encountered native Node/Rolldown SIGBUS/SIGSEGV in the instrument test. These were not assertion successes or GPU failures. Both small test harnesses now disable unnecessary dependency discovery, and the instrument test no longer loads the app configuration. Five consecutive conversation-library processes subsequently exited successfully. Final chained output: `/tmp/polythetic-final-runtime-no-discovery.log`. -- Browser interaction coverage and the six-domain interface review are recorded in [BASE_MODEL_INTERFACE_REVIEW.md](BASE_MODEL_INTERFACE_REVIEW.md). The tested browser runtime is deterministic and explicitly marked as a development fixture. -- **Final result:** after the test-harness changes above, `npm run test:runtime` completes all **44 scripts** sequentially with exit code 0. This includes the new installed-bundle Qwen contract test and external-stop regression. Log: `/tmp/polythetic-final-runtime-no-discovery.log`. This supersedes the intermediate 43/44 result, not the real-model validation limitations. - -### Download availability check - -Anonymous HEAD requests to each pinned repository's `hosted-artifacts.json` returned **HTTP 401**: - -| Catalog model | Repository under `logitsml/` | Pinned revision | -| --- | --- | --- | -| Gemma 3 270M Instruct | `polythetic-web-gemma3-270m` | `ab831929b3266cc3f09c4a2b81c0090193455bd6` | -| Gemma 3 1B Instruct | `polythetic-web-gemma3-1b` | `f4a082a06d5947572eb6a2753fa4093fd222904c` | -| Gemma 3 4B Instruct | `polythetic-web-gemma3-4b` | `b54703553af5b3f1fbbed016a895de01a988f5f6` | -| Qwen 3 1.7B | `polythetic-web-qwen3-1.7b` | `cda345a4200f08cca112502d99c700b04026fefe` | -| Qwen 3 4B | `polythetic-web-qwen3-4b` | `87ef453995eacc71c475dd319193760bafcedded` | - -The status alone does not distinguish private repositories from unavailable or otherwise access-controlled repositories. Existing locally cached files may still work; public installation was not established. No account settings, credentials or repository visibility were changed. - -### Still blocking “all models usable” - -1. True Top-K SAE encoding is still unsupported. The passing pack suite tests rejection, not K=16/K=50 encoding, globally selected feature masks, ties, preprocessing or correct gated/steered reads. -2. GPT-2, Pythia/GPT-NeoX and Qwen 3.5 candidate libraries still need actual checkpoint conversion, linking, and WebGPU generation/capture/replay parity tests. Synthetic compiler exports do not establish these outcomes. GPT-2's 1024-position limit also needs production-builder support before packaging it. -3. The pinned public artifact URLs must be made accessible or replaced with validated accessible artifacts, and matched instrument packs must be packaged. Public publishing and fresh release attestations have not happened. - -Do not enable these unverified downloads or claim arbitrary base architecture support on the strength of these interface and consumer-contract tests. - -## Optional base-model instruments — 2026-09-05 - -Base-model setup now separates generation readiness from tool availability. Signed catalogs may contain base-model/core closures with no J-lens or SAE, or optional instruments covering only some contexts. Supplied packs still undergo the existing strict compatibility, schema, and integrity checks. Fresh base installs leave tools unselected; already installed tools retain their selection. A selected tool's hardware limits and the combined instrument-memory budget still apply. Existing chat-model setup behavior is unchanged. - -Validation: 65 runtime-foundation tests, 45 shell-controller tests, catalog-builder tests, and `npm run check` passed. Tests cover core-only installation, incomplete optional coverage, default selection, and combined-budget rejection after explicit selection. These are setup tests, not new checkpoint inference evidence. - -## Real GPT-2 / Pythia checkpoint pass — 2026-09-05 - -This section supersedes the earlier statements that no base checkpoints had been -converted or run in a browser. These are **local Chromium smoke and numerical -checks**, not Safari results, instrument validation, or release certification. -No model downloads were enabled in the public catalog and nothing was published. - -### Conversion and compiler changes - -- The production builder now accepts GPT-2 and GPT-NeoX adapters, GPT-2's real - 1024-position limit, explicit base/raw completion policy, source EOS ID zero, - and canonical browser dimensions alongside GPT-2's native config fields. -- `q0f32` now explicitly requests raw float32 tensor storage. The converter's - default BF16 storage is lossy even with float32 computation; merely selecting - `q0f32` did not previously guarantee lossless converted weights. All 76 raw - Pythia tensors were checked against the source, accounting for the native QKV - reorder, and matched exactly. -- Pythia exposed a TVM GPU attention bug: valid late-layer scores fall below the - hardcoded `-50000` initial maximum and masked-score sentinel. Prefill and decode - now initialize at the minimum finite float32 value and give masked entries - exactly zero weight. This is a local fix, separate from the read-only-buffer - upstream backport in the same overlay. -- `verify-tvm-attention.py` compiles and executes the actual prefill macros on - CPU with synchronization barriers removed. All six negative-score / empty-tile - cases pass; the original pinned source fails the first causal case, assigning - weights `[0, .25, .25, .25]` instead of `[1, 0, 0, 0]`. This tests serial - arithmetic, not GPU synchronization. The compiler image runs this regression. - -### Physical-browser evidence - -Both tests used Chrome 152 with an Apple `metal-3` WebGPU adapter, local -integrity-checked files, no persistent model cache, and the exact prefix -`I love marmots because`. The harness generated 24 greedy tokens, captured every -prompt position at every block, repeated capture, regenerated after capture, -and unloaded the model. The independent reference uses the same pinned source -files, CPU float32, eager Hugging Face attention, and identical tokenizer IDs. - -| Candidate | Source revision | Result | -| --- | --- | --- | -| GPT-2 small, raw float32, 1024 context | `607a30d783dfa663caf39e06633721c8d4cfcd7e` | Corrected attention build: all 24 greedy tokens match; logit RMSE `3.219e-5`; worst layer/position residual relative L2 `1.952e-6`. Repeat capture is exact and post-capture generation matches. | -| Pythia-70M deduped, raw float32, 2048 context | `e93a9faa9c77e5d09219f6c868bfc7a1bd65593c` | Corrected attention build: all 24 greedy tokens match; centered-logit RMSE `5.400e-4`; worst layer/position residual relative L2 `7.273e-5`. Repeat capture is exact and post-capture generation matches. | - -Pythia's new library SHA-256 is -`b037136145cdff7d39ce2b43d711c754c2427cf0201fe2fd8d7c879827a98e97`; -the conversion manifest SHA-256 is -`b434d2f07751fab67b8da94efd1c907a9b9bd31ceed9961fe33f21079bdd7afa`. -GPT-2's new library SHA-256 is -`84f2b9e5793facbea2c6262f0db3a714e27c63a43dbf7e0d421ec44a14b33142`; -its conversion manifest SHA-256 is -`e1a1f757872a0908ce30ed1851c6c714393fe776b986d0f4202794eacab7bccb`. -The raw model closures occupy about 284 MB (Pythia) and 655 MB (GPT-2, including -the materialized tied head). Earlier q4f16 candidates did not establish acceptable -checkpoint parity and remain unverified; finite output alone was insufficient. - -Local diagnostic records: - -- `/tmp/polythetic-pythia-checkpoint-comparison-attention.json` -- `/tmp/polythetic-gpt2-checkpoint-comparison-attention.json` -- `/tmp/polythetic-attention-macro-test.log` and - `/tmp/polythetic-attention-macro-baseline.log` - -The harness and checker are reproducible with -`webui/scripts/base-model-browser-harness.mjs` and -`browser-runtime/compare-base-checkpoint.py`. Their reports intentionally do not -claim release certification. Safari, EOS/context-limit behavior, cancellation, -steering and instrument coordinates, Qwen hybrid inference, and Gemma PT remain -outside these results. Old GPU attestations were not restamped after the -toolchain change. - -Final local checks pass: all 44 runtime scripts, `npm run check`, the hosted -build (291-file isolation), 25 production-toolchain tests, overlay integrity, -and the non-release runtime-lock check. Logs use the -`/tmp/polythetic-base-final-*` and `/tmp/polythetic-attention-*` prefixes. - -## Gemma PT and Qwen 3.5 checkpoint diagnostics — 2026-09-05 - -These are local candidate results, not catalog additions or release attestations. -The Gemma source download was verified against revision -`fcf18a2a879aab110ca39f8bffbccd5d49d8eb29` with `hf cache verify`: all ten -requested files passed. Account access is no longer blocking this checkpoint. - -### Runtime and builder changes - -- Qwen 3.5 base now participates in the production builder with the explicit - `kv-rnn-v1` state ABI and architecture-specific adapter/source digests. - EOS and position limits come from the nested text config, not the multimodal - wrapper. Base completions do not acquire an instruction-model thinking profile. -- Raw completion text now retains a tokenizer's required special-token prefix. - Gemma's prefix is BOS ID `2`; the actual text remains exactly - `I love marmots because`. The builder checks that special-token encoding is - a pure prefix, pins it in the build manifest, and aligns generation and capture. - The runtime counts prefix tokens against the context limit. Word tokenization - remains prefix-free, and chat templates are not applied to base completions. -- The verified artifact cache rejects invalid, mismatched or missing required - BOS metadata. This does not loosen model/tool compatibility or integrity checks. -- The local runtime package is now `.34`, SHA-256 - `79e9e88edd7213370da67d464fa490254f5fe30bb2d7949c6e477b5eb02642fd`. - Fork manifest SHA-256 is - `3e17cab1323a86b16df3f4d16b5a84494a0d5cc973d2534b59f9211eccb56852`; - runtime identity is - `2efbf2380150a1d59740596ec0e1951c6f713e7ceeb15ab4abc330fd2ee025b1`. - Earlier packages and GPU evidence were retained, not relabeled. - -### Actual Chromium results - -Chrome 152 / Apple `metal-3` ran these pinned, integrity-checked local files. -All prompts used the required marmot prefix. The harness unloads after each run. - -| Candidate | Observed result | Limitation | -| --- | --- | --- | -| Qwen 3.5 2B Base, `q4f16_1`, 2048 context, revision `b1485b2fa6dfa1287294f269f5fb618e03d52d7c` | 24-token generation, all 24-layer prompt captures, exact repeat capture, identical 24 token IDs after capture | Original-checkpoint float32 diagnostic differs after the first 12 generated tokens; logit RMSE `0.4154`. A matched-quantization reference is still required. | -| Gemma 3 1B PT, `q4f16_1`, without BOS | Generation and repeat capture pass, but completion repeats “because” | The original checkpoint also repeats without BOS; this was an invalid prompt policy, not useful evidence of ordinary base completion quality. | -| Gemma 3 1B PT, raw `q0f32`, without BOS | Model loading exits with `Program terminated with exit(1)` while fetching parameters | No generation or numerical result. The embedding exceeds the runtime's 1 GiB requested buffer limit; the adapter advertises a larger limit, but the precise exit cause was not captured. Production admission was not loosened. | -| Gemma 3 1B PT, `q4f16_1`, with BOS | Generation is rejected for invalid probabilities; all first-step logits are non-finite | The BOS residual overflows at zero-based block 11, followed by non-finite values across the next block. This is a failure, not a smoke pass. | -| Gemma 3 1B PT, `q4f32_1`, with BOS | Finite 24-token generation, all 26-layer prompt captures, exact repeat capture, identical 24 token IDs after capture | Float32 computation fixes the observed overflow. Source-architecture numerical and long-context correctness are separate requirements. | - -For the BOS run, capture records a maximum finite BOS magnitude of `62176` at -block 10, one non-finite coordinate at block 11, and entirely non-finite -residuals from block 12 onward. A CPU reference using the exact dequantized -float16 browser weights **and the original source architecture** reproduces -the same onset. The original float32 checkpoint produces finite completions. -This establishes a float16 range problem, independently of the separate -positional-encoding issue below. The float32-compute q4 candidate passes the -four Chromium smoke/replay checks. Its closure is 602,358,293 bytes (float32 -computation, 4-bit packed weights; float32 scale payloads use the converter's -BF16 storage encoding). Library SHA-256: -`2427408ca735cdb751e568a7ea4772ce2bb1166092066ddc4f4dc1a35a94ace1`; -conversion manifest SHA-256: -`30e8862c6836da6969a37cddda334a59cb0fbf70cbc42e338a82cdb47609a65b`. - -The exact-dequantized/source-architecture reference is **not a numerical pass**: -first-step logit RMSE is `0.12869`, relative L2 `0.01735`; worst per-position -residual relative L2 is `0.04698`. The first 11 greedy token IDs agree before -the reference selects “love” and the browser selects “have”. This discrepancy -cannot be attributed simply to comparing q4 with original unquantized weights: -both sides of this diagnostic use the same converted q4 tensors. The known -local-RoPE mismatch remains a concrete compiler issue; its contribution has -not yet been isolated by an A/B compiler fix. Record: -`/tmp/polythetic-gemma-pt-q4f32-source-comparison.json`. - -Qwen's library SHA-256 is -`18eca88b2bff223bdf0103df3fe45c9b7f3d079bfd5f01faeaefdcf6a676a1f0`; -its conversion manifest SHA-256 is -`996c751dad97539878a67005399ad1674fb0deb7e0a01d33512cb972aee7729c`. -The closure is about 1.083 GB. These earlier smoke reports identify the exact -runtime bundle they used; they do not certify the subsequent `.34` package. - -### Independent reference and unresolved Gemma geometry - -`compare-base-checkpoint.py --converted DIRECTORY` adds a Gemma-only diagnostic -using exactly the hashed, dequantized browser tensors with the **source config**. -It preserves different local/global RoPE frequencies, source sliding-window -width and layer types. Norms account for the converter's already-folded `+1`, -and linear operations use float32 accumulation before the configured output -cast. It does not inject browser residuals into the reference or change source -geometry to match a suspect compiler. Non-finite outputs cannot yield an -accuracy result. The original-checkpoint reference remains the default. - -The pinned MLC Gemma cache applies normal-mode RoPE with global frequency -`1e6` before attention; its inline-mode local `1e4` setting does not correct -that pre-rotation. Source Gemma 1B requires local `1e4`. The TVM layer-sliding -path also contains a hardcoded 1024-token window, whereas the 1B source uses -512, and initial ragged prefill needs a local-window mask. These remain -unresolved; short-prompt output cannot certify long-context Gemma fidelity. - -### Regression checks and records - -- WebLLM: all 20 suites / 307 tests pass, including seven completion-prefix and - context-budget regressions. Build and local packaging pass. -- App: `npm run check`, all 44 runtime scripts, and the hosted build pass - (293-file isolation; existing chunk-size advisory). A native Node shutdown - assertion in the session-persistence test was removed by disabling unnecessary - test-server dependency discovery; three repeated processes then exited cleanly. -- Production builder: 29 tests pass; non-release runtime-lock checking passes. -- Source-config reference plus existing q4 helpers: 13 tests pass, covering both - compute precisions, distinct local/global frequencies, source window policy, - exact state closure and unsupported-precision rejection. -- Diagnostic logs: `/tmp/polythetic-gemma-f16-source-geometry.log`, - `/tmp/polythetic-gemma-bos-original-reference.log`, - `/tmp/polythetic-qwen35-checkpoint-comparison-v1.json`, and - `/tmp/polythetic-completion-prefix-*.log`. - -No public visibility, publishing, model catalog availability, project version, -or old release attestation was changed. The nine-model Chromium/Safari milestone -and full instrument compatibility remain incomplete. - -## Updated-runtime lifecycle checks — 2026-09-05 - -The harness's optional `--lifecycle` mode additionally interrupts a real stream -after three sampled tokens, checks that partial text is retained, and compares -a fresh greedy run to the original. It then submits an independently tokenized -overlong marmot-prefixed prompt, requires `ContextWindowSizeExceededError`, and -checks fresh generation again. These are engine-level tests, not Loom branching -or natural-EOS tests. - -| Browser and checkpoint | Result | -| --- | --- | -| Chrome 152, GPT-2 `q0f32`, 1024 context | All six smoke/lifecycle checks pass. Three tokens retained on cancellation; 2054-token input rejected; all 24 output IDs match after recovery. | -| Safari 26.6.2, GPT-2 `q0f32`, 1024 context | All six checks pass on the Apple WebGPU adapter. Logits and all prompt captures are bit-for-bit identical to Chromium, with identical 24-token output. | -| Chrome 152, Pythia-70M deduped `q0f32`, 2048 context | All six checks pass. Three tokens retained on cancellation; 6150-token input rejected; all 24 output IDs match after recovery. | -| Safari, Pythia | Not run in this pass: Safari became user-active while the test tab was being selected, so UI automation was paused. | - -The new Chromium GPT-2 and Pythia reports also have **zero difference** in -logits and every captured value from their respective earlier `.33` reports -that were checked against the original float32 checkpoints. These actual `.34` -runs provide updated evidence; old attestation files were not rewritten. - -Records: GPT-2 reports `run-1.json` (Chromium) and `run-2.json` (Safari) under -`/var/folders/q6/8tf71hmx2qq_v74d8rvwg1ww0000gn/T/polythetic-base-browser-T9QfkO/`; -Pythia report `run-1.json` under -`/var/folders/q6/8tf71hmx2qq_v74d8rvwg1ww0000gn/T/polythetic-base-browser-NnkXbJ/`. -The combined production-builder/source-reference/q4-helper suite passes all -42 tests. Overlay integrity, Python compilation and harness JavaScript syntax -checks pass. These results still do not cover the full nine-model roster, -long-context attention fidelity, model instruments or release certification. -The current runtime identity is -`e2ad88fea0f132ebf6dc8ce6887f325861a7c3ff6562de5ad33bbc9f0ef65002`. - -### Access and remaining work - -The pinned Qwen 3.5 2B Base source -`b1485b2fa6dfa1287294f269f5fb618e03d52d7c` is downloaded locally, including the -4.2 GiB weight shard; it has not been converted or run. The production compiler -still needs hybrid-adapter registration, nested text-config/EOS handling, and -architecture-specific source/adapter provenance. Its cached config is a -multimodal wrapper; the requested text backbone must not be mistaken for a -Qwen3 architecture or a different checkpoint. - -An exact-source download of `google/gemma-3-1b-pt` revision -`fcf18a2a879aab110ca39f8bffbccd5d49d8eb29` failed with **Access denied; repository -requires approval**. User-approved access or a locally supplied checkpoint is -required. No terms were accepted, account permissions changed, or replacement -checkpoint substituted. - -The overall milestone is incomplete. Remaining scope includes the other real -model checks, Top-K SAE and instrument parity, min-p/repetition-penalty plumbing, -the remaining completion controls and nondestructive Loom split/local exports, -Safari coverage, and fresh candidate release evidence. Comparison experiments -remain explicitly excluded; publishing remains unauthorized. - -## Signed base installs and long-context validation — 2026-09-06 - -This release work follows the request to enable in-app installation. The -following model repositories are public, with model files and their required -core geometry pack bound to the same immutable commit: - -| Model | Computation | Context | Published commit | -| --- | --- | --- | --- | -| GPT-2 Base | `q0f32` | 1024 | `787a18eed89e1c5e342382c6b88fb5f4dcd5f978` | -| Pythia 70M Deduped Base | `q0f32` | 2048 | `b312ef57bd3852969fd43c8254ceb93b79317d27` | -| Gemma 3 1B PT | `q4f32_1` | 2048 | `b771368a80809580545d340358de1ceab28632f4` | -| Qwen 3.5 2B Base | `q4f32_1` | 2048 | `4a839d1c2a91f397a91bc25dbaa07825930adea7` | - -Repositories are `logitsml/drowse-web-` on Hugging Face. Catalog -sequence 3 at `logitsml/drowse-web-catalog` includes these four models and -required core packs only. Every published model/core file passed full-byte -size/SHA-256 checks and anonymous download, range, and CORS preflight. The -catalog uses the new Drowse current/next signing-key pair; only public keys are -in the repository. Earlier chat-model runtime pins remain unchanged and are -not silently relabeled as base models. - -The catalog's immutable publication is -`9ed3c63c8840fd93a53fcf8012c9c2d46315a5aa`; the updated runtime identity is -`8cf065c1ace9e8e2bc35bcbde1f5f0b8bf039284dc746a1f22ed47e41630415c`. - -The model picker now assesses a base model against its highest supported -context no larger than the requested context. This makes GPT-2's native 1024 -profile installable while preserving strict actual-load admission, memory -checks, and the policy that base models are never automatically recommended -as chat assistants. Missing J-lens or SAE packs do not block base generation -or core steering. - -### Gemma attention repair and independent accuracy - -Gemma's paged-KV path now uses the source model's actual rotary frequency and -absolute query positions, including chunk offsets. Its 512-token local-window -mask and global-layer mask enforce absolute causality even when the underlying -append-before-attention prefill call supplies `causal=0`. The missing causal -mask had let early query positions attend to later tokens; changing rotary -parameters alone did not repair it. Eleven serialized kernel checks exercise -the masked path, including local/global and chunk-boundary cases. - -The corrected final `q4f32_1` library passes actual Chrome/Metal generation, -capture, repeat, cancellation, context rejection/recovery, branch/reset, and -forced-EOS/recovery checks. The source-architecture reference consumes the -exact converted quantized weights, without modified source attention settings -or residual corrections. The float16-compute Gemma build is not released. - -| Final model | Input tokens | Relative logit L2 error | Maximum per-layer capture relative L2 | Greedy output | -| --- | ---: | ---: | ---: | --- | -| GPT-2 | 996 | `1.70e-7` | `9.83e-7` | 24/24 source-checkpoint IDs match | -| Pythia | 1926 | `1.29e-6` | `3.00e-4` | 24/24 source-checkpoint IDs match | -| Gemma PT, short | 6 | `9.66e-7` | `1.29e-6` | 24/24 matched-quantization IDs match | -| Gemma PT, long | 1806 | `7.07e-6` | `2.63e-6` | 24/24 matched-quantization IDs match | -| Qwen 3.5 Base, short | 6 | `1.75e-6` | `3.10e-6` | 24/24 matched-quantization IDs match | -| Qwen 3.5 Base, long | 1626 | `2.53e-5` | `1.16e-5` | 24/24 matched-quantization IDs match | - -Long captures sample positions on both sides of 128, 512, and 1024 when -present, including the last input token. Gemma's worst sampled-position -relative error is `1.74e-5`. These checks cover the advertised browser profiles, -not the source models' larger maximum contexts or every possible prompt. - -### Core-only runtime, cache, and app checks - -All four final model/core closures pass the production runtime -worker harness: SHA-verified OPFS staging, 24-token baseline generation, -physically active core steering, a changed finite conditional logprob for the -same forced token, and an unchanged subsequent baseline. A new runtime and -core compiler then reopen freshly read OPFS file handles with all model HTTP -requests blocked. Baseline and steered token IDs reproduce, with zero network -attempts and zero device losses. Optional instrument count is zero. - -This network-blocked test verifies model reload, not offline page navigation. -Separately, the real app's signed-catalog installer was exercised for all four -models: download/open, ordinary and core-steered completion, full page -reload, saved-conversation reopening, and further generation all pass. The -offline-ready notice initially covered the completion button in the short -test viewport; dismissing it restored normal clicks without an engine change. -Gemma and Qwen at steering strength 0.5 can repeat heavily; Gemma's 0.1 smoke -completion was readable. These are functional steering checks, not a -semantic-quality study. - -### Qwen matched-quantization and replay investigation - -The final FP16-compute Qwen build is withheld. Some repeated captures and -branch replays differ by up to `0.171875`, despite matching greedy tokens and -other successful runs. Passing runs alone are not treated as repeatability -evidence. - -A freshly converted/compiled `q4f32_1` build retains the exact pinned -`Qwen/Qwen3.5-2B-Base` text backbone and hybrid KV/recurrent-state ABI. At 1626 -input tokens its independent source-config reference with the exact quantized -weights matches all 24 output IDs: relative logit error `2.53e-5`, maximum -per-layer capture relative error `1.16e-5`, and worst sampled-position relative -error `2.73e-5`. - -An eight-branch diagnostic run also preserves greedy generation after capture, -cancellation, rejected context, explicit reset, and forced EOS. Its small -within-browser residual differences exceed the original absolute-only `1e-5` -check: maximum absolute difference `5.15e-5`, maximum per-layer relative L2 -`3.00e-6`. That diagnostic remains labeled `diagnostic-only`, not retroactively -passed. A separate explicit FP32 replay policy requires **both** maximum -absolute error at most `1e-4` and relative L2 at most `1e-5` in **every layer**; -the strict default is unchanged and FP16 builds cannot opt into the FP32 -policy. This is numerical repeatability, not a bit-exact claim. - -A fresh long-context run passes all eight smoke/lifecycle checks and eight -branch replays under that declared FP32 policy. Repeated capture differs by -at most `2.48e-5` absolute / `2.11e-6` per-layer relative L2. Across the eight -branches, maxima are `8.78e-5` absolute and `2.68e-6` per-layer relative L2; -every comparison satisfies both limits. All 24 greedy output IDs reproduce -after capture, cancellation, rejected context, reset, and forced EOS. A fresh -short-context run passes the same lifecycle checks plus three branch replays -with bit-identical captures. This does not establish bit-exact long replay or -all-prompt/platform fidelity. - -The final Qwen core-only production worker test also passes: 24-token baseline -and core-steered generation, a changed finite logprob for the same forced -token, unchanged subsequent baseline, and fresh runtime/core-compiler reload -from verified OPFS handles with all model HTTP requests blocked. Reopened -baseline and steered sequences reproduce, with zero network attempts, zero -device losses, and zero optional instruments installed. - -The final combined runtime suite passes all 44 runners. The production -builder/source-reference/quantized-weight suite passes 47 tests. Fork-overlay -integrity, Svelte checking, hosted build and isolation checks pass; the existing -large-chunk build warning remains. Standalone replay-policy tests cover both -bounds, individual-layer isolation, shape mismatches, and non-finite values. - -Compact artifact identities, public preflight receipts, reference metrics, -browser lifecycle results, rejected diagnostics, core-only offline reloads, -and actual app-check outcomes are recorded in -[`base-model-release-evidence.json`](base-model-release-evidence.json). -Qwen's final actual app check used catalog sequence 3: the 1.1 GB download -verified and opened without optional packs, generated 24 tokens normally and -with the included core direction, survived a full-page reload, reopened the -saved two-branch completion, and generated 24 further tokens. No warning or -error was reported in the browser console. - -The model packages and signed catalog were published to Hugging Face. The app -was rebuilt and verified locally; this work does not deploy a production -website, publish git commits, or certify the older nine-model release roster. - -### Existing-origin upgrade recheck — blocked - -At `http://127.0.0.1:4173/app?choose=1`, the in-app browser initially used an -older cached app. The normal **Update and reload** flow successfully loaded -the current Drowse build, but the model catalog still failed admission. A -temporary console diagnostic identified the exact error: **The catalog -sequence is older than the last accepted release**. The diagnostic was then -removed. No catalog state, model files, or saved conversations were cleared, -and signature and rollback enforcement were not weakened. - -The public catalog still returns sequence 3 at immutable commit -`9ed3c63c8840fd93a53fcf8012c9c2d46315a5aa`. It is valid for fresh clients but -cannot replace a higher sequence already accepted by this existing client. -The corrective release must use a newer signed sequence and then pass the -actual installer, load, generation, and reopen checks at the existing origin. -That publication has not been performed during this recheck. - -The unavailable-download message previously displayed a model's descriptive -blurb in place of the global catalog failure. It now prioritizes the actual -download failure, with six regression assertions covering global failures, -model-specific setup issues, and no selected model. The full 44-runner runtime -suite also passed during this recheck, before this message-only change; it -does not supersede the observed upgrade failure. - -## Existing-origin upgrade and lifecycle repair — 2026-09-06 - -The original `http://127.0.0.1:4173` app accepted the normal **Update and -reload** flow and signed catalog sequence **7** without clearing catalog -history, model files, or saved conversations. The published catalog commit is -`da488a3de729bc649ca70465b1da56409a0b98eb` in -`logitsml/drowse-web-catalog`. Its four model/core entries are unchanged from -sequence 3. Public preflight verified **126 immutable files / 2,731,824,423 -bytes**. Signature verification and rollback protection remain enabled. - -### Reproduced failures and repairs - -- The catalog publisher now authenticates the previous published catalog, - rejects a non-advancing sequence, and rechecks the repository revision before - uploading. The app's minimum accepted sequence is 7; regression coverage - includes an existing legacy-key client with a sequence-6 high-water mark. -- Normal unload/takeover no longer erases compatibility approval. Each model - load still requests a fresh GPU adapter and checks it against the approved - fingerprint. Stateful regressions reproduce the old second-load failure and - verify both unload/takeover reloads plus rejection of a changed adapter. -- Forced replay at temperature zero can legitimately produce a sampler - log-probability of negative infinity. Raw analysis callbacks retain that - value. JSON-facing token statistics use null, non-finite display alternatives - are omitted, and the aggregate is null if a response log-probability is - non-finite. This avoids corrupting the saved session or inventing a finite - probability. The exact previously failing GPT-2 continuation now generates - and autosaves successfully, including after unload/reopen. -- Tree revision ordering is now scoped to both model and session identity. - Previously, two different models sharing session `default` could cause the - lower-revision model's tree to be ignored. Switching now adopts the correct - tree and clears the previous model's live speed/status counters; stale - revisions within the same model/session remain rejected. - -### Actual app checks - -All checks used real downloaded models, not layout fixtures. The initial raw -prompt was `I love marmots because`, temperature 0, with 24 newly generated -tokens per completion. The steering condition used the included -`default/welcoming.detached%welcoming` core direction at strength 0.1. - -| Model | Signed install/open | Ordinary + core-steered generation | Saved reopen + continuation | -| --- | --- | --- | --- | -| GPT-2 Base | Passed | Passed | Passed | -| Pythia 70M Deduped Base | Passed | Passed | Passed | -| Gemma 3 1B PT | Passed | Passed | Passed | -| Qwen 3.5 2B Base | Passed | Passed | Passed | - -Qwen's 1.1 GB download was also paused at approximately 21%, resumed, verified, -and opened. Direct in-app switches among the installed models passed without -requiring a page refresh. Original saved user work remained present. No new -browser warnings/errors appeared during the final four-model verification. - -The 44-runner runtime suite, publisher regressions, Svelte/UI checks, and both -native and hosted builds pass. Existing bundle-size warnings remain. -[`base-model-upgrade-evidence.json`](base-model-upgrade-evidence.json) records -this app-level recheck separately from the earlier numerical/model-artifact -attestations. These are functional smoke checks on this device, not a -semantic-quality evaluation or an all-browser guarantee. Optional J-lens and -SAE packs are not installed or required for these core-only checks. No git -push, production website deployment, or version bump was performed. diff --git a/browser-runtime/README.md b/browser-runtime/README.md index 1534058a..7cec8d7d 100644 --- a/browser-runtime/README.md +++ b/browser-runtime/README.md @@ -49,6 +49,12 @@ log/parallel-transport/exp translation, and nearest-foot solve as the Python domain. These TypeScript and compiled-kernel contracts are implemented but do not by themselves constitute production-model or physical-device verification. +Hosted browsers start optional live J-lens and SAE readouts off on every device. +Users enable them through the instrument Live controls. Explicit probes, steering +gates, and token replay still request their required computations. Plain chat +therefore avoids full-vocabulary and full-dictionary analysis on every token, +including when the instrument sidebar is hidden; model sampling is unchanged. + Optional instrument packs are executable inputs rather than capability placeholders. A local SAE v1 fp32 artifact provides `W_dec[id]` steering and the exact `relu((h - b_dec) @ W_enc + b_enc)` probe used by `sae/` gates. A diff --git a/browser-runtime/SYNTHETIC_SURFACE_VALIDATION_2026-09-05.md b/browser-runtime/SYNTHETIC_SURFACE_VALIDATION_2026-09-05.md deleted file mode 100644 index 2131caa5..00000000 --- a/browser-runtime/SYNTHETIC_SURFACE_VALIDATION_2026-09-05.md +++ /dev/null @@ -1,134 +0,0 @@ -# Synthetic surfaces and quotient steering - -## Scope - -Validation uses synthetic manifold-shaped data in R^n. Real-model experiments -are not required for this scope. No semantic or model-behavior claims follow -from these checks. - -Two capabilities are deliberately separate: - -- `polythetic.core.surface_topology.detect_surface(points)` measures evidence - for a closed surface from unlabelled point coordinates. It does not receive - the generating surface's name or parameter coordinates. -- `KleinBottleDomain` and `ProjectivePlaneDomain` provide native, seam-aware - steering when the node coordinates are authored. A detected homology - signature is not automatically converted into a coordinate chart. - -The hosted app remains gated. Its archive validator and compiled hook ABI -support box, sphere, and custom domains, not these new quotient tags. No model -bundle, browser artifact, deployment, or saved user manifold was rewritten. - -## Detection - -The optional `topology` extra installs Ripser and SciPy. Detection computes -Vietoris–Rips H0, H1, and H2 over F2 and F3, using the full distance matrix of -32–384 finite, distinct points. Larger inputs raise instead of silently -subsampling away thin features. Inputs are explicitly Euclidean synthetic -coordinates; activation-space callers must supply a whitened representation. - -Birth-normalized persistence compares features at their own scale. A dominant -F2 H2 bar must exceed competing bars by 3:1. Both fields must have a simultaneous -surface signature over a scale interval at least 15% of its starting radius. -Every barcode endpoint participates in the interval sweep; a coarse grid -cannot hide an intervening contradictory class. F3 is computed only after the -F2 screen passes. These are conservative heuristic thresholds, not calibrated -confidence probabilities. - -| Conditional surface interpretation | F2 Betti numbers | F3 Betti numbers | -| --- | --- | --- | -| Sphere | 1, 0, 1 | 1, 0, 1 | -| Torus | 1, 2, 1 | 1, 2, 1 | -| Real projective plane | 1, 1, 1 | 1, 0, 0 | -| Klein bottle | 1, 2, 1 | 1, 1, 0 | - -These signatures distinguish the listed **connected closed two-manifolds**. -Homology alone does not prove that an arbitrary point cloud samples such a -manifold, nor determine arbitrary topology. Boundary surfaces, intersecting -immersions, non-manifold complexes, missing regions, and insufficient sampling -remain outside a certified classification claim. `candidate=None` means -unresolved, not flat or contractible. Higher-genus signature names are -implemented but have not been positively validated here. - -`scale_interval` is expressed in median-pairwise-distance units. -`relative_persistence` is interval width divided by its starting radius. - -## Seam-correct native geometry - -- Klein bottle: `(u + 2π, v) ~ (u, -v)`, with a crossing-free embedding in R4. - Shortest deck lifts include the orientation-reversing seam, and tangent - translation flips the second component when required. Its connection is the - flat quotient metric, not the metric induced by the R4 embedding. -- Projective plane: antipodal unit vectors, represented by a trace-free - Veronese embedding in R5. Paths select the nearest antipodal lift. Local - two-dimensional tangent frames and sphere retractions keep the foot solver - full-rank at spherical-coordinate poles. -- The existing RBF fit, unified injection kernel, off-subspace preservation, - sigma-field calculation, and safetensors codec consume the new domains. - Probe summaries average in embedding space and project back, rather than - averaging across a coordinate seam. Projective means with tied top - eigenvalues retain the reference coordinate. -- Cut loci have genuinely non-unique shortest paths. The implementation makes - a deterministic choice; it does not promise globally continuous path choices - or encode arbitrary winding-number instructions. - -Native domain specifications are `{"type": "klein"}` and -`{"type": "projective", "dim": 2}`. Both use two authoring coordinates. -Their artifact tags are rejected by older/hosted readers rather than being -misinterpreted as periodic boxes. - -## Reproducible validation - -```sh -.venv/bin/python -m pytest tests/test_surface_topology.py tests/test_quotient_domains.py -q -.venv/bin/python -m pytest tests/test_topology_adversarial.py tests/test_manifold_topology.py tests/test_browser_topology_rbf_fixture.py tests/test_manifold_discover.py tests/test_manifold_math.py tests/test_manifold_extraction.py tests/test_manifold_monitor.py tests/test_manifold_steering.py tests/test_manifolds_io.py -q -.venv/bin/ruff check polythetic/core/manifold.py polythetic/core/monitor.py polythetic/core/surface_topology.py tests/test_quotient_domains.py tests/test_surface_topology.py -``` - -Regression cases include random spheres/RP2, stratified Klein/product-torus -samples embedded in 11 dimensions with shuffled rows and changed units, and -3D doughnut tori with major radius 2 and minor radii 0.6 and 0.3. These cases -informed development and are not independent holdouts. The 3D cases use 24×16 -and 48×8 samples respectively, with parameter jitter. - -After freezing the algorithm, seeds 10091 and 10093 test the four main families -in R17 with independent Gaussian coordinate noise of standard deviation 0.002. -These are held-out seed/noise variants of the same generators, not an -independently designed benchmark or broad noise-tolerance calibration. - -Negative cases include a disk-like cloud, a cylinder, a Möbius strip, a -seven-dimensional cloud, disconnected spheres, and a very thin 1:0.025 -product torus. Refusal on the thin torus is a recovery limitation, not a -successful identification. Geometry tests cover equivalent representatives, -seam continuity, Jacobians, poles, ambiguous means, batched injection, -off-subspace residual preservation, zero-strength identity, and native -save/load round trips. - -Final local results: - -- 41 surface-detection tests passed in 197.69 seconds, including all eight - frozen noisy holdouts and all four jittered 3D doughnut-torus cases. -- 34 quotient-geometry tests passed in 0.95 seconds, including nonlinear RBF - fits and preservation of normal-residual norms across seams. -- 652 related existing math, extraction, topology, monitor, steering, and - artifact tests passed (run together with the first 30 quotient tests: 682 - passed in 21.14 seconds). One expected authoring-rank warning was emitted. -- Ruff, Python compilation, and targeted Pyright passed (zero errors/warnings, - with the project interpreter selected). A local wheel built successfully and - included the new module and optional dependency. No package version changed. - -These timings are local test-run measurements, not browser latency guarantees. -The full unrelated Python/server/GPU suite and hosted runtime suite were not -rerun for this native-only update. - -## Remaining work - -Automatic chart recovery, the corresponding browser compiler/ABI operations, -and synthetic parity tests of those compiled operations are still outstanding. -The point-cloud diagnostic is opt-in Python, not connected to the existing -`fit_mode="auto"` selector. Do not advertise arbitrary-manifold detection or -enable hosted automatic steering on the strength of this native implementation. - -References: [Ripser API](https://ripser.scikit-tda.org/en/latest/reference/stubs/ripser.Rips.html), -[Ripser algorithm](https://arxiv.org/abs/1908.02518), -[Hatcher, Algebraic Topology](https://pi.math.cornell.edu/~hatcher/AT/AT.pdf). diff --git a/browser-runtime/TOPOLOGY_VALIDATION_2026-09-05.md b/browser-runtime/TOPOLOGY_VALIDATION_2026-09-05.md deleted file mode 100644 index b9783767..00000000 --- a/browser-runtime/TOPOLOGY_VALIDATION_2026-09-05.md +++ /dev/null @@ -1,121 +0,0 @@ -# Topology validation — 5 September 2026 - -## Status - -This report records the earlier periodic-chart implementation. The subsequent -[synthetic surface and quotient-domain update](SYNTHETIC_SURFACE_VALIDATION_2026-09-05.md) -adds native two-field surface evidence and seam-aware Klein/RP2 steering. -Synthetic R^n validation is the acceptance scope; real-model validation is no -longer a prerequisite for geometric detection. - -The SAE source-contract assertion is fixed. Automatic topology discovery has -been hardened in Python and Rust/WASM, but it is **not an arbitrary-manifold -classifier** and remains disabled in the hosted production backend. Linear -fitting and explicitly authored geometry remain available. - -The `torus-Tn` identifier is retained for artifact compatibility. It names a -proposed periodic parameterization, not a certified homeomorphism or a semantic -claim about a model's representations. A PCA or spectral fallback is an -approximation, not evidence that the source manifold is flat or contractible. - -## Repairs - -- SAE source listings omit absent optional metadata rather than returning keys - with `undefined`. Real layer lists, description provenance, and explicit null - description bindings survive. Tests exercise both the in-process contract and - its JSON representation. -- The H1 counter no longer discards every finite bar. A small torus cycle can - die inside the observation window without being noise. Lifetime and an - interior connectivity margin screen candidates; these thresholds remain - heuristics, not calibrated confidence probabilities. -- A triangle-budget failure now raises. Dropping filling triangles can invent - cycles, so truncated reductions must never be treated as evidence. -- Constant quadratic forms in a distance-MDS span recover separate circle - factors when an arbitrary eigensolver basis mixes them. The checked - Laplacian fallback rejects vanishing/radially inconsistent eigenpairs and - harmonic duplicates. Geometry checks reject collapsed neighborhoods, - insufficient phase coverage, duplicate samples, and impossible ambient rank. -- The selector will not truncate an excessive H1 count into a supported torus - dimension. A periodic fit must also beat a mean-only GCV prediction baseline. - A plane can reconstruct a circle perfectly, so comparing only against flat - reconstruction would incorrectly discard periodic structure. -- Explicit errors remain errors or unresolved diagnostics, not successful - topology classifications. Existing authored geometry and the injection - kernel are unchanged. - -## Reproducible checks - -`fixtures/topology-adversarial-v1.csv` is shared by the Python and Rust tests. -Its 20 cases run in original, reordered, and rescaled variants. Positive cases -also require recovered phase coherence above 0.95, with distinct matches for -the torus axes; merely returning the expected axis count is insufficient. - -| Fixture family | What the tests establish | -| --- | --- | -| Circles, noisy circles, 6:1 ellipse | One periodic axis with accurate sampled phases | -| Product tori, including radii 1:0.3 and unequal sample counts | Two independent axes, without mixed-eigenvector folds | -| Very thin, disconnected 16×8 product-torus sample | Refusal, not a fabricated connected manifold | -| Sampled 3D doughnut tori | Currently unresolved; these are false-negative limitations, not successful detection | -| Wide and thin Möbius strips, cylinders | Tested collapsed-circle interpretations are rejected; surface type is not inferred | -| Fibonacci spheres and 50 seeded random spheres | Tested false periodic interpretations are rejected; no sphere classification claim | -| Open arc, grid, line | No periodic interpretation in the tested variants | -| Invalid matrices, duplicate points, invalid thresholds, exhausted budgets | Explicit validation or chart refusal | - -The shipped WASM exports additionally run thin-torus, thin-Möbius, sphere, -reordering, and poor-prediction-baseline checks under Node's WebAssembly engine. -This is not a live WebGPU model experiment or browser visual QA. - -Commands, from the repository root: - -```sh -.venv/bin/python -m pytest tests/test_topology_adversarial.py tests/test_manifold_topology.py tests/test_browser_topology_rbf_fixture.py tests/test_manifold_discover.py tests/test_manifold_math.py tests/test_manifold_extraction.py -q -cargo test --release --manifest-path browser-runtime/fitting-wasm/Cargo.toml -cargo clippy --manifest-path browser-runtime/fitting-wasm/Cargo.toml --all-targets -- -D warnings -npm --prefix webui run build:fitting-wasm -npm --prefix webui run test:runtime -npm --prefix webui run build:hosted -``` - -Existing fitted artifacts are not rewritten or re-certified. Explicitly refit -old automatic fits with `force=True` / `-f`; do not assume a cached fit has -passed the new checks. No package version was changed. - -## Required before general topology detection can ship - -Verification used the verify-changes workflow to trace the SAE contract, -topology consumers, and artifact boundary. Final results for this change: - -- 382 focused Python tests passed. -- 38 Rust tests passed, including 60 shared adversarial fixture variants; - Clippy passed with warnings denied. -- The complete `test:runtime` command passed, including the new WASM checks. -- Hosted build, build isolation, preview-shell checks, and reproducible WASM - asset verification passed. Svelte reported zero errors and zero warnings. -- The broader `npm run check` command is **not green**: its separate - `color-contrast.test.mjs:148` favicon/interaction-accent assertion fails. - Those styling files were not changed for this task. - -### Remaining implementation and validation work - -1. A richer, validated representation: higher homology, boundary and - orientability evidence, and compatible charts/atlas transitions. H1 alone - cannot distinguish a circle, cylinder, and Möbius strip. The current global - box/sphere domain choices are not an arbitrary-topology atlas. -2. A larger-sample, bounded sparse-persistence/circular-coordinate pipeline. - The current 128-node ceiling cannot resolve every thin or long torus. - Missing geometric features must lead to abstention, not inferred certainty. -3. Independent held-out geometry benchmarks: varied nonuniform sampling, - missing regions, contamination, aspect ratios, and embeddings. The included - regression fixtures helped develop these guards and are not an independent - validation set. Thresholds require sensitivity analysis and false-positive - calibration before a confidence score is meaningful. -4. Browser/runtime parity and validated chart recovery for any newly enabled - automatic domain. Native synthetic diagnostics alone do not implement the - compiled browser domain operations. Real-model semantic/behavioral claims - are outside the requested synthetic-geometry acceptance scope. - -Finite-sample recovery needs sampling and geometric assumptions; it does not -identify every arbitrary manifold from an arbitrary point cloud. See -[Niyogi, Smale and Weinberger, homology recovery from samples](https://math.uchicago.edu/~shmuel/NSW1.pdf). -For principled circle-valued coordinates rather than arbitrary eigenpair -angles, see [de Silva, Morozov and Vejdemo-Johansson](https://www.sci.utah.edu/~beiwang/teaching/cs6170-spring-2017/SilvaMorozovJohansson_2011.pdf). diff --git a/browser-runtime/USER_JOURNEY_E2E_AUDIT.md b/browser-runtime/USER_JOURNEY_E2E_AUDIT.md deleted file mode 100644 index eab798e8..00000000 --- a/browser-runtime/USER_JOURNEY_E2E_AUDIT.md +++ /dev/null @@ -1,175 +0,0 @@ -# Hosted Polythetic user-journey audit - -Audit date: 2026-08-30 - -This document records the end-to-end state of the hosted application. It separates four kinds of evidence so a deterministic fixture or unit test is never presented as proof of a production model release: - -- **Hands-on**: exercised through the rendered application in the Codex in-app browser. -- **Browser E2E**: exercised in Chromium through Playwright, including IndexedDB, OPFS, workers, service workers, offline mode, accessibility, mobile, and RTL layouts. -- **Physical WebGPU**: exercised with the current Gemma 3 270M q4f32 runtime, model files, core manifold pack, provider J-lens pack, and Gemma Scope 2 SAE pack at the 2K context profile on the local Apple/Metal WebGPU adapter. -- **Contract/math**: deterministic TypeScript, Python, or Rust/WASM coverage for lower-level behavior. - -The current result is: **the local development build and current Gemma physical -path pass, but the public hosted release remains intentionally locked**. The -model artifacts and signed distribution have not been published, so the -non-fixture `/app` correctly refuses model downloads. Cross-platform and -authoring evidence are optional QA, not release gates. - -## User journey catalogue - -| User journey | Result | Evidence and notes | -|---|---|---| -| Open `/` | Pass | Hands-on: landing page rendered the project purpose, local-processing promise, supported-device explanation, model tiers, source, license, and `Open Polythetic` action with a coherent heading hierarchy and skip link. Browser E2E also covers routing, 404 handling, 320 px reflow, and automated accessibility. | -| Open `/app` for the first time | Pass | Hands-on: compatibility check completed on a real WebGPU-capable browser and retained the adapter for the runtime path. The UI explained secure context, storage, browser, and hardware facts without calling advisory memory values VRAM. | -| Visit `/app` while production distribution is unverified | Pass, fail-closed | Hands-on: compatible hardware was reported as compatible, while model downloads remained disabled with an explicit distribution-verification explanation. This is the intended current public behavior. | -| Receive a model recommendation | Pass in fixture and policy tests | The selection and unsafe/uncertain distinction are covered by onboarding and policy tests. Unknown devices remain conservative; confirmed OOM history requires explicit retry. Production recommendations remain disabled until the signed model distribution is provisioned. | -| Choose optional tools on first install | Pass | Hands-on: J-lens and SAE were selected independently, their sizes were included, and the required core response controls were always included. Browser E2E covers omit, add, remove, reinstall, family replacement, runtime compatibility, and resident-memory rejection. | -| Start a download | Pass in fixture and physical signed-catalog run | Fixture onboarding showed exact bytes and clear source/license copy. The physical production-app harness admitted an ephemeral signed catalog, verified 27 signed files/25 unique hashes, and installed 330,178,828 bytes across model, core, J-lens, and SAE assets. | -| See progress, ETA, cancellation, and resume | Pass | Runtime and browser tests cover sequential files, one-second EWMA, stall handling, cancellation checkpoints, offline pause/resume, exact `Content-Range` validation, ignored ranges, changed ETags, hash/size corruption, quota checks, and crash recovery. | -| Open the installed model | Pass | Hands-on fixture opened the shared workbench. Physical WebGPU opened Gemma 3 270M q4f32 from verified OPFS content and later reopened it after explicit unload and worker/page recreation. | -| Send a chat message | Pass | Hands-on fixture streamed and completed two prompts. The physical production-app run completed online and offline responses using the real q4f32 backend. The 270M checkpoint is the fastest tier, not a quality tier. | -| Stop generation | Pass | Browser E2E covers the visible stop flow and reload-during-generation recovery. Physical WebGPU interrupted a 64-token request after one token and reported `finishReason: abort`. | -| Repeat generation and recover from reload | Pass | Browser E2E covers repeated generate/stop/reload cycles and removal of partial assistant output after mid-generation reload. The authoritative user turn remains stable. | -| Reroll a reply | Pass | Hands-on: reroll created a second assistant sibling under the same user turn with its changed steering recipe visible. Browser E2E independently asserts the sibling topology. | -| Explore conversation branches | Pass | Hands-on: the branch map showed depth, alternatives, steering deltas, and log-probability summaries. Keyboard-scoped tree navigation, filtering, starring, notes, branch mutation, and restoration are covered by E2E/runtime tests. | -| Compare two branches | Pass | Hands-on: side-by-side comparison rendered recipe delta, per-token log-probability changes, approximate KL, rank changes, and J-lens/SAE reading deltas. | -| Save, open, export, and import a conversation | Pass | Save/open drawers are included in responsive/accessibility coverage. Browser E2E round-trips transcript YAML through the worker and verifies authoritative loom persistence. | -| Change sampling | Pass | Hands-on: creativity, maximum length, raw/chat behavior, roles, and help text were visible; unsupported reasoning was disabled. Contract tests verify capability-filtered thinking modes and sampling persistence. | -| Change speakers and roles | Pass | Hands-on: role seats and cast editing opened correctly. Physical curved generation selected the named role `distant_voice`; explicit and inferred role-baseline conflicts fail before generation. | -| Add a concept or flat response direction | Pass in runtime/physical path | The fixture has no installed concept inventory, so this control is deliberately empty in the hands-on fixture. The physical core pack loaded `default/welcoming.detached`; the physical gate applied flat gated geometry, and shared Python/browser lowering fixtures cover push, projection, erasure, ablation, DLS, and affine composition. | -| Add a curved mood or scale | Pass in runtime/physical path | Physical WebGPU captured ten rows, spooled them through OPFS, ran the Rust/WASM fitting lifecycle, installed `local/browser_e2e_curve`, and generated with an active curved and geometry slot. Multidimensional, periodic, sphere, sigma, carried-foot, overlap, and orthogonalization cases are covered by structured hook/runtime tests. | -| Add J-lens steering or readings | Pass with the provider pack | Hands-on J-lens controls and readings remained usable. Physical Gemma attached `jlens/fake`, loaded 17 fitted layer matrices and the curated token dictionary, emitted exact probability readouts, and restored them after unload/offline reopen. | -| Add SAE steering or readings | Pass with Gemma Scope 2 | Hands-on SAE controls and readings remained usable. Physical Gemma loaded the layer-12 16,384-feature JumpReLU dictionary, emitted exact full-dictionary feature measurements, and restored it after unload/offline reopen. Browser SAE training remains absent. | -| Combine controls and use gates | Pass | Hands-on recipe combined J-lens and SAE terms. Contract tests cover manifold, SAE, J-lens, ablation, phases, prior-step dynamic gates, full-vocabulary J-lens probability gates, multidimensional/periodic curves, overlapping-curve rejection, and fixed-width GPU lanes. Physical WebGPU activated geometry, lens, and SAE gate families in one run. | -| Inspect a generated token | Pass | Hands-on: selecting `Polythetic` opened J-lens aggregate/per-layer data, SAE feature strength and metadata, explicit empty geometry state, and an actionable unavailable-alternatives state. Keyboard entry and focus restoration are covered by E2E. | -| Replay or fork a token | Pass | Physical forced replay scored alternatives, replayed two tokens, selected an alternate first token, and created a one-token fork. Browser E2E verifies recoverable replay failure when a fixture intentionally lacks the capability. | -| Inspect geometry and correlations | Pass | Hands-on empty states explained missing inputs instead of failing. Runtime tests cover Mahalanobis geometry, correlations, pairwise analysis, cross-layer comparison, and exclusion of J-lens/SAE readouts from residual-direction correlations. | -| Author a manifold | Pass in automated browser/runtime coverage | Browser E2E validates authored, discover, and template-backed forms; delayed validation focuses each blocking field. Runtime tests cover generate, extract, fit, merge, exact artifact publication, and rollback. A real physical curved fit passed. | -| Score prompt templates | Pass in automated browser/runtime coverage | The fitting lifecycle supports exact template scoring and cancellation. Browser artifact tests persist the exact template closure and reject conflicting identities or malformed storage. | -| Import, export, search, or delete `.polythetic` controls | Pass | Hands-on pack manager exposed import and Hugging Face discovery with publisher-integrity wording. Browser tests stream immutable HF packs through OPFS, bind provenance, round-trip exports, and roll back malformed installs. Python and browser ZIP validation cover traversal, collisions, links, special files, compression bombs, tensor schema, checksums, and limits. | -| View model health | Pass | Hands-on health drawer showed model/runtime, generation, loom revision/depth, artifacts, probe rows, matrix state, and warnings without console errors. | -| Close a drawer | Fixed and passing | The backdrop and visible close button previously shared the same accessible name. The backdrop is now pointer-only and `aria-hidden`; the visible button and Escape remain accessible. A regression test asserts one `Close drawer` action plus backdrop dismissal. | -| Manage the model and storage | Pass | Hands-on: close model, change model, model deletion, pack deletion, quota/persistence status, technical details, and clear-all were distinct. Browser E2E performs deletion in disposable storage and verifies that only the selected model, pack, session, or Polythetic-owned data is removed. | -| Use multiple tabs | Pass | Browser E2E verifies idle cooperative takeover, repeated transfer, and explicit approval before interrupting a busy owner. A requester times out rather than pretending Web Locks can force eviction. | -| Recover from device loss or OOM | Pass in orchestration tests | Worker tests cover one clean unknown-loss reload, changed-artifact rejection, verified-object eviction, loss during load/restore/generation, cleanup escalation, stale callbacks, and confirmed-OOM history. These destructive cases are not induced on the physical developer GPU. | -| Reload and work offline | Pass | Browser E2E covers PWA shell offline navigation and fixture generation without redownload. Physical production-app and lower-level gates both reopened the real installed model offline with zero artifact/network requests during the quiet window. | -| Receive a PWA update | Pass | E2E verifies update detection, explicit consent, clean runtime unload before reload, and preservation of local data. | -| Use mobile, keyboard, screen reader semantics, or RTL | Pass in automation | All hosted command and context drawers were tested at 320 px; touch targets, composer size, bidi fields, radio arrow behavior, focus return, landmark hierarchy, and RTL mirroring passed. Automated WCAG checks passed on landing, onboarding, workbench, every command drawer, and context-launched drawers. | -| Keep prompts and activations local | Pass in tested flows | Browser E2E asserts online fixture generation sends neither prompts nor activations. The physical production-app audit found no prompt uploads or unexpected external requests; the installed offline run made zero artifact requests. | -| Use the Python server/dashboard | Pass | The isolated default Vite build remained separate from the hosted PWA. Package isolation verified the 24-file dashboard closure, and the full Python suite preserved HTTP/WebSocket, CLI, server, artifact, SAE, J-lens, manifold, and bundled-dashboard behavior. | - -## Defects found and fixed - -### Duplicate accessible drawer-close action - -Every open drawer exposed two elements named `Close drawer`: the visible close button and the full-screen backdrop. Assistive technology and semantic browser automation could choose the backdrop, whose center was covered by the drawer, leaving the drawer open. - -The backdrop remains clickable for pointer dismissal but is now `aria-hidden` and no longer declares button semantics or a duplicate keyboard handler. The visible close button and Escape are the two clear keyboard-accessible dismissal paths. The regression exercises both the named close button and a click on the uncovered backdrop. - -### Gemma fp16 overflow - -Gemma 3 270M produced non-finite late-layer residuals in fp16 in both PyTorch and the browser runtime. The hosted variant now uses q4f32 weights and fp32 compute, does not require `shader-f16`, and has a separate runtime fingerprint. The real q4f32 model, core pack, J-lens pack, and SAE pack pass the production-app and 12-stage physical gates. - -### Missing exact JumpReLU VM registration - -The compiled model exported the exact JumpReLU readout kernel, but WebLLM did not load it into the VM function registry. The registry now includes `polythetic_sae_jump_relu_readout_accumulate`, with overlay and physical-generation regression coverage. - -### Gemma named-role rendering - -Named assistant roles initially supported only ChatML `<|im_start|>` headers. Gemma uses `model`; the role renderer now preserves both prefix families, de-slugs the label, and leaves ordinary unnamed chat rendering unchanged. The physical curved-fit and named-role generation stages pass. - -### Production-q4 parity ordering and probe metric - -The first parity fixture compared outputs from separate ordinary-capture and -rank-one-capture VM functions. Small compiled-graph drift could therefore appear -before the enabled layer and corrupt the steering cosine. Schema-v3 captures now -run disabled and enabled programs through the same rank-one VM function, require -zero pre-enabled delta, and compare enabled-minus-disabled steering. - -Probe parity is normalized by the activation scale rather than by the norm of a -possibly near-zero scalar trace. Browser probe readback is separately checked -against the dot product of its own captured residual. Fresh SmolLM2, Gemma, and -Qwen3 candidates all pass the unchanged 1% capture/probe and 0.99 cosine gates. - -### Exact q4f32 comparator dispatch - -The local PyTorch/Metal comparator accepted Gemma q4f32 metadata but routed every -bias-free linear through its fp16-only kernel. It now dispatches float16 and -float32 tensors to separate exact Metal FMA kernels. The fresh Gemma comparison -passes with maximum capture error `8.29e-6`, maximum activation-normalized probe -error `2.13e-7`, steering cosine `1.0000005`, and exact greedy tokens. - -### Minimal-tokenizer capture compatibility - -Trailing ChatML whitespace trimming initially assumed every tokenizer exposed -`decode()`. The capture path now retains the older special-token-only behavior -for minimal tokenizer implementations while real tokenizers still trim the -terminal newline. The affected 151-test capture/manifold/neutral-cache cluster -and the complete Python suites pass. - -No other application error, warning, failed request, uncaught page error, or WebGPU error was observed in the hands-on or physical-browser audits. - -## Verification results - -| Gate | Result | -|---|---| -| Hands-on landing, first run, fixture install, workbench, generation, steering, probes, reload, drawers, reroll, branch comparison, transcript, storage, and browser-console audit | Pass; browser console had 0 warnings and 0 errors | -| Playwright hosted E2E | 79 passed | -| Svelte/type/theme/runtime-boundary/interface policy | Pass; 0 Svelte errors and 0 warnings; 239 source files checked | -| Hosted runtime, downloader, worker, storage, authoring, release-tool, and dependency audit | Pass; `npm run test:hosted`; 0 high-severity npm vulnerabilities and 0 total reported vulnerabilities | -| Hosted production build isolation | Pass; 40 files; PWA generated with 39 precache entries | -| Python-dashboard production build isolation | Pass; 24 files | -| Wheel and source distribution dirty-cache isolation | Pass; wheel and sdist built; 24 dashboard files verified | -| Rust/WASM | 37 tests passed; Clippy passed with warnings denied | -| Python regression suite | Pass; non-GPU: 3,465 passed and 20 skipped; real MPS: 48 passed and 3 skipped | -| Physical production-q4 parity | Pass locally for SmolLM2-360M, Gemma 3 270M, and Qwen3-1.7B; exact greedy tokens, ordered rank-one steering, capture/probe tolerance, and steering cosine gates all passed | -| Physical production-app Gemma 3 270M gate | Pass; verified install/load/reopen, provider J-lens and Gemma Scope 2 SAE measurements, online/offline generation, 0 artifact requests after install, empty network/error audits | -| Physical 12-stage Gemma WebGPU gate | Pass; all required checks passed in order, including replay, capture, flat gated instruments, curved fitting/generation with a named role, stop, reload, and offline reuse | -| Local model/context WebGPU matrix | Current Gemma 2K macOS/Chrome path passed; broader device coverage remains optional support QA | -| Instrument pack validation | Pass; the precomputed provider J-lens and Gemma Scope 2 JumpReLU SAE load and execute on the GPU without browser-side fitting or training | -| Public release guard | Correctly fails closed on unpublished model artifacts and the unprovisioned signed distribution; evidence registries are informational | - -Physical reports from this audit: - -- `/private/tmp/polythetic-gemma-production-app-candidate-v4.json` -- `/private/tmp/polythetic-gemma-full-runtime-candidate-v4.json` -- `/private/tmp/polythetic-gemma-candidate-capture-dense-v1/` -- `/private/tmp/polythetic-smollm2-capture-dense-probe-v1/` -- `/private/tmp/polythetic-qwen3-1.7b-candidate-20260830/capture-v3/` - -The JSON reports explicitly set `releaseEvidence: false`, and the captures use -candidate runtime-lock overrides. They remain useful local engineering checks. -Their throughput fields come from the harness's short ordinary-generation -prompt; they are diagnostics, not a long-context benchmark claim. - -## Remaining public-release blockers - -The application itself is locally functional, but deployment remains -download-locked until these practical requirements are resolved: - -1. Choose the model subset to ship and publish immutable converted revisions - for those models. A Gemma-only 2K launch is valid. -2. Publish each shipped model's required core pack and any compatible - precomputed J-lens or SAE packs that already exist. - Publish the SAE pack only when SAE features are offered for that model. -3. Fill the artifact hashes/revisions and mark `runtime-lock.json` verified. -4. Publish and sign the production catalog, fill the observed artifact redirect - origins, and mark `distribution-lock.json` verified. -5. Validate Hugging Face CORS/range/redirect behavior and the production - Cloudflare CSP/COOP/COEP headers at the deployed origin. - -Fork and compiler attestations, authoring evidence, evidence producers, Git -ancestry checks, all-three-model closure, mandatory 4K support, and the 48-cell -benchmark matrix are no longer public-release blockers. - -Until those are complete, a compatible visitor sees a truthful compatibility result and an unavailable download action. That is the correct behavior, not a user-facing runtime failure. - -## Deliberate hosted limits - -These are not bugs and should remain hidden or explicitly unavailable in hosted mode: - -- SAE training. -- J-lens fitting. -- OpenAI/Ollama/server HTTP endpoints. -- Python server-session administration. -- CPU-only or cloud inference fallback. diff --git a/browser-runtime/authoring-evidence.json b/browser-runtime/authoring-evidence.json deleted file mode 100644 index 95bd024c..00000000 --- a/browser-runtime/authoring-evidence.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "./authoring-evidence.schema.json", - "schemaVersion": 3, - "status": "feasibility-required", - "polytheticRevision": null, - "evidence": { - "activationCapture": null, - "fittingKernelParity": null, - "topologyOrchestration": null, - "manifoldSerialization": null, - "instrumentIntegration": null, - "sharedGoldenResults": null, - "physicalBrowserFitting": null - } -} diff --git a/browser-runtime/base-model-release-evidence.json b/browser-runtime/base-model-release-evidence.json deleted file mode 100644 index 30e88da0..00000000 --- a/browser-runtime/base-model-release-evidence.json +++ /dev/null @@ -1,3035 +0,0 @@ -{ - "schemaVersion": 1, - "recordedAt": "2026-09-06T09:16:57.751Z", - "scope": "Core-only base-model installation and measured numerical behavior on one Apple Metal/Chrome device. Not universal platform, prompt, semantic steering-quality, or bit-exact certification.", - "catalog": { - "repository": "logitsml/drowse-web-catalog", - "revision": "9ed3c63c8840fd93a53fcf8012c9c2d46315a5aa", - "sequence": 3, - "catalogSha256": "a6ac8309c0fd1f14c87ea79c14c44faa1195609fdced66e5d91c3fe43d06946c", - "models": [ - "gpt2-base", - "pythia-70m-base", - "gemma3-1b-pt", - "qwen35-2b-base" - ] - }, - "models": [ - { - "id": "gpt2-base", - "repository": "logitsml/drowse-web-gpt2-base", - "revision": "787a18eed89e1c5e342382c6b88fb5f4dcd5f978", - "preflight": { - "reportSha256": "033d6bd7279c52d10ed32dc22a2b4c3cb370acc3a26c9a03cafc05470c5cf6d0", - "files": 29, - "bytes": 672193509, - "checkedAt": "2026-09-06T08:09:55.596Z" - }, - "browserRuns": [ - { - "reportSha256": "87d82b93eb80eef06d4e60be71c450c7d6853faadaac3c411ab9e148ace6e68d", - "status": "passed-smoke-only", - "startedAt": "2026-09-06T08:25:43.186Z", - "finishedAt": "2026-09-06T08:25:57.469Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "bgra8unorm-storage", - "texture-formats-tier1", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "timestamp-query", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "gpt2", - "quantization": "q0f32", - "sourceRepository": "openai-community/gpt2", - "sourceRevision": "607a30d783dfa663caf39e06633721c8d4cfcd7e", - "modelBuildSha256": "d7e9eb8f5fb9b64f4f77221f99373c1d1f1ebcbf0bc8bbb1f9e822e7df8abd29", - "librarySha256": "858a656f68972067a27d8d702dbec641300b3fff266f0be96c519f05ba1bda48", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 996, - "inputIdsSha256": "6d73227930540b93c924b40719f65eb8e4662bde6a0310396321c97ee684a12d", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 995 - ], - "captureShape": [ - 12, - 9, - 768 - ], - "generatedIds": [ - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0, - "branchReplayMaxAbs": 0, - "forcedEosChecks": [ - { - "token": 50256, - "finishReason": "stop", - "completion": "" - } - ] - } - ], - "accuracy": [ - { - "reportSha256": "68ea7fd31c18862cef74f17d86fec831bf53d6652753cf517c0690ad10e75a5f", - "referenceWeights": "original-checkpoint", - "referenceArchitecture": "source-config", - "referenceAttention": "eager", - "referencePrecision": "torch.float32", - "referenceDevice": "cpu", - "torchVersion": "2.13.0", - "inputTokens": 996, - "logits": { - "cosine": 0.9999999999999801, - "relativeL2": 1.6980542267273408e-7, - "rmse": 0.00004331705788323176, - "maxAbs": 0.000152587890625 - }, - "maximumLayerRelativeL2": 9.827628942051264e-7, - "maximumPositionRelativeL2": 0.0000019707431792362045, - "maximumLayerAbsolute": 0.000701904296875, - "greedyTokenIdsMatch": true, - "referenceGeneratedIds": [ - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926 - ], - "browserGeneratedIds": [ - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926, - 1667, - 27926 - ], - "browserArtifact": { - "schemaVersion": 1, - "source": { - "chatTemplateSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "files": [ - { - "bytes": 8092, - "path": "README.md", - "sha256": "0fcd631078093c2aa1d93438b898320b8a1167784e2a1ab37b8016e9de8b3c2e" - }, - { - "bytes": 665, - "path": "config.json", - "sha256": "0daed7749b4f02b8f76240d5444551d7b08712dab4d0adb8239c56ba823bb7b4" - }, - { - "bytes": 124, - "path": "generation_config.json", - "sha256": "ed0b32ac72c0f5f44a719abb2d7786ea5146c871f83717b7f2018065954de02b" - }, - { - "bytes": 456318, - "path": "merges.txt", - "sha256": "1ce1664773c50f3e0cc8842619a93edc4624525b728b188a9e0be33b7726adc5" - }, - { - "bytes": 548105171, - "path": "model.safetensors", - "sha256": "248dfc3911869ec493c76e65bf2fcf7f615828b0254c12b473182f0f81d3a707" - }, - { - "bytes": 1355256, - "path": "tokenizer.json", - "sha256": "8414cab924d8b9b33013f0d221c5862f365ee9be39c5c2bfae8a5a9e970478a6" - }, - { - "bytes": 26, - "path": "tokenizer_config.json", - "sha256": "5e04eb606e3a1583530a42e36c2a6b6615c86f34fe77e44d9ddeb43ff940931f" - }, - { - "bytes": 1042301, - "path": "vocab.json", - "sha256": "196139668be63f3b5d6574427317ae82f612a97c5d1cdaf36ed2256dbf636783" - } - ], - "repository": "openai-community/gpt2", - "revision": "607a30d783dfa663caf39e06633721c8d4cfcd7e" - }, - "modelBuildSha256": "d7e9eb8f5fb9b64f4f77221f99373c1d1f1ebcbf0bc8bbb1f9e822e7df8abd29", - "librarySha256": "858a656f68972067a27d8d702dbec641300b3fff266f0be96c519f05ba1bda48", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "architecture": "gpt2", - "quantization": "q0f32", - "contextTokens": 1024 - } - } - ], - "coreOnlyRuntime": { - "reportSha256": "5b1e7c8ac35984cf0aae3b19daea55d28ea9683ce86512f60c74eb7c4c041fac", - "scope": "production runtime core-only load and offline model reload; not signed installation or offline page navigation", - "optionalPacks": 0, - "networkAttempts": [], - "deviceLosses": [], - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "status": "passed", - "checks": [ - { - "type": "check", - "name": "core-only load", - "values": { - "identity": "986375f3fe036f2a2170d1dc57beaaeb132c6e40be792e61da4cc9fb6388fb0e", - "optionalPacks": 0, - "layers": 12 - } - }, - { - "type": "check", - "name": "base generation", - "values": { - "ids": [ - 484, - 821, - 523, - 2562, - 284, - 787, - 13, - 314, - 1842, - 262, - 835, - 484, - 804, - 13, - 314, - 1842, - 262, - 835, - 484, - 804, - 13, - 314, - 1842, - 262 - ], - "performance": { - "text": " they're so easy to make. I love the way they look. I love the way they look. I love the", - "thinkingText": null, - "tokens": 24, - "finishReason": "length", - "terminalReason": "length", - "usage": { - "promptTokens": 6, - "completionTokens": 24, - "totalTokens": 30 - }, - "meanLogprob": 0, - "meanSurprise": 0, - "prefillTokensPerSecond": 7.81753864800526, - "decodeTokensPerSecond": 22.019894491158578 - } - } - }, - { - "type": "check", - "name": "physical core steering", - "values": { - "expression": "0.5 default/welcoming.detached", - "ordinaryLogprob": -0.7599400766089991, - "steeredLogprob": -1.3728146313335237, - "ids": [ - 314, - 1101, - 523, - 12008, - 286, - 606, - 526, - 198, - 198, - 1, - 40, - 1101, - 407, - 1107, - 257, - 1263, - 11, - 314, - 1101, - 407, - 1107, - 257, - 1263, - 11 - ] - } - }, - { - "type": "check", - "name": "network-blocked OPFS model reload", - "values": { - "networkAttempts": 0, - "baselineIds": [ - 484, - 821, - 523, - 2562, - 284, - 787, - 13, - 314, - 1842, - 262, - 835, - 484, - 804, - 13, - 314, - 1842, - 262, - 835, - 484, - 804, - 13, - 314, - 1842, - 262 - ], - "steeredIds": [ - 314, - 1101, - 523, - 12008, - 286, - 606, - 526, - 198, - 198, - 1, - 40, - 1101, - 407, - 1107, - 257, - 1263, - 11, - 314, - 1101, - 407, - 1107, - 257, - 1263, - 11 - ] - } - } - ], - "blockedServerRequests": [], - "modelId": "gpt2-base", - "runtimeIdentity": { - "sourceModel": "openai-community/gpt2", - "sourceRevision": "607a30d783dfa663caf39e06633721c8d4cfcd7e", - "convertedManifestSha256": "571e5c3a42148b976ceb2b714408cf48589d6fc2d71ff20101586577773124d5", - "quantization": "q0f32", - "tokenizerSha256": "8414cab924d8b9b33013f0d221c5862f365ee9be39c5c2bfae8a5a9e970478a6", - "chatTemplateSha256": "5e04eb606e3a1583530a42e36c2a6b6615c86f34fe77e44d9ddeb43ff940931f", - "modelLibrarySha256": "858a656f68972067a27d8d702dbec641300b3fff266f0be96c519f05ba1bda48", - "runtimeAbi": "drowse-web-runtime-v1", - "hookAbi": "post-block-residual-v4", - "hiddenSize": 768, - "layerMap": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11 - ] - }, - "recordedAt": "2026-09-06T08:04:01.366Z" - }, - "appUiChecks": { - "method": "manual interaction in physical Chrome with signed catalog and real model weights", - "signedDownloadAndOpen": true, - "rawGeneration": true, - "coreSteeringGeneration": true, - "fullPageReload": true, - "reopenSavedCompletion": true, - "generationAfterReopen": true, - "optionalPacksInstalled": 0, - "offlinePageNavigationTested": false - } - }, - { - "id": "pythia-70m-base", - "repository": "logitsml/drowse-web-pythia-70m-base", - "revision": "b312ef57bd3852969fd43c8254ceb93b79317d27", - "preflight": { - "reportSha256": "229a892a2ea6e9f5d2bb3b678f72536302a9abdce4e41d955784d3466d75564c", - "files": 19, - "bytes": 294738051, - "checkedAt": "2026-09-06T08:10:54.060Z" - }, - "browserRuns": [ - { - "reportSha256": "5cfbe784cf79f1106c7300521d6c368d6e7c0d26630f05cc97f23abdbad16705", - "status": "passed-smoke-only", - "startedAt": "2026-09-06T08:26:55.507Z", - "finishedAt": "2026-09-06T08:27:22.523Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "timestamp-query", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "gpt_neox", - "quantization": "q0f32", - "sourceRepository": "EleutherAI/pythia-70m-deduped", - "sourceRevision": "e93a9faa9c77e5d09219f6c868bfc7a1bd65593c", - "modelBuildSha256": "6523423c1b898671726687f94fdaec03f6220c06077f2871d44c9bf2484905a5", - "librarySha256": "f44343c7f80be8c1a9aa058f57ee21aa0882cbbba13060b59f91916fcffb83f2", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1926, - "inputIdsSha256": "3509e285c6ed0b6d6fadf414faae6eed9b5dafc65bf2b040f602b6751c92dab7", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1925 - ], - "captureShape": [ - 6, - 12, - 512 - ], - "generatedIds": [ - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0, - "branchReplayMaxAbs": 0, - "forcedEosChecks": [ - { - "token": 0, - "finishReason": "stop", - "completion": "" - } - ] - } - ], - "accuracy": [ - { - "reportSha256": "86fee6bb6bc1ba6b4f1ede23115508949b2c3461865f94d38652ab463b09ee39", - "referenceWeights": "original-checkpoint", - "referenceArchitecture": "source-config", - "referenceAttention": "eager", - "referencePrecision": "torch.float32", - "referenceDevice": "cpu", - "torchVersion": "2.13.0", - "inputTokens": 1926, - "logits": { - "cosine": 0.9999999999995638, - "relativeL2": 0.0000012902040491668387, - "rmse": 0.002005498225841566, - "maxAbs": 0.0076904296875 - }, - "maximumLayerRelativeL2": 0.0003002113626412633, - "maximumPositionRelativeL2": 0.0009829584639300865, - "maximumLayerAbsolute": 0.003325223922729492, - "greedyTokenIdsMatch": true, - "referenceGeneratedIds": [ - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302 - ], - "browserGeneratedIds": [ - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302, - 278, - 1513, - 302 - ], - "browserArtifact": { - "schemaVersion": 1, - "source": { - "chatTemplateSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "files": [ - { - "bytes": 13677, - "path": "README.md", - "sha256": "0b8eff9fd326d9089f00c4984db07f89a9dac674ae3191a9bc8ae128b8a37580" - }, - { - "bytes": 567, - "path": "config.json", - "sha256": "002050231a9b1ec3ac77aa6b9b3bbdc4d923f4068a7dd33b8da72a9bd6ad9a43" - }, - { - "bytes": 166029852, - "path": "model.safetensors", - "sha256": "3da388330e4549156d76b58d6d268c63cd005e9336b4f4d2d378421e7b7a33fd" - }, - { - "bytes": 99, - "path": "special_tokens_map.json", - "sha256": "6f50ab5a5a509a1c309d6171f339b196a900dc9c99ad0408ff23bb615fdae7ad" - }, - { - "bytes": 2113710, - "path": "tokenizer.json", - "sha256": "c24618a1b3e6a38167beff1c72cffd126c3a66254347304b50547d12c5f25624" - }, - { - "bytes": 396, - "path": "tokenizer_config.json", - "sha256": "70e38394e494931c6f773ba41e19460dd4436526b852207367f04341b4066d3f" - } - ], - "repository": "EleutherAI/pythia-70m-deduped", - "revision": "e93a9faa9c77e5d09219f6c868bfc7a1bd65593c" - }, - "modelBuildSha256": "6523423c1b898671726687f94fdaec03f6220c06077f2871d44c9bf2484905a5", - "librarySha256": "f44343c7f80be8c1a9aa058f57ee21aa0882cbbba13060b59f91916fcffb83f2", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "architecture": "gpt_neox", - "quantization": "q0f32", - "contextTokens": 2048 - } - } - ], - "coreOnlyRuntime": { - "reportSha256": "0be23fc8106ee30d60522d2f2269ee36d58824ba730d550ef2223640fdaed012", - "scope": "production runtime core-only load and offline model reload; not signed installation or offline page navigation", - "optionalPacks": 0, - "networkAttempts": [], - "deviceLosses": [], - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "status": "passed", - "checks": [ - { - "type": "check", - "name": "core-only load", - "values": { - "identity": "40d46d0ca1a69f14a40eaf707aa65bb35750aa0283d5a358ac5b7034e497531b", - "optionalPacks": 0, - "layers": 6 - } - }, - { - "type": "check", - "name": "base generation", - "values": { - "ids": [ - 597, - 403, - 253, - 1682, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731 - ], - "performance": { - "text": " they are the best. I love them. I love them. I love them. I love them. I love them", - "thinkingText": null, - "tokens": 24, - "finishReason": "length", - "terminalReason": "length", - "usage": { - "promptTokens": 6, - "completionTokens": 24, - "totalTokens": 30 - }, - "meanLogprob": 0, - "meanSurprise": 0, - "prefillTokensPerSecond": 6.4879243511031435, - "decodeTokensPerSecond": 41.514372087975964 - } - } - }, - { - "type": "check", - "name": "physical core steering", - "values": { - "expression": "0.5 default/welcoming.detached", - "ordinaryLogprob": -1.3255881640731364, - "steeredLogprob": -1.5769882339144625, - "ids": [ - 309, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449 - ] - } - }, - { - "type": "check", - "name": "network-blocked OPFS model reload", - "values": { - "networkAttempts": 0, - "baselineIds": [ - 597, - 403, - 253, - 1682, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731, - 15, - 309, - 2389, - 731 - ], - "steeredIds": [ - 309, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449, - 346, - 42, - 2389, - 731, - 449 - ] - } - } - ], - "blockedServerRequests": [], - "modelId": "pythia-70m-base", - "runtimeIdentity": { - "sourceModel": "EleutherAI/pythia-70m-deduped", - "sourceRevision": "e93a9faa9c77e5d09219f6c868bfc7a1bd65593c", - "convertedManifestSha256": "587eee3dadf689c9354c76452e618a14df7c6ad50b0ea88b3e68dcca9ed4872d", - "quantization": "q0f32", - "tokenizerSha256": "c24618a1b3e6a38167beff1c72cffd126c3a66254347304b50547d12c5f25624", - "chatTemplateSha256": "70e38394e494931c6f773ba41e19460dd4436526b852207367f04341b4066d3f", - "modelLibrarySha256": "f44343c7f80be8c1a9aa058f57ee21aa0882cbbba13060b59f91916fcffb83f2", - "runtimeAbi": "drowse-web-runtime-v1", - "hookAbi": "post-block-residual-v4", - "hiddenSize": 512, - "layerMap": [ - 0, - 1, - 2, - 3, - 4, - 5 - ] - }, - "recordedAt": "2026-09-06T08:07:56.964Z" - }, - "appUiChecks": { - "method": "manual interaction in physical Chrome with signed catalog and real model weights", - "signedDownloadAndOpen": true, - "rawGeneration": true, - "coreSteeringGeneration": true, - "fullPageReload": true, - "reopenSavedCompletion": true, - "generationAfterReopen": true, - "optionalPacksInstalled": 0, - "offlinePageNavigationTested": false - } - }, - { - "id": "gemma3-1b-pt", - "repository": "logitsml/drowse-web-gemma3-1b-pt", - "revision": "b771368a80809580545d340358de1ceab28632f4", - "preflight": { - "reportSha256": "cc153cdce6c5a524aeca1f66edb41f204331e28082305d66512cd831ef76a715", - "files": 31, - "bytes": 638672075, - "checkedAt": "2026-09-06T08:10:59.869Z" - }, - "browserRuns": [ - { - "reportSha256": "ecc08bd9d91e541a2b99558c11e30d91ef33a965cc4f09f8791fa45d62bf617f", - "status": "passed-smoke-only", - "startedAt": "2026-09-06T07:43:42.008Z", - "finishedAt": "2026-09-06T07:44:26.048Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "shader-f16", - "texture-formats-tier2", - "clip-distances", - "timestamp-query", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "gemma3_text", - "quantization": "q4f32_1", - "sourceRepository": "google/gemma-3-1b-pt", - "sourceRevision": "fcf18a2a879aab110ca39f8bffbccd5d49d8eb29", - "modelBuildSha256": "3691c7875d4b52c335b70bde9347768a2ca388be03405c821a90b2a3c39e8a76", - "librarySha256": "9a53f7e3ec75a531441ad190191c7c183d945110f0c05c31882688fca4eba451", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 6, - "inputIdsSha256": "11e794857213ed37d12af68d884920c67a921dce4a598ff6d8921edf24c3266f", - "capturePositions": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "captureShape": [ - 26, - 6, - 1152 - ], - "generatedIds": [ - 901, - 659, - 834, - 12864, - 532, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498, - 1547, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0, - "branchReplayMaxAbs": 0, - "forcedEosChecks": [ - { - "token": 1, - "finishReason": "stop", - "completion": "" - }, - { - "token": 106, - "finishReason": "stop", - "completion": "" - } - ] - }, - { - "reportSha256": "9ce168285359be4f445f7d83dd89c1d4eac7ff4d1cf311c6e130f21b2c2ed63d", - "status": "passed-smoke-only", - "startedAt": "2026-09-06T07:46:15.976Z", - "finishedAt": "2026-09-06T07:49:38.512Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "timestamp-query", - "shader-f16", - "clip-distances", - "texture-formats-tier2", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "gemma3_text", - "quantization": "q4f32_1", - "sourceRepository": "google/gemma-3-1b-pt", - "sourceRevision": "fcf18a2a879aab110ca39f8bffbccd5d49d8eb29", - "modelBuildSha256": "3691c7875d4b52c335b70bde9347768a2ca388be03405c821a90b2a3c39e8a76", - "librarySha256": "9a53f7e3ec75a531441ad190191c7c183d945110f0c05c31882688fca4eba451", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1806, - "inputIdsSha256": "9df099c749f6528e926e9906577c2c6d6295ff3056323d49728859fb68849dd0", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1805 - ], - "captureShape": [ - 26, - 12, - 1152 - ], - "generatedIds": [ - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0, - "branchReplayMaxAbs": 0, - "forcedEosChecks": [ - { - "token": 1, - "finishReason": "stop", - "completion": "" - }, - { - "token": 106, - "finishReason": "stop", - "completion": "" - } - ] - } - ], - "accuracy": [ - { - "reportSha256": "426b640db8ca25e329accd0560ee22b14217aa5abc70e5fc95922fef2a4bf840", - "referenceWeights": "exact-dequantized-browser", - "referenceArchitecture": "source-config", - "referenceAttention": "eager", - "referencePrecision": "torch.float32", - "referenceDevice": "cpu", - "torchVersion": "2.13.0", - "inputTokens": 6, - "logits": { - "cosine": 0.9999999999995084, - "relativeL2": 9.658430104632945e-7, - "rmse": 0.000007163434439414066, - "maxAbs": 0.0000400543212890625 - }, - "maximumLayerRelativeL2": 0.0000012945004571110207, - "maximumPositionRelativeL2": 0.0000024863181598439893, - "maximumLayerAbsolute": 0.015625, - "greedyTokenIdsMatch": true, - "referenceGeneratedIds": [ - 901, - 659, - 834, - 12864, - 532, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498, - 1547, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498 - ], - "browserGeneratedIds": [ - 901, - 659, - 834, - 12864, - 532, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498, - 1547, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498 - ], - "browserArtifact": { - "schemaVersion": 1, - "source": { - "chatTemplateSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "files": [ - { - "bytes": 23496, - "path": "README.md", - "sha256": "1a07e8c0d17528f69c487b2f84abcdd9144ab959335417cd00bf9930f2598fdd" - }, - { - "bytes": 35, - "path": "added_tokens.json", - "sha256": "50b2f405ba56a26d4913fd772089992252d7f942123cc0a034d96424221ba946" - }, - { - "bytes": 880, - "path": "config.json", - "sha256": "4dd5218cebc4fdea9004b944d34672a2d47f9ef930e3bb16a3fc4bbbe0fcee81" - }, - { - "bytes": 215, - "path": "generation_config.json", - "sha256": "fd9324becc53c4be610db39e13a613006f09fd6ef71a95fb6320dc33157490a3" - }, - { - "bytes": 1999811208, - "path": "model.safetensors", - "sha256": "ee5250f6eb1aa7cfb729dfd4dc8d9964fd772324776c6d00bf2bc674c069cb27" - }, - { - "bytes": 662, - "path": "special_tokens_map.json", - "sha256": "2f7b0adf4fb469770bb1490e3e35df87b1dc578246c5e7e6fc76ecf33213a397" - }, - { - "bytes": 33384570, - "path": "tokenizer.json", - "sha256": "7d4046bf0505a327dd5a0abbb427ecd4fc82f99c2ceaa170bc61ecde12809b0c" - }, - { - "bytes": 4689074, - "path": "tokenizer.model", - "sha256": "1299c11d7cf632ef3b4e11937501358ada021bbdf7c47638d13c0ee982f2e79c" - }, - { - "bytes": 1155349, - "path": "tokenizer_config.json", - "sha256": "4d97b6d876fd05ffaf72c3243231975c50263ad4fc620bc9f0b44be2ca11fa31" - } - ], - "repository": "google/gemma-3-1b-pt", - "revision": "fcf18a2a879aab110ca39f8bffbccd5d49d8eb29" - }, - "modelBuildSha256": "3691c7875d4b52c335b70bde9347768a2ca388be03405c821a90b2a3c39e8a76", - "librarySha256": "9a53f7e3ec75a531441ad190191c7c183d945110f0c05c31882688fca4eba451", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "architecture": "gemma3_text", - "quantization": "q4f32_1", - "contextTokens": 2048 - } - }, - { - "reportSha256": "f7c4e9828ddcf7c56bab03dfb756c99104cf53c0ccf8c8ef3335280dfea5af11", - "referenceWeights": "exact-dequantized-browser", - "referenceArchitecture": "source-config", - "referenceAttention": "eager", - "referencePrecision": "torch.float32", - "referenceDevice": "cpu", - "torchVersion": "2.13.0", - "inputTokens": 1806, - "logits": { - "cosine": 0.9999999999858911, - "relativeL2": 0.0000070703578094593805, - "rmse": 0.000049053374083495015, - "maxAbs": 0.000217437744140625 - }, - "maximumLayerRelativeL2": 0.0000026333325977528664, - "maximumPositionRelativeL2": 0.000017361638168987536, - "maximumLayerAbsolute": 0.208984375, - "greedyTokenIdsMatch": true, - "referenceGeneratedIds": [ - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557 - ], - "browserGeneratedIds": [ - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557, - 96863, - 557 - ], - "browserArtifact": { - "schemaVersion": 1, - "source": { - "chatTemplateSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "files": [ - { - "bytes": 23496, - "path": "README.md", - "sha256": "1a07e8c0d17528f69c487b2f84abcdd9144ab959335417cd00bf9930f2598fdd" - }, - { - "bytes": 35, - "path": "added_tokens.json", - "sha256": "50b2f405ba56a26d4913fd772089992252d7f942123cc0a034d96424221ba946" - }, - { - "bytes": 880, - "path": "config.json", - "sha256": "4dd5218cebc4fdea9004b944d34672a2d47f9ef930e3bb16a3fc4bbbe0fcee81" - }, - { - "bytes": 215, - "path": "generation_config.json", - "sha256": "fd9324becc53c4be610db39e13a613006f09fd6ef71a95fb6320dc33157490a3" - }, - { - "bytes": 1999811208, - "path": "model.safetensors", - "sha256": "ee5250f6eb1aa7cfb729dfd4dc8d9964fd772324776c6d00bf2bc674c069cb27" - }, - { - "bytes": 662, - "path": "special_tokens_map.json", - "sha256": "2f7b0adf4fb469770bb1490e3e35df87b1dc578246c5e7e6fc76ecf33213a397" - }, - { - "bytes": 33384570, - "path": "tokenizer.json", - "sha256": "7d4046bf0505a327dd5a0abbb427ecd4fc82f99c2ceaa170bc61ecde12809b0c" - }, - { - "bytes": 4689074, - "path": "tokenizer.model", - "sha256": "1299c11d7cf632ef3b4e11937501358ada021bbdf7c47638d13c0ee982f2e79c" - }, - { - "bytes": 1155349, - "path": "tokenizer_config.json", - "sha256": "4d97b6d876fd05ffaf72c3243231975c50263ad4fc620bc9f0b44be2ca11fa31" - } - ], - "repository": "google/gemma-3-1b-pt", - "revision": "fcf18a2a879aab110ca39f8bffbccd5d49d8eb29" - }, - "modelBuildSha256": "3691c7875d4b52c335b70bde9347768a2ca388be03405c821a90b2a3c39e8a76", - "librarySha256": "9a53f7e3ec75a531441ad190191c7c183d945110f0c05c31882688fca4eba451", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "architecture": "gemma3_text", - "quantization": "q4f32_1", - "contextTokens": 2048 - } - } - ], - "coreOnlyRuntime": { - "reportSha256": "9f815cbeb21298a4652908440e1cf29ce82ed13db6f493bf08d809c75ef30426", - "scope": "production runtime core-only load and offline model reload; not signed installation or offline page navigation", - "optionalPacks": 0, - "networkAttempts": [], - "deviceLosses": [], - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "status": "passed", - "checks": [ - { - "type": "check", - "name": "core-only load", - "values": { - "identity": "df89e3eafd8c8cea7ab2039b24079341a587480c4d072165326928af49cb3738", - "optionalPacks": 0, - "layers": 26 - } - }, - { - "type": "check", - "name": "base generation", - "values": { - "ids": [ - 901, - 659, - 834, - 12864, - 532, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498, - 1547, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498 - ], - "performance": { - "text": " they are so cute and they are so cute. I love marmots because they are so cute. I love marmots", - "thinkingText": null, - "tokens": 24, - "finishReason": "length", - "terminalReason": "length", - "usage": { - "promptTokens": 6, - "completionTokens": 24, - "totalTokens": 30 - }, - "meanLogprob": 0, - "meanSurprise": 0, - "prefillTokensPerSecond": 11.158534885952946, - "decodeTokensPerSecond": 11.990313912167894 - } - } - }, - { - "type": "check", - "name": "physical core steering", - "values": { - "expression": "0.5 default/welcoming.detached", - "ordinaryLogprob": -0.37906629591659713, - "steeredLogprob": -1.586014839851826, - "ids": [ - 564, - 2765, - 47656, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602 - ] - } - }, - { - "type": "check", - "name": "network-blocked OPFS model reload", - "values": { - "networkAttempts": 0, - "baselineIds": [ - 901, - 659, - 834, - 12864, - 532, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498, - 1547, - 901, - 659, - 834, - 12864, - 236761, - 564, - 2765, - 96863, - 1498 - ], - "steeredIds": [ - 564, - 2765, - 47656, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602, - 29602 - ] - } - } - ], - "blockedServerRequests": [], - "modelId": "gemma3-1b-pt", - "runtimeIdentity": { - "sourceModel": "google/gemma-3-1b-pt", - "sourceRevision": "fcf18a2a879aab110ca39f8bffbccd5d49d8eb29", - "convertedManifestSha256": "41bb76ef5854f93346114bb6ff8e6028960012470a0e96e5d6eedc060ac079cd", - "quantization": "q4f32_1", - "tokenizerSha256": "7d4046bf0505a327dd5a0abbb427ecd4fc82f99c2ceaa170bc61ecde12809b0c", - "chatTemplateSha256": "4d97b6d876fd05ffaf72c3243231975c50263ad4fc620bc9f0b44be2ca11fa31", - "modelLibrarySha256": "9a53f7e3ec75a531441ad190191c7c183d945110f0c05c31882688fca4eba451", - "runtimeAbi": "drowse-web-runtime-v1", - "hookAbi": "post-block-residual-v4", - "hiddenSize": 1152, - "layerMap": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25 - ] - }, - "recordedAt": "2026-09-06T08:06:30.993Z" - }, - "appUiChecks": { - "method": "manual interaction in physical Chrome with signed catalog and real model weights", - "signedDownloadAndOpen": true, - "rawGeneration": true, - "coreSteeringGeneration": true, - "fullPageReload": true, - "reopenSavedCompletion": true, - "generationAfterReopen": true, - "optionalPacksInstalled": 0, - "offlinePageNavigationTested": false - } - }, - { - "id": "qwen35-2b-base", - "repository": "logitsml/drowse-web-qwen35-2b-base", - "revision": "4a839d1c2a91f397a91bc25dbaa07825930adea7", - "preflight": { - "reportSha256": "56773d0c9c886e559c8d7f0344522b08fb2a7cffb94c293b751d7aec238c056e", - "files": 47, - "bytes": 1126220788, - "checkedAt": "2026-09-06T09:11:31.912Z" - }, - "browserRuns": [ - { - "reportSha256": "dbb7fcc3950f36bc8c777125354eff617099fe0266e2ad00fc3b008332d59934", - "status": "passed-smoke-only", - "startedAt": "2026-09-06T08:57:03.307Z", - "finishedAt": "2026-09-06T09:00:33.365Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "bgra8unorm-storage", - "texture-formats-tier1", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "timestamp-query", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "qwen3_5", - "quantization": "q4f32_1", - "sourceRepository": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "modelBuildSha256": "bc90954c0d4ff118975aa7fdd6ef0b3fb5f17ef7cb9ba7db08f2c3d8604c125c", - "librarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1626, - "inputIdsSha256": "d2438de0c5bde9c650215b57122a9eef9622d5e64edad2a06dc5f57bc5fe80b1", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1625 - ], - "captureShape": [ - 24, - 12, - 2048 - ], - "generatedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0.0000247955322265625, - "branchReplayMaxAbs": 0.0000247955322265625, - "replayComparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000247955322265625, - "maxRelativeL2": 0.0000021091009425797027, - "passed": true - }, - "branches": [ - { - "round": 0, - "branchTokens": 1629, - "maxAbs": 0.0000247955322265625, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000247955322265625, - "maxRelativeL2": 0.0000021091009425797027, - "passed": true - } - }, - { - "round": 1, - "branchTokens": 1632, - "maxAbs": 0.0000667572021484375, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000667572021484375, - "maxRelativeL2": 0.0000026790759630744377, - "passed": true - } - }, - { - "round": 2, - "branchTokens": 1635, - "maxAbs": 0.0000247955322265625, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000247955322265625, - "maxRelativeL2": 0.0000021091009425797027, - "passed": true - } - }, - { - "round": 3, - "branchTokens": 1638, - "maxAbs": 0.0000247955322265625, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000247955322265625, - "maxRelativeL2": 0.0000021091009425797027, - "passed": true - } - }, - { - "round": 4, - "branchTokens": 1641, - "maxAbs": 0.0000247955322265625, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000247955322265625, - "maxRelativeL2": 0.0000021091009425797027, - "passed": true - } - }, - { - "round": 5, - "branchTokens": 1644, - "maxAbs": 0.000023603439331054688, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.000023603439331054688, - "maxRelativeL2": 0.0000020968642375100193, - "passed": true - } - }, - { - "round": 6, - "branchTokens": 1647, - "maxAbs": 0.000087738037109375, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.000087738037109375, - "maxRelativeL2": 0.0000025288695048671927, - "passed": true - } - }, - { - "round": 7, - "branchTokens": 1650, - "maxAbs": 0.0000247955322265625, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0.0000247955322265625, - "maxRelativeL2": 0.0000021091009425797027, - "passed": true - } - } - ], - "forcedEosChecks": [ - { - "token": 248044, - "finishReason": "stop", - "completion": "" - } - ] - }, - { - "reportSha256": "922ea6de94db3976aa50a21355d21bea8051892d1317d3b39129011a39d96021", - "status": "passed-smoke-only", - "startedAt": "2026-09-06T09:02:01.152Z", - "finishedAt": "2026-09-06T09:02:51.910Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "bgra8unorm-storage", - "texture-formats-tier1", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "timestamp-query", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "qwen3_5", - "quantization": "q4f32_1", - "sourceRepository": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "modelBuildSha256": "bc90954c0d4ff118975aa7fdd6ef0b3fb5f17ef7cb9ba7db08f2c3d8604c125c", - "librarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 6, - "inputIdsSha256": "eb7d9b0522f833b009e02b45ccac12c52f51d94daf8cc403449bc0a52816c9fd", - "capturePositions": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "captureShape": [ - 24, - 6, - 2048 - ], - "generatedIds": [ - 781, - 513, - 748, - 18268, - 321, - 781, - 513, - 748, - 7539, - 13, - 198, - 760, - 220, - 16, - 15, - 6886, - 43282, - 303, - 710, - 1554, - 772, - 11, - 6650, - 198 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0, - "branchReplayMaxAbs": 0, - "replayComparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0, - "maxRelativeL2": 0, - "passed": true - }, - "branches": [ - { - "round": 0, - "branchTokens": 9, - "maxAbs": 0, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0, - "maxRelativeL2": 0, - "passed": true - } - }, - { - "round": 1, - "branchTokens": 12, - "maxAbs": 0, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0, - "maxRelativeL2": 0, - "passed": true - } - }, - { - "round": 2, - "branchTokens": 15, - "maxAbs": 0, - "comparison": { - "policy": "fp32", - "tolerance": { - "maxAbsolute": 0.0001, - "maxRelativeL2": 0.00001 - }, - "maxAbsolute": 0, - "maxRelativeL2": 0, - "passed": true - } - } - ], - "forcedEosChecks": [ - { - "token": 248044, - "finishReason": "stop", - "completion": "" - } - ] - } - ], - "accuracy": [ - { - "reportSha256": "56b6877ac9dcee2294df7c42e7511f1992c3526068c7a234823e01b5daf50d06", - "referenceWeights": "exact-dequantized-browser", - "referenceArchitecture": "source-config", - "referenceAttention": "eager", - "referencePrecision": "torch.float32", - "referenceDevice": "cpu", - "torchVersion": "2.13.0", - "inputTokens": 1626, - "logits": { - "cosine": 0.9999999996813765, - "relativeL2": 0.00002525739645210886, - "rmse": 0.00006281738468494245, - "maxAbs": 0.00041878223419189453 - }, - "maximumLayerRelativeL2": 0.00001151285400214211, - "maximumPositionRelativeL2": 0.000027203609162242967, - "maximumLayerAbsolute": 0.0001277923583984375, - "greedyTokenIdsMatch": true, - "referenceGeneratedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "browserGeneratedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "browserArtifact": { - "schemaVersion": 1, - "source": { - "chatTemplateSha256": "273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80", - "files": [ - { - "bytes": 11343, - "path": "LICENSE", - "sha256": "50cbab8a892c5f2993b8c7351a99182507472def3b1374558308605d99b86b32" - }, - { - "bytes": 3721, - "path": "README.md", - "sha256": "50ca45b87d976d9850de95ad00e76fba77e105c2cdef1093b8e3bb261d9a1787" - }, - { - "bytes": 2908, - "path": "config.json", - "sha256": "ed1c1723241f23f7f4e23430759cbd7dcfb4103cbdfe052bfe7626b57c2615b4" - }, - { - "bytes": 3353259, - "path": "merges.txt", - "sha256": "a9d356d7bdf1ef4949e3e748e95b8e10ad9d4e2e838eddc38a0a7b6b94d1db8d" - }, - { - "bytes": 4548221488, - "path": "model.safetensors-00001-of-00001.safetensors", - "sha256": "928acbf11878c32185bbd863514d191769285065ab9ea14fbfe431303f5fdf2d" - }, - { - "bytes": 64460, - "path": "model.safetensors.index.json", - "sha256": "74d2ddfe79f10f35b27b498632f02b97b60dd9ec39b35d7c5a890c399284e319" - }, - { - "bytes": 12807196, - "path": "tokenizer.json", - "sha256": "fe000e3ed39ed12b8d2481d527d44f93c65d37e87645d2dcc80d1bf9d50d2927" - }, - { - "bytes": 16712, - "path": "tokenizer_config.json", - "sha256": "e611fbccc7c29ef3b1cafb1cb7ea548d189968632901d678fd62be68c47885de" - }, - { - "bytes": 6722759, - "path": "vocab.json", - "sha256": "ce99b4cb2983d118806ce0a8b777a35b093e2000a503ebde25853284c9dfa003" - } - ], - "repository": "Qwen/Qwen3.5-2B-Base", - "revision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c" - }, - "modelBuildSha256": "bc90954c0d4ff118975aa7fdd6ef0b3fb5f17ef7cb9ba7db08f2c3d8604c125c", - "librarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "architecture": "qwen3_5", - "quantization": "q4f32_1", - "contextTokens": 2048 - } - }, - { - "reportSha256": "27325177861e5d9d7c1a8fa8519f65eb1f164c4d9f14606c1b64361802d11b07", - "referenceWeights": "exact-dequantized-browser", - "referenceArchitecture": "source-config", - "referenceAttention": "eager", - "referencePrecision": "torch.float32", - "referenceDevice": "cpu", - "torchVersion": "2.13.0", - "inputTokens": 6, - "logits": { - "cosine": 0.999999999998422, - "relativeL2": 0.0000017546017992484809, - "rmse": 0.000003909211590263263, - "maxAbs": 0.000026702880859375 - }, - "maximumLayerRelativeL2": 0.00000309251423462991, - "maximumPositionRelativeL2": 0.000006621395276166779, - "maximumLayerAbsolute": 0.00004863739013671875, - "greedyTokenIdsMatch": true, - "referenceGeneratedIds": [ - 781, - 513, - 748, - 18268, - 321, - 781, - 513, - 748, - 7539, - 13, - 198, - 760, - 220, - 16, - 15, - 6886, - 43282, - 303, - 710, - 1554, - 772, - 11, - 6650, - 198 - ], - "browserGeneratedIds": [ - 781, - 513, - 748, - 18268, - 321, - 781, - 513, - 748, - 7539, - 13, - 198, - 760, - 220, - 16, - 15, - 6886, - 43282, - 303, - 710, - 1554, - 772, - 11, - 6650, - 198 - ], - "browserArtifact": { - "schemaVersion": 1, - "source": { - "chatTemplateSha256": "273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80", - "files": [ - { - "bytes": 11343, - "path": "LICENSE", - "sha256": "50cbab8a892c5f2993b8c7351a99182507472def3b1374558308605d99b86b32" - }, - { - "bytes": 3721, - "path": "README.md", - "sha256": "50ca45b87d976d9850de95ad00e76fba77e105c2cdef1093b8e3bb261d9a1787" - }, - { - "bytes": 2908, - "path": "config.json", - "sha256": "ed1c1723241f23f7f4e23430759cbd7dcfb4103cbdfe052bfe7626b57c2615b4" - }, - { - "bytes": 3353259, - "path": "merges.txt", - "sha256": "a9d356d7bdf1ef4949e3e748e95b8e10ad9d4e2e838eddc38a0a7b6b94d1db8d" - }, - { - "bytes": 4548221488, - "path": "model.safetensors-00001-of-00001.safetensors", - "sha256": "928acbf11878c32185bbd863514d191769285065ab9ea14fbfe431303f5fdf2d" - }, - { - "bytes": 64460, - "path": "model.safetensors.index.json", - "sha256": "74d2ddfe79f10f35b27b498632f02b97b60dd9ec39b35d7c5a890c399284e319" - }, - { - "bytes": 12807196, - "path": "tokenizer.json", - "sha256": "fe000e3ed39ed12b8d2481d527d44f93c65d37e87645d2dcc80d1bf9d50d2927" - }, - { - "bytes": 16712, - "path": "tokenizer_config.json", - "sha256": "e611fbccc7c29ef3b1cafb1cb7ea548d189968632901d678fd62be68c47885de" - }, - { - "bytes": 6722759, - "path": "vocab.json", - "sha256": "ce99b4cb2983d118806ce0a8b777a35b093e2000a503ebde25853284c9dfa003" - } - ], - "repository": "Qwen/Qwen3.5-2B-Base", - "revision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c" - }, - "modelBuildSha256": "bc90954c0d4ff118975aa7fdd6ef0b3fb5f17ef7cb9ba7db08f2c3d8604c125c", - "librarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "architecture": "qwen3_5", - "quantization": "q4f32_1", - "contextTokens": 2048 - } - } - ], - "coreOnlyRuntime": { - "reportSha256": "7a2d1c3f68a078f7aee0f799a73ec09937452dfc017a1d6cf1b0238ec006f302", - "scope": "production runtime core-only load and offline model reload; not signed installation or offline page navigation", - "optionalPacks": 0, - "networkAttempts": [], - "deviceLosses": [], - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "status": "passed", - "checks": [ - { - "type": "check", - "name": "core-only load", - "values": { - "identity": "2848a526dffb0b89c03a6d429c321fb4494597df45f8c7ca990ea3e80775a6e3", - "optionalPacks": 0, - "layers": 24 - } - }, - { - "type": "check", - "name": "base generation", - "values": { - "ids": [ - 781, - 513, - 748, - 18268, - 321, - 781, - 513, - 748, - 7539, - 13, - 198, - 760, - 220, - 16, - 15, - 6886, - 43282, - 303, - 710, - 1554, - 772, - 11, - 6650, - 198 - ], - "performance": { - "text": " they are so cute and they are so smart.\nThe 10 Best Hotels in Kitchener, Canada\n", - "thinkingText": null, - "tokens": 24, - "finishReason": "length", - "terminalReason": "length", - "usage": { - "promptTokens": 6, - "completionTokens": 24, - "totalTokens": 30 - }, - "meanLogprob": 0, - "meanSurprise": 0, - "prefillTokensPerSecond": 6.255440929863912, - "decodeTokensPerSecond": 10.559516651359987 - } - } - }, - { - "type": "check", - "name": "physical core steering", - "values": { - "expression": "0.5 default/welcoming.detached", - "ordinaryLogprob": -0.5733752658916785, - "steeredLogprob": -0.6381370296412325, - "ids": [ - 781, - 2224, - 748, - 2993, - 321, - 781, - 2224, - 748, - 7539, - 13, - 198, - 40, - 2688, - 748, - 15252, - 488, - 2224, - 1532, - 13, - 198, - 40, - 2688, - 748, - 15252 - ] - } - }, - { - "type": "check", - "name": "network-blocked OPFS model reload", - "values": { - "networkAttempts": 0, - "baselineIds": [ - 781, - 513, - 748, - 18268, - 321, - 781, - 513, - 748, - 7539, - 13, - 198, - 760, - 220, - 16, - 15, - 6886, - 43282, - 303, - 710, - 1554, - 772, - 11, - 6650, - 198 - ], - "steeredIds": [ - 781, - 2224, - 748, - 2993, - 321, - 781, - 2224, - 748, - 7539, - 13, - 198, - 40, - 2688, - 748, - 15252, - 488, - 2224, - 1532, - 13, - 198, - 40, - 2688, - 748, - 15252 - ] - } - } - ], - "blockedServerRequests": [], - "modelId": "qwen35-2b-base", - "runtimeIdentity": { - "sourceModel": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "convertedManifestSha256": "6f4d36a4eebec65a1764d304a0ea563a7b57ffb21b1558056207ef3a34c11831", - "quantization": "q4f32_1", - "tokenizerSha256": "fe000e3ed39ed12b8d2481d527d44f93c65d37e87645d2dcc80d1bf9d50d2927", - "chatTemplateSha256": "e611fbccc7c29ef3b1cafb1cb7ea548d189968632901d678fd62be68c47885de", - "modelLibrarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "runtimeAbi": "drowse-web-runtime-v1", - "hookAbi": "post-block-residual-v4", - "hiddenSize": 2048, - "layerMap": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - "recordedAt": "2026-09-06T08:56:32.328Z" - }, - "appUiChecks": { - "method": "manual interaction in physical Chrome with signed catalog and real model weights", - "signedDownloadAndOpen": true, - "rawGeneration": true, - "coreSteeringGeneration": true, - "fullPageReload": true, - "reopenSavedCompletion": true, - "generationAfterReopen": true, - "optionalPacksInstalled": 0, - "offlinePageNavigationTested": false - } - } - ], - "withheldFp16Qwen": [ - { - "reportSha256": "cdd336265d7706537281fe095d47a82de3b1b76e0a51f3d2ac2d591eb61b9bec", - "status": "failed", - "startedAt": "2026-09-06T08:11:07.954Z", - "finishedAt": "2026-09-06T08:12:20.721Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "timestamp-query", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "qwen3_5", - "quantization": "q4f16_1", - "sourceRepository": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "modelBuildSha256": "3bcd529396a5f47ef9c0c37a60db23364bbd5bbdbcb02f03c83408a34ca6c3c5", - "librarySha256": "3abe520c27ef80595ef768361a9beae1feff67fc2ba4bd8d4ea2e83493d39e51", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1626, - "inputIdsSha256": "d2438de0c5bde9c650215b57122a9eef9622d5e64edad2a06dc5f57bc5fe80b1", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1625 - ], - "captureShape": [ - 24, - 12, - 2048 - ], - "generatedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "repeat capture parity", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity" - ], - "unloaded": true, - "error": "Error: A different branch contaminated recurrent or KV state\n at run.onclick (http://127.0.0.1:4215/:143:51)", - "failedStage": "Checking branch isolation and explicit state reset", - "captureReplayMaxAbs": 0, - "branchReplayMaxAbs": 0.09375 - }, - { - "reportSha256": "93801e164363a118c6a801c156e5a28c3495b597f3da7e8bd6c8d31e30346937", - "status": "failed", - "startedAt": "2026-09-06T08:20:36.611Z", - "finishedAt": "2026-09-06T08:21:10.203Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "timestamp-query", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "qwen3_5", - "quantization": "q4f16_1", - "sourceRepository": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "modelBuildSha256": "3bcd529396a5f47ef9c0c37a60db23364bbd5bbdbcb02f03c83408a34ca6c3c5", - "librarySha256": "3abe520c27ef80595ef768361a9beae1feff67fc2ba4bd8d4ea2e83493d39e51", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1626, - "inputIdsSha256": "d2438de0c5bde9c650215b57122a9eef9622d5e64edad2a06dc5f57bc5fe80b1", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1625 - ], - "captureShape": [ - 24, - 12, - 2048 - ], - "generatedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals" - ], - "unloaded": true, - "error": "Error: Repeated capture changed residuals\n at run.onclick (http://127.0.0.1:4221/:88:50)", - "failedStage": "Capturing residuals", - "captureReplayMaxAbs": 0.171875 - } - ], - "fp32QwenStrictDiagnostic": { - "reportSha256": "3aa5341061514900350de6a1963e69e1b8c386eff847a924db5f5e636088410a", - "status": "diagnostic-only", - "startedAt": "2026-09-06T08:43:40.582Z", - "finishedAt": "2026-09-06T08:48:39.170Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "timestamp-query", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "qwen3_5", - "quantization": "q4f32_1", - "sourceRepository": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "modelBuildSha256": "bc90954c0d4ff118975aa7fdd6ef0b3fb5f17ef7cb9ba7db08f2c3d8604c125c", - "librarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1626, - "inputIdsSha256": "d2438de0c5bde9c650215b57122a9eef9622d5e64edad2a06dc5f57bc5fe80b1", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1625 - ], - "captureShape": [ - 24, - 12, - 2048 - ], - "generatedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals", - "generation after capture parity", - "cancellation and fresh generation parity", - "overlong context rejection and recovery parity", - "branch isolation and explicit state reset parity", - "forced EOS termination and recovery parity" - ], - "unloaded": true, - "captureReplayMaxAbs": 0.00002822279930114746, - "branchReplayMaxAbs": 0.000011444091796875, - "branches": [ - { - "round": 0, - "branchTokens": 1629, - "maxAbs": 0.0000514984130859375 - }, - { - "round": 1, - "branchTokens": 1632, - "maxAbs": 0.000011444091796875 - }, - { - "round": 2, - "branchTokens": 1635, - "maxAbs": 0.0000514984130859375 - }, - { - "round": 3, - "branchTokens": 1638, - "maxAbs": 0.000011444091796875 - }, - { - "round": 4, - "branchTokens": 1641, - "maxAbs": 0.000012964010238647461 - }, - { - "round": 5, - "branchTokens": 1644, - "maxAbs": 0.000011444091796875 - }, - { - "round": 6, - "branchTokens": 1647, - "maxAbs": 0.000030517578125 - }, - { - "round": 7, - "branchTokens": 1650, - "maxAbs": 0.000011444091796875 - } - ], - "forcedEosChecks": [ - { - "token": 248044, - "finishReason": "stop", - "completion": "" - } - ], - "diagnosticFailures": [ - "repeat capture exceeds absolute 1e-5", - "branch 0 exceeds absolute 1e-5", - "branch 1 exceeds absolute 1e-5", - "branch 2 exceeds absolute 1e-5", - "branch 3 exceeds absolute 1e-5", - "branch 4 exceeds absolute 1e-5", - "branch 5 exceeds absolute 1e-5", - "branch 6 exceeds absolute 1e-5", - "branch 7 exceeds absolute 1e-5" - ] - }, - "fp32QwenSourceAccuracyBrowserRun": { - "reportSha256": "045129404c352abb8f8ab63c162733b9ac0996a3daca13cefc466f74bfc93645", - "status": "failed", - "startedAt": "2026-09-06T08:38:09.446Z", - "finishedAt": "2026-09-06T08:39:08.201Z", - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36", - "adapter": { - "vendor": "apple", - "architecture": "metal-3", - "device": "", - "description": "", - "features": [ - "depth32float-stencil8", - "rg11b10ufloat-renderable", - "texture-formats-tier1", - "bgra8unorm-storage", - "texture-compression-bc", - "dual-source-blending", - "core-features-and-limits", - "float32-filterable", - "indirect-first-instance", - "texture-compression-astc-sliced-3d", - "float32-blendable", - "texture-compression-astc", - "texture-compression-etc2", - "depth-clip-control", - "texture-compression-bc-sliced-3d", - "timestamp-query", - "texture-formats-tier2", - "shader-f16", - "clip-distances", - "primitive-index", - "texture-component-swizzle", - "subgroups" - ], - "maxBufferSize": 4294967292, - "maxStorageBufferBindingSize": 4294967292 - }, - "architecture": "qwen3_5", - "quantization": "q4f32_1", - "sourceRepository": "Qwen/Qwen3.5-2B-Base", - "sourceRevision": "b1485b2fa6dfa1287294f269f5fb618e03d52d7c", - "modelBuildSha256": "bc90954c0d4ff118975aa7fdd6ef0b3fb5f17ef7cb9ba7db08f2c3d8604c125c", - "librarySha256": "dc379bbccd2b1f5bf2c8726e02eae49ffc9925a5e76bbd305d9065b7fe85ff00", - "webllmSha256": "35a8398dc34db22ff59d4a2c22174995b2d7bcc63f264fe990009e1ba8001b4e", - "inputTokens": 1626, - "inputIdsSha256": "d2438de0c5bde9c650215b57122a9eef9622d5e64edad2a06dc5f57bc5fe80b1", - "capturePositions": [ - 0, - 1, - 2, - 127, - 128, - 511, - 512, - 513, - 1023, - 1024, - 1025, - 1625 - ], - "captureShape": [ - 24, - 12, - 2048 - ], - "generatedIds": [ - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349, - 295, - 2109, - 349 - ], - "steps": [ - "finite generation logits", - "finite post-block residuals" - ], - "unloaded": true, - "error": "Error: Repeated capture changed residuals\n at run.onclick (http://127.0.0.1:4222/:88:50)", - "failedStage": "Capturing residuals", - "captureReplayMaxAbs": 0.0000247955322265625 - }, - "verification": { - "runtimeTestRunners": 44, - "pythonBuilderAndReferenceTests": 47, - "replayPolicyUnitTests": true, - "hostedBuild": true, - "svelteCheck": true, - "overlayIntegrity": true, - "hostedIsolation": true, - "knownWarnings": [ - "existing large bundle chunk warning" - ], - "steeringCaveat": "Gemma and Qwen at 0.5 UI strength can over-steer into repetition. The Gemma 0.1 smoke completion remains readable; these are not semantic-quality evaluations." - } -} diff --git a/browser-runtime/base-model-upgrade-evidence.json b/browser-runtime/base-model-upgrade-evidence.json deleted file mode 100644 index 77c5500e..00000000 --- a/browser-runtime/base-model-upgrade-evidence.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "schemaVersion": 1, - "recordedAt": "2026-09-06T16:06:11Z", - "evidenceKind": "observed-app-ui-smoke", - "origin": "http://127.0.0.1:4173", - "browserSurface": "Codex in-app browser", - "existingOrigin": true, - "siteStorageCleared": false, - "existingUserChatRetained": true, - "catalog": { - "repository": "logitsml/drowse-web-catalog", - "revision": "da488a3de729bc649ca70465b1da56409a0b98eb", - "sequence": 7, - "previousPublishedSequence": 3, - "minimumAcceptedSequence": 7, - "entriesChanged": false, - "publicPreflight": { - "passed": true, - "immutableFiles": 126, - "bytes": 2731824423 - }, - "signatureAndRollbackProtectionRetained": true - }, - "conditions": { - "initialPrompt": "I love marmots because", - "temperature": 0, - "newTokensPerGeneration": 24, - "steeringExpression": "0.1 default/welcoming.detached%welcoming", - "optionalInstrumentPacksInstalled": 0, - "semanticQualityEvaluation": false - }, - "models": [ - { - "id": "gpt2-base", - "signedInstallAndOpen": "passed", - "ordinaryGeneration": "passed", - "coreSteeredGeneration": "passed", - "fullPageReopen": "passed", - "continuedGenerationAfterReopen": "passed", - "samePageUnloadReopenAndContinuation": "passed" - }, - { - "id": "pythia-70m-base", - "signedInstallAndOpen": "passed", - "ordinaryGeneration": "passed", - "coreSteeredGeneration": "passed", - "fullPageReopen": "passed", - "continuedGenerationAfterReopen": "passed", - "crossModelSwitchAndContinuation": "passed" - }, - { - "id": "gemma3-1b-pt", - "signedInstallAndOpen": "passed", - "ordinaryGeneration": "passed", - "coreSteeredGeneration": "passed", - "fullPageReopen": "passed", - "continuedGenerationAfterReopen": "passed" - }, - { - "id": "qwen35-2b-base", - "signedInstallAndOpen": "passed", - "downloadPauseAndResume": "passed", - "ordinaryGeneration": "passed", - "coreSteeredGeneration": "passed", - "fullPageReopen": "passed", - "continuedGenerationAfterReopen": "passed", - "steeredRepeatTextMatched": true - } - ], - "reproducedAndFixed": [ - "catalog sequence rejected by an existing client's higher accepted sequence", - "normal unload invalidated compatibility approval before the next model load", - "negative-infinite forced-replay log probabilities prevented session persistence", - "different models sharing a session id incorrectly shared tree revision ordering", - "model switches retained the previous model's live performance counters" - ], - "sourceSha256": { - "webui/src/hosted/runtime/worker.ts": "7304ff9f35d02f6338bf9df5b67763c1b6f30ad02fd3dbaf273f59c2f053234f", - "webui/src/hosted/runtime/webLlmGeneration.ts": "fe3e1a86201412f50eb67b7986521c6be201cc2d05008ef1cec737751d73479c", - "webui/src/lib/stores/loom.svelte.ts": "e74f64966bcdffa89936b62ab0d95e0ff8383709e780f498f48abd4e7112dda6" - }, - "verification": { - "runtimeTestRunnersPassed": 44, - "workerOrchestrationTestsPassed": 115, - "publisherRegressions": "passed", - "svelteAndUiChecks": "passed", - "nativeBuild": "passed", - "hostedBuild": "passed", - "newBrowserWarningsOrErrorsInFinalModelChecks": 0, - "modelSwitchResetsStatusToReady": true, - "knownBuildWarnings": ["existing large bundle chunk warning"] - }, - "numericalArtifactEvidence": "base-model-release-evidence.json", - "numericalArtifactEvidenceReplaced": false, - "productionWebsiteDeployed": false, - "gitPushed": false, - "versionBumped": false -} diff --git a/browser-runtime/benchmark-evidence.json b/browser-runtime/benchmark-evidence.json deleted file mode 100644 index 5c4e9757..00000000 --- a/browser-runtime/benchmark-evidence.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "./benchmark-evidence.schema.json", - "schemaVersion": 4, - "status": "feasibility-required", - "polytheticRevision": null, - "requiredMatrix": { - "modelIds": ["smollm2-360m-instruct", "gemma3-270m-instruct", "qwen3-1.7b"], - "contextTokens": [2048, 4096], - "platforms": ["macos", "windows", "linux", "android"], - "browsers": ["chrome", "edge"] - }, - "supportPolicy": { - "minimumChromeMajor": null, - "minimumEdgeMajor": null, - "maximumEvidenceAgeDays": 180 - }, - "runs": [] -} diff --git a/browser-runtime/evidence-configs/README.md b/browser-runtime/evidence-configs/README.md index ec75bd8a..06ce9624 100644 --- a/browser-runtime/evidence-configs/README.md +++ b/browser-runtime/evidence-configs/README.md @@ -21,25 +21,12 @@ node webui/scripts/hosted-release-evidence-producer.mjs \ --nonce 0000000000000000000000000000000000000000000000000000000000000000 ``` -Creating a candidate evidence record still requires a committed clean worktree -and an immutable tested Polythetic revision. Acceptance additionally requires a -GitHub OIDC/Sigstore attestation from -`OWNER/REPOSITORY/.github/workflows/ci.yml`; the CI trust job rejects otherwise -valid but unattested JSON. The four configs above can be run through that -workflow's `release_evidence_target` dispatch input. The remaining configs -cannot be pinned truthfully until their compiled model artifacts or physical -environments exist: -tiny and production model parity, Gemma long-prefill, lifecycle device loss, -production activation capture, production instrument rejection checks, physical -desktop/Android fitting, and the 48-cell physical benchmark matrix. - -Physical configs and their records must be executed and attested on controlled -self-hosted runners. Adding an attestation after copying a local result does not -establish the observation: the registered producer and attestation action must -share the source-bound workflow run. The resulting bundle may be retained for -offline audit, while normal CI verification uses GitHub's attestation service. +Creating a candidate evidence record requires a committed clean worktree and +an immutable tested Drowse revision. Physical observer configs also require +the matching compiled model artifacts and hardware. These are optional +engineering records; the current CI workflow has no evidence-target dispatch +input or evidence attestation job. The shared-golden observer runs both the Python and browser consumers for the structured-program, measurement, loom-transcript, topology/RBF, sampling, and -reciprocal artifact fixtures. The gate remains null until that observer is run -from a clean, committed revision through the recorder. +reciprocal artifact fixtures. Use the recorder from a clean, committed revision to capture its results. diff --git a/browser-runtime/evidence/PROVENANCE_AUDIT.md b/browser-runtime/evidence/PROVENANCE_AUDIT.md deleted file mode 100644 index a1d127d6..00000000 --- a/browser-runtime/evidence/PROVENANCE_AUDIT.md +++ /dev/null @@ -1,31 +0,0 @@ -# Browser runtime provenance audit - -Audit date: 2026-09-04. - -The repository has exact, independently reproducible hashes for the overlay -manifest, compiler recipe, and vendored WebLLM package: - -- `forks/manifest.json`: `a2d316eb02b30733f92474d6a00925a4ca43accff93f7dd1ec5d08fcbe452f7a` -- `compiler/Dockerfile`: `afaa21db01a3049256787ab6ce1b773811de0db4e199105bb45c9aa8473e9d59` -- `vendor/polythetic-web-llm-0.2.84-polythetic.32.tgz`: `1d28468f22a3c51f9463527fcdb2fecfb2a1d1beb03e2f6ebac9460e2784e881` - -The overlay manifest pins MLC-LLM base commit -`9fa644f54b04983adea4d0168f49fc6af4a893ba`, WebLLM base commit -`90f67096b68d3b77509c938f2221e4cef03b7d76`, every patch digest, and the -result-file digests. Those facts reproduce the working-tree overlay, but they -do not establish an immutable commit in either intended fork. - -The source-provenance fields for local-only fork and compiler steps remain -`null`: - -- MLC-LLM fork commit is not recorded. -- WebLLM fork and package source commits are not recorded. -- Compiler image reference and digest are not recorded; the recipe hash is - pinned. - -Converted model revisions are commit-pinned for every model in the lock. - -A local image ID, a dirty checkout, a mutable branch head, or an empty Hugging -Face repository is not substituted for any of these immutable identities. The -release checker must continue to distinguish those identities from immutable -source and compiler provenance. diff --git a/browser-runtime/evidence/README.md b/browser-runtime/evidence/README.md index 9f360c65..93b1424a 100644 --- a/browser-runtime/evidence/README.md +++ b/browser-runtime/evidence/README.md @@ -1,37 +1,12 @@ -# Release evidence records +# Engineering evidence records -This directory is intentionally empty while the browser runtime is in the -`feasibility-required` state. Once the authoring implementation is complete, -`BROWSER_AUTHORING_IMPLEMENTATION_INTEGRATED = true` and -`BROWSER_AUTHORING_RUNTIME_INTEGRATED = true` record that the production path -is connected. Preview builds may exercise that path, while release builds keep -it unavailable unless `BROWSER_AUTHORING_RELEASE_VERIFIED` is backed by a -verified authoring evidence set. An evidence set with partial records may use -the parallel `integrated-unverified` status. Release tooling accepts -evidence only through a -content-addressed reference in `runtime-feasibility-evidence.json` or -`authoring-evidence.json`. +These optional records support regression tracking and support-policy decisions. +Their status does not gate downloads, generation, fitting, or release builds; +see [the runtime policy](../README.md). -Every release gate and physical benchmark has a registered executable -producer. The recorder is deliberately fail-closed about its inputs: -hand-authored measurements, tool-version strings, commands, device labels, and -throughput claims cannot create a candidate record through that process. Its -in-process receipt marker is only an API-misuse guard, not a durable trust -boundary. A candidate becomes acceptable release evidence only after GitHub -Actions signs its exact bytes with the repository CI workflow's OIDC identity -and the `release-evidence-trust` job verifies that attestation against both the -signer workflow and the tested source commit. - -`workflow_dispatch` on `.github/workflows/ci.yml` can execute and attest the -four deterministic local observers. It emits the exact record plus its -Sigstore bundle as a workflow artifact; the attestation is also retained by -GitHub's attestations service. Download the record without changing its bytes, -add its `{path, sha256}` reference to the appropriate evidence set, and let CI -verify it before merge. A locally generated record without that attestation is -intentionally rejected by the trust job even if its JSON is otherwise valid. -Repository rules must require the `release-evidence-trust` check for changes to -reach a release branch; configuring and preserving that branch protection is an -external repository-administration step. +The recorder executes registered observers and labels its output +`candidate-unattested`. The current CI workflow does not include an evidence +attestation job or evidence-target dispatch input. Producer arguments live in a checked-in JSON config so the tested command is part of the clean source revision. `arguments` is one string array for a @@ -64,55 +39,15 @@ file, the worktree must otherwise be clean, and the output must be a new JSON file directly under `browser-runtime/evidence/`. The recorder executes the registered observer itself; it does not accept a prewritten measurement file. -Every referenced JSON file must contain the exact runtime and hook ABIs, the -canonical SHA-256 of `runtime-lock.json` with only its mutable `status` omitted, -the tested Polythetic source revision, production time, tool version, a passing -result, and gate-specific results. The lock checker reads the referenced file, -verifies its SHA-256, validates numerical tolerances and lifecycle assertions, -and rejects records older than 180 days. Opaque digests or status-marker changes -cannot satisfy a release gate, and toolchain or model identity drift changes the -canonical runtime digest. - Evidence records use `../release-evidence-record.schema.json` schema version 4. Each record also binds the registered producer ID, the checked-in config path, the config SHA-256, and a tool version that hashes both the producer closure and the exact config bytes. Benchmark rows carry the same four fields. Renaming or editing an observer config therefore invalidates old evidence instead of silently changing what its command means. -Every record, evidence-set lock, and physical benchmark run carries the same -lowercase 40-character `polytheticRevision`: the commit whose executable source was -actually tested. The release revision supplied with `--polythetic-revision`, -`POLYTHETIC_RELEASE_REVISION`, or `CF_PAGES_COMMIT_SHA` names the release HEAD and -must equal `git rev-parse HEAD`; conflicting CLI and environment values are -rejected. - -The tested revision must be an ancestor of the release HEAD. Between those -commits, only the evidence JSON records and locks, runtime/distribution -promotion locks, and hosted header promotion may change. Runtime, frontend, -package, and WASM source drift is rejected. The checker also reads -`runtime-lock.json` at the tested commit and requires its canonical identity to -match the release lock, so the permitted runtime-lock path can change only in -non-identity fields such as `status`. This ancestor-plus-allowlist model permits -evidence to be committed after testing without asking a Git commit to contain -its own hash. - -The attestation verifier checks referenced gate files directly. Benchmark rows -are canonicalized with the same recursive key ordering and trailing newline as -the recorder, then verified by digest against the attestation for the original -standalone run record. This keeps the inline benchmark schema while preventing -a copied or edited row from inheriting another run's attestation. - -Physical evidence still has to be produced on controlled hardware. The same -record-and-attest sequence must run in this repository's CI identity on a -trusted physical runner; an artifact attestation proves which workflow and -source revision produced the bytes, not that an untrusted self-hosted runner's -hardware labels were honest. Runner custody, environment protection/approval, -and actually executing the workflow therefore remain release operations rather -than facts local tests can synthesize. - Every gate result names a repository-relative `fixturePath` and the SHA-256 of that exact file. The path must resolve to a regular, checked-in file inside the -Polythetic repository. Symlinks, missing or untracked fixtures, path traversal, and +Drowse repository. Symlinks, missing or untracked fixtures, path traversal, and digest drift fail the gate. Runtime gates retain their numerical tolerances. Gemma 3 270M is the long-prefill regression model and its record must identify stock WebLLM `0.2.84` exactly. Qwen3-1.7B has independent tiny-fp32 and @@ -123,25 +58,11 @@ has exact result fields in `release-evidence-record.schema.json`: activation capture covers the post-block boundary and requested positions; fitting covers neutral centering, whitening, PCA/spectral projection, RBF, and geometry error bounds; topology covers flat, curved, periodic, and automatic selection; -serialization covers manifold v10, safetensors, `.polythetic`, and runtime +serialization covers manifold v10, safetensors, `.drowse`, and runtime fingerprint rejection; instruments cover core geometry, J-lens v6, SAE v1, and binding/tensor validation; shared goldens cover every shared contract family; physical fitting covers desktop and Android Chrome, OPFS spooling, a confirmed non-fallback adapter, responsiveness, and a 50 ms maximum main-thread task. -Authoring release promotion remains evidence-gated. The runtime wiring stays -enabled for preview testing, while the release build requires every authoring -record to be verified and source-bound. `capabilities.ts` checks that evidence, -the runtime evidence, and the benchmark evidence before advertising fitting in -a release build, and the release checker rejects the build before bundling if -any gate is unresolved. - -`benchmark-evidence.json` declares the release matrix. Verified evidence needs -at least one successful, current, confirmed-hardware run for every launch model -at 2K and 4K on every declared platform/browser combination. The development -files intentionally retain `polytheticRevision: null`, empty runs, and null evidence -references; never replace those nulls with synthetic results. - -Deterministic local configs and their remaining prerequisites are documented in -`../evidence-configs/README.md`. The current immutable-pin audit is recorded in -`PROVENANCE_AUDIT.md`. +Deterministic local observer configs are documented in +[the config README](../evidence-configs/README.md). diff --git a/browser-runtime/fitting-wasm/Cargo.lock b/browser-runtime/fitting-wasm/Cargo.lock index 5220a26a..68bf31d8 100644 --- a/browser-runtime/fitting-wasm/Cargo.lock +++ b/browser-runtime/fitting-wasm/Cargo.lock @@ -14,12 +14,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - [[package]] name = "drowse-fitting-wasm" version = "0.1.0" @@ -27,6 +21,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + [[package]] name = "proc-macro2" version = "1.0.107" diff --git a/browser-runtime/fitting-wasm/src/linalg.rs b/browser-runtime/fitting-wasm/src/linalg.rs index 89e2e645..13c4dcc3 100644 --- a/browser-runtime/fitting-wasm/src/linalg.rs +++ b/browser-runtime/fitting-wasm/src/linalg.rs @@ -146,17 +146,13 @@ pub fn symmetric_eigen(matrix: &[f64], size: usize) -> KernelResult<(Vec, V vectors[index * size + index] = 1.0; } - for _ in 0..(100 * size.max(2) * size.max(2)) { - let mut pivot_row = 0; - let mut pivot_column = 0; + for _ in 0..100 { let mut largest = 0.0_f64; for row in 0..size { for column in (row + 1)..size { let candidate = values[row * size + column].abs(); if candidate > largest { largest = candidate; - pivot_row = row; - pivot_column = column; } } } @@ -185,39 +181,44 @@ pub fn symmetric_eigen(matrix: &[f64], size: usize) -> KernelResult<(Vec, V return Ok((eigenvalues, eigenvectors)); } - let p = pivot_row; - let q = pivot_column; - let app = values[p * size + p]; - let aqq = values[q * size + q]; - let apq = values[p * size + q]; - let tau = (aqq - app) / (2.0 * apq); - let tangent = if tau >= 0.0 { - 1.0 / (tau + (1.0 + tau * tau).sqrt()) - } else { - -1.0 / (-tau + (1.0 + tau * tau).sqrt()) - }; - let cosine = 1.0 / (1.0 + tangent * tangent).sqrt(); - let sine = tangent * cosine; + for p in 0..size { + for q in (p + 1)..size { + if values[p * size + q].abs() <= EIGEN_TOLERANCE * diagonal_scale { + continue; + } + let app = values[p * size + p]; + let aqq = values[q * size + q]; + let apq = values[p * size + q]; + let tau = (aqq - app) / (2.0 * apq); + let tangent = if tau >= 0.0 { + 1.0 / (tau + tau.hypot(1.0)) + } else { + -1.0 / (-tau + tau.hypot(1.0)) + }; + let cosine = 1.0 / (1.0 + tangent * tangent).sqrt(); + let sine = tangent * cosine; - values[p * size + p] = app - tangent * apq; - values[q * size + q] = aqq + tangent * apq; - values[p * size + q] = 0.0; - values[q * size + p] = 0.0; - for index in 0..size { - if index != p && index != q { - let aip = values[index * size + p]; - let aiq = values[index * size + q]; - let next_ip = cosine * aip - sine * aiq; - let next_iq = sine * aip + cosine * aiq; - values[index * size + p] = next_ip; - values[p * size + index] = next_ip; - values[index * size + q] = next_iq; - values[q * size + index] = next_iq; + values[p * size + p] = app - tangent * apq; + values[q * size + q] = aqq + tangent * apq; + values[p * size + q] = 0.0; + values[q * size + p] = 0.0; + for index in 0..size { + if index != p && index != q { + let aip = values[index * size + p]; + let aiq = values[index * size + q]; + let next_ip = cosine * aip - sine * aiq; + let next_iq = sine * aip + cosine * aiq; + values[index * size + p] = next_ip; + values[p * size + index] = next_ip; + values[index * size + q] = next_iq; + values[q * size + index] = next_iq; + } + let vip = vectors[index * size + p]; + let viq = vectors[index * size + q]; + vectors[index * size + p] = cosine * vip - sine * viq; + vectors[index * size + q] = sine * vip + cosine * viq; + } } - let vip = vectors[index * size + p]; - let viq = vectors[index * size + q]; - vectors[index * size + p] = cosine * vip - sine * viq; - vectors[index * size + q] = sine * vip + cosine * viq; } } @@ -497,6 +498,33 @@ mod tests { } } + #[test] + fn cyclic_eigen_preserves_residual_and_orthogonality_with_repeated_spectrum() { + for size in [3, 16, 64] { + let mut matrix = vec![0.0; size * size]; + for row in 0..size { + for column in 0..size { + let u = ((row + 1) as f64).sin(); + let v = ((column + 1) as f64).sin(); + matrix[row * size + column] = u * v + if row == column { 2.0 } else { 0.0 }; + } + } + let (values, vectors) = symmetric_eigen(&matrix, size).unwrap(); + for row in 0..size { + for column in 0..size { + let av = (0..size) + .map(|k| matrix[row * size + k] * vectors[k * size + column]) + .sum::(); + assert!((av - vectors[row * size + column] * values[column]).abs() < 1e-10); + let dot = (0..size) + .map(|k| vectors[k * size + row] * vectors[k * size + column]) + .sum::(); + assert!((dot - if row == column { 1.0 } else { 0.0 }).abs() < 1e-12); + } + } + } + } + #[test] fn pivoted_solve_handles_zero_leading_diagonal() { let solution = solve(vec![0.0, 1.0, 2.0, 3.0], 2, vec![1.0, 5.0], 1).unwrap(); diff --git a/browser-runtime/fixtures/smollm2-q4-parity-input-v1.json b/browser-runtime/fixtures/smollm2-q4-parity-input-v1.json deleted file mode 100644 index 67c68581..00000000 --- a/browser-runtime/fixtures/smollm2-q4-parity-input-v1.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "inputIds": [504, 2365, 6354, 16438, 27003, 690, 260, 23790, 2767, 30], - "positions": [0, 4, 9] -} diff --git a/browser-runtime/fixtures/smollm2-q4-parity-input-v2.json b/browser-runtime/fixtures/smollm2-q4-parity-input-v2.json deleted file mode 100644 index 02035cf4..00000000 --- a/browser-runtime/fixtures/smollm2-q4-parity-input-v2.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "inputIds": [ - 504, - 2240, - 4971, - 10573, - 897, - 5738, - 284, - 7803, - 20151, - 1012, - 2905, - 28, - 6811, - 4658, - 28, - 284, - 1692, - 2821, - 1092, - 6139, - 1478, - 738, - 260, - 5949, - 30 - ], - "positions": [4, 8, 16, 24] -} diff --git a/browser-runtime/forks/KERNEL_VALIDATION.md b/browser-runtime/forks/KERNEL_VALIDATION.md new file mode 100644 index 00000000..f46c8576 --- /dev/null +++ b/browser-runtime/forks/KERNEL_VALIDATION.md @@ -0,0 +1,23 @@ +# WebGPU kernel validation + +Export fixtures inside the pinned compiler environment after applying the fork overlays: + +```sh +python browser-runtime/forks/export-webgpu-kernel-goldens.py \ + --mlc-repository /path/to/mlc-llm \ + --tvm-repository /path/to/tvm \ + --output /tmp/drowse-kernels +``` + +After installing the web UI dependencies, run the emitted WGSL on the installed Chrome WebGPU adapter: + +```sh +node browser-runtime/forks/verify-webgpu-kernel-goldens.mjs \ + /tmp/drowse-kernels/manifest.json /path/to/web-llm /tmp/drowse-kernel-results.json +``` + +The second command also compiles the native sampling and curve-control shaders from the supplied WebLLM checkout. It uses normal headless Chrome without GPU-enabling flags. Missing WebGPU support fails the check. + +The fixtures cover inactive, push, ablation, and sequential affine groups; curved reconstruction and norm clipping; parallel J-lens transport; static and dynamic-width exact instrument top-eight; sampling top-k capacities 1 through 1024; and sparse curve-mask updates. Shapes include non-multiple hidden widths, tied scores, tail blocks, multiple positions, and vocabulary widths up to 262144. Token indices must match the CPU ordering exactly, including lower-ID tie breaks. Numeric comparisons use fixed absolute and relative tolerances, declared in the verifier before execution. Validation errors and device loss fail the run. + +These are kernel checks. They do not attest a released model, signed catalog, optional fitted instrument pack, or physical iPhone. Rebuilding a model changes its runtime identity; fitted pack and release provenance must be rebuilt and validated through the existing release tools before deployment. diff --git a/browser-runtime/forks/build-production-webgpu.py b/browser-runtime/forks/build-production-webgpu.py index 3f8a84de..99b97871 100644 --- a/browser-runtime/forks/build-production-webgpu.py +++ b/browser-runtime/forks/build-production-webgpu.py @@ -24,7 +24,7 @@ "python/mlc_llm/model/llama/llama_model.py": "2a34402c81074ce0a773f9a73dc95aea20a7a0533b2561708d32ceeb72aec7dc", "python/mlc_llm/model/qwen3/qwen3_model.py": "0621190a80fc12ec58ca3fd5d439411135815c4f4f6596a5a0d258475b5c7291", "python/mlc_llm/model/gemma3/gemma3_model.py": "fd219c4779b1a7497fa533b264d5c77a973c5a1f46f41ed29923c312d6220f18", - "python/mlc_llm/model/drowse_hooks.py": "bc1763ba32ef304b4c45be05bcbd2f2eb1240fc5fd7f95f48e025d96dce76c9e", + "python/mlc_llm/model/drowse_hooks.py": "4fadef9db1c875c81ca9cde76dfdbc477a3755f4d982ba9d097ccc730f6778b1", } TVM_RESULT_DIGESTS = { "python/tvm/relax/frontend/nn/llm/_decode_kernels.py": "4cfba82db3cd92e0b02081bd9679f24663fdca327de767966ae50c135c92e3ce", @@ -65,8 +65,8 @@ TOPK_TILE_SHADER_PREFIX = b"// Function: drowse_exact_top8_tiles" TOPK_MERGE_SHADER_PREFIX = b"// Function: drowse_exact_top8_merge" JLENS_TRANSPORT_SHADER_PREFIX = b"// Function: drowse_jlens_transport" -TOPK_WORKGROUP_LINE = b"@compute @workgroup_size(1, 1, 1)" -JLENS_TRANSPORT_WORKGROUP_LINE = b"@compute @workgroup_size(1, 1, 1)" +TOPK_WORKGROUP_LINE = b"@compute @workgroup_size(64, 1, 1)" +JLENS_TRANSPORT_WORKGROUP_LINE = b"@compute @workgroup_size(128, 1, 1)" MAX_WEBGPU_STORAGE_BINDINGS_PER_STAGE = 8 TOKENIZER_SOURCE_FILES = [ "tokenizer.model", @@ -213,7 +213,9 @@ def verify_portable_topk_source(repository: Path) -> None: '"drowse_exact_top8_tiles"', '"drowse_exact_top8_merge"', '"drowse_jlens_transport"', - "_exact_readout_not_selected", + "_exact_readout_is_better", + "while candidate_count > 1:", + 'for thread in T.thread_binding(0, 64, "threadIdx.x"):', "T.And(", "T.Or(", ): @@ -222,8 +224,8 @@ def verify_portable_topk_source(repository: Path) -> None: exact_source = hooks.split("def exact_readout_topk", 1)[-1].split( "def structured_geometry_payload_layout", 1 )[0] - if 'scope="shared"' in exact_source or "tvm_storage_sync" in exact_source: - raise SystemExit("Drowse exact tiled top-8 must not use workgroup storage or barriers") + if 'scope="shared"' not in exact_source or "tvm_storage_sync" not in exact_source: + raise SystemExit("Drowse exact tiled top-8 requires bounded cooperative reduction") for relative_path in ( "python/mlc_llm/model/llama/llama_model.py", "python/mlc_llm/model/qwen3/qwen3_model.py", @@ -278,6 +280,8 @@ def convert(args, mlc_repository: Path, tvm_repository: Path) -> None: generate_config(args, source, stage, model, quantization) complete_config(stage, source) + if args.architecture == "gemma3_text": + validate_gemma_attention_config(source, stage) copy_notices(source, stage, args.source_repository) write_build_manifest(args, source, stage) stage.rename(output) @@ -301,7 +305,12 @@ def validate_source(source: Path, expected_revision: str, architecture: str) -> if revision != expected_revision: raise SystemExit(f"{filename} came from {revision}, expected {expected_revision}") config = json.loads((source / "config.json").read_text(encoding="utf-8")) - if config.get("model_type") != architecture: + gemma_text_backbone = ( + architecture == "gemma3_text" + and config.get("model_type") == "gemma3" + and config.get("text_config", {}).get("model_type") == "gemma3_text" + ) + if config.get("model_type") != architecture and not gemma_text_backbone: raise SystemExit( f"source model type is {config.get('model_type')!r}, expected {architecture!r}" ) @@ -493,6 +502,22 @@ def complete_config(output: Path, source: Path) -> None: config_path.write_text(json.dumps(config, indent=2, sort_keys=True) + "\n", encoding="utf-8") +def validate_gemma_attention_config(source: Path, output: Path) -> None: + source_config = json.loads((source / "config.json").read_text(encoding="utf-8")) + source_text = source_config.get("text_config", source_config) + compiled = json.loads((output / "mlc-chat-config.json").read_text(encoding="utf-8")) + compiled_text = compiled["model_config"]["text_config"] + for source_key, compiled_key in ( + ("rope_theta", "position_embedding_base"), + ("rope_local_base_freq", "rope_local_base_freq"), + ("rope_scaling", "rope_scaling"), + ("sliding_window", "sliding_window_size"), + ("sliding_window_pattern", "sliding_window_pattern"), + ): + if source_key in source_text and compiled_text.get(compiled_key) != source_text[source_key]: + raise SystemExit(f"Gemma conversion changed source attention setting {source_key}") + + def base_special_token_config(tokenizer, eos_ids): return { "bos_token_id": tokenizer.bos_token_id, @@ -503,7 +528,7 @@ def base_special_token_config(tokenizer, eos_ids): def source_eos_ids(source: Path) -> list[int]: config = json.loads((source / "config.json").read_text(encoding="utf-8")) - if config.get("model_type") == "qwen3_5": + if config.get("model_type") in {"qwen3_5", "gemma3"}: config = dict(config["text_config"]) generation = source / "generation_config.json" if generation.is_file(): @@ -521,8 +546,8 @@ def validate_completion_policy(args, source: Path) -> None: if args.architecture in BASE_MODEL_SOURCE_DIGESTS and args.model_type != "base": raise SystemExit("candidate base architectures require explicit base classification") config = json.loads((source / "config.json").read_text(encoding="utf-8")) - if args.architecture == "qwen3_5": - config = config["text_config"] + if args.architecture in {"qwen3_5", "gemma3_text"}: + config = config.get("text_config", config) limit = config.get("n_positions") if args.architecture == "gpt2" else config.get("max_position_embeddings") if type(limit) is not int or limit <= 0 or args.context_window_size > limit: raise SystemExit("requested context exceeds the source model's verified position limit") @@ -723,10 +748,9 @@ def verify_topk_shader_workgroups(wasm: bytes) -> None: TOPK_TILE_SHADER_PREFIX, 3, ( - b"var local_values : array;", - b"var local_indices : array;", + b"var best_values : array;", + b"var best_indices : array;", b"rank < 8i", - b"step < 256i", ), ), ( @@ -734,10 +758,9 @@ def verify_topk_shader_workgroups(wasm: bytes) -> None: TOPK_MERGE_SHADER_PREFIX, 4, ( - b"var local_values : array;", - b"var local_indices : array;", + b"var best_values : array;", + b"var best_indices : array;", b"rank < 8i", - b"candidate < podArgs.candidates_per_row", ), ), ): @@ -756,19 +779,19 @@ def verify_topk_shader_workgroups(wasm: bytes) -> None: workgroup = shader.find(b"@compute @workgroup_size(", 0, 2048) line_end = shader.find(b"\n", workgroup, 2048) if workgroup < 0 or line_end < 0 or shader[workgroup:line_end] != TOPK_WORKGROUP_LINE: - raise SystemExit(f"compiled exact top-8 {label} shader is not single-thread tiled") + raise SystemExit(f"compiled exact top-8 {label} shader does not use 64-thread tiles") bindings = shader[:workgroup].count(b"var" in shader - or b"workgroupBarrier();" in shader + or b"var" not in shader + or b"workgroupBarrier();" not in shader or b"candidate_thread" in shader or b"array" in shader or b"array" in shader or any(fragment not in shader for fragment in required_fragments) ): raise SystemExit( - f"compiled exact top-8 {label} shader violates the barrier-free tiled schedule: " + f"compiled exact top-8 {label} shader violates the bounded cooperative tiled schedule: " f"bindings={bindings}" ) kernels += 1 @@ -798,13 +821,13 @@ def verify_jlens_transport_shader(wasm: bytes) -> None: or line_end < 0 or shader[workgroup:line_end] != JLENS_TRANSPORT_WORKGROUP_LINE or bindings != 3 - or b"var" in shader - or b"workgroupBarrier();" in shader + or b"var" not in shader + or b"workgroupBarrier();" not in shader or b"fma(" not in shader - or b"source_coordinate" not in shader + or b"var partial : array;" not in shader ): raise SystemExit( - "compiled J-lens transport shader violates the barrier-free fp32 schedule: " + "compiled J-lens transport shader violates the bounded cooperative fp32 schedule: " f"bindings={bindings}" ) kernels += 1 diff --git a/browser-runtime/forks/compile-tiny-webgpu.py b/browser-runtime/forks/compile-tiny-webgpu.py index 2b24892b..112c3b95 100644 --- a/browser-runtime/forks/compile-tiny-webgpu.py +++ b/browser-runtime/forks/compile-tiny-webgpu.py @@ -23,7 +23,7 @@ "python/mlc_llm/model/llama/llama_model.py": "2a34402c81074ce0a773f9a73dc95aea20a7a0533b2561708d32ceeb72aec7dc", "python/mlc_llm/model/qwen3/qwen3_model.py": "0621190a80fc12ec58ca3fd5d439411135815c4f4f6596a5a0d258475b5c7291", "python/mlc_llm/model/gemma3/gemma3_model.py": "fd219c4779b1a7497fa533b264d5c77a973c5a1f46f41ed29923c312d6220f18", - "python/mlc_llm/model/drowse_hooks.py": "bc1763ba32ef304b4c45be05bcbd2f2eb1240fc5fd7f95f48e025d96dce76c9e", + "python/mlc_llm/model/drowse_hooks.py": "4fadef9db1c875c81ca9cde76dfdbc477a3755f4d982ba9d097ccc730f6778b1", } TVM_RESULT_DIGESTS = { "python/tvm/relax/frontend/nn/llm/_decode_kernels.py": "4cfba82db3cd92e0b02081bd9679f24663fdca327de767966ae50c135c92e3ce", diff --git a/browser-runtime/forks/create-tiny-webgpu-model.py b/browser-runtime/forks/create-tiny-webgpu-model.py index bbdee746..b0b6b4d3 100644 --- a/browser-runtime/forks/create-tiny-webgpu-model.py +++ b/browser-runtime/forks/create-tiny-webgpu-model.py @@ -22,7 +22,7 @@ "python/mlc_llm/model/llama/llama_model.py": "2a34402c81074ce0a773f9a73dc95aea20a7a0533b2561708d32ceeb72aec7dc", "python/mlc_llm/model/qwen3/qwen3_model.py": "0621190a80fc12ec58ca3fd5d439411135815c4f4f6596a5a0d258475b5c7291", "python/mlc_llm/model/gemma3/gemma3_model.py": "fd219c4779b1a7497fa533b264d5c77a973c5a1f46f41ed29923c312d6220f18", - "python/mlc_llm/model/drowse_hooks.py": "bc1763ba32ef304b4c45be05bcbd2f2eb1240fc5fd7f95f48e025d96dce76c9e", + "python/mlc_llm/model/drowse_hooks.py": "4fadef9db1c875c81ca9cde76dfdbc477a3755f4d982ba9d097ccc730f6778b1", } diff --git a/browser-runtime/forks/export-webgpu-kernel-goldens.py b/browser-runtime/forks/export-webgpu-kernel-goldens.py new file mode 100644 index 00000000..e562d2e1 --- /dev/null +++ b/browser-runtime/forks/export-webgpu-kernel-goldens.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +"""Export numerical WebGPU fixtures with the pinned MLC/TVM overlay.""" + +import argparse +import importlib.util +import json +import pathlib +import sys + +parser = argparse.ArgumentParser() +parser.add_argument("--mlc-repository", required=True, type=pathlib.Path) +parser.add_argument("--tvm-repository", required=True, type=pathlib.Path) +parser.add_argument("--output", required=True, type=pathlib.Path) +args = parser.parse_args() +mlc = args.mlc_repository.resolve(strict=True) +tvm_root = args.tvm_repository.resolve(strict=True) +sys.path[:0] = [str(tvm_root / "python"), str(mlc / "python")] +verification_spec = importlib.util.spec_from_file_location( + "verify_mlc", pathlib.Path(__file__).with_name("verify-mlc-hook.py") +) +verify_mlc = importlib.util.module_from_spec(verification_spec) +verification_spec.loader.exec_module(verify_mlc) +verify_mlc.require_commit(mlc, verify_mlc.MLC_BASE_COMMIT, "MLC-LLM") +verify_mlc.require_commit(tvm_root, verify_mlc.TVM_COMMIT, "TVM") +verify_mlc.verify_result_files(mlc) +import tvm +from tvm.relax.frontend import nn +from tvm.relax.frontend.nn import spec + +verify_mlc.bootstrap_mlc_package(mlc) +from mlc_llm.model.drowse_hooks import ( + apply_structured_affine_hook, + exact_readout_topk, + transport_jlens_hidden, + _reconstruct_curve_tir, + STRUCTURED_CURVE_PARAMETER_STRIDE, +) + +out = args.output.resolve() +out.mkdir(parents=True, exist_ok=True) +metadata = [] + + +def emit(module, label, metadata_fields): + for name in module.get_global_vars(): + if name.name_hint.startswith( + ("drowse_structured_affine", "drowse_exact_top8", "drowse_jlens_transport", "drowse_curve_reconstruct") + ): + function = module[name].with_attr("global_symbol", "main") + compiled = tvm.compile( + tvm.tirx.transform.ForceNarrowIndexToInt32()(tvm.IRModule({"main": function})), + target=tvm.target.Target("webgpu"), + ) + source = compiled.mod.imports[0].inspect_source() + filename = f"{label}-{name.name_hint}.wgsl" + (out / filename).write_text(source) + metadata.append({"file": filename, "kernel": name.name_hint, **metadata_fields}) + print("compiled", filename, flush=True) + + +class Affine(nn.Module): + def forward(self, residual, active, basis, neutral, target, along, kappa, kind, direction, bias, threshold): + return apply_structured_affine_hook( + residual, 0, active, basis, neutral, target, along, kappa, kind, direction, bias, threshold + ) + + +for h, b, t in [(2, 1, 1), (65, 1, 1), (512, 1, 1), (2560, 1, 1), (128, 1, 3)]: + shapes = { + "residual": [b, t, h], + "active": [1, 4], + "basis": [1, 4, 8, h], + "neutral": [1, 4, h], + "target": [1, 4, 8], + "along": [1, 4], + "kappa": [1, 4, 8], + "kind": [1, 8], + "direction": [1, 8, h], + "bias": [1, 8], + "threshold": [1, 8], + } + module, _, _ = Affine().export_tvm( + spec={"forward": {k: spec.Tensor(v, "uint32" if k == "kind" else "float32") for k, v in shapes.items()}}, + allow_extern=True, + ) + emit(module, f"affine-{h}-{b}-{t}", {"family": "affine", "h": h, "b": b, "t": t}) + + +class TopK(nn.Module): + def forward(self, scores): + return exact_readout_topk(scores) + + +for columns in [17, 257, 70001, 262144]: + module, _, _ = TopK().export_tvm( + spec={"forward": {"scores": spec.Tensor([2, columns], "float32")}}, allow_extern=True + ) + emit(module, f"topk-{columns}", {"family": "topk", "rows": 2, "columns": columns}) +module, _, _ = TopK().export_tvm( + spec={"forward": {"scores": spec.Tensor([2, "columns"], "float32")}}, allow_extern=True +) +emit(module, "topk-dynamic", {"family": "topk-dynamic", "rows": 2}) + + +class Transport(nn.Module): + def forward(self, hidden, jacobians): + return transport_jlens_hidden(hidden, jacobians) + + +for h in [65, 512, 2560]: + module, _, _ = Transport().export_tvm( + spec={"forward": {"hidden": spec.Tensor([3, h], "float32"), "jacobians": spec.Tensor([3, h, h], "float32")}}, + allow_extern=True, + ) + emit(module, f"transport-{h}", {"family": "transport", "h": h, "layers": 3}) + + +class Curve(nn.Module): + def forward(self, residual, basis, neutral, q, coordinates, parameters): + return _reconstruct_curve_tir(residual, basis, neutral, q, coordinates, parameters, 0, 0) + + +for h in [65, 512, 2560]: + shapes = { + "residual": [1, 3, h], + "basis": [1, 4, 8, h], + "neutral": [1, 4, h], + "q": [1, 3, 8], + "coordinates": [1, 3, 8], + "parameters": [1, 4, STRUCTURED_CURVE_PARAMETER_STRIDE], + } + module, _, _ = Curve().export_tvm( + spec={"forward": {k: spec.Tensor(v, "float32") for k, v in shapes.items()}}, allow_extern=True + ) + emit(module, f"curve-{h}", {"family": "curve", "h": h, "t": 3, "stride": STRUCTURED_CURVE_PARAMETER_STRIDE}) +(out / "manifest.json").write_text(json.dumps(metadata, indent=2)) +print("all kernels compiled") diff --git a/browser-runtime/forks/manifest.json b/browser-runtime/forks/manifest.json index baabb7d4..f85df103 100644 --- a/browser-runtime/forks/manifest.json +++ b/browser-runtime/forks/manifest.json @@ -50,12 +50,12 @@ "baseCommit": "9fa644f54b04983adea4d0168f49fc6af4a893ba", "baseTree": "3ecd325c3ab1f631e4c1390917ae48bbf07bf965", "patch": "mlc-llm-drowse.patch", - "patchBytes": 316446, - "patchSha256": "0dd13a8be446b1db856ca9723cbfcee7a8d2e689f87335677b7c3d04a0cd3d84", + "patchBytes": 324160, + "patchSha256": "e8f6c00f7cd9c262564820d590495f690c77f50cb80911681043a891b410d2b3", "resultFiles": { "python/mlc_llm/interface/compile.py": "435876d96e9ba6fbc3f02dd6f5ed858df559ebded169ce91c5cdd8151e610d32", "python/mlc_llm/interface/convert_weight.py": "dffc4af8487f54087bc27f9a35f959df318a70c4c33326b65d4a6d9f6479a1b5", - "python/mlc_llm/model/drowse_hooks.py": "bc1763ba32ef304b4c45be05bcbd2f2eb1240fc5fd7f95f48e025d96dce76c9e", + "python/mlc_llm/model/drowse_hooks.py": "4fadef9db1c875c81ca9cde76dfdbc477a3755f4d982ba9d097ccc730f6778b1", "python/mlc_llm/model/gemma3/gemma3_model.py": "fd219c4779b1a7497fa533b264d5c77a973c5a1f46f41ed29923c312d6220f18", "python/mlc_llm/model/llama/llama_model.py": "2a34402c81074ce0a773f9a73dc95aea20a7a0533b2561708d32ceeb72aec7dc", "python/mlc_llm/model/qwen3/qwen3_model.py": "0621190a80fc12ec58ca3fd5d439411135815c4f4f6596a5a0d258475b5c7291", @@ -69,36 +69,41 @@ "baseCommit": "90f67096b68d3b77509c938f2221e4cef03b7d76", "baseTree": "ac223f95dc7ea27acaba299fe6b780ccb5d67b6f", "patch": "web-llm-drowse.patch", - "patchBytes": 392927, - "patchSha256": "0a80debfe0693955577e1d7f293f4b707f0c0d318c0317f94c087b18cc948668", + "patchBytes": 423783, + "patchSha256": "ee3781856877e06f774a06b07717aa76be8a1a320813abe27159657916879661", "resultFiles": { - "package-lock.json": "c01a525defae1664dae121e3645b51ac6e9a0ebed13cac5c3a3dd7b7cadf18a3", - "package.json": "b1635062bc71a34e6333cccdf84c8b178f0e6870fa09eac4410262e0fbb17e67", + "package-lock.json": "7d92728f73ee85f8dd936718780fc74ef3bd96806864373048b6cae2dd232a9c", + "package.json": "b38b56c9f41c4c9cab40cb7ced1ad158854f5723ae88a6ebe468ec9eebdc808b", + "rollup.config.js": "509d7ae65c5f1d3a9844f317854c191c2e4ea0978880b1e9cb4abb9216209273", "src/cache_util.ts": "22068a3108e0df16d9bd6c1397283cdb0f33aafa5f22eb2c26678cc30342ec08", - "src/config.ts": "eb970e2a5c3a5fde7eff65ac4c2d453aa8e832f3d669392ef6a739a3bb79addd", + "src/config.ts": "2d30bcc6ffd8ce39cea8207a1313e76469fdc83cbb2436532db72854cdee6492", "src/conversation.ts": "2a078e8a777689a8ebb885916d68823e674c4e5c56b0834dfd3be0496e9ff63c", - "src/drowse.ts": "24d0e584e18d79eef3104ab63321169f74ea1e2486d4bf8cb142600539e00124", - "src/engine.ts": "e2e788270dfd3043cadcc6ebb75c253a5c8fa0577d852d0f7eeccb18bb808815", + "src/drowse_gpu_controls.ts": "31415bce2481fa0df2ef59d0c5d937001f688ef84ab30ee43dc098df03e34c08", + "src/drowse_gpu_topk.ts": "b6267e699827327913e6513eb46868a769de5535fe8e042608821509cc93850b", + "src/drowse.ts": "e8709fe08aab43d5c1988552bd22d2d8cbc9db81eda23384d555edee38f39e8f", + "src/engine.ts": "b30af63be2c170a9e1855c833c387425018f8992ca06d7227f279676cc4f296f", "src/gpu.ts": "0a8659a2b19f9ecad0ce9d7aeae621ff276190fb895d9cc0e5d8097889f8ca3d", "src/index.ts": "9d8f7765b16b275f03560a17113aafd8cc98e4fa4524d68a666724edecf71385", - "src/llm_chat.ts": "f173796266f5a860dc9a7eedea19251ef23f2d3f5b60e251fb86130c66628a12", + "src/llm_chat.ts": "ddfb88d1777f7d7a754b450e0c0a1d62d293b782c481acac7b11978e42596221", "src/message.ts": "6e8e949e1313fd782fb72b801409eba0fc19b3b7237fa300cce58ff58c4f032e", - "src/openai_api_protocols/chat_completion.ts": "a8f89455d4f4c5c6f022ca3092c19a62f993d1e0e8eb254aa3a508ac939d5743", - "src/openai_api_protocols/completion.ts": "4fa1472e257293603d6d639e0ea726dcd4b8afc968240c6d79ebe21bf460d42a", + "src/openai_api_protocols/chat_completion.ts": "46d335621a17b0f20d21fd5a980166b8eba7bf7a9bb00b069869fe4d3e445521", + "src/openai_api_protocols/completion.ts": "b49405d53beafb0fac21468a2d8d716c5580dd2cea967acaa6c350267641aa8b", "src/openai_api_protocols/index.ts": "13b993b69d41bdfc8d7118dd2dbc5dd45021b87853cf7fe396000ba9e3c85cbe", "src/types.ts": "6bfbd71fe8015fa26dc3b1f86b0c88a22ae40eae5ac53ef16b832d68d4212c28", "src/utils.ts": "d462c6a68a159c863ce382dd3ea367da649f5801b877265d3080d9436ae8fef4", "src/web_worker.ts": "1f17d1cd3468aa497aa0244f4f4b21080ba5c3fc7a145d00422e1828d704a4bf", "tests/cache_util.test.ts": "7ea1dd54414e9a9b8cff3c82bf3bedcf5d7d4e44bc7f1aae57d54ef2cebf2a94", "tests/conversation.test.ts": "b8f9da1d951f507db7f49596d1d96b9ea6a44a14689015c7234acd60af9114cb", - "tests/drowse_pipeline.test.ts": "27177cf79695b54ba59f8398c22f74bc6c5a94f5c7690958710592c24e52d1a0", + "tests/drowse_pipeline.test.ts": "acdcde49e801fcdbfe7a1cadb0ab591adb1d520ee9f4db1ffed2236a2423111c", "tests/drowse.test.ts": "034c5a81ea624df0bd4bd9ee35ffefc05bee9a9818544244cf0890364a1c4e4f", "tests/engine_integration.test.ts": "395859e36419227e1a74835fc4c55d4bb7494a08cab216b3d51754ee13c9867f", - "tests/generation_config.test.ts": "82b9d418f2fbb2e33870ba3f9f028b9c5e55d9ad0854afbaf0b744a710494147", + "tests/generation_config.test.ts": "da77e7217e89947160baa806b5c97e1ac80409820e33a13b746811e141969d3e", "tests/gpu.test.ts": "d6e798cf62547d2835569d9e59636fc578d9a2d43db09e603e26bcd13a783edf", "tests/llm_chat_abi.test.ts": "11e39a16bbd4015f6db94f9499f77ee60f43d90549d5bc548adc72ec4835328b", - "tests/llm_chat_pipeline.test.ts": "2c8943d0f48627c76c208c11d9503c902bec47981aa7ac44e5a4acdd0a7295f2", - "tests/web_worker_handler.test.ts": "726f53f4e38496c6d00ac5ccca0087d37345f6544f5f038abb073118851d405a" + "tests/llm_chat_pipeline.test.ts": "9f6830bb1f2f96c0d4a1fe6ce47dc2b9ec41e7dbd179b935f88d9eb6ac395671", + "tests/web_worker_handler.test.ts": "726f53f4e38496c6d00ac5ccca0087d37345f6544f5f038abb073118851d405a", + "tvm-direct-upload.mjs": "d9bb0ff1cc8402d00f5483446fc84dead774fb5f8a9efc91f9cfb8928f7f3973", + "tvm-direct-upload.test.mjs": "f39680d8817baf4eb7563f8411d5be32e3321c34cc8a73ce695f7e458ed0b895" } } ], diff --git a/browser-runtime/forks/mlc-llm-drowse.patch b/browser-runtime/forks/mlc-llm-drowse.patch index 75b2a47f..4e9d2981 100644 --- a/browser-runtime/forks/mlc-llm-drowse.patch +++ b/browser-runtime/forks/mlc-llm-drowse.patch @@ -66,10 +66,10 @@ index c5f33250..5f8096e5 100644 allowed_lora_source_formats = {"huggingface-safetensor", "huggingface-torch"} diff --git a/python/mlc_llm/model/drowse_hooks.py b/python/mlc_llm/model/drowse_hooks.py new file mode 100644 -index 00000000..6c9e0e66 +index 00000000..f51368cf --- /dev/null +++ b/python/mlc_llm/model/drowse_hooks.py -@@ -0,0 +1,4527 @@ +@@ -0,0 +1,4535 @@ +"""Drowse post-block residual hooks for browser model libraries.""" + +from tvm import te @@ -162,19 +162,6 @@ index 00000000..6c9e0e66 + ) + + -+def _exact_readout_init(values, indices): -+ for slot in range(READOUT_TOP_K): -+ T.buffer_store(values, T.min_value("float32"), indices=[slot]) -+ T.buffer_store(indices, -1, indices=[slot]) -+ -+ -+def _exact_readout_not_selected(index, indices): -+ result = index != indices[0] -+ for slot in range(1, READOUT_TOP_K): -+ result = T.And(result, index != indices[slot]) -+ return result -+ -+ +def exact_readout_topk(scores: Tensor, k: int = READOUT_TOP_K) -> tuple[Tensor, Tensor]: + if k != READOUT_TOP_K: + raise ValueError(f"Drowse exact readout supports top-{READOUT_TOP_K} only") @@ -182,143 +169,167 @@ index 00000000..6c9e0e66 + raise ValueError("Drowse exact readout requires a rank-2 float32 tensor") + row_count, column_count = scores.shape + candidate_count = T.ceildiv(column_count, EXACT_READOUT_TOPK_BLOCK_SIZE) ++ symbolic_columns = not isinstance(getattr(column_count, "value", column_count), int) ++ merge_lane_candidates = 8 if symbolic_columns else 4 + + @T.prim_func(private=True, s_tir=True) -+ def _tile_top8( -+ var_scores: T.handle, -+ var_candidate_values: T.handle, -+ var_candidate_indices: T.handle, -+ ) -> None: ++ def _tile_top8(var_scores: T.handle, var_values: T.handle, var_indices: T.handle) -> None: + T.func_attr({"tirx.noalias": True, "tirx.is_scheduled": True}) + rows = T.int64() + source = T.match_buffer(var_scores, (rows, column_count), "float32") -+ candidate_values = T.match_buffer( -+ var_candidate_values, -+ (rows, candidate_count, READOUT_TOP_K), -+ "float32", -+ ) -+ candidate_indices = T.match_buffer( -+ var_candidate_indices, -+ (rows, candidate_count, READOUT_TOP_K), -+ "int32", -+ ) -+ local_values = T.sblock_alloc_buffer( -+ (READOUT_TOP_K,), dtype="float32", scope="local" -+ ) -+ local_indices = T.sblock_alloc_buffer( -+ (READOUT_TOP_K,), dtype="int32", scope="local" -+ ) -+ for block in T.thread_binding(0, rows * candidate_count, "blockIdx.x"): -+ for _thread in T.thread_binding(0, 1, "threadIdx.x"): -+ with T.sblock("drowse_exact_top8_tile"): -+ row = T.axis.spatial(rows, T.floordiv(block, candidate_count)) -+ candidate = T.axis.spatial( -+ candidate_count, T.floormod(block, candidate_count) -+ ) -+ _exact_readout_init(local_values, local_indices) ++ blocks = T.meta_var(candidate_count) ++ output_values = T.match_buffer(var_values, (rows, blocks, READOUT_TOP_K), "float32") ++ output_indices = T.match_buffer(var_indices, (rows, blocks, READOUT_TOP_K), "int32") ++ local_values = T.sblock_alloc_buffer((4,), "float32", scope="local") ++ local_indices = T.sblock_alloc_buffer((4,), "int32", scope="local") ++ local_best_values = T.sblock_alloc_buffer((2,), "float32", scope="local") ++ local_best_indices = T.sblock_alloc_buffer((2,), "int32", scope="local") ++ winner = T.sblock_alloc_buffer((1,), "int32", scope="local") ++ best_values = T.sblock_alloc_buffer((64,), "float32", scope="shared") ++ best_indices = T.sblock_alloc_buffer((64,), "int32", scope="shared") ++ for block in T.thread_binding(0, rows * blocks, "blockIdx.x"): ++ for thread in T.thread_binding(0, 64, "threadIdx.x"): ++ with T.sblock("drowse_exact_top8_select"): ++ lane = T.axis.spatial(64, thread) ++ row = T.axis.spatial(rows, T.floordiv(block, blocks)) ++ tile = T.axis.spatial(blocks, T.floormod(block, blocks)) ++ for step in T.unroll(4): ++ local_values[step] = T.min_value("float32") ++ local_indices[step] = -1 ++ column = T.meta_var(tile * EXACT_READOUT_TOPK_BLOCK_SIZE + step * 64 + lane) ++ if column < column_count: ++ local_values[step] = source[row, column] ++ local_indices[step] = T.cast(column, "int32") + for rank in T.serial(READOUT_TOP_K): -+ for step in T.serial(EXACT_READOUT_TOPK_BLOCK_SIZE): -+ column = T.meta_var( -+ candidate * EXACT_READOUT_TOPK_BLOCK_SIZE + step -+ ) -+ if T.And( -+ column < column_count, -+ T.And( -+ _exact_readout_not_selected(column, local_indices), -+ _exact_readout_is_better( -+ source[row, column], -+ column, -+ local_values[rank], -+ local_indices[rank], -+ ), -+ ), -+ ): -+ local_values[rank] = source[row, column] -+ local_indices[rank] = column -+ for slot in T.unroll(0, READOUT_TOP_K): -+ candidate_values[row, candidate, slot] = local_values[slot] -+ candidate_indices[row, candidate, slot] = local_indices[slot] -+ -+ candidates = op.tensor_ir_op( -+ _tile_top8, -+ "drowse_exact_top8_tiles", -+ args=[scores], -+ out=( -+ Tensor.placeholder( -+ [row_count, candidate_count, READOUT_TOP_K], "float32" -+ ), -+ Tensor.placeholder( -+ [row_count, candidate_count, READOUT_TOP_K], "int32" -+ ), -+ ), -+ ) ++ local_best_values[0] = T.min_value("float32") ++ local_best_indices[0] = -1 ++ for step in T.unroll(4): ++ if _exact_readout_is_better(local_values[step], local_indices[step], local_best_values[0], local_best_indices[0]): ++ local_best_values[0] = local_values[step] ++ local_best_indices[0] = local_indices[step] ++ best_values[lane] = local_best_values[0] ++ best_indices[lane] = local_best_indices[0] ++ T.tvm_storage_sync("shared") ++ for stage in T.unroll(6): ++ offset = T.meta_var(32 >> stage) ++ local_best_values[0] = best_values[lane] ++ local_best_indices[0] = best_indices[lane] ++ local_best_values[1] = best_values[T.floormod(lane + offset, 64)] ++ local_best_indices[1] = best_indices[T.floormod(lane + offset, 64)] ++ T.tvm_storage_sync("shared") ++ if lane < offset: ++ if _exact_readout_is_better(local_best_values[1], local_best_indices[1], local_best_values[0], local_best_indices[0]): ++ best_values[lane] = local_best_values[1] ++ best_indices[lane] = local_best_indices[1] ++ T.tvm_storage_sync("shared") ++ winner[0] = best_indices[0] ++ if lane == 0: ++ output_values[row, tile, rank] = best_values[0] ++ output_indices[row, tile, rank] = best_indices[0] ++ for step in T.unroll(4): ++ if local_indices[step] == winner[0]: ++ local_indices[step] = -1 ++ T.tvm_storage_sync("shared") + + @T.prim_func(private=True, s_tir=True) -+ def _merge_top8( -+ var_candidate_values: T.handle, -+ var_candidate_indices: T.handle, -+ var_values: T.handle, -+ var_indices: T.handle, -+ ) -> None: ++ def _merge_top8(var_input_values: T.handle, var_input_indices: T.handle, var_values: T.handle, var_indices: T.handle) -> None: + T.func_attr({"tirx.noalias": True, "tirx.is_scheduled": True}) + rows = T.int64() + candidates_per_row = T.int64() -+ candidate_values = T.match_buffer( -+ var_candidate_values, -+ (rows, candidates_per_row, READOUT_TOP_K), -+ "float32", -+ ) -+ candidate_indices = T.match_buffer( -+ var_candidate_indices, -+ (rows, candidates_per_row, READOUT_TOP_K), -+ "int32", -+ ) -+ output_values = T.match_buffer(var_values, (rows, READOUT_TOP_K), "float32") -+ output_indices = T.match_buffer(var_indices, (rows, READOUT_TOP_K), "int32") -+ local_values = T.sblock_alloc_buffer( -+ (READOUT_TOP_K,), dtype="float32", scope="local" -+ ) -+ local_indices = T.sblock_alloc_buffer( -+ (READOUT_TOP_K,), dtype="int32", scope="local" -+ ) -+ for row_block in T.thread_binding(0, rows, "blockIdx.x"): -+ for _thread in T.thread_binding(0, 1, "threadIdx.x"): -+ with T.sblock("drowse_exact_top8_merge"): -+ row = T.axis.spatial(rows, row_block) -+ _exact_readout_init(local_values, local_indices) ++ source_values = T.match_buffer(var_input_values, (rows, candidates_per_row, READOUT_TOP_K), "float32") ++ source_indices = T.match_buffer(var_input_indices, (rows, candidates_per_row, READOUT_TOP_K), "int32") ++ blocks = T.meta_var(1 if symbolic_columns else T.ceildiv(candidates_per_row * READOUT_TOP_K, EXACT_READOUT_TOPK_BLOCK_SIZE)) ++ output_values = T.match_buffer(var_values, (rows, blocks, READOUT_TOP_K), "float32") ++ output_indices = T.match_buffer(var_indices, (rows, blocks, READOUT_TOP_K), "int32") ++ local_values = T.sblock_alloc_buffer((merge_lane_candidates,), "float32", scope="local") ++ local_indices = T.sblock_alloc_buffer((merge_lane_candidates,), "int32", scope="local") ++ local_best_values = T.sblock_alloc_buffer((2,), "float32", scope="local") ++ local_best_indices = T.sblock_alloc_buffer((2,), "int32", scope="local") ++ winner = T.sblock_alloc_buffer((1,), "int32", scope="local") ++ best_values = T.sblock_alloc_buffer((64,), "float32", scope="shared") ++ best_indices = T.sblock_alloc_buffer((64,), "int32", scope="shared") ++ for block in T.thread_binding(0, rows * blocks, "blockIdx.x"): ++ for thread in T.thread_binding(0, 64, "threadIdx.x"): ++ with T.sblock("drowse_exact_top8_select"): ++ lane = T.axis.spatial(64, thread) ++ row = T.axis.spatial(rows, T.floordiv(block, blocks)) ++ tile = T.axis.spatial(blocks, T.floormod(block, blocks)) ++ if symbolic_columns: ++ for step in T.unroll(READOUT_TOP_K): ++ local_values[step] = T.min_value("float32") ++ local_indices[step] = -1 ++ for chunk in T.serial(T.ceildiv(candidates_per_row * READOUT_TOP_K, 64)): ++ column = T.meta_var(chunk * 64 + lane) ++ if column < candidates_per_row * READOUT_TOP_K: ++ local_best_values[0] = source_values[row, T.floordiv(column, READOUT_TOP_K), T.floormod(column, READOUT_TOP_K)] ++ local_best_indices[0] = source_indices[row, T.floordiv(column, READOUT_TOP_K), T.floormod(column, READOUT_TOP_K)] ++ for slot in T.unroll(READOUT_TOP_K): ++ if _exact_readout_is_better(local_best_values[0], local_best_indices[0], local_values[slot], local_indices[slot]): ++ local_best_values[1] = local_values[slot] ++ local_best_indices[1] = local_indices[slot] ++ local_values[slot] = local_best_values[0] ++ local_indices[slot] = local_best_indices[0] ++ local_best_values[0] = local_best_values[1] ++ local_best_indices[0] = local_best_indices[1] ++ else: ++ for step in T.unroll(merge_lane_candidates): ++ local_values[step] = T.min_value("float32") ++ local_indices[step] = -1 ++ column = T.meta_var(tile * EXACT_READOUT_TOPK_BLOCK_SIZE + step * 64 + lane) ++ if column < candidates_per_row * READOUT_TOP_K: ++ local_values[step] = source_values[row, T.floordiv(column, READOUT_TOP_K), T.floormod(column, READOUT_TOP_K)] ++ local_indices[step] = source_indices[row, T.floordiv(column, READOUT_TOP_K), T.floormod(column, READOUT_TOP_K)] + for rank in T.serial(READOUT_TOP_K): -+ for candidate in T.serial(candidates_per_row): -+ for slot in T.serial(READOUT_TOP_K): -+ index = T.meta_var( -+ candidate_indices[row, candidate, slot] -+ ) -+ value = T.meta_var( -+ candidate_values[row, candidate, slot] -+ ) -+ if T.And( -+ _exact_readout_not_selected(index, local_indices), -+ _exact_readout_is_better( -+ value, -+ index, -+ local_values[rank], -+ local_indices[rank], -+ ), -+ ): -+ local_values[rank] = value -+ local_indices[rank] = index -+ for slot in T.unroll(0, READOUT_TOP_K): -+ output_values[row, slot] = local_values[slot] -+ output_indices[row, slot] = local_indices[slot] ++ local_best_values[0] = T.min_value("float32") ++ local_best_indices[0] = -1 ++ for step in T.unroll(merge_lane_candidates): ++ if _exact_readout_is_better(local_values[step], local_indices[step], local_best_values[0], local_best_indices[0]): ++ local_best_values[0] = local_values[step] ++ local_best_indices[0] = local_indices[step] ++ best_values[lane] = local_best_values[0] ++ best_indices[lane] = local_best_indices[0] ++ T.tvm_storage_sync("shared") ++ for stage in T.unroll(6): ++ offset = T.meta_var(32 >> stage) ++ local_best_values[0] = best_values[lane] ++ local_best_indices[0] = best_indices[lane] ++ local_best_values[1] = best_values[T.floormod(lane + offset, 64)] ++ local_best_indices[1] = best_indices[T.floormod(lane + offset, 64)] ++ T.tvm_storage_sync("shared") ++ if lane < offset: ++ if _exact_readout_is_better(local_best_values[1], local_best_indices[1], local_best_values[0], local_best_indices[0]): ++ best_values[lane] = local_best_values[1] ++ best_indices[lane] = local_best_indices[1] ++ T.tvm_storage_sync("shared") ++ winner[0] = best_indices[0] ++ if lane == 0: ++ output_values[row, tile, rank] = best_values[0] ++ output_indices[row, tile, rank] = best_indices[0] ++ for step in T.unroll(merge_lane_candidates): ++ if local_indices[step] == winner[0]: ++ local_indices[step] = -1 ++ T.tvm_storage_sync("shared") + -+ return op.tensor_ir_op( -+ _merge_top8, -+ "drowse_exact_top8_merge", -+ args=list(candidates), -+ out=( -+ Tensor.placeholder([row_count, READOUT_TOP_K], "float32"), -+ Tensor.placeholder([row_count, READOUT_TOP_K], "int32"), -+ ), ++ candidates = op.tensor_ir_op( ++ _tile_top8, "drowse_exact_top8_tiles", args=[scores], ++ out=(Tensor.placeholder([row_count, candidate_count, READOUT_TOP_K], "float32"), ++ Tensor.placeholder([row_count, candidate_count, READOUT_TOP_K], "int32")), + ) ++ if symbolic_columns: ++ candidates = op.tensor_ir_op( ++ _merge_top8, "drowse_exact_top8_merge", args=list(candidates), ++ out=(Tensor.placeholder([row_count, 1, READOUT_TOP_K], "float32"), ++ Tensor.placeholder([row_count, 1, READOUT_TOP_K], "int32")), ++ ) ++ else: ++ while candidate_count > 1: ++ candidate_count = T.ceildiv(candidate_count * READOUT_TOP_K, EXACT_READOUT_TOPK_BLOCK_SIZE) ++ candidates = op.tensor_ir_op( ++ _merge_top8, "drowse_exact_top8_merge", args=list(candidates), ++ out=(Tensor.placeholder([row_count, candidate_count, READOUT_TOP_K], "float32"), ++ Tensor.placeholder([row_count, candidate_count, READOUT_TOP_K], "int32")), ++ ) ++ return op.reshape(candidates[0], [row_count, READOUT_TOP_K]), op.reshape(candidates[1], [row_count, READOUT_TOP_K]) + + +def transport_jlens_hidden(hidden_states: Tensor, jacobians: Tensor) -> Tensor: @@ -345,24 +356,29 @@ index 00000000..6c9e0e66 + output = T.match_buffer( + var_output, (layers, 1, hidden_size), "float32" + ) -+ for block in T.thread_binding( -+ 0, layers * hidden_size, "blockIdx.x" -+ ): -+ for _thread in T.thread_binding(0, 1, "threadIdx.x"): ++ partial = T.sblock_alloc_buffer((128,), "float32", scope="shared") ++ for block in T.thread_binding(0, layers * T.ceildiv(hidden_size, 4), "blockIdx.x"): ++ for thread in T.thread_binding(0, 128, "threadIdx.x"): + with T.sblock("drowse_jlens_transport"): -+ layer = T.axis.spatial( -+ layers, T.floordiv(block, hidden_size) -+ ) -+ coordinate = T.axis.spatial( -+ hidden_size, T.floormod(block, hidden_size) -+ ) -+ output[layer, 0, coordinate] = T.float32(0) -+ for source_coordinate in T.serial(0, hidden_size): -+ output[layer, 0, coordinate] = ( -+ output[layer, 0, coordinate] -+ + source[layer, source_coordinate] -+ * matrices[layer, coordinate, source_coordinate] -+ ) ++ lane = T.axis.spatial(128, thread) ++ layer = T.axis.spatial(layers, T.floordiv(block, T.ceildiv(hidden_size, 4))) ++ tile = T.axis.spatial(T.ceildiv(hidden_size, 4), T.floormod(block, T.ceildiv(hidden_size, 4))) ++ coordinate = T.meta_var(tile * 4 + T.floordiv(lane, 32)) ++ source_lane = T.meta_var(T.floormod(lane, 32)) ++ partial[lane] = 0.0 ++ if coordinate < hidden_size: ++ for step in T.serial(T.ceildiv(hidden_size, 32)): ++ source_coordinate = T.meta_var(step * 32 + source_lane) ++ if source_coordinate < hidden_size: ++ partial[lane] = partial[lane] + source[layer, source_coordinate] * matrices[layer, coordinate, source_coordinate] ++ T.tvm_storage_sync("shared") ++ for stage in T.unroll(5): ++ offset = T.meta_var(16 >> stage) ++ if source_lane < offset: ++ partial[lane] = partial[lane] + partial[lane + offset] ++ T.tvm_storage_sync("shared") ++ if T.And(source_lane == 0, coordinate < hidden_size): ++ output[layer, 0, coordinate] = partial[lane] + + return op.tensor_ir_op( + _transport, @@ -1020,55 +1036,56 @@ index 00000000..6c9e0e66 + (batch_size, sequence_length, hidden_size), + residual_dtype, + ) -+ current = T.sblock_alloc_buffer((hidden_size,), "float32", scope="local") -+ coordinate = T.sblock_alloc_buffer( -+ (STRUCTURED_MAX_RANK,), "float32", scope="local" -+ ) -+ delta = T.sblock_alloc_buffer( -+ (STRUCTURED_MAX_RANK,), "float32", scope="local" -+ ) ++ current = T.sblock_alloc_buffer((T.ceildiv(hidden_size, 64),), "float32", scope="local") ++ partial = T.sblock_alloc_buffer((64,), "float32", scope="shared") ++ delta = T.sblock_alloc_buffer((STRUCTURED_MAX_RANK,), "float32", scope="shared") + scratch = T.sblock_alloc_buffer((1,), "float32", scope="local") -+ -+ for block in T.thread_binding( -+ batch_size * sequence_length, thread="blockIdx.x" -+ ): -+ for _thread in T.thread_binding(1, thread="threadIdx.x"): ++ for block in T.thread_binding(batch_size * sequence_length, thread="blockIdx.x"): ++ for thread in T.thread_binding(64, thread="threadIdx.x"): + with T.sblock("structured_affine"): -+ batch = T.axis.spatial( -+ batch_size, T.floordiv(block, sequence_length) -+ ) -+ sequence = T.axis.spatial( -+ sequence_length, T.floormod(block, sequence_length) -+ ) -+ for hidden in T.serial(hidden_size): -+ current[hidden] = T.cast( -+ residual[batch, sequence, hidden], "float32" -+ ) ++ lane = T.axis.spatial(64, thread) ++ batch = T.axis.spatial(batch_size, T.floordiv(block, sequence_length)) ++ sequence = T.axis.spatial(sequence_length, T.floormod(block, sequence_length)) ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ current[chunk] = T.cast(residual[batch, sequence, hidden], "float32") + for group in T.serial(STRUCTURED_MAX_AFFINE_GROUPS): -+ for row in T.serial(STRUCTURED_MAX_RANK): -+ coordinate[row] = 0.0 -+ for hidden in T.serial(hidden_size): -+ coordinate[row] = coordinate[row] + ( -+ current[hidden] - neutral[layer_id, group, hidden] -+ ) * basis[layer_id, group, row, hidden] -+ delta[row] = target[layer_id, group, row] - ( -+ kappa[layer_id, group, row] * coordinate[row] -+ ) -+ for hidden in T.serial(hidden_size): -+ scratch[0] = 0.0 ++ if T.And(active[layer_id, group] != 0, along[layer_id, group] != 0): + for row in T.serial(STRUCTURED_MAX_RANK): -+ scratch[0] = scratch[0] + ( -+ delta[row] * basis[layer_id, group, row, hidden] -+ ) -+ current[hidden] = current[hidden] + ( -+ active[layer_id, group] -+ * along[layer_id, group] -+ * scratch[0] -+ ) -+ for hidden in T.serial(hidden_size): -+ output[batch, sequence, hidden] = T.cast( -+ current[hidden], residual_dtype -+ ) ++ if kappa[layer_id, group, row] != 0: ++ partial[lane] = 0.0 ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ partial[lane] = partial[lane] + ( ++ current[chunk] - neutral[layer_id, group, hidden] ++ ) * basis[layer_id, group, row, hidden] ++ T.tvm_storage_sync("shared") ++ for stage in T.unroll(6): ++ offset = T.meta_var(32 >> stage) ++ if lane < offset: ++ partial[lane] = partial[lane] + partial[lane + offset] ++ T.tvm_storage_sync("shared") ++ if lane == 0: ++ delta[row] = target[layer_id, group, row] - kappa[layer_id, group, row] * partial[0] ++ T.tvm_storage_sync("shared") ++ else: ++ if lane == 0: ++ delta[row] = target[layer_id, group, row] ++ T.tvm_storage_sync("shared") ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ scratch[0] = 0.0 ++ for row in T.serial(STRUCTURED_MAX_RANK): ++ scratch[0] = scratch[0] + delta[row] * basis[layer_id, group, row, hidden] ++ current[chunk] = current[chunk] + active[layer_id, group] * along[layer_id, group] * scratch[0] ++ T.tvm_storage_sync("shared") ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ output[batch, sequence, hidden] = T.cast(current[chunk], residual_dtype) + + steered = op.tensor_ir_op( + _affine, @@ -2527,63 +2544,54 @@ index 00000000..6c9e0e66 + (batch_size, sequence_length, hidden_size), + "float32", + ) -+ curved = T.sblock_alloc_buffer((hidden_size,), "float32", scope="local") -+ scratch = T.sblock_alloc_buffer((4,), "float32", scope="local") ++ curved = T.sblock_alloc_buffer((T.ceildiv(hidden_size, 64),), "float32", scope="local") ++ scratch = T.sblock_alloc_buffer((2,), "float32", scope="local") ++ original_norm = T.sblock_alloc_buffer((64,), "float32", scope="shared") ++ curved_norm = T.sblock_alloc_buffer((64,), "float32", scope="shared") ++ sums = T.sblock_alloc_buffer((2,), "float32", scope="local") ++ scale = T.sblock_alloc_buffer((1,), "float32", scope="shared") + -+ for block in T.thread_binding( -+ batch_size * sequence_length, thread="blockIdx.x" -+ ): -+ for _thread in T.thread_binding(1, thread="threadIdx.x"): ++ for block in T.thread_binding(batch_size * sequence_length, thread="blockIdx.x"): ++ for thread in T.thread_binding(64, thread="threadIdx.x"): + with T.sblock("reconstruct_curve"): -+ batch = T.axis.spatial( -+ batch_size, T.floordiv(block, sequence_length) -+ ) -+ sequence = T.axis.spatial( -+ sequence_length, T.floormod(block, sequence_length) -+ ) -+ scratch[0] = 0.0 -+ scratch[1] = 0.0 -+ for hidden in T.serial(hidden_size): -+ scratch[2] = 0.0 -+ scratch[3] = 0.0 -+ for row in T.serial(STRUCTURED_MAX_RANK): -+ scratch[2] = scratch[2] + ( -+ q_buffer[batch, sequence, row] -+ * basis_buffer[layer_id, curve_id, row, hidden] -+ ) -+ scratch[3] = scratch[3] + ( -+ coordinate_buffer[batch, sequence, row] -+ * basis_buffer[layer_id, curve_id, row, hidden] -+ ) -+ curved[hidden] = ( -+ residual_buffer[batch, sequence, hidden] -+ - scratch[2] -+ + scratch[3] -+ ) -+ scratch[0] = scratch[0] + ( -+ residual_buffer[batch, sequence, hidden] -+ * residual_buffer[batch, sequence, hidden] -+ ) -+ scratch[1] = scratch[1] + curved[hidden] * curved[hidden] -+ scratch[0] = T.min( -+ 3.0 -+ * T.sqrt(scratch[0]) -+ / T.max(T.sqrt(scratch[1]), 1e-6), -+ 1.0, -+ ) -+ for hidden in T.serial(hidden_size): -+ output[batch, sequence, hidden] = ( -+ parameter_buffer[layer_id, curve_id, CURVE_ACTIVE_OFFSET] -+ * curved[hidden] -+ * scratch[0] -+ + ( -+ 1.0 -+ - parameter_buffer[ -+ layer_id, curve_id, CURVE_ACTIVE_OFFSET -+ ] -+ ) -+ * residual_buffer[batch, sequence, hidden] -+ ) ++ lane = T.axis.spatial(64, thread) ++ batch = T.axis.spatial(batch_size, T.floordiv(block, sequence_length)) ++ sequence = T.axis.spatial(sequence_length, T.floormod(block, sequence_length)) ++ if parameter_buffer[layer_id, curve_id, CURVE_ACTIVE_OFFSET] != 0.0: ++ sums[0] = 0.0 ++ sums[1] = 0.0 ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ scratch[0] = 0.0 ++ scratch[1] = 0.0 ++ for row in T.serial(STRUCTURED_MAX_RANK): ++ scratch[0] = scratch[0] + q_buffer[batch, sequence, row] * basis_buffer[layer_id, curve_id, row, hidden] ++ scratch[1] = scratch[1] + coordinate_buffer[batch, sequence, row] * basis_buffer[layer_id, curve_id, row, hidden] ++ curved[chunk] = residual_buffer[batch, sequence, hidden] - scratch[0] + scratch[1] ++ sums[0] = sums[0] + residual_buffer[batch, sequence, hidden] * residual_buffer[batch, sequence, hidden] ++ sums[1] = sums[1] + curved[chunk] * curved[chunk] ++ original_norm[lane] = sums[0] ++ curved_norm[lane] = sums[1] ++ T.tvm_storage_sync("shared") ++ for step in T.unroll(6): ++ stride = T.meta_var(32 >> step) ++ if lane < stride: ++ original_norm[lane] = original_norm[lane] + original_norm[lane + stride] ++ curved_norm[lane] = curved_norm[lane] + curved_norm[lane + stride] ++ T.tvm_storage_sync("shared") ++ if lane == 0: ++ scale[0] = T.min(3.0 * T.sqrt(original_norm[0]) / T.max(T.sqrt(curved_norm[0]), 1e-6), 1.0) ++ T.tvm_storage_sync("shared") ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ output[batch, sequence, hidden] = parameter_buffer[layer_id, curve_id, CURVE_ACTIVE_OFFSET] * curved[chunk] * scale[0] + (1.0 - parameter_buffer[layer_id, curve_id, CURVE_ACTIVE_OFFSET]) * residual_buffer[batch, sequence, hidden] ++ else: ++ for chunk in T.serial(T.ceildiv(hidden_size, 64)): ++ hidden = T.meta_var(chunk * 64 + lane) ++ if hidden < hidden_size: ++ output[batch, sequence, hidden] = residual_buffer[batch, sequence, hidden] + + return op.tensor_ir_op( + _reconstruct, diff --git a/browser-runtime/forks/regenerate-overlays.mjs b/browser-runtime/forks/regenerate-overlays.mjs index b4f9e213..b664d902 100644 --- a/browser-runtime/forks/regenerate-overlays.mjs +++ b/browser-runtime/forks/regenerate-overlays.mjs @@ -8,6 +8,12 @@ import { spawnSync } from "node:child_process"; const manifestPath = resolve(import.meta.dirname, "manifest.json"); const manifest = JSON.parse(await readFile(manifestPath, "utf8")); +const selectedIds = new Set(process.argv.slice(2)); +for (const id of selectedIds) { + if (!manifest.overlays.some((overlay) => overlay.id === id)) { + throw new Error(`Unknown overlay: ${id}`); + } +} const repositories = new Map([ ["tvm-webgpu-readonly", process.env.DROWSE_TVM_REPOSITORY], ["mlc-llm-drowse", process.env.DROWSE_MLC_REPOSITORY ?? @@ -17,6 +23,7 @@ const repositories = new Map([ ]); for (const overlay of manifest.overlays) { + if (selectedIds.size > 0 && !selectedIds.has(overlay.id)) continue; const repository = repositories.get(overlay.id); if (repository === undefined) continue; requireOutput(repository, ["rev-parse", "HEAD"], overlay.baseCommit); diff --git a/browser-runtime/forks/verify-mlc-hook.py b/browser-runtime/forks/verify-mlc-hook.py index 5bb05302..0ee4c214 100644 --- a/browser-runtime/forks/verify-mlc-hook.py +++ b/browser-runtime/forks/verify-mlc-hook.py @@ -21,7 +21,7 @@ "python/mlc_llm/model/llama/llama_model.py": "2a34402c81074ce0a773f9a73dc95aea20a7a0533b2561708d32ceeb72aec7dc", "python/mlc_llm/model/qwen3/qwen3_model.py": "0621190a80fc12ec58ca3fd5d439411135815c4f4f6596a5a0d258475b5c7291", "python/mlc_llm/model/gemma3/gemma3_model.py": "fd219c4779b1a7497fa533b264d5c77a973c5a1f46f41ed29923c312d6220f18", - "python/mlc_llm/model/drowse_hooks.py": "bc1763ba32ef304b4c45be05bcbd2f2eb1240fc5fd7f95f48e025d96dce76c9e", + "python/mlc_llm/model/drowse_hooks.py": "4fadef9db1c875c81ca9cde76dfdbc477a3755f4d982ba9d097ccc730f6778b1", } REQUIRED_FUNCTIONS = { "drowse_hook_profile", @@ -1456,25 +1456,75 @@ def parse_args() -> argparse.Namespace: def strip_gpu_thread_bindings(module, tvm): - def rewrite(node): - if isinstance(node, tvm.tirx.For) and node.kind == tvm.tirx.ForKind.THREAD_BINDING: - return tvm.tirx.For( - node.loop_var, - node.min, - node.extent, - tvm.tirx.ForKind.SERIAL, - node.body, - annotations=node.annotations, - step=node.step, - span=node.span, - ) - return None - - for global_var in list(module.get_global_vars()): - function = module[global_var] - if isinstance(function, tvm.tirx.PrimFunc): - body = tvm.tirx.stmt_functor.ir_transform(function.body, None, rewrite) - module.update_func(global_var, function.with_body(body)) + """Execute workgroup phases serially on CPU, retaining per-lane local state.""" + tir = tvm.tirx + def has_sync(node): + found = [] + tir.stmt_functor.post_order_visit(node, lambda n: found.append(n) if isinstance(n, tvm.ir.Call) and n.op.name == "tirx.tvm_storage_sync" else None) + return bool(found) + + def lower(function): + # Resolve block axes before moving a phase across its thread loop. + one = tvm.IRModule({"main": function}) + one = tvm.s_tir.transform.ConvertBlocksToOpaque()(one) + function = one["main"] + lanes = [] + tir.stmt_functor.post_order_visit(function.body, lambda n: lanes.append(n) if isinstance(n, tir.For) and n.thread_binding is not None and n.thread_binding.thread_tag == "threadIdx.x" else None) + if not lanes: + return function + extent = lanes[0].extent + locals_ = {} + def find_buffers(node): + if isinstance(node, tir.SBlock): + for buf in node.alloc_buffers: + if buf.scope() == "local": + locals_[buf] = tir.decl_buffer((extent, *buf.shape), buf.dtype, name=buf.name) + elif buf.scope() == "shared": + locals_[buf] = tir.decl_buffer(buf.shape, buf.dtype, name=buf.name) + tir.stmt_functor.post_order_visit(function.body, find_buffers) + thread = lanes[0].loop_var + def buffers(node): + if isinstance(node, tir.BufferLoad) and node.buffer in locals_: + indices = [thread, *node.indices] if node.buffer.scope() == "local" else node.indices + return tir.BufferLoad(locals_[node.buffer], indices) + if isinstance(node, tir.BufferStore) and node.buffer in locals_: + indices = [thread, *node.indices] if node.buffer.scope() == "local" else node.indices + return tir.BufferStore(locals_[node.buffer], node.value, indices) + if isinstance(node, tir.SBlock): + return tir.SBlock(node.iter_vars, node.reads, node.writes, node.name_hint, node.body, node.init, + [locals_.get(b,b) for b in node.alloc_buffers], node.match_buffers, node.annotations) + return None + body = tir.stmt_functor.ir_transform(function.body, None, buffers) + def serial_loop(node, body): + return tir.For(node.loop_var,node.min,node.extent,tir.ForKind.SERIAL,body,annotations=node.annotations,step=node.step) + def lane_loop(node): + return tir.For(thread,0,extent,tir.ForKind.SERIAL,node) + def phases(node): + if not has_sync(node): + return lane_loop(node) + if isinstance(node,tir.Evaluate): + return tir.Evaluate(0) + if isinstance(node,tir.SeqStmt): + return tir.SeqStmt([phases(s) for s in node.seq]) + if isinstance(node,tir.For): + return serial_loop(node,phases(node.body)) + if isinstance(node,tir.IfThenElse): + return tir.IfThenElse(node.condition,phases(node.then_case),phases(node.else_case) if node.else_case is not None else None) + if isinstance(node,tir.SBlockRealize): + b=node.block + return tir.SBlockRealize(node.iter_values,node.predicate,tir.SBlock(b.iter_vars,b.reads,b.writes,b.name_hint,phases(b.body),b.init,b.alloc_buffers,b.match_buffers,b.annotations)) + raise ValueError(f"unsupported cooperative CPU phase: {type(node)}") + def threads(node): + if isinstance(node,tir.For) and node.kind == tir.ForKind.THREAD_BINDING: + if node.thread_binding.thread_tag == "threadIdx.x": + return phases(node.body) + return serial_loop(node,node.body) + return None + body=tir.stmt_functor.ir_transform(body,None,threads) + return function.with_body(body) + for var in list(module.get_global_vars()): + if isinstance(module[var],tir.PrimFunc): + module.update_func(var,lower(module[var])) return module @@ -1513,16 +1563,16 @@ def verify_portable_topk_source(repository: Path) -> None: "candidate_count = T.ceildiv(column_count, EXACT_READOUT_TOPK_BLOCK_SIZE)", '"drowse_exact_top8_tiles"', '"drowse_exact_top8_merge"', - "_exact_readout_not_selected", - "for block in T.thread_binding(0, rows * candidate_count, \"blockIdx.x\")", - "for candidate in T.serial(candidates_per_row):", + "_exact_readout_is_better", + "while candidate_count > 1:", + 'for thread in T.thread_binding(0, 64, "threadIdx.x"):', "T.And(", "T.Or(", ): if fragment not in hooks_source: raise SystemExit(f"Drowse exact tiled top-8 omits {fragment}") - if 'scope="shared"' in exact_source or "tvm_storage_sync" in exact_source: - raise SystemExit("Drowse exact tiled top-8 must not use workgroup storage or barriers") + if 'scope="shared"' not in exact_source or "tvm_storage_sync" not in exact_source: + raise SystemExit("Drowse exact tiled top-8 requires bounded cooperative reduction") for relative_path in ( "python/mlc_llm/model/llama/llama_model.py", "python/mlc_llm/model/qwen3/qwen3_model.py", diff --git a/browser-runtime/forks/verify-webgpu-kernel-goldens.mjs b/browser-runtime/forks/verify-webgpu-kernel-goldens.mjs new file mode 100644 index 00000000..06b67ec9 --- /dev/null +++ b/browser-runtime/forks/verify-webgpu-kernel-goldens.mjs @@ -0,0 +1,578 @@ +import { chromium } from "../../webui/node_modules/playwright/index.mjs"; +import ts from "../../webui/node_modules/typescript/lib/typescript.js"; +import { dirname, resolve } from "node:path"; +import { createServer } from "node:http"; +import { readFile, writeFile } from "node:fs/promises"; +const [ + manifestPath, + webllmRepository, + reportPath = "/tmp/drowse-webgpu-kernel-goldens.json", +] = process.argv.slice(2); +if (!manifestPath || !webllmRepository) + throw Error( + "usage: node verify-webgpu-kernel-goldens.mjs MANIFEST WEBLLM_REPOSITORY [REPORT]", + ); +const root = dirname(resolve(manifestPath)); +const manifest = JSON.parse( + await readFile(resolve(manifestPath), "utf8"), +).filter((entry) => entry.family !== "sampling" && entry.family !== "controls"); +for (const entry of manifest) + entry.code = await readFile(resolve(root, entry.file), "utf8"); +const importTypescript = async (name) => { + const source = await readFile( + resolve(webllmRepository, "src", name + ".ts"), + "utf8", + ); + const javascript = ts.transpileModule(source, { + compilerOptions: { + target: ts.ScriptTarget.ES2022, + module: ts.ModuleKind.ES2022, + }, + }).outputText; + return import( + "data:text/javascript;base64," + Buffer.from(javascript).toString("base64") + ); +}; +const { drowseSamplingTopKShader } = await importTypescript("drowse_gpu_topk"); +for (const capacity of [1, 8, 64, 1024]) + for (const merge of [false, true]) + manifest.push({ + file: `sampling-${capacity}-${merge}`, + family: "sampling", + capacity, + merge, + code: drowseSamplingTopKShader(capacity, merge), + }); +const { drowseCurveControlShader } = await importTypescript( + "drowse_gpu_controls", +); +manifest.push({ + file: "curve-control-update", + family: "controls", + stride: 97, + code: drowseCurveControlShader(97), +}); +const server = createServer((req, res) => + res.end("Numerical GPU validation"), +); +await new Promise((r) => server.listen(0, "127.0.0.1", r)); +const browser = await chromium.launch({ channel: "chrome", headless: true }); +try { + const page = await browser.newPage(); + await page.goto(`http://127.0.0.1:${server.address().port}`); + const result = await page.evaluate(async (manifest) => { + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) throw Error("WebGPU unavailable"); + const device = await adapter.requestDevice(); + let lost = null; + device.lost.then((i) => (lost = i.message)); + const report = []; + const data = (n, fn) => Float32Array.from({ length: n }, (_, i) => fn(i)); + function buffer(array) { + const b = device.createBuffer({ + size: Math.max(16, array.byteLength), + usage: + GPUBufferUsage.STORAGE | + GPUBufferUsage.COPY_DST | + GPUBufferUsage.COPY_SRC, + }); + device.queue.writeBuffer(b, 0, array); + return b; + } + async function dispatch(entry, arrays, groups, args = {}) { + device.pushErrorScope("validation"); + const module = device.createShaderModule({ code: entry.code }); + const info = await module.getCompilationInfo(); + if (info.messages.some((m) => m.type === "error")) + throw Error( + entry.file + ": " + info.messages.map((m) => m.message).join("\n"), + ); + const pipeline = await device.createComputePipelineAsync({ + layout: "auto", + compute: { module, entryPoint: "main_kernel" }, + }); + const entries = [], + owned = []; + for (const m of entry.code.matchAll( + /@binding\((\d+)\) var]+> (\w+)\s*:/g, + )) { + if (!arrays[m[2]]) throw Error("missing " + m[2]); + const b = buffer(arrays[m[2]]); + owned.push(b); + entries.push({ binding: +m[1], resource: { buffer: b } }); + } + const fields = [ + ...entry.code + .match(/struct PODArgs \{([\s\S]*?)\}/)[1] + .matchAll(/(\w+): [iu]32/g), + ].map((m) => m[1]); + const uniform = device.createBuffer({ + size: Math.max(16, fields.length * 4), + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + device.queue.writeBuffer( + uniform, + 0, + Int32Array.from(fields, (f) => + f === "packGridDimX" ? groups : (args[f] ?? 1), + ), + ); + owned.push(uniform); + const ub = +entry.code.match(/@binding\((\d+)\) var/)[1]; + entries.push({ binding: ub, resource: { buffer: uniform } }); + const bind = device.createBindGroup({ + layout: pipeline.getBindGroupLayout(0), + entries, + }); + const encoder = device.createCommandEncoder(); + const pass = encoder.beginComputePass(); + pass.setPipeline(pipeline); + pass.setBindGroup(0, bind); + pass.dispatchWorkgroups(groups); + pass.end(); + const reads = []; + for (const m of entry.code.matchAll( + /@binding\((\d+)\) var (\w+)\s*:/g, + )) { + const a = arrays[m[2]], + src = entries.find((e) => e.binding === +m[1]).resource.buffer; + const read = device.createBuffer({ + size: Math.max(16, a.byteLength), + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }); + encoder.copyBufferToBuffer(src, 0, read, 0, a.byteLength); + reads.push({ name: m[2], read, array: a }); + } + device.queue.submit([encoder.finish()]); + const output = {}; + for (const r of reads) { + await r.read.mapAsync(GPUMapMode.READ); + output[r.name] = new r.array.constructor( + r.read.getMappedRange().slice(0, r.array.byteLength), + ); + r.read.unmap(); + r.read.destroy(); + } + const err = await device.popErrorScope(); + for (const b of owned) b.destroy(); + if (err) throw Error(entry.file + ": " + err.message); + if (lost) throw Error("device lost " + lost); + return output; + } + function compare(actual, expected, label, atol = 2e-5, rtol = 2e-5) { + let max = 0; + for (let i = 0; i < expected.length; i++) { + const e = Math.abs(actual[i] - expected[i]); + max = Math.max(max, e); + if ( + !Number.isFinite(actual[i]) || + e > atol + rtol * Math.abs(expected[i]) + ) + throw Error( + label + + " mismatch " + + i + + ": " + + actual[i] + + " expected " + + expected[i] + + " error " + + e, + ); + } + return max; + } + for (const entry of manifest.filter((e) => e.family === "affine")) { + const { h, b, t } = entry; + for (const mode of ["inactive", "push", "ablate", "mixed"]) { + const residual = data(b * t * h, (i) => Math.sin(i * 0.13)), + active = data(4, (i) => (mode === "inactive" ? 0 : i === 2 ? 0 : 1)), + along = data(4, (i) => (i - 1.5) * 0.1), + basis = data(4 * 8 * h, (i) => Math.sin(i * 0.27) / Math.sqrt(h)), + neutral = data(4 * h, (i) => Math.cos(i * 0.19) * 0.1), + target = data(4 * 8, (i) => Math.sin(i * 0.17)), + kappa = data(4 * 8, (i) => + mode === "ablate" + ? 1 + : mode === "mixed" + ? i % 3 === 0 + ? 1 + : 0 + : 0, + ); + const expected = Float64Array.from(residual); + for (let tok = 0; tok < b * t; tok++) + for (let g = 0; g < 4; g++) + if (active[g] && along[g]) { + const delta = new Float64Array(8); + for (let r = 0; r < 8; r++) { + let dot = 0; + if (kappa[g * 8 + r]) + for (let j = 0; j < h; j++) + dot += + (expected[tok * h + j] - neutral[g * h + j]) * + basis[(g * 8 + r) * h + j]; + delta[r] = target[g * 8 + r] - kappa[g * 8 + r] * dot; + } + for (let j = 0; j < h; j++) { + let shift = 0; + for (let r = 0; r < 8; r++) + shift += delta[r] * basis[(g * 8 + r) * h + j]; + expected[tok * h + j] += active[g] * along[g] * shift; + } + } + const output = await dispatch( + entry, + { + residual_ptr: residual, + active_ptr: active, + along_ptr: along, + basis_ptr: basis, + neutral_ptr: neutral, + target_ptr: target, + kappa_ptr: kappa, + output_ptr: new Float32Array(b * t * h), + }, + b * t, + ); + report.push({ + family: "affine", + h, + t, + mode, + maxError: compare( + output.output_ptr, + expected, + entry.file + mode, + mode === "inactive" ? 0 : 2e-5, + mode === "inactive" ? 0 : 2e-5, + ), + }); + } + } + for (const entry of manifest.filter( + (e) => e.family === "topk" && e.kernel === "drowse_exact_top8_tiles", + )) { + const { columns, rows } = entry; + for (const mode of ["ties", "tails", "random"]) { + const scores = data(rows * columns, (i) => + mode === "ties" + ? 1 + : mode === "tails" + ? i % columns === columns - 1 + ? 100 + : -2 + : Math.sin(i * 4.17), + ); + let candidates = Math.ceil(columns / 256); + let output = await dispatch( + entry, + { + source_ptr: scores, + output_values_ptr: new Float32Array(rows * candidates * 8), + output_indices_ptr: new Int32Array(rows * candidates * 8), + }, + rows * candidates, + ); + const merge = manifest.find( + (m) => + m.family === "topk" && + m.columns === columns && + m.kernel === "drowse_exact_top8_merge", + ); + while (candidates > 1) { + const blocks = Math.ceil(candidates / 32); + output = await dispatch( + merge, + { + source_values_ptr: output.output_values_ptr, + source_indices_ptr: output.output_indices_ptr, + output_values_ptr: new Float32Array(rows * blocks * 8), + output_indices_ptr: new Int32Array(rows * blocks * 8), + }, + rows * blocks, + { candidates_per_row: candidates, cse_v3: blocks }, + ); + candidates = blocks; + } + for (let r = 0; r < rows; r++) { + const ids = Array.from({ length: columns }, (_, i) => i) + .sort( + (a, b) => + scores[r * columns + b] - scores[r * columns + a] || a - b, + ) + .slice(0, 8); + for (let k = 0; k < 8; k++) + if ( + output.output_indices_ptr[r * 8 + k] !== ids[k] || + output.output_values_ptr[r * 8 + k] !== + scores[r * columns + ids[k]] + ) + throw Error( + entry.file + + mode + + " row " + + r + + " rank " + + k + + " got " + + output.output_indices_ptr[r * 8 + k] + + " expected " + + ids[k], + ); + } + report.push({ family: "topk", columns, rows, mode, exact: true }); + } + } + for (const columns of [17, 257, 4096, 70001]) { + const rows = 2, + candidates = Math.ceil(columns / 256), + scores = data(rows * columns, (i) => + i % 7 === 0 ? 1 : Math.sin(i * 0.21), + ); + const tile = manifest.find( + (e) => + e.family === "topk-dynamic" && e.kernel === "drowse_exact_top8_tiles", + ); + let output = await dispatch( + tile, + { + source_ptr: scores, + output_values_ptr: new Float32Array(rows * candidates * 8), + output_indices_ptr: new Int32Array(rows * candidates * 8), + }, + rows * candidates, + { columns, cse_v1: candidates }, + ); + const merge = manifest.find( + (e) => + e.family === "topk-dynamic" && e.kernel === "drowse_exact_top8_merge", + ); + output = await dispatch( + merge, + { + source_values_ptr: output.output_values_ptr, + source_indices_ptr: output.output_indices_ptr, + output_values_ptr: new Float32Array(rows * 8), + output_indices_ptr: new Int32Array(rows * 8), + }, + rows, + { rows, candidates_per_row: candidates }, + ); + for (let r = 0; r < rows; r++) { + const ids = Array.from({ length: columns }, (_, i) => i) + .sort( + (a, b) => + scores[r * columns + b] - scores[r * columns + a] || a - b, + ) + .slice(0, 8); + for (let k = 0; k < 8; k++) + if ( + output.output_indices_ptr[r * 8 + k] !== ids[k] || + output.output_values_ptr[r * 8 + k] !== scores[r * columns + ids[k]] + ) + throw Error( + "dynamic " + + columns + + " row " + + r + + " rank " + + k + + " got " + + output.output_indices_ptr[r * 8 + k] + + " expected " + + ids[k], + ); + } + report.push({ family: "topk-dynamic", columns, rows, exact: true }); + } + for (const entry of manifest.filter((e) => e.family === "transport")) { + const { h, layers } = entry; + const source = data(layers * h, (i) => Math.sin(i * 0.17)), + matrices = data( + layers * h * h, + (i) => Math.cos(i * 0.29) / Math.sqrt(h), + ); + const expected = new Float64Array(layers * h); + for (let l = 0; l < layers; l++) + for (let j = 0; j < h; j++) + for (let k = 0; k < h; k++) + expected[l * h + j] += + source[l * h + k] * matrices[(l * h + j) * h + k]; + const output = await dispatch( + entry, + { + source_ptr: source, + matrices_ptr: matrices, + output_ptr: new Float32Array(layers * h), + }, + layers * Math.ceil(h / 4), + { layers }, + ); + report.push({ + family: "transport", + h, + layers, + maxError: compare(output.output_ptr, expected, entry.file), + }); + } + for (const entry of manifest.filter((e) => e.family === "curve")) { + const { h, t, stride } = entry; + for (const active of [0, 0.4, 1]) + for (const magnitude of [1, 100]) { + const residual = data(t * h, (i) => Math.sin(i * 0.13)), + basis = data(4 * 8 * h, (i) => Math.sin(i * 0.27) / Math.sqrt(h)), + neutral = new Float32Array(4 * h), + q = data(t * 8, (i) => Math.cos(i * 0.17)), + coordinates = data(t * 8, (i) => Math.sin(i * 0.19) * magnitude), + parameters = new Float32Array(4 * stride); + parameters[0] = active; + const expected = new Float64Array(t * h); + for (let tok = 0; tok < t; tok++) { + let norm0 = 0, + norm1 = 0; + for (let j = 0; j < h; j++) { + let before = 0, + after = 0; + for (let r = 0; r < 8; r++) { + before += q[tok * 8 + r] * basis[r * h + j]; + after += coordinates[tok * 8 + r] * basis[r * h + j]; + } + expected[tok * h + j] = residual[tok * h + j] - before + after; + norm0 += residual[tok * h + j] ** 2; + norm1 += expected[tok * h + j] ** 2; + } + const scale = Math.min( + (3 * Math.sqrt(norm0)) / Math.max(Math.sqrt(norm1), 1e-6), + 1, + ); + for (let j = 0; j < h; j++) + expected[tok * h + j] = + active * expected[tok * h + j] * scale + + (1 - active) * residual[tok * h + j]; + } + const output = await dispatch( + entry, + { + residual_buffer_ptr: residual, + basis_buffer_ptr: basis, + neutral_buffer_ptr: neutral, + q_buffer_ptr: q, + coordinate_buffer_ptr: coordinates, + parameter_buffer_ptr: parameters, + output_ptr: new Float32Array(t * h), + }, + t, + ); + report.push({ + family: "curve", + h, + t, + active, + magnitude, + maxError: compare( + output.output_ptr, + expected, + entry.file, + 3e-5, + 3e-5, + ), + }); + } + } + for (const capacity of [1, 8, 64, 1024]) + for (const columns of [17, 257, 50003, 262144]) + for (const pattern of ["ties", "tail", "random"]) { + const count = Math.min(capacity, columns), + scores = data(columns, (i) => pattern === "ties" ? (i % 7 === 0 ? 1 : Math.sin(i * 0.21)) + : pattern === "tail" ? (i === columns - 1 ? 2 : -1) : Math.sin(i * 0.21)); + let lists = Math.ceil(columns / Math.max(256, capacity)); + const tile = manifest.find( + (e) => e.family === "sampling" && e.capacity === capacity && !e.merge, + ); + let output = await dispatch( + tile, + { + source_values: scores, + output_values: new Float32Array(lists * capacity), + output_indices: new Int32Array(lists * capacity), + }, + lists, + { columns, lists }, + ); + const merge = manifest.find( + (e) => e.family === "sampling" && e.capacity === capacity && e.merge, + ); + while (lists > 1) { + const nextLists = Math.ceil(lists / (capacity === 1 ? 256 : 2)); + output = await dispatch( + merge, + { + source_values: output.output_values, + source_indices: output.output_indices, + output_values: new Float32Array(nextLists * capacity), + output_indices: new Int32Array(nextLists * capacity), + }, + nextLists, + { columns, lists }, + ); + lists = nextLists; + } + const ids = Array.from({ length: columns }, (_, i) => i) + .sort((a, b) => scores[b] - scores[a] || a - b) + .slice(0, count); + for (let k = 0; k < count; k++) + if ( + output.output_indices[k] !== ids[k] || + output.output_values[k] !== scores[ids[k]] + ) + throw Error( + "sampling " + + columns + + " capacity " + + capacity + + " rank " + + k + + " got " + + output.output_indices[k] + + " expected " + + ids[k], + ); + report.push({ + family: "sampling", + pattern, + columns, + capacity, + count, + exact: true, + }); + } + for (const count of [4, 132]) { + const entry = manifest.find((e) => e.family === "controls"), + parameters = data(count * entry.stride, (i) => i * 0.01), + active = data(count, (i) => i % 2), + expected = parameters.slice(); + for (let i = 0; i < count; i++) expected[i * entry.stride] = active[i]; + const output = await dispatch( + entry, + { masks: active, parameters }, + Math.ceil(count / 64), + { count }, + ); + report.push({ + family: "controls", + count, + exact: + compare(output.parameters, expected, "sparse curve masks", 0, 0) === + 0, + }); + } + device.destroy(); + return { adapter: adapter.info, checks: report }; + }, manifest); + await writeFile(reportPath, JSON.stringify(result, null, 2)); + console.log(JSON.stringify(result, null, 2)); +} finally { + await browser.close(); + await new Promise((r) => server.close(r)); +} diff --git a/browser-runtime/forks/web-llm-drowse.patch b/browser-runtime/forks/web-llm-drowse.patch index 26f0ab2a..b447676c 100644 --- a/browser-runtime/forks/web-llm-drowse.patch +++ b/browser-runtime/forks/web-llm-drowse.patch @@ -1,5 +1,5 @@ diff --git a/package-lock.json b/package-lock.json -index 0070bde..79ea513 100644 +index 0070bde..ec5b039 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,21 @@ @@ -7,7 +7,7 @@ index 0070bde..79ea513 100644 - "name": "@mlc-ai/web-llm", - "version": "0.2.84", + "name": "@drowse/web-llm", -+ "version": "0.2.84-drowse.34", ++ "version": "0.2.84-drowse.38", "lockfileVersion": 3, "requires": true, "packages": { @@ -15,7 +15,7 @@ index 0070bde..79ea513 100644 - "name": "@mlc-ai/web-llm", - "version": "0.2.84", + "name": "@drowse/web-llm", -+ "version": "0.2.84-drowse.34", ++ "version": "0.2.84-drowse.38", "license": "Apache-2.0", "dependencies": { - "loglevel": "^1.9.1" @@ -170,18 +170,25 @@ index 0070bde..79ea513 100644 "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", diff --git a/package.json b/package.json -index cabfc3d..53aa196 100644 +index cabfc3d..c64c3c4 100644 --- a/package.json +++ b/package.json -@@ -1,6 +1,6 @@ +@@ -1,12 +1,12 @@ { - "name": "@mlc-ai/web-llm", - "version": "0.2.84", + "name": "@drowse/web-llm", -+ "version": "0.2.84-drowse.34", ++ "version": "0.2.84-drowse.38", "description": "Hardware accelerated language model chats on browsers", "main": "lib/index.js", "types": "lib/index.d.ts", + "type": "module", + "scripts": { +- "build": "rollup -c && ./cleanup-index-js.sh", ++ "build": "node --test tvm-direct-upload.test.mjs && rollup -c && ./cleanup-index-js.sh", + "lint": "npx eslint ./src/ ./tests/ ./examples/ && npx prettier ./src/ ./tests/ ./examples/ --check", + "test": "jest --coverage", + "format": "prettier --write \"./src/\" \"./examples/\" \"./tests/\"", @@ -17,7 +17,7 @@ ], "repository": { @@ -224,6 +231,26 @@ index cabfc3d..53aa196 100644 + } } } +diff --git a/rollup.config.js b/rollup.config.js +index 60fbfe9..abc1c0b 100644 +--- a/rollup.config.js ++++ b/rollup.config.js +@@ -2,6 +2,7 @@ import { nodeResolve } from "@rollup/plugin-node-resolve"; + import ignore from "rollup-plugin-ignore"; + import commonjs from "@rollup/plugin-commonjs"; + import typescript from "@rollup/plugin-typescript"; ++import { directUploadPlugin } from "./tvm-direct-upload.mjs"; + + export default { + input: "src/index.ts", +@@ -15,6 +16,7 @@ export default { + }, + ], + plugins: [ ++ directUploadPlugin(), + ignore(["fs", "path", "crypto", "node:fs", "node:path", "node:crypto"]), + nodeResolve({ browser: true }), + commonjs({ diff --git a/src/cache_util.ts b/src/cache_util.ts index 6bf8d4f..69bf5db 100644 --- a/src/cache_util.ts @@ -248,7 +275,7 @@ index 6bf8d4f..69bf5db 100644 } diff --git a/src/config.ts b/src/config.ts -index 6c45add..117c6ae 100644 +index 6c45add..13aff98 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,5 @@ @@ -281,18 +308,20 @@ index 6c45add..117c6ae 100644 temperature?: number | null; // Only in OpenAI APIs max_tokens?: number | null; -@@ -162,6 +167,10 @@ export interface GenerationConfig { +@@ -162,6 +167,12 @@ export interface GenerationConfig { // extra_body in ChatCompletionsRequest enable_thinking?: boolean | null; enable_latency_breakdown?: boolean | null; + drowse_generation_role?: string | null; + drowse_generation_seat?: "user" | "assistant" | null; + drowse_forced_prefix_token_ids?: number[] | null; ++ drowse_readout_start_index?: number; ++ drowse_readout_target_index?: number; + drowse_score_token_ids?: number[] | null; } export function postInitAndCheckGenerationConfigValues( -@@ -171,6 +180,34 @@ export function postInitAndCheckGenerationConfigValues( +@@ -171,6 +182,44 @@ export function postInitAndCheckGenerationConfigValues( // if we use `if value` directly, `value` being 0 evaluates to false, violating semantics return value !== undefined && value !== null; } @@ -310,6 +339,16 @@ index 6c45add..117c6ae 100644 + ) { + throw new TypeError("drowse_generation_seat must be `user` or `assistant`"); + } ++ for (const index of [ ++ config.drowse_readout_start_index, ++ config.drowse_readout_target_index, ++ ]) { ++ if (index !== undefined && (!Number.isSafeInteger(index) || index < 0)) { ++ throw new TypeError( ++ "Drowse readout indices must be non-negative integers", ++ ); ++ } ++ } + for (const [name, tokenIds] of [ + ["drowse_forced_prefix_token_ids", config.drowse_forced_prefix_token_ids], + ["drowse_score_token_ids", config.drowse_score_token_ids], @@ -327,7 +366,7 @@ index 6c45add..117c6ae 100644 if ( config.frequency_penalty && (config.frequency_penalty < -2.0 || config.frequency_penalty > 2.0) -@@ -189,11 +226,26 @@ export function postInitAndCheckGenerationConfigValues( +@@ -189,11 +238,27 @@ export function postInitAndCheckGenerationConfigValues( if (_hasValue(config.max_tokens) && config.max_tokens! <= 0) { throw new MinValueError("max_tokens", 0); } @@ -351,13 +390,26 @@ index 6c45add..117c6ae 100644 + } + if ( + _hasValue(config.temperature) && -+ (typeof config.temperature !== "number" || !Number.isFinite(config.temperature)) ++ (typeof config.temperature !== "number" || ++ !Number.isFinite(config.temperature)) + ) { + throw new TypeError("temperature must be finite"); } // If only one of frequency or presence penatly is set, make the other one 0.0 if ( -@@ -305,6 +357,14 @@ export interface ModelRecord { +@@ -235,9 +300,8 @@ export function postInitAndCheckGenerationConfigValues( + if (!config.logprobs) { + throw new DependencyError("top_logprobs", "logprobs", true); + } +- // top_logprobs should be in range [0,5] +- if (config.top_logprobs! < 0 || config.top_logprobs! > 5) { +- throw new RangeError("top_logprobs", 0, 5, "Got " + config.top_logprobs); ++ if (!Number.isSafeInteger(config.top_logprobs) || config.top_logprobs! < 0) { ++ throw new RangeError("top_logprobs", 0, Number.MAX_SAFE_INTEGER, "Got " + config.top_logprobs); + } + } + // If defined logprobs but not top_logprobs, simply make it 0 +@@ -305,6 +369,14 @@ export interface ModelRecord { * - "sync": require OPFS sync access handles. * - "auto": use sync access handles when available and fall back to async OPFS otherwise. * @@ -372,7 +424,7 @@ index 6c45add..117c6ae 100644 * @note Note that the Cache API is the most well-tested in WebLLM as of now. */ export type CacheBackend = "cache" | "indexeddb" | "cross-origin" | "opfs"; -@@ -314,6 +374,9 @@ export interface AppConfig { +@@ -314,6 +386,9 @@ export interface AppConfig { model_list: Array; cacheBackend?: CacheBackend; opfsAccessMode?: OPFSAccessMode; @@ -586,12 +638,278 @@ index 122e933..a9fb36b 100644 ); } const iterEnd = includeLastMsg ? input.length : input.length - 1; +diff --git a/src/drowse_gpu_controls.ts b/src/drowse_gpu_controls.ts +new file mode 100644 +index 0000000..156b4b9 +--- /dev/null ++++ b/src/drowse_gpu_controls.ts +@@ -0,0 +1,36 @@ ++import type * as tvmjs from "@mlc-ai/web-runtime"; ++ ++export function drowseCurveControlShader(stride: number): string { ++ return ` ++@group(0) @binding(0) var masks: array; ++@group(0) @binding(1) var parameters: array; ++struct PODArgs { count: u32, packGridDimX: u32 } ++@group(0) @binding(2) var args: PODArgs; ++@compute @workgroup_size(64, 1, 1) ++fn main_kernel(@builtin(global_invocation_id) position: vec3) { ++ if (position.x < args.count) { ++ parameters[position.x * ${stride}u] = masks[position.x]; ++ } ++}`; ++} ++ ++export function createDrowseCurveControlKernel( ++ tvm: tvmjs.Instance, ++ stride: number, ++): tvmjs.PackedFunc { ++ const create = tvm.getGlobalFunc("wasm.WebGPUCreateShader"); ++ try { ++ return tvm.detachFromCurrentScope( ++ create( ++ JSON.stringify({ ++ name: "main_kernel", ++ arg_types: ["handle", "handle", "uint32"], ++ launch_param_tags: ["blockIdx.x", "paramWriteAccess:[false,true]"], ++ }), ++ drowseCurveControlShader(stride), ++ ) as tvmjs.PackedFunc, ++ ); ++ } finally { ++ create.dispose(); ++ } ++} +diff --git a/src/drowse_gpu_topk.ts b/src/drowse_gpu_topk.ts +new file mode 100644 +index 0000000..74d754a +--- /dev/null ++++ b/src/drowse_gpu_topk.ts +@@ -0,0 +1,218 @@ ++import type * as tvmjs from "@mlc-ai/web-runtime"; ++ ++export function drowseSamplingTopKShader( ++ capacity: number, ++ merge: boolean, ++): string { ++ if (capacity === 1) return drowseSamplingArgmaxShader(merge); ++ const width = merge ? capacity * 2 : Math.max(256, capacity); ++ return ` ++@group(0) @binding(0) var output_values: array; ++@group(0) @binding(1) var output_indices: array; ++@group(0) @binding(2) var source_values: array; ++${merge ? "@group(0) @binding(3) var source_indices: array;" : ""} ++struct PODArgs { columns: u32, lists: u32, packGridDimX: u32 } ++@group(0) @binding(${merge ? 4 : 3}) var args: PODArgs; ++var values: array; ++var indices: array; ++fn better(av: f32, ai: i32, bv: f32, bi: i32) -> bool { ++ return ai >= 0 && (bi < 0 || av > bv || (av == bv && ai < bi)); ++} ++@compute @workgroup_size(128, 1, 1) ++fn main_kernel(@builtin(workgroup_id) group: vec3, @builtin(local_invocation_id) local: vec3) { ++ for (var i = local.x; i < ${width}u; i += 128u) { ++ values[i] = -3.402823e38; ++ indices[i] = -1; ++ ${ ++ merge ++ ? ` ++ let list = group.x * 2u + i / ${capacity}u; ++ let column = select(i, ${width - 1}u - i, i >= ${capacity}u); ++ if (list < args.lists) { ++ let source = list * ${capacity}u + column; ++ values[i] = source_values[source]; ++ indices[i] = source_indices[source]; ++ }` ++ : ` ++ let source = group.x * ${width}u + i; ++ if (source < args.columns) { ++ values[i] = source_values[source]; ++ indices[i] = i32(source); ++ }` ++ } ++ } ++ workgroupBarrier(); ++ ${ ++ merge ++ ? `for (var distance = ${capacity}u; distance > 0u; distance /= 2u) {` ++ : ` ++ for (var size = 2u; size <= ${width}u; size *= 2u) { ++ for (var distance = size / 2u; distance > 0u; distance /= 2u) {` ++ } ++ for (var i = local.x; i < ${merge ? capacity : width}u; i += 128u) { ++ let peer = i ^ distance; ++ if (i < peer) { ++ let av = values[i]; let ai = indices[i]; ++ let bv = values[peer]; let bi = indices[peer]; ++ let descending = ${merge ? "true" : "(i & size) == 0u"}; ++ if ((descending && better(bv, bi, av, ai)) || (!descending && better(av, ai, bv, bi))) { ++ values[i] = bv; indices[i] = bi; ++ values[peer] = av; indices[peer] = ai; ++ } ++ } ++ } ++ workgroupBarrier(); ++ } ++ ${merge ? "" : "}"} ++ for (var i = local.x; i < ${capacity}u; i += 128u) { ++ output_values[group.x * ${capacity}u + i] = values[i]; ++ output_indices[group.x * ${capacity}u + i] = indices[i]; ++ } ++}`; ++} ++ ++function drowseSamplingArgmaxShader(merge: boolean): string { ++ return ` ++@group(0) @binding(0) var output_values: array; ++@group(0) @binding(1) var output_indices: array; ++@group(0) @binding(2) var source_values: array; ++${merge ? "@group(0) @binding(3) var source_indices: array;" : ""} ++struct PODArgs { columns: u32, lists: u32, packGridDimX: u32 } ++@group(0) @binding(${merge ? 4 : 3}) var args: PODArgs; ++var values: array; ++var indices: array; ++fn better(av: f32, ai: i32, bv: f32, bi: i32) -> bool { ++ return ai >= 0 && (bi < 0 || av > bv || (av == bv && ai < bi)); ++} ++@compute @workgroup_size(128, 1, 1) ++fn main_kernel(@builtin(workgroup_id) group: vec3, @builtin(local_invocation_id) local: vec3) { ++ var value = -3.402823e38; ++ var index = -1; ++ for (var offset = local.x; offset < 256u; offset += 128u) { ++ let source = group.x * 256u + offset; ++ if (source < args.${merge ? "lists" : "columns"}) { ++ let candidate = ${merge ? "source_indices[source]" : "i32(source)"}; ++ let score = source_values[source]; ++ if (better(score, candidate, value, index)) { ++ value = score; ++ index = candidate; ++ } ++ } ++ } ++ values[local.x] = value; ++ indices[local.x] = index; ++ workgroupBarrier(); ++ for (var distance = 64u; distance > 0u; distance /= 2u) { ++ if (local.x < distance) { ++ let peer = local.x + distance; ++ if (better(values[peer], indices[peer], values[local.x], indices[local.x])) { ++ values[local.x] = values[peer]; ++ indices[local.x] = indices[peer]; ++ } ++ } ++ workgroupBarrier(); ++ } ++ if (local.x == 0u) { ++ output_values[group.x] = values[0]; ++ output_indices[group.x] = indices[0]; ++ } ++}`; ++} ++ ++export class DrowseGpuTopK { ++ private kernels = new Map(); ++ ++ constructor(private readonly tvm: tvmjs.Instance) {} ++ ++ select( ++ probabilities: tvmjs.Tensor, ++ count: number, ++ ): [tvmjs.Tensor, tvmjs.Tensor] { ++ const columns = probabilities.shape.at(-1)!; ++ if ( ++ !Number.isSafeInteger(count) || ++ count < 1 || ++ count > Math.min(columns, 1024) ++ ) { ++ throw new RangeError( ++ "Drowse GPU sampling supports 1 through 1024 candidates", ++ ); ++ } ++ const capacity = 2 ** Math.ceil(Math.log2(count)); ++ let kernels = this.kernels.get(capacity); ++ if (!kernels) { ++ const create = this.tvm.getGlobalFunc("wasm.WebGPUCreateShader"); ++ try { ++ kernels = [false, true].map((merge) => { ++ const handles = merge ? 4 : 3; ++ const kernel = create( ++ JSON.stringify({ ++ name: "main_kernel", ++ arg_types: [...Array(handles).fill("handle"), "uint32", "uint32"], ++ launch_param_tags: [ ++ "blockIdx.x", ++ `paramWriteAccess:${JSON.stringify([true, true, ...Array(handles - 2).fill(false)])}`, ++ ], ++ }), ++ drowseSamplingTopKShader(capacity, merge), ++ ) as tvmjs.PackedFunc; ++ return this.tvm.detachFromCurrentScope(kernel); ++ }) as [tvmjs.PackedFunc, tvmjs.PackedFunc]; ++ } finally { ++ create.dispose(); ++ } ++ this.kernels.set(capacity, kernels); ++ } ++ let lists = Math.ceil(columns / Math.max(256, capacity)); ++ let values = this.tvm.empty( ++ [lists * capacity], ++ "float32", ++ probabilities.device, ++ ); ++ let indices = this.tvm.empty( ++ [lists * capacity], ++ "int32", ++ probabilities.device, ++ ); ++ kernels[0]( ++ values.getDataPtr(), ++ indices.getDataPtr(), ++ probabilities.getDataPtr(), ++ columns, ++ lists, ++ lists, ++ ); ++ while (lists > 1) { ++ const nextLists = Math.ceil(lists / (capacity === 1 ? 256 : 2)); ++ const nextValues = this.tvm.empty( ++ [nextLists * capacity], ++ "float32", ++ probabilities.device, ++ ); ++ const nextIndices = this.tvm.empty( ++ [nextLists * capacity], ++ "int32", ++ probabilities.device, ++ ); ++ kernels[1]( ++ nextValues.getDataPtr(), ++ nextIndices.getDataPtr(), ++ values.getDataPtr(), ++ indices.getDataPtr(), ++ columns, ++ lists, ++ nextLists, ++ ); ++ values = nextValues; ++ indices = nextIndices; ++ lists = nextLists; ++ } ++ return [values.view([count]), indices.view([count])]; ++ } ++ ++ dispose(): void { ++ for (const pair of this.kernels.values()) ++ for (const kernel of pair) kernel.dispose(); ++ this.kernels.clear(); ++ } ++} diff --git a/src/drowse.ts b/src/drowse.ts new file mode 100644 -index 0000000..86c0bc2 +index 0000000..b551af2 --- /dev/null +++ b/src/drowse.ts -@@ -0,0 +1,1338 @@ +@@ -0,0 +1,1352 @@ +export const DROWSE_HOOK_ABI = "post-block-residual-v4" as const; +export const DROWSE_EXACT_READOUT_ABI = "exact-readout-v1" as const; + @@ -922,6 +1240,7 @@ index 0000000..86c0bc2 + geometryFeet?: Float32Array; + jLensBindingId?: string; + jLensLayerIndices?: Int32Array; ++ jLensReadoutLayerIndices?: Int32Array; + jLensTokenIds?: Int32Array; + saeBindingId?: string; +} @@ -1615,12 +1934,25 @@ index 0000000..86c0bc2 + for (const value of program.probeKind) { + if (value > 4) throw new TypeError("Drowse probe kind is invalid"); + } ++ if ( ++ program.jLensReadoutLayerIndices !== undefined && ++ (!(program.jLensReadoutLayerIndices instanceof Int32Array) || ++ program.jLensLayerIndices === undefined || ++ program.jLensReadoutLayerIndices.some( ++ (layer, index) => ++ !program.jLensLayerIndices!.includes(layer) || ++ (index > 0 && layer <= program.jLensReadoutLayerIndices![index - 1]), ++ )) ++ ) ++ throw new TypeError( ++ "J-lens readout layers must be an ordered subset of probability layers", ++ ); + const hasJlensProbe = program.probeKind.some((value) => value === 3); + const hasJlensProgram = program.jLensBindingId !== undefined; + if ( + hasJlensProgram !== (program.jLensLayerIndices !== undefined) || + hasJlensProgram !== (program.jLensTokenIds !== undefined) || -+ hasJlensProbe && !hasJlensProgram ++ (hasJlensProbe && !hasJlensProgram) + ) { + throw new TypeError( + "Drowse J-lens probes require one complete probability program", @@ -1931,7 +2263,7 @@ index 0000000..86c0bc2 + } +} diff --git a/src/engine.ts b/src/engine.ts -index 1934771..49deb22 100644 +index 1934771..9de3869 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -76,11 +76,44 @@ import { @@ -2212,7 +2544,7 @@ index 1934771..49deb22 100644 temperature: request.temperature, logit_bias: request.logit_bias, logprobs: request.logprobs, -@@ -822,6 +894,11 @@ export class MLCEngine implements MLCEngineInterface { +@@ -822,6 +894,15 @@ export class MLCEngine implements MLCEngineInterface { ignore_eos: request.ignore_eos, enable_thinking: request.extra_body?.enable_thinking, enable_latency_breakdown: request.extra_body?.enable_latency_breakdown, @@ -2221,10 +2553,14 @@ index 1934771..49deb22 100644 + drowse_forced_prefix_token_ids: + request.extra_body?.drowse_forced_prefix_token_ids, + drowse_score_token_ids: request.extra_body?.drowse_score_token_ids, ++ drowse_readout_start_index: ++ request.extra_body?.drowse_readout_start_index, ++ drowse_readout_target_index: ++ request.extra_body?.drowse_readout_target_index, }; // 0.5 Block wait until this pipeline finishes all previous requests -@@ -842,6 +919,7 @@ export class MLCEngine implements MLCEngineInterface { +@@ -842,6 +923,7 @@ export class MLCEngine implements MLCEngineInterface { // Big try-finally to release lock in case of errors try { @@ -2232,7 +2568,7 @@ index 1934771..49deb22 100644 if (request.seed !== null && request.seed !== undefined) { selectedPipeline.setSeed(request.seed); } -@@ -889,12 +967,14 @@ export class MLCEngine implements MLCEngineInterface { +@@ -889,12 +971,14 @@ export class MLCEngine implements MLCEngineInterface { choices.push({ finish_reason: finish_reason, @@ -2252,7 +2588,7 @@ index 1934771..49deb22 100644 message: isFunctionCalling ? { content: null, -@@ -906,7 +986,8 @@ export class MLCEngine implements MLCEngineInterface { +@@ -906,7 +990,8 @@ export class MLCEngine implements MLCEngineInterface { role: "assistant", }, }); @@ -2262,7 +2598,7 @@ index 1934771..49deb22 100644 prompt_tokens += selectedPipeline.getCurRoundPrefillTotalTokens(); prefill_time += selectedPipeline.getCurRoundPrefillTotalTime(); decode_time += selectedPipeline.getCurRoundDecodingTotalTime(); -@@ -997,11 +1078,16 @@ export class MLCEngine implements MLCEngineInterface { +@@ -997,11 +1082,20 @@ export class MLCEngine implements MLCEngineInterface { max_tokens: request.max_tokens, stop: request.stop, top_p: request.top_p, @@ -2276,10 +2612,14 @@ index 1934771..49deb22 100644 + drowse_forced_prefix_token_ids: + request.extra_body?.drowse_forced_prefix_token_ids, + drowse_score_token_ids: request.extra_body?.drowse_score_token_ids, ++ drowse_readout_start_index: ++ request.extra_body?.drowse_readout_start_index, ++ drowse_readout_target_index: ++ request.extra_body?.drowse_readout_target_index, }; // 0.5 Block wait until this pipeline finishes all previous requests -@@ -1022,6 +1108,7 @@ export class MLCEngine implements MLCEngineInterface { +@@ -1022,6 +1116,7 @@ export class MLCEngine implements MLCEngineInterface { // Big try-finally to release lock in case of errors try { @@ -2287,7 +2627,7 @@ index 1934771..49deb22 100644 if (request.seed !== null && request.seed !== undefined) { selectedPipeline.setSeed(request.seed); } -@@ -1051,15 +1138,18 @@ export class MLCEngine implements MLCEngineInterface { +@@ -1051,15 +1146,18 @@ export class MLCEngine implements MLCEngineInterface { choices.push({ finish_reason: finish_reason, @@ -2312,7 +2652,7 @@ index 1934771..49deb22 100644 prompt_tokens += selectedPipeline.getCurRoundPrefillTotalTokens(); prefill_time += selectedPipeline.getCurRoundPrefillTotalTime(); decode_time += selectedPipeline.getCurRoundDecodingTotalTime(); -@@ -1302,6 +1392,459 @@ export class MLCEngine implements MLCEngineInterface { +@@ -1302,6 +1400,459 @@ export class MLCEngine implements MLCEngineInterface { return selectedPipeline.forwardTokensAndSample(inputIds, isPrefill); } @@ -2772,7 +3112,7 @@ index 1934771..49deb22 100644 /** * Get the current generated response. * -@@ -1402,8 +1945,16 @@ export class MLCEngine implements MLCEngineInterface { +@@ -1402,8 +1953,16 @@ export class MLCEngine implements MLCEngineInterface { ] as ChatCompletionMessageParam; input_str = last_msg.content as string; input_role_str = @@ -2958,10 +3298,17 @@ index d583419..146eb24 100644 hasModelInCache, deleteChatConfigInCache, diff --git a/src/llm_chat.ts b/src/llm_chat.ts -index 616cff4..254fa3e 100644 +index 616cff4..34a2209 100644 --- a/src/llm_chat.ts +++ b/src/llm_chat.ts -@@ -10,11 +10,13 @@ import { +@@ -1,4 +1,6 @@ + import * as tvmjs from "@mlc-ai/web-runtime"; ++import { DrowseGpuTopK } from "./drowse_gpu_topk"; ++import { createDrowseCurveControlKernel } from "./drowse_gpu_controls"; + import * as xgr from "@mlc-ai/web-xgrammar"; + import log from "loglevel"; + import { Tokenizer } from "@mlc-ai/web-tokenizers"; +@@ -10,11 +12,13 @@ import { getImageDataFromURL, getRGBArrayFromImageData, getTokenTableFromTokenizer, @@ -2976,7 +3323,7 @@ index 616cff4..254fa3e 100644 TopLogprob, ResponseFormat, ChatCompletionContentPartImage, -@@ -23,6 +25,7 @@ import { +@@ -23,6 +27,7 @@ import { AttentionSinkSizeError, ContextWindowSizeExceededError, MinValueError, @@ -2984,7 +3331,7 @@ index 616cff4..254fa3e 100644 RangeError, WindowSizeConfigurationError, WindowSizeSpecificationError, -@@ -30,6 +33,50 @@ import { +@@ -30,6 +35,50 @@ import { TextCompletionExpectsKVEmptyError, CannotFindImageEmbedError, } from "./error"; @@ -3035,7 +3382,7 @@ index 616cff4..254fa3e 100644 type ImageURL = ChatCompletionContentPartImage.ImageURL; -@@ -47,6 +94,421 @@ type VMFunctionAvailability = { +@@ -47,6 +96,418 @@ type VMFunctionAvailability = { type VMFunctionRegistry = Record; @@ -3203,6 +3550,7 @@ index 616cff4..254fa3e 100644 + curveBasis?: tvmjs.Tensor; + curveNeutral?: tvmjs.Tensor; + curveParameters?: tvmjs.Tensor; ++ curveActive?: tvmjs.Tensor; + curveFeet?: tvmjs.Tensor; + curveDomainKind?: tvmjs.Tensor; + jLensTokenIds?: tvmjs.Tensor; @@ -3318,10 +3666,7 @@ index 616cff4..254fa3e 100644 + +export const DROWSE_DEFAULT_TOP_K = 1024; + -+export function effectiveDrowseTopK( -+ topK: number, -+ vocabSize: number, -+): number { ++export function effectiveDrowseTopK(topK: number, vocabSize: number): number { + if (!Number.isSafeInteger(topK) || topK < 0) { + throw new Error("Drowse sampler received an invalid top-k value"); + } @@ -3338,14 +3683,13 @@ index 616cff4..254fa3e 100644 + topK: number, + uniformSample: number, + selectedTokenIds: readonly number[] = [], ++ topLogprobCount = 32, +): DrowseSamplerResult { + if ( + sortedProbabilities.length === 0 || + sortedProbabilities.length !== sortedTokenIds.length + ) { -+ throw new Error( -+ "Drowse sampler received an invalid sorted distribution", -+ ); ++ throw new Error("Drowse sampler received an invalid sorted distribution"); + } + if (!Number.isFinite(topP) || topP < 0 || topP > 1) { + throw new Error("Drowse sampler received an invalid top-p value"); @@ -3353,6 +3697,9 @@ index 616cff4..254fa3e 100644 + if (!Number.isSafeInteger(topK) || topK < 0) { + throw new Error("Drowse sampler received an invalid top-k value"); + } ++ if (!Number.isSafeInteger(topLogprobCount) || topLogprobCount < 0) { ++ throw new Error("Drowse sampler received an invalid alternative count"); ++ } + if ( + !Number.isFinite(uniformSample) || + uniformSample < 0 || @@ -3361,10 +3708,7 @@ index 616cff4..254fa3e 100644 + throw new Error("Drowse sampler received an invalid uniform draw"); + } + -+ const candidateCount = effectiveDrowseTopK( -+ topK, -+ sortedProbabilities.length, -+ ); ++ const candidateCount = effectiveDrowseTopK(topK, sortedProbabilities.length); + let topKMass = 0; + for (let index = 0; index < candidateCount; index += 1) { + const probability = sortedProbabilities[index]; @@ -3425,7 +3769,7 @@ index 616cff4..254fa3e 100644 + logprob: selectedById.get(tokenId) ?? Number.NEGATIVE_INFINITY, + })); + const topLogprobs = Array.from( -+ { length: Math.min(32, supportCount) }, ++ { length: Math.min(topLogprobCount, supportCount) }, + (_, index) => ({ + token_id: sortedTokenIds[index], + logprob: logprobAt(index), @@ -3435,7 +3779,7 @@ index 616cff4..254fa3e 100644 + sampledTokenId, + sampledLogprob, + selectedLogprobs, -+ argmax: topLogprobs[0], ++ argmax: { token_id: sortedTokenIds[0], logprob: logprobAt(0) }, + topLogprobs, + entropyNats, + perplexity: Math.exp(entropyNats), @@ -3457,7 +3801,7 @@ index 616cff4..254fa3e 100644 type ResolvedModelABI = { kvStateKind: Exclude; prefillABI: ComputeABIKind; -@@ -67,6 +529,25 @@ export class LLMChatPipeline { +@@ -67,6 +528,25 @@ export class LLMChatPipeline { private vm: tvmjs.VirtualMachine; private prefill: tvmjs.PackedFunc; private decoding: tvmjs.PackedFunc; @@ -3483,10 +3827,15 @@ index 616cff4..254fa3e 100644 private resolvedModelABI!: ResolvedModelABI; private kvStateKind: KVStateKind = "kv_cache"; private image_embed: tvmjs.PackedFunc | undefined; -@@ -94,6 +575,26 @@ export class LLMChatPipeline { +@@ -94,7 +574,34 @@ export class LLMChatPipeline { private prefillLogitPositionHost = new Int32Array(1); private maxHistorySize = 1; private logitsOnCPU?: tvmjs.Tensor = undefined; ++ private drowseGpuTopK?: DrowseGpuTopK; ++ private drowseCurveControlKernel?: tvmjs.PackedFunc; ++ private drowseAffineActiveStaging?: Float32Array; ++ private drowseAffineAlongStaging?: Float32Array; ++ private drowseCurveActiveStaging?: Float32Array; + private drowseProgram?: DrowseRankOneBuffers; + private drowseStructuredProgram?: DrowseStructuredBuffers; + private drowseStructuredMode?: "structured" | "curved"; @@ -3494,6 +3843,7 @@ index 616cff4..254fa3e 100644 + private drowseCurveParametersHost?: Float32Array; + private drowseMeasurements?: tvmjs.Tensor; + private drowseGeometryMeasurements?: tvmjs.Tensor; ++ private drowseJlensReadoutLayers: Set | undefined; + private drowseJlensChunks?: DrowseJlensChunk[]; + private drowseJlensDictionary?: DrowseJlensBuffers; + private drowseJlensBufferLimits?: DrowseJlensBufferLimits; @@ -3508,9 +3858,11 @@ index 616cff4..254fa3e 100644 + private drowseExactReadoutAttested = false; + private drowseProbeKindHost?: Uint32Array; private filledKVCacheLength = 0; ++ private drowseCachedInputIds: number[] | null = []; // meta data -@@ -109,8 +610,12 @@ export class LLMChatPipeline { + private bosTokenId = 1; +@@ -109,8 +616,12 @@ export class LLMChatPipeline { // states private outputMessage = ""; private outputIds: Array = []; @@ -3523,16 +3875,18 @@ index 616cff4..254fa3e 100644 // frequency of appeared token ids till now (refresh after PrefillStep); token_id mapped to freq private appearedTokensFreq = new Map(); private imageDataCache = new Map(); -@@ -130,6 +635,8 @@ export class LLMChatPipeline { +@@ -130,6 +641,10 @@ export class LLMChatPipeline { private curRoundPrefillTotalTokens = 0; private curRoundDecodingTotalTime = 0; private curRoundPrefillTotalTime = 0; + private curRoundSampledTokens = 0; + private curRoundDrowseCompletionTokens = 0; ++ private drowseReadoutStart = 0; ++ private drowseReadoutTarget: number | undefined; // additional stats, reset at every prefillStep() public curRoundLatencyBreakdown: LatencyBreakdown = { -@@ -181,12 +688,14 @@ export class LLMChatPipeline { +@@ -181,12 +696,14 @@ export class LLMChatPipeline { tokenizer: Tokenizer, config: ChatConfig, logitProcessor?: LogitProcessor, @@ -3547,7 +3901,7 @@ index 616cff4..254fa3e 100644 this.fullVocabSize = this.config.vocab_size; this.bitmaskSize = Math.ceil(this.fullVocabSize / 32); -@@ -233,6 +742,31 @@ export class LLMChatPipeline { +@@ -233,6 +750,31 @@ export class LLMChatPipeline { "batch_prefill", "decode", "batch_decode", @@ -3579,7 +3933,7 @@ index 616cff4..254fa3e 100644 "create_tir_paged_kv_cache", "create_rnn_state", "sample_with_top_p", -@@ -244,6 +778,7 @@ export class LLMChatPipeline { +@@ -244,6 +786,7 @@ export class LLMChatPipeline { "apply_logit_bias_inplace", "softmax_with_temperature", ]); @@ -3587,7 +3941,7 @@ index 616cff4..254fa3e 100644 const fgetMetadata = this.vm.getFunction("_metadata"); const ret_value = fgetMetadata(); -@@ -253,9 +788,15 @@ export class LLMChatPipeline { +@@ -253,9 +796,15 @@ export class LLMChatPipeline { const vmFunctionAvailability = LLMChatPipeline.getVMFunctionAvailability(vmFunctionRegistry); @@ -3603,7 +3957,7 @@ index 616cff4..254fa3e 100644 ); const stateKinds: string[] = []; if (this.resolvedModelABI.needsKVCache) { -@@ -287,6 +828,139 @@ export class LLMChatPipeline { +@@ -287,6 +836,132 @@ export class LLMChatPipeline { vmFunctionRegistry, ), ); @@ -3618,10 +3972,8 @@ index 616cff4..254fa3e 100644 + const drowsePrefill = vmFunctionRegistry[drowsePrefillName]; + const drowseDecoding = vmFunctionRegistry[drowseDecodeName]; + if (drowsePrefill !== undefined && drowseDecoding !== undefined) { -+ this.drowsePrefill = -+ this.tvm.detachFromCurrentScope(drowsePrefill); -+ this.drowseDecoding = -+ this.tvm.detachFromCurrentScope(drowseDecoding); ++ this.drowsePrefill = this.tvm.detachFromCurrentScope(drowsePrefill); ++ this.drowseDecoding = this.tvm.detachFromCurrentScope(drowseDecoding); + } + if ( + this.resolvedModelABI.prefillABI === "batch" && @@ -3645,10 +3997,8 @@ index 616cff4..254fa3e 100644 + this.drowseCurvedDecoding = + this.tvm.detachFromCurrentScope(curvedDecode); + } -+ const geometryPrefill = -+ vmFunctionRegistry.drowse_geometry_batch_prefill; -+ const geometryDecode = -+ vmFunctionRegistry.drowse_geometry_batch_decode; ++ const geometryPrefill = vmFunctionRegistry.drowse_geometry_batch_prefill; ++ const geometryDecode = vmFunctionRegistry.drowse_geometry_batch_decode; + if (geometryPrefill !== undefined && geometryDecode !== undefined) { + this.drowseGeometryPrefill = + this.tvm.detachFromCurrentScope(geometryPrefill); @@ -3658,8 +4008,7 @@ index 616cff4..254fa3e 100644 + } + const jlensReadout = vmFunctionRegistry.drowse_jlens_probabilities; + if (jlensReadout !== undefined) { -+ this.drowseJlensReadout = -+ this.tvm.detachFromCurrentScope(jlensReadout); ++ this.drowseJlensReadout = this.tvm.detachFromCurrentScope(jlensReadout); + } + const jlensReadoutAccumulate = + vmFunctionRegistry.drowse_jlens_readout_accumulate; @@ -3687,8 +4036,9 @@ index 616cff4..254fa3e 100644 + const saeJumpReluReadoutAccumulate = + vmFunctionRegistry.drowse_sae_jump_relu_readout_accumulate; + if (saeJumpReluReadoutAccumulate !== undefined) { -+ this.drowseSaeJumpReluReadoutAccumulate = -+ this.tvm.detachFromCurrentScope(saeJumpReluReadoutAccumulate); ++ this.drowseSaeJumpReluReadoutAccumulate = this.tvm.detachFromCurrentScope( ++ saeJumpReluReadoutAccumulate, ++ ); + } + const hookProfile = vmFunctionRegistry.drowse_hook_profile; + if (hookProfile !== undefined) { @@ -3702,17 +4052,14 @@ index 616cff4..254fa3e 100644 + this.resolvedModelABI.decodeABI === "batch" + ? "drowse_capture_batch_decode" + : "drowse_capture_decode"; -+ const drowseCapturePrefill = -+ vmFunctionRegistry[drowseCapturePrefillName]; -+ const drowseCaptureDecoding = -+ vmFunctionRegistry[drowseCaptureDecodeName]; ++ const drowseCapturePrefill = vmFunctionRegistry[drowseCapturePrefillName]; ++ const drowseCaptureDecoding = vmFunctionRegistry[drowseCaptureDecodeName]; + if ( + drowseCapturePrefill !== undefined && + drowseCaptureDecoding !== undefined + ) { -+ this.drowseCapturePrefill = this.tvm.detachFromCurrentScope( -+ drowseCapturePrefill, -+ ); ++ this.drowseCapturePrefill = ++ this.tvm.detachFromCurrentScope(drowseCapturePrefill); + this.drowseCaptureDecoding = this.tvm.detachFromCurrentScope( + drowseCaptureDecoding, + ); @@ -3743,38 +4090,10 @@ index 616cff4..254fa3e 100644 if (this.resolvedModelABI.prefillABI === "batch") { log.info("Using batch_prefill kernel."); } -@@ -483,28 +1157,1757 @@ export class LLMChatPipeline { - tvm.endScope(); - } - -- dispose() { -- // TODO: Do we need to dispose all PackedFuncs here? -- this.grammarMatcher?.dispose(); -- this.params.dispose(); -- this.decoding.dispose(); -- this.prefill.dispose(); -- this.embed.dispose(); -- this.image_embed?.dispose(); -- this.prefillLogitPositions?.dispose(); -- this.rnnState?.dispose(); -- this.kvCache?.dispose(); -- this.fsampleWithTopP.dispose(); -- this.fargsortProbs.dispose(); -- this.sampleIndicesDevice?.dispose(); -- this.topPDevice?.dispose(); -- this.vm.dispose(); -- this.fclearKVCaches.dispose(); -- this.logitsOnCPU?.dispose(); -- this.tvm.dispose(); -- this.tokenizer.dispose(); -- this.xgTokenizerInfo?.dispose(); -- this.grammarCompiler?.dispose(); -+ dispose() { -+ // TODO: Do we need to dispose all PackedFuncs here? -+ this.grammarMatcher?.dispose(); -+ this.params.dispose(); -+ this.decoding.dispose(); -+ this.prefill.dispose(); +@@ -489,6 +1164,32 @@ export class LLMChatPipeline { + this.params.dispose(); + this.decoding.dispose(); + this.prefill.dispose(); + this.drowseDecoding?.dispose(); + this.drowsePrefill?.dispose(); + this.drowseStructuredDecoding?.dispose(); @@ -3794,31 +4113,23 @@ index 616cff4..254fa3e 100644 + this.drowseSaeReadoutAccumulate?.dispose(); + this.drowseSaeJumpReluReadoutAccumulate?.dispose(); + this.drowseHookProfile?.dispose(); ++ this.drowseCurveControlKernel?.dispose(); ++ this.drowseCurveControlKernel = undefined; ++ this.drowseGpuTopK?.dispose(); ++ this.drowseGpuTopK = undefined; + this.disposeDrowseProgram(); + this.disposeDrowseJlensDictionary(); + this.disposeDrowseSaeDictionary(); -+ this.embed.dispose(); -+ this.image_embed?.dispose(); -+ this.prefillLogitPositions?.dispose(); -+ this.rnnState?.dispose(); -+ this.kvCache?.dispose(); -+ this.fsampleWithTopP.dispose(); -+ this.fargsortProbs.dispose(); -+ this.sampleIndicesDevice?.dispose(); -+ this.topPDevice?.dispose(); -+ this.vm.dispose(); -+ this.fclearKVCaches.dispose(); -+ this.logitsOnCPU?.dispose(); -+ this.tvm.dispose(); -+ this.tokenizer.dispose(); -+ this.xgTokenizerInfo?.dispose(); -+ this.grammarCompiler?.dispose(); -+ } -+ + this.embed.dispose(); + this.image_embed?.dispose(); + this.prefillLogitPositions?.dispose(); +@@ -507,6 +1208,1761 @@ export class LLMChatPipeline { + this.grammarCompiler?.dispose(); + } + + supportsDrowseRankOneHooks(): boolean { + return ( -+ this.drowsePrefill !== undefined && -+ this.drowseDecoding !== undefined ++ this.drowsePrefill !== undefined && this.drowseDecoding !== undefined + ); + } + @@ -3858,8 +4169,7 @@ index 616cff4..254fa3e 100644 + replayScoring: true, + tokenizer: true, + namedRoles: this.conversation.supportsDrowseNamedRoles(), -+ userSeatGeneration: -+ this.conversation.supportsDrowseUserSeatGeneration(), ++ userSeatGeneration: this.conversation.supportsDrowseUserSeatGeneration(), + sceneStitching: this.conversation.supportsDrowseUserSeatGeneration(), + }; + } @@ -3903,9 +4213,7 @@ index 616cff4..254fa3e 100644 + tokenId >= this.fullVocabSize, + ) + ) { -+ throw new TypeError( -+ "Drowse tokenizer IDs must be inside the vocabulary", -+ ); ++ throw new TypeError("Drowse tokenizer IDs must be inside the vocabulary"); + } + return this.tokenizer.decode(Int32Array.from(tokenIds)); + } @@ -4247,7 +4555,9 @@ index 616cff4..254fa3e 100644 + ); + } + const hasCurve = program.curveRank.some((rank) => rank > 0); -+ const hasGeometry = program.format === DROWSE_STRUCTURED_HOOK_FORMAT; ++ const hasGeometry = ++ program.format === DROWSE_STRUCTURED_HOOK_FORMAT && ++ program.geometryActive!.some(Boolean); + if ( + hasCurve + ? !this.supportsDrowseCurvedHooks() @@ -4375,6 +4685,10 @@ index 616cff4..254fa3e 100644 + [layerCount, DROWSE_STRUCTURED_MAX_CURVES], + program.curveDomainKind!, + ), ++ curveActive: f32( ++ [layerCount, DROWSE_STRUCTURED_MAX_CURVES], ++ Float32Array.from(program.curveActive), ++ ), + curveParameters: f32( + [ + layerCount, @@ -4452,6 +4766,10 @@ index 616cff4..254fa3e 100644 + this.disposeDrowseProgram(); + this.drowseStructuredProgram = next; + this.drowseJlensChunks = nextJlensChunks; ++ this.drowseJlensReadoutLayers = ++ program.jLensReadoutLayerIndices === undefined ++ ? undefined ++ : new Set(program.jLensReadoutLayerIndices); + this.drowseSaeReadoutActive = program.saeBindingId !== undefined; + this.drowseStructuredMode = hasCurve ? "curved" : "structured"; + this.drowseAffineAlongHost = new Float32Array(program.affineAlong); @@ -4474,18 +4792,17 @@ index 616cff4..254fa3e 100644 + ) { + throw new TypeError("Drowse affine controls have the wrong length"); + } -+ program.affineActive.copyFrom(Float32Array.from(affineActive)); -+ program.affineAlong.copyFrom( -+ Float32Array.from( -+ this.drowseAffineAlongHost!, -+ (value, index) => value * affineActive[index], -+ ), -+ ); ++ this.drowseAffineActiveStaging ??= new Float32Array(affineActive.length); ++ this.drowseAffineAlongStaging ??= new Float32Array(affineActive.length); ++ for (let index = 0; index < affineActive.length; index += 1) { ++ this.drowseAffineActiveStaging[index] = affineActive[index]; ++ this.drowseAffineAlongStaging[index] = ++ this.drowseAffineAlongHost![index] * affineActive[index]; ++ } ++ program.affineActive.copyFrom(this.drowseAffineActiveStaging); ++ program.affineAlong.copyFrom(this.drowseAffineAlongStaging); + if (curveActive !== undefined) { -+ if ( -+ curveActive.length !== -+ layerCount * DROWSE_STRUCTURED_MAX_CURVES -+ ) { ++ if (curveActive.length !== layerCount * DROWSE_STRUCTURED_MAX_CURVES) { + throw new TypeError( + "Drowse curve controls do not match the installed program", + ); @@ -4501,16 +4818,33 @@ index 616cff4..254fa3e 100644 + this.drowseCurveParametersHost!, + curveActive, + ); -+ program.curveParameters.copyFrom(this.drowseCurveParametersHost!); ++ this.drowseCurveActiveStaging ??= new Float32Array(curveActive.length); ++ this.drowseCurveActiveStaging.set(curveActive); ++ program.curveActive!.copyFrom(this.drowseCurveActiveStaging); ++ if (!this.drowseCurveControlKernel) { ++ this.tvm.beginScope(); ++ try { ++ this.drowseCurveControlKernel = createDrowseCurveControlKernel( ++ this.tvm, ++ DROWSE_STRUCTURED_CURVE_PARAMETER_STRIDE, ++ ); ++ } finally { ++ this.tvm.endScope(); ++ } ++ } ++ this.drowseCurveControlKernel( ++ program.curveActive!.getDataPtr(), ++ program.curveParameters.getDataPtr(), ++ curveActive.length, ++ Math.ceil(curveActive.length / 64), ++ ); + } + } + // WebGPU preserves copyFrom uploads before the next forward on this queue. + this.resetDrowseReadbackState(); + } + -+ async setDrowseSaeDictionary( -+ dictionary: DrowseSaeDictionary, -+ ): Promise { ++ async setDrowseSaeDictionary(dictionary: DrowseSaeDictionary): Promise { + await this.requireDrowseExactReadout("sae"); + const hiddenSize = this.requireModelDimension("hidden_size"); + const layerCount = this.requireModelDimension("num_hidden_layers"); @@ -4600,8 +4934,7 @@ index 616cff4..254fa3e 100644 + + async clearDrowseJlensDictionary(): Promise { + await this.requireDrowseExactReadout("jlens"); -+ if (this.drowseJlensChunks !== undefined) -+ this.disposeDrowseProgram(); ++ if (this.drowseJlensChunks !== undefined) this.disposeDrowseProgram(); + this.disposeDrowseJlensDictionary(); + } + @@ -4625,9 +4958,7 @@ index 616cff4..254fa3e 100644 + + async readDrowseMeasurementBundle(): Promise { + if (this.drowseMeasurementBundleHost !== undefined) { -+ return cloneDrowseMeasurementBundle( -+ this.drowseMeasurementBundleHost, -+ ); ++ return cloneDrowseMeasurementBundle(this.drowseMeasurementBundleHost); + } + this.tvm.beginScope(); + try { @@ -4635,11 +4966,7 @@ index 616cff4..254fa3e 100644 + this.drowseMeasurements === undefined + ? undefined + : this.tvm -+ .empty( -+ this.drowseMeasurements.shape, -+ "float32", -+ this.tvm.cpu(), -+ ) ++ .empty(this.drowseMeasurements.shape, "float32", this.tvm.cpu()) + .copyFrom(this.drowseMeasurements); + const geometryHost = + this.drowseGeometryMeasurements === undefined @@ -4688,9 +5015,7 @@ index 616cff4..254fa3e 100644 + ? {} + : { saeTopFeatures: this.drowseSaeTopFeaturesHost }), + }; -+ return cloneDrowseMeasurementBundle( -+ this.drowseMeasurementBundleHost, -+ ); ++ return cloneDrowseMeasurementBundle(this.drowseMeasurementBundleHost); + } finally { + this.disposeDrowsePendingReadbacks(); + this.tvm.endScope(); @@ -4701,9 +5026,7 @@ index 616cff4..254fa3e 100644 + return (await this.readDrowseMeasurementBundle()).scalar; + } + -+ async readDrowseGeometryMeasurements(): Promise< -+ Float32Array | undefined -+ > { ++ async readDrowseGeometryMeasurements(): Promise { + return (await this.readDrowseMeasurementBundle()).geometry; + } + @@ -4787,6 +5110,14 @@ index 616cff4..254fa3e 100644 + return selected; + } + ++ private drowseDiscoveryRequested(): boolean { ++ return ( ++ this.curRoundDrowseCompletionTokens >= this.drowseReadoutStart && ++ (this.drowseReadoutTarget === undefined || ++ this.curRoundDrowseCompletionTokens === this.drowseReadoutTarget) ++ ); ++ } ++ + private async computeDrowseJlensProbabilities( + hiddenStates: tvmjs.Tensor, + tokenIds: tvmjs.Tensor, @@ -4795,15 +5126,20 @@ index 616cff4..254fa3e 100644 + this.drowseJlensProbabilitiesHost = undefined; + this.drowseJlensTopTokensHost = undefined; + if ( ++ !this.drowseDiscoveryRequested() && ++ !this.drowseProbeKindHost?.some((kind) => kind === 3) ++ ) ++ return; ++ if ( + this.drowseJlensReadout === undefined || + this.drowseProbeKindHost === undefined || + this.drowseJlensChunks === undefined + ) { -+ throw new Error( -+ "The Drowse J-lens probability runtime is unavailable", -+ ); ++ throw new Error("The Drowse J-lens probability runtime is unavailable"); + } + if ( ++ this.drowseDiscoveryRequested() && ++ this.drowseJlensReadoutLayers?.size !== 0 && + this.drowseExactReadoutAttested && + this.drowseJlensReadoutAccumulate !== undefined && + this.drowseJlensReadoutTopK !== undefined @@ -4870,6 +5206,31 @@ index 616cff4..254fa3e 100644 + let fittedLayerCount = 0; + for (const [chunkIndex, chunk] of this.drowseJlensChunks!.entries()) { + stage = `running chunk ${chunkIndex + 1}/${this.drowseJlensChunks!.length}`; ++ if ( ++ this.drowseJlensReadoutLayers !== undefined && ++ !this.drowseJlensReadoutLayers.has(chunk.layerIds[0]) ++ ) { ++ const selected = this.drowseJlensReadout!( ++ hiddenStates, ++ chunk.jacobians, ++ tokenIds, ++ chunk.layerIdsDevice, ++ this.params, ++ ); ++ this.requireDrowseTensorShape( ++ selected, ++ [chunk.layerIds.length, DROWSE_STRUCTURED_MAX_PROBES], ++ "J-lens probabilities", ++ ); ++ const selectedHost = this.tvm.empty( ++ selected.shape, ++ "float32", ++ this.tvm.cpu(), ++ ); ++ selectedHost.copyFrom(selected); ++ pending.push({ chunk, selectedHost }); ++ continue; ++ } + const accumulated = this.drowseJlensReadoutAccumulate!( + hiddenStates, + chunk.jacobians, @@ -4978,8 +5339,10 @@ index 616cff4..254fa3e 100644 + statsHost.copyFrom(statsDevice); + for (const row of pending) { + this.tvm.detachFromCurrentScope(row.selectedHost); -+ this.tvm.detachFromCurrentScope(row.layerTokenIdsHost!); -+ this.tvm.detachFromCurrentScope(row.layerProbabilitiesHost!); ++ if (row.layerTokenIdsHost) ++ this.tvm.detachFromCurrentScope(row.layerTokenIdsHost); ++ if (row.layerProbabilitiesHost) ++ this.tvm.detachFromCurrentScope(row.layerProbabilitiesHost); + } + this.tvm.detachFromCurrentScope(tokenIdsHost); + this.tvm.detachFromCurrentScope(statsHost); @@ -4995,9 +5358,7 @@ index 616cff4..254fa3e 100644 + : typeof error === "object" && error !== null && "message" in error + ? String(error.message) + : String(error); -+ throw new Error( -+ `Drowse exact J-lens failed while ${stage}: ${message}`, -+ ); ++ throw new Error(`Drowse exact J-lens failed while ${stage}: ${message}`); + } finally { + this.tvm.endScope(); + } @@ -5156,6 +5517,7 @@ index 616cff4..254fa3e 100644 + ? this.drowseSaeJumpReluReadoutAccumulate + : this.drowseSaeReadoutAccumulate; + if ( ++ !this.drowseDiscoveryRequested() || + !this.drowseSaeReadoutActive || + dictionary === undefined || + accumulate === undefined @@ -5263,12 +5625,15 @@ index 616cff4..254fa3e 100644 + let fittedLayerOffset = 0; + for (const row of pending.chunks) { + if ( ++ this.drowseJlensReadoutLayers !== undefined && ++ !this.drowseJlensReadoutLayers.has(row.chunk.layerIds[0]) ++ ) ++ continue; ++ if ( + row.layerTokenIdsHost === undefined || + row.layerProbabilitiesHost === undefined + ) { -+ throw new Error( -+ "The Drowse J-lens aggregate readback is incomplete", -+ ); ++ throw new Error("The Drowse J-lens aggregate readback is incomplete"); + } + layerIndices.set(row.chunk.layerIds, fittedLayerOffset); + layerTokenIds.set( @@ -5285,10 +5650,7 @@ index 616cff4..254fa3e 100644 + this.drowseJlensTopTokensHost = { + tokenIds: new Int32Array(aggregate.tokenIdsHost.toArray()), + strength: stats.slice(0, DROWSE_READOUT_TOP_K), -+ centerOfMass: stats.slice( -+ DROWSE_READOUT_TOP_K, -+ 2 * DROWSE_READOUT_TOP_K, -+ ), ++ centerOfMass: stats.slice(DROWSE_READOUT_TOP_K, 2 * DROWSE_READOUT_TOP_K), + spread: stats.slice(2 * DROWSE_READOUT_TOP_K), + fittedLayerCount: aggregate.fittedLayerCount, + layerIndices, @@ -5372,9 +5734,7 @@ index 616cff4..254fa3e 100644 + + private requireDrowseJlensBufferLimits(): DrowseJlensBufferLimits { + if (this.drowseJlensBufferLimits === undefined) { -+ throw new Error( -+ "The Drowse J-lens WebGPU buffer limits are unavailable", -+ ); ++ throw new Error("The Drowse J-lens WebGPU buffer limits are unavailable"); + } + return this.drowseJlensBufferLimits; + } @@ -5403,9 +5763,7 @@ index 616cff4..254fa3e 100644 + const byLayer = new Map(); + for (const chunk of dictionary.chunks) { + if (chunk.layerIds.length !== 1) { -+ throw new Error( -+ "The resident Drowse J-lens chunk layout is invalid", -+ ); ++ throw new Error("The resident Drowse J-lens chunk layout is invalid"); + } + byLayer.set(chunk.layerIds[0], chunk); + } @@ -5473,10 +5831,12 @@ index 616cff4..254fa3e 100644 + this.drowseSaeReadoutActive = false; + this.drowseProbeKindHost = undefined; + this.drowseAffineAlongHost = undefined; ++ this.drowseAffineActiveStaging = undefined; ++ this.drowseAffineAlongStaging = undefined; ++ this.drowseCurveActiveStaging = undefined; + this.drowseCurveParametersHost = undefined; + if (this.drowseProgram !== undefined) { -+ for (const tensor of Object.values(this.drowseProgram)) -+ tensor.dispose(); ++ for (const tensor of Object.values(this.drowseProgram)) tensor.dispose(); + this.drowseProgram = undefined; + } + if (this.drowseStructuredProgram !== undefined) { @@ -5520,10 +5880,12 @@ index 616cff4..254fa3e 100644 + this.disposeDrowsePendingSaeReadback(); + this.drowseSaeTopFeaturesHost = undefined; + this.drowseMeasurementBundleHost = undefined; - } - ++ } ++ /** -@@ -514,6 +2917,11 @@ export class LLMChatPipeline { + * Get the current message. + */ +@@ -514,6 +2970,11 @@ export class LLMChatPipeline { return this.outputMessage; } @@ -5535,7 +5897,7 @@ index 616cff4..254fa3e 100644 /** * Reset the runtime statistics */ -@@ -535,6 +2943,7 @@ export class LLMChatPipeline { +@@ -535,6 +2996,7 @@ export class LLMChatPipeline { } this.resetKVCache(); this.filledKVCacheLength = 0; @@ -5543,7 +5905,15 @@ index 616cff4..254fa3e 100644 this.logitProcessor?.resetState(); this.tvm.endScope(); } -@@ -572,6 +2981,10 @@ export class LLMChatPipeline { +@@ -543,6 +3005,7 @@ export class LLMChatPipeline { + * Reset KV Cache + */ + resetKVCache() { ++ this.drowseCachedInputIds = []; + const states = this.getActiveKVStates(); + for (const state of states) { + this.fclearKVCaches(state); +@@ -572,6 +3035,10 @@ export class LLMChatPipeline { return this.finishReason; } @@ -5554,7 +5924,7 @@ index 616cff4..254fa3e 100644 /** * @returns tokenLogprobArray for this current round of autoregressive generation. * Updated upon each sampled token, cleared upon each prefillStep(). -@@ -587,6 +3000,10 @@ export class LLMChatPipeline { +@@ -587,6 +3054,10 @@ export class LLMChatPipeline { return this.curRoundDecodingTotalTokens; } @@ -5565,7 +5935,7 @@ index 616cff4..254fa3e 100644 /** * @returns the number of tokens decoded for a single request or a single choice in the request. */ -@@ -721,13 +3138,17 @@ export class LLMChatPipeline { +@@ -721,13 +3192,17 @@ export class LLMChatPipeline { */ async prefillStep( inp: string, @@ -5586,7 +5956,7 @@ index 616cff4..254fa3e 100644 ); } if (this.resetStatsPerPrefill) { -@@ -738,8 +3159,10 @@ export class LLMChatPipeline { +@@ -738,8 +3213,10 @@ export class LLMChatPipeline { // cleanup the per convo states this.outputIds = []; @@ -5597,16 +5967,18 @@ index 616cff4..254fa3e 100644 this.tokenLogprobArray = []; this.curRoundDecodingTotalTokens = 0; this.curRoundPrefillTotalTokens = 0; -@@ -747,6 +3170,8 @@ export class LLMChatPipeline { +@@ -747,6 +3224,10 @@ export class LLMChatPipeline { this.curRoundDecodingTotalTime = 0; this.curRoundGrammarInitTotalTime = 0; this.curRoundGrammarPerTokenTotalTime = 0; + this.curRoundSampledTokens = 0; + this.curRoundDrowseCompletionTokens = 0; ++ this.drowseReadoutStart = genConfig?.drowse_readout_start_index ?? 0; ++ this.drowseReadoutTarget = genConfig?.drowse_readout_target_index; this.curRoundLatencyBreakdown = { logitProcessorTime: [], -@@ -758,6 +3183,8 @@ export class LLMChatPipeline { +@@ -758,6 +3239,8 @@ export class LLMChatPipeline { }; this.stopTriggered = false; @@ -5615,7 +5987,7 @@ index 616cff4..254fa3e 100644 const conversation = this.conversation; // -1. Instantiate grammar matcher according to generation config. This step is overlapped -@@ -835,17 +3262,28 @@ export class LLMChatPipeline { +@@ -835,17 +3318,28 @@ export class LLMChatPipeline { conversation.prompt = inp; } else { conversation.appendMessage(msgRole, inp, inp_role_str); @@ -5648,7 +6020,7 @@ index 616cff4..254fa3e 100644 } } const [inputData, promptLen, getEmbedSize] = await this.getInputData(); -@@ -944,8 +3382,9 @@ export class LLMChatPipeline { +@@ -944,8 +3438,9 @@ export class LLMChatPipeline { } this.stopTriggered = true; this.finishReason = "abort"; @@ -5659,7 +6031,7 @@ index 616cff4..254fa3e 100644 } } -@@ -999,9 +3438,11 @@ export class LLMChatPipeline { +@@ -999,9 +3494,11 @@ export class LLMChatPipeline { if (stopTokens.includes(nextToken)) { this.stopTriggered = true; this.finishReason = "stop"; @@ -5671,7 +6043,7 @@ index 616cff4..254fa3e 100644 // Update token appearance frequency const curFreq = this.appearedTokensFreq.get(nextToken); if (curFreq !== undefined) { -@@ -1013,6 +3454,7 @@ export class LLMChatPipeline { +@@ -1013,6 +3510,7 @@ export class LLMChatPipeline { // Stop condition 2: stop string; update `this.outputMessage` subsequently let outputMessage = this.tokenizer.decode(new Int32Array(this.outputIds)); @@ -5679,7 +6051,7 @@ index 616cff4..254fa3e 100644 let stopPos = -1; for (const stopStr of stopStrs) { // Stop at the first stopStr we find -@@ -1021,32 +3463,36 @@ export class LLMChatPipeline { +@@ -1021,32 +3519,36 @@ export class LLMChatPipeline { outputMessage = outputMessage.substring(0, stopPos); this.stopTriggered = true; this.finishReason = "stop"; @@ -5718,7 +6090,7 @@ index 616cff4..254fa3e 100644 } } } -@@ -1227,7 +3673,15 @@ export class LLMChatPipeline { +@@ -1227,7 +3729,15 @@ export class LLMChatPipeline { private async embedAndForward( inputData: Array | ImageURL>, inputDataLen: number, @@ -5734,7 +6106,7 @@ index 616cff4..254fa3e 100644 if (inputDataLen > this.prefillChunkSize) { throw new Error( "InternalError: expect inputDataLen <= this.prefillChunkSize.", -@@ -1238,51 +3692,120 @@ export class LLMChatPipeline { +@@ -1238,51 +3748,129 @@ export class LLMChatPipeline { // 1. Embed all inputData this.tvm.beginScope(); @@ -5879,6 +6251,15 @@ index 616cff4..254fa3e 100644 + while (forwardBegun > 0) { + this.fKVCacheEndForward!(forwardStates[--forwardBegun]); + } ++ if (this.drowseCachedInputIds?.length === this.filledKVCacheLength) { ++ for (const input of inputData) { ++ if (!Array.isArray(input)) { ++ this.drowseCachedInputIds = null; ++ break; ++ } ++ for (const token of input) this.drowseCachedInputIds.push(token); ++ } ++ } + this.filledKVCacheLength += inputDataLen; + logits = this.tvm.detachFromCurrentScope(retValue.get(0)); + } finally { @@ -5896,26 +6277,31 @@ index 616cff4..254fa3e 100644 this.tvm.attachToCurrentScope(logits); return logits; } -@@ -1292,7 +3815,9 @@ export class LLMChatPipeline { +@@ -1292,7 +3880,14 @@ export class LLMChatPipeline { names: string[], ): VMFunctionRegistry { const registry: VMFunctionRegistry = {}; - for (const name of names) { -+ const legacyNames = names.filter((name) => name.startsWith("drowse_")) -+ .flatMap((name) => ["polythetic_", "saklas_"].map((prefix) => `${prefix}${name.slice("drowse_".length)}`)); ++ const legacyNames = names ++ .filter((name) => name.startsWith("drowse_")) ++ .flatMap((name) => ++ ["polythetic_", "saklas_"].map( ++ (prefix) => `${prefix}${name.slice("drowse_".length)}`, ++ ), ++ ); + for (const name of [...names, ...legacyNames]) { try { const func = vm.getFunction(name) as unknown; if (typeof func === "function") { -@@ -1305,6 +3830,17 @@ export class LLMChatPipeline { +@@ -1305,6 +3900,17 @@ export class LLMChatPipeline { return registry; } -+ private static applyLegacyDrowseAliases( -+ registry: VMFunctionRegistry, -+ ): void { ++ private static applyLegacyDrowseAliases(registry: VMFunctionRegistry): void { + for (const [name, func] of Object.entries(registry)) { -+ const prefix = ["polythetic_", "saklas_"].find((value) => name.startsWith(value)); ++ const prefix = ["polythetic_", "saklas_"].find((value) => ++ name.startsWith(value), ++ ); + if (prefix === undefined || func === undefined) continue; + const currentName = `drowse_${name.slice(prefix.length)}`; + if (registry[currentName] === undefined) registry[currentName] = func; @@ -5925,7 +6311,7 @@ index 616cff4..254fa3e 100644 private static getRequiredVMFunctionByName( name: string, registry: VMFunctionRegistry, -@@ -1365,6 +3901,7 @@ export class LLMChatPipeline { +@@ -1365,6 +3971,7 @@ export class LLMChatPipeline { private static resolveModelABI( kvStateKind: KVStateKind, availability: VMFunctionAvailability, @@ -5933,7 +6319,7 @@ index 616cff4..254fa3e 100644 ): ResolvedModelABI { const hasSingleKernelPair = availability.prefill && availability.decode; const hasBatchKernelPair = -@@ -1450,6 +3987,17 @@ export class LLMChatPipeline { +@@ -1450,6 +4057,17 @@ export class LLMChatPipeline { } // kv_cache @@ -5951,7 +6337,7 @@ index 616cff4..254fa3e 100644 if (hasSingleKernelPair) { return { kvStateKind, -@@ -1525,14 +4073,279 @@ export class LLMChatPipeline { +@@ -1525,14 +4143,267 @@ export class LLMChatPipeline { return states; } @@ -6004,9 +6390,7 @@ index 616cff4..254fa3e 100644 + inputIds.length, + capturePositions, + ); -+ const captures = retValue.get( -+ this.drowseOutputOffset(), -+ ) as tvmjs.Tensor; ++ const captures = retValue.get(this.drowseOutputOffset()) as tvmjs.Tensor; + const layerCount = this.requireModelDimension("num_hidden_layers"); + const hiddenSize = this.requireModelDimension("hidden_size"); + const expectedShape = [layerCount, positions.length, hiddenSize]; @@ -6162,9 +6546,7 @@ index 616cff4..254fa3e 100644 + : this.resolvedModelABI.decodeABI; + const drowseArgs = this.getDrowseForwardArguments(); + if (drowseArgs.length === 0) { -+ throw new Error( -+ "Drowse rank-one capture requires an installed program", -+ ); ++ throw new Error("Drowse rank-one capture requires an installed program"); + } + if (abi === "single") { + return forward( @@ -6209,20 +6591,12 @@ index 616cff4..254fa3e 100644 + let forward = this.prefill; + if (useDrowseProgram && this.drowseProgram !== undefined) { + forward = this.drowsePrefill!; -+ } else if ( -+ useDrowseProgram && -+ this.drowseStructuredMode === "structured" -+ ) { ++ } else if (useDrowseProgram && this.drowseStructuredMode === "structured") { + forward = this.drowseStructuredPrefill!; -+ } else if ( -+ useDrowseProgram && -+ this.drowseStructuredMode === "curved" -+ ) { ++ } else if (useDrowseProgram && this.drowseStructuredMode === "curved") { + forward = this.drowseCurvedPrefill!; + } -+ const drowseArgs = useDrowseProgram -+ ? this.getDrowseForwardArguments() -+ : []; ++ const drowseArgs = useDrowseProgram ? this.getDrowseForwardArguments() : []; if (this.resolvedModelABI.prefillABI === "single") { - return this.prefill( + return forward( @@ -6232,7 +6606,7 @@ index 616cff4..254fa3e 100644 this.params, ); } -@@ -1549,27 +4362,50 @@ export class LLMChatPipeline { +@@ -1549,27 +4420,42 @@ export class LLMChatPipeline { this.resolvedModelABI.needsKVCache && this.resolvedModelABI.needsRNNState ) { @@ -6264,20 +6638,12 @@ index 616cff4..254fa3e 100644 + let forward = this.decoding; + if (useDrowseProgram && this.drowseProgram !== undefined) { + forward = this.drowseDecoding!; -+ } else if ( -+ useDrowseProgram && -+ this.drowseStructuredMode === "structured" -+ ) { ++ } else if (useDrowseProgram && this.drowseStructuredMode === "structured") { + forward = this.drowseStructuredDecoding!; -+ } else if ( -+ useDrowseProgram && -+ this.drowseStructuredMode === "curved" -+ ) { ++ } else if (useDrowseProgram && this.drowseStructuredMode === "curved") { + forward = this.drowseCurvedDecoding!; + } -+ const drowseArgs = useDrowseProgram -+ ? this.getDrowseForwardArguments() -+ : []; ++ const drowseArgs = useDrowseProgram ? this.getDrowseForwardArguments() : []; if (this.resolvedModelABI.decodeABI === "single") { - return this.decoding( + return forward( @@ -6287,7 +6653,7 @@ index 616cff4..254fa3e 100644 this.params, ); } -@@ -1577,20 +4413,73 @@ export class LLMChatPipeline { +@@ -1577,20 +4463,73 @@ export class LLMChatPipeline { this.resolvedModelABI.needsKVCache && this.resolvedModelABI.needsRNNState ) { @@ -6363,7 +6729,7 @@ index 616cff4..254fa3e 100644 // NOTE: caller must call device.sync() private updateLogitsOnCPU(logits: tvmjs.Tensor): tvmjs.Tensor { if (this.logitsOnCPU == undefined) { -@@ -1610,7 +4499,7 @@ export class LLMChatPipeline { +@@ -1610,7 +4549,7 @@ export class LLMChatPipeline { logitsOnGPU: tvmjs.Tensor, genConfig?: GenerationConfig, ) { @@ -6372,7 +6738,7 @@ index 616cff4..254fa3e 100644 // Also load other genConfig items like logit_bias. Consume all fields of `genConfig` here. function _hasValue(value: any): boolean { // if we use `if value` directly, `value` being 0 evaluates to false, violating semantics -@@ -1618,6 +4507,7 @@ export class LLMChatPipeline { +@@ -1618,6 +4557,7 @@ export class LLMChatPipeline { } let temperature: number = this.config.temperature; let top_p: number = this.config.top_p; @@ -6380,7 +6746,7 @@ index 616cff4..254fa3e 100644 let repetition_penalty: number = this.config.repetition_penalty; let frequency_penalty: number = this.config.frequency_penalty; let presence_penalty: number = this.config.presence_penalty; -@@ -1633,6 +4523,9 @@ export class LLMChatPipeline { +@@ -1633,6 +4573,9 @@ export class LLMChatPipeline { if (_hasValue(genConfig.top_p)) { top_p = genConfig.top_p!; } @@ -6390,7 +6756,7 @@ index 616cff4..254fa3e 100644 // TODO: setting top_p to 1.0 by default might run into issues since // top_p masking in relax uses < instead of <= // Set default top_p to 1.0 if not set -@@ -1675,11 +4568,14 @@ export class LLMChatPipeline { +@@ -1675,11 +4618,14 @@ export class LLMChatPipeline { } } // Check range validity @@ -6408,7 +6774,7 @@ index 616cff4..254fa3e 100644 } if (repetition_penalty <= 0) { throw new MinValueError("repetition_penalty", 0); -@@ -1894,13 +4790,38 @@ export class LLMChatPipeline { +@@ -1894,13 +4840,38 @@ export class LLMChatPipeline { // 4. Sample token from logits const sampleBegin = performance.now(); @@ -6451,17 +6817,15 @@ index 616cff4..254fa3e 100644 this.tvm.beginScope(); const temperaturesDevice = this.tvm -@@ -1913,79 +4834,119 @@ export class LLMChatPipeline { +@@ -1913,79 +4884,131 @@ export class LLMChatPipeline { ); probs = probs.view([numProbs, this.fullVocabSize]); - const topPValue = Math.max(top_p, 1e-5); - let sampledToken = -1; -+ const topPValue = deterministic ? 0 : top_p; -+ const captureLogprobs = Boolean(logprobs) || replayRequested; - const argsortResults = this.fargsortProbs(probs); - const sortedProbsDevice = argsortResults.get(0); - const sortedIndicesDevice = argsortResults.get(1); +- const argsortResults = this.fargsortProbs(probs); +- const sortedProbsDevice = argsortResults.get(0); +- const sortedIndicesDevice = argsortResults.get(1); - const uniformSamplesDevice = this.tvm.uniform([1], 0.0, 1.0, this.device); - - const topPHost = new Float32Array(numProbs).fill(-1); @@ -6481,6 +6845,26 @@ index 616cff4..254fa3e 100644 - this.tvm - .empty([numSeqs], "int32", this.tvm.cpu()) - .copyFrom(sampledTokensDevice), +- ); +- if (logprobs && top_logprobs! > 0) { +- this.updateLogitsOnCPU(probs); ++ const topPValue = deterministic ? 0 : top_p; ++ const captureLogprobs = Boolean(logprobs) || replayRequested; ++ const readbackCandidates = deterministic ? 1 : effectiveTopK; ++ let sortedProbsDevice: tvmjs.Tensor; ++ let sortedIndicesDevice: tvmjs.Tensor; ++ if (readbackCandidates <= 1024) { ++ this.drowseGpuTopK ??= new DrowseGpuTopK(this.tvm); ++ [sortedProbsDevice, sortedIndicesDevice] = this.drowseGpuTopK.select( ++ probs, ++ readbackCandidates, ++ ); ++ } else { ++ const sorted = this.fargsortProbs(probs); ++ sortedProbsDevice = sorted.get(0); ++ sortedIndicesDevice = sorted.get(1); + } +- this.tvm.endScope(); + const sortedProbsHost = this.tvm + .empty(sortedProbsDevice.shape, sortedProbsDevice.dtype, this.tvm.cpu()) + .copyFrom(sortedProbsDevice); @@ -6496,7 +6880,10 @@ index 616cff4..254fa3e 100644 + : this.tvm + .empty([1], "float32", this.tvm.cpu()) + .copyFrom(this.tvm.uniform([1], 0.0, 1.0, this.device)); -+ await this.device.sync(); + await this.device.sync(); +- +- sampledToken = sampledTokensHost.toArray()[0]; +- sampledTokensHost.dispose(); + const samplerResult = sampleDrowseTopKTopP( + sortedProbsHost.toArray() as Float32Array, + sortedIndicesHost.toArray() as Int32Array, @@ -6506,16 +6893,10 @@ index 616cff4..254fa3e 100644 + ? 0 + : (uniformSamplesHost.toArray() as Float32Array)[0], + samplerSelectedTokenIds, - ); -- if (logprobs && top_logprobs! > 0) { -- this.updateLogitsOnCPU(probs); -- } ++ Math.max(logprobs ? (top_logprobs ?? 0) : 0, replayRequested ? 32 : 0), ++ ); + const sampledToken = samplerResult.sampledTokenId; - this.tvm.endScope(); -- await this.device.sync(); -- -- sampledToken = sampledTokensHost.toArray()[0]; -- sampledTokensHost.dispose(); ++ this.tvm.endScope(); if (sampledToken < 0) { throw new Error("InternalError: failed to sample a valid token."); } @@ -6618,27 +6999,56 @@ index 616cff4..254fa3e 100644 } /** -@@ -2028,6 +4989,19 @@ export class LLMChatPipeline { +@@ -2028,20 +5051,37 @@ export class LLMChatPipeline { if (this.filledKVCacheLength !== 0) { throw new TextCompletionExpectsKVEmptyError(); } + const legacyConfig = this.config as ChatConfig & Record; -+ const prefixes = ["drowse", "polythetic", "saklas"].map((name) => legacyConfig[`${name}_completion_prefix_token_ids`]) ++ const prefixes = ["drowse", "polythetic", "saklas"] ++ .map((name) => legacyConfig[`${name}_completion_prefix_token_ids`]) + .filter((value) => value !== undefined); -+ if (prefixes.some((value) => JSON.stringify(value) !== JSON.stringify(prefixes[0]))) { -+ throw new Error("The completion-prefix metadata contains conflicting values"); ++ if ( ++ prefixes.some( ++ (value) => JSON.stringify(value) !== JSON.stringify(prefixes[0]), ++ ) ++ ) { ++ throw new Error( ++ "The completion-prefix metadata contains conflicting values", ++ ); + } + const prefix = (prefixes[0] ?? []) as number[]; -+ if (!Array.isArray(prefix) || prefix.some((id) => -+ !Number.isSafeInteger(id) || id < 0 || id >= this.fullVocabSize -+ )) { -+ throw new TypeError("Text completion prefix must contain valid vocabulary token IDs"); ++ if ( ++ !Array.isArray(prefix) || ++ prefix.some( ++ (id) => ++ !Number.isSafeInteger(id) || id < 0 || id >= this.fullVocabSize, ++ ) ++ ) { ++ throw new TypeError( ++ "Text completion prefix must contain valid vocabulary token IDs", ++ ); + } + curTokens = [...prefix]; prompts = this.conversation.getPromptArrayTextCompletion(); } else { // 1.2. Conversation style -@@ -2082,7 +5056,7 @@ export class LLMChatPipeline { +- if (this.filledKVCacheLength === 0) { +- if ( +- this.conversation.config.system_prefix_token_ids !== undefined && +- this.conversation.config.system_prefix_token_ids !== null +- ) { +- curTokens = [...this.conversation.config.system_prefix_token_ids]; +- } +- prompts = this.conversation.getPromptArray(this.config); +- } else { +- prompts = this.conversation.getPromptArrayLastRound(this.config); +- } ++ curTokens = [...(this.conversation.config.system_prefix_token_ids ?? [])]; ++ prompts = this.conversation.getPromptArray(this.config); + } + + // 1.5. Preload image dimensions to compute per-image embed sizes +@@ -2082,7 +5122,7 @@ export class LLMChatPipeline { // 3. Encode all prompts. Iterate through each message in the prompt array, where each // prompt can either be a string, or an array of a mixture of string and ImageURLs. @@ -6647,7 +7057,31 @@ index 616cff4..254fa3e 100644 for (let i = 0; i < prompts.length; i++) { const curPrompt = prompts[i]; if (typeof curPrompt === "string") { -@@ -2186,50 +5160,53 @@ export class LLMChatPipeline { +@@ -2116,6 +5156,23 @@ export class LLMChatPipeline { + } + } + } ++ if (!this.conversation.isTextCompletion && this.filledKVCacheLength > 0) { ++ const cached = this.drowseCachedInputIds; ++ if (ret.length === 0 && cached?.length === this.filledKVCacheLength && ++ cached.length < curTokens.length && ++ cached.every((token, index) => curTokens[index] === token)) { ++ curTokens = curTokens.slice(cached.length); ++ numPromptTokens = curTokens.length; ++ } else { ++ this.tvm.beginScope(); ++ try { ++ this.resetKVCache(); ++ this.filledKVCacheLength = 0; ++ } finally { ++ this.tvm.endScope(); ++ } ++ } ++ } + // Deal with last curTokens + if (curTokens.length !== 0) { + ret.push([...curTokens]); +@@ -2186,50 +5243,51 @@ export class LLMChatPipeline { } /** @@ -6711,13 +7145,11 @@ index 616cff4..254fa3e 100644 + entropy_nats: samplerResult.entropyNats, + perplexity: samplerResult.perplexity, + }, -+ ...(drowseReplay === undefined -+ ? {} -+ : { drowse_replay: drowseReplay }), ++ ...(drowseReplay === undefined ? {} : { drowse_replay: drowseReplay }), } as ChatCompletionTokenLogprob; } -@@ -2284,3 +5261,10 @@ export class LLMChatPipeline { +@@ -2284,3 +5342,10 @@ export class LLMChatPipeline { log.info(msg); } } @@ -6874,7 +7306,7 @@ index 8be38bb..e9ca605 100644 | ChatCompletionChunk | CreateEmbeddingResponse diff --git a/src/openai_api_protocols/chat_completion.ts b/src/openai_api_protocols/chat_completion.ts -index 0ec5040..ffe762e 100644 +index 0ec5040..15f80c3 100644 --- a/src/openai_api_protocols/chat_completion.ts +++ b/src/openai_api_protocols/chat_completion.ts @@ -162,6 +162,12 @@ export interface ChatCompletionRequestBase { @@ -6890,7 +7322,16 @@ index 0ec5040..ffe762e 100644 /** * Modify the likelihood of specified tokens appearing in the completion. * -@@ -283,6 +289,21 @@ export interface ChatCompletionRequestBase { +@@ -191,7 +197,7 @@ export interface ChatCompletionRequestBase { + logprobs?: boolean | null; + + /** +- * An integer between 0 and 5 specifying the number of most likely tokens to return ++ * A nonnegative integer specifying the number of most likely tokens to return + * at each token position, each with an associated log probability. `logprobs` must + * be set to `true` if this parameter is used. + */ +@@ -283,6 +289,23 @@ export interface ChatCompletionRequestBase { * stages of token sampling. */ enable_latency_breakdown?: boolean | null; @@ -6906,13 +7347,15 @@ index 0ec5040..ffe762e 100644 + * every step so the normal RNG stream is preserved. + */ + drowse_forced_prefix_token_ids?: number[] | null; ++ drowse_readout_start_index?: number; ++ drowse_readout_target_index?: number; + + /** Token IDs whose exact sampler log probabilities are returned per step. */ + drowse_score_token_ids?: number[] | null; }; } -@@ -476,14 +497,20 @@ export function postInitAndCheckFields( +@@ -476,14 +499,20 @@ export function postInitAndCheckFields( }, ); @@ -6939,7 +7382,7 @@ index 0ec5040..ffe762e 100644 ); } -@@ -880,6 +907,9 @@ export type ChatCompletionToolChoiceOption = +@@ -880,6 +909,9 @@ export type ChatCompletionToolChoiceOption = //////////////////////////////// 3.1. LOG PROBS //////////////////////////////// export interface TopLogprob { @@ -6949,7 +7392,7 @@ index 0ec5040..ffe762e 100644 /** * The token. */ -@@ -903,6 +933,9 @@ export interface TopLogprob { +@@ -903,6 +935,9 @@ export interface TopLogprob { } export interface ChatCompletionTokenLogprob { @@ -6959,7 +7402,7 @@ index 0ec5040..ffe762e 100644 /** * The token. */ -@@ -930,6 +963,31 @@ export interface ChatCompletionTokenLogprob { +@@ -930,6 +965,31 @@ export interface ChatCompletionTokenLogprob { * `top_logprobs` returned. */ top_logprobs: Array; @@ -6991,7 +7434,7 @@ index 0ec5040..ffe762e 100644 } //////////////////////////////// 3.2. OTHERS //////////////////////////////// -@@ -1039,6 +1097,13 @@ export type ChatCompletionFinishReason = +@@ -1039,6 +1099,13 @@ export type ChatCompletionFinishReason = | "tool_calls" | "abort"; @@ -7005,7 +7448,7 @@ index 0ec5040..ffe762e 100644 export namespace ChatCompletion { export interface Choice { /** -@@ -1049,6 +1114,9 @@ export namespace ChatCompletion { +@@ -1049,6 +1116,9 @@ export namespace ChatCompletion { */ finish_reason: ChatCompletionFinishReason; @@ -7015,7 +7458,7 @@ index 0ec5040..ffe762e 100644 /** * The index of the choice in the list of choices. */ -@@ -1093,6 +1161,9 @@ export namespace ChatCompletionChunk { +@@ -1093,6 +1163,9 @@ export namespace ChatCompletionChunk { */ finish_reason: ChatCompletionFinishReason | null; @@ -7026,7 +7469,7 @@ index 0ec5040..ffe762e 100644 * The index of the choice in the list of choices. */ diff --git a/src/openai_api_protocols/completion.ts b/src/openai_api_protocols/completion.ts -index 0534fe9..256ffb4 100644 +index 0534fe9..6391ef2 100644 --- a/src/openai_api_protocols/completion.ts +++ b/src/openai_api_protocols/completion.ts @@ -27,6 +27,7 @@ import { @@ -7037,6 +7480,15 @@ index 0534fe9..256ffb4 100644 } from "./chat_completion"; export class Completions { +@@ -108,7 +109,7 @@ export interface CompletionCreateParamsBase { + logprobs?: boolean | null; + + /** +- * An integer between 0 and 5 specifying the number of most likely tokens to return ++ * A nonnegative integer specifying the number of most likely tokens to return + * at each token position, each with an associated log probability. `logprobs` must + * be set to `true` if this parameter is used. + */ @@ -189,6 +190,12 @@ export interface CompletionCreateParamsBase { */ top_p?: number | null; @@ -7050,7 +7502,7 @@ index 0534fe9..256ffb4 100644 /** * If true, will ignore stop string and stop token and generate until max_tokens hit. * If unset, will treat as false. -@@ -242,6 +249,15 @@ export interface CompletionCreateParamsBase { +@@ -242,6 +249,17 @@ export interface CompletionCreateParamsBase { * stages of token sampling. */ enable_latency_breakdown?: boolean | null; @@ -7060,13 +7512,15 @@ index 0534fe9..256ffb4 100644 + * every step so the normal RNG stream is preserved. + */ + drowse_forced_prefix_token_ids?: number[] | null; ++ drowse_readout_start_index?: number; ++ drowse_readout_target_index?: number; + + /** Token IDs whose exact sampler log probabilities are returned per step. */ + drowse_score_token_ids?: number[] | null; }; } -@@ -319,6 +335,9 @@ export interface CompletionChoice { +@@ -319,6 +337,9 @@ export interface CompletionChoice { */ finish_reason: ChatCompletionFinishReason | null; @@ -8225,10 +8679,10 @@ index 8fa04b2..92ae4af 100644 type ImageURL = ChatCompletionContentPartImage.ImageURL; diff --git a/tests/drowse_pipeline.test.ts b/tests/drowse_pipeline.test.ts new file mode 100644 -index 0000000..d4810a5 +index 0000000..02b47b8 --- /dev/null +++ b/tests/drowse_pipeline.test.ts -@@ -0,0 +1,1086 @@ +@@ -0,0 +1,1131 @@ +import { jest, test, expect } from "@jest/globals"; + +import { @@ -8273,6 +8727,8 @@ index 0000000..d4810a5 + +function pipeline(): any { + const result = Object.create(LLMChatPipeline.prototype) as any; ++ result["curRoundDrowseCompletionTokens"] = 0; ++ result["drowseReadoutStart"] = 0; + result["drowsePrefill"] = jest.fn(); + result["drowseDecoding"] = jest.fn(); + result["config"] = { @@ -8508,10 +8964,12 @@ index 0000000..d4810a5 + +test("one synchronization materializes every token readout before queued control changes", async () => { + const result = pipeline(); -+ const dataTensor = ( -+ shape: number[], -+ data: Float32Array | Int32Array, -+ ) => ({ ...tensor(), shape, data, toArray: jest.fn(() => data) }); ++ const dataTensor = (shape: number[], data: Float32Array | Int32Array) => ({ ++ ...tensor(), ++ shape, ++ data, ++ toArray: jest.fn(() => data), ++ }); + result["drowseMeasurements"] = dataTensor( + [2, 8], + Float32Array.from({ length: 16 }, (_value, index) => index), @@ -8537,16 +8995,18 @@ index 0000000..d4810a5 + ); + result["drowsePendingJlensReadback"] = { + layerCount: 2, -+ chunks: [{ -+ chunk: { -+ layerIds: Int32Array.of(0), -+ jacobians: tensor(), -+ layerIdsDevice: tensor(), ++ chunks: [ ++ { ++ chunk: { ++ layerIds: Int32Array.of(0), ++ jacobians: tensor(), ++ layerIdsDevice: tensor(), ++ }, ++ selectedHost, ++ layerTokenIdsHost, ++ layerProbabilitiesHost, + }, -+ selectedHost, -+ layerTokenIdsHost, -+ layerProbabilitiesHost, -+ }], ++ ], + aggregate: { + tokenIdsHost: dataTensor( + [1, 8], @@ -8560,10 +9020,7 @@ index 0000000..d4810a5 + }, + }; + result["drowsePendingSaeReadback"] = { -+ valuesHost: dataTensor( -+ [1, 8], -+ Float32Array.from([9, 8, 7, 6, 5, 4, 3, 2]), -+ ), ++ valuesHost: dataTensor([1, 8], Float32Array.from([9, 8, 7, 6, 5, 4, 3, 2])), + featureIdsHost: dataTensor( + [1, 8], + Int32Array.from([8, 3, 10, 1, 11, 0, 9, 2]), @@ -8651,11 +9108,7 @@ index 0000000..d4810a5 + result["tvm"].endScope.mockClear(); + + await expect( -+ result.resolveDrowseJlensTokenDirections( -+ JLENS_BINDING, -+ [0, 1], -+ [3, 7], -+ ), ++ result.resolveDrowseJlensTokenDirections(JLENS_BINDING, [0, 1], [3, 7]), + ).resolves.toEqual( + Float32Array.from([0, 1, 2, 3, 4, 5, 6, 7, 32, 33, 34, 35, 36, 37, 38, 39]), + ); @@ -8710,18 +9163,22 @@ index 0000000..d4810a5 + await result.setDrowseJlensDictionary(dictionary); + const resident = result["drowseJlensDictionary"]; + -+ await expect(result.setDrowseJlensDictionary({ -+ ...dictionary, -+ layerIndices: Int32Array.from([0]), -+ matrices: [new Float32Array(16)], -+ })).rejects.toThrow(/conflicting metadata/); ++ await expect( ++ result.setDrowseJlensDictionary({ ++ ...dictionary, ++ layerIndices: Int32Array.from([0]), ++ matrices: [new Float32Array(16)], ++ }), ++ ).rejects.toThrow(/conflicting metadata/); + expect(result["drowseJlensDictionary"]).toBe(resident); + + result["device"].sync.mockRejectedValueOnce(new Error("device lost")); -+ await expect(result.setDrowseJlensDictionary({ -+ ...dictionary, -+ bindingId: "c".repeat(64), -+ })).rejects.toThrow("device lost"); ++ await expect( ++ result.setDrowseJlensDictionary({ ++ ...dictionary, ++ bindingId: "c".repeat(64), ++ }), ++ ).rejects.toThrow("device lost"); + expect(result["drowseJlensDictionary"]).toBe(resident); + for (const chunk of resident.chunks) { + expect(chunk.jacobians.dispose).not.toHaveBeenCalled(); @@ -8793,7 +9250,10 @@ index 0000000..d4810a5 + }); + const chunks = await result["uploadDrowseJlensChunks"]( + Array.from({ length: 3 }, (_value, matrix) => -+ Float32Array.from({ length: 4 * 4 }, (_entry, index) => matrix * 16 + index) ++ Float32Array.from( ++ { length: 4 * 4 }, ++ (_entry, index) => matrix * 16 + index, ++ ), + ), + Int32Array.from([0, 2, 3]), + plans, @@ -9035,17 +9495,21 @@ index 0000000..d4810a5 + await result.setDrowseSaeDictionary(dictionary); + const resident = result["drowseSaeDictionary"]; + -+ await expect(result.setDrowseSaeDictionary({ -+ ...dictionary, -+ runtimeLayerIndex: 0, -+ })).rejects.toThrow(/conflicting metadata/); ++ await expect( ++ result.setDrowseSaeDictionary({ ++ ...dictionary, ++ runtimeLayerIndex: 0, ++ }), ++ ).rejects.toThrow(/conflicting metadata/); + expect(result["drowseSaeDictionary"]).toBe(resident); + + result["device"].sync.mockRejectedValueOnce(new Error("device lost")); -+ await expect(result.setDrowseSaeDictionary({ -+ ...dictionary, -+ bindingId: "d".repeat(64), -+ })).rejects.toThrow("device lost"); ++ await expect( ++ result.setDrowseSaeDictionary({ ++ ...dictionary, ++ bindingId: "d".repeat(64), ++ }), ++ ).rejects.toThrow("device lost"); + expect(result["drowseSaeDictionary"]).toBe(resident); + expect(resident.decoderBias.dispose).not.toHaveBeenCalled(); + expect(resident.runtimeLayerIndexDevice.dispose).not.toHaveBeenCalled(); @@ -9226,18 +9690,15 @@ index 0000000..d4810a5 + return host; + }); + -+ await result["computeDrowseJlensProbabilities"]( -+ tensor(), -+ tensor(), -+ ); ++ await result["computeDrowseJlensProbabilities"](tensor(), tensor()); + expect(result["device"].sync).not.toHaveBeenCalled(); + const bundle = await result.readDrowseMeasurementBundle(); -+ expect(Array.from(result["drowseJlensProbabilitiesHost"].slice(0, 8))).toEqual( -+ [0, 1, 2, 3, 4, 5, 6, 7], -+ ); -+ expect(Array.from(result["drowseJlensProbabilitiesHost"].slice(16, 24))).toEqual([ -+ 8, 9, 10, 11, 12, 13, 14, 15, -+ ]); ++ expect( ++ Array.from(result["drowseJlensProbabilitiesHost"].slice(0, 8)), ++ ).toEqual([0, 1, 2, 3, 4, 5, 6, 7]); ++ expect( ++ Array.from(result["drowseJlensProbabilitiesHost"].slice(16, 24)), ++ ).toEqual([8, 9, 10, 11, 12, 13, 14, 15]); + expect(result["drowseJlensReadout"]).not.toHaveBeenCalled(); + expect(result["drowseJlensReadoutAccumulate"]).toHaveBeenCalledTimes(2); + expect( @@ -9315,6 +9776,44 @@ index 0000000..d4810a5 + ); + expect(result["drowseExactReadoutAttested"]).not.toBe(true); +}); ++ ++test("replay discovery runs only at the requested raw token", () => { ++ const result = pipeline(); ++ result.drowseReadoutStart = 2; ++ result.drowseReadoutTarget = 4; ++ const demanded = [0, 1, 2, 3, 4, 5].map((index) => { ++ result.curRoundDrowseCompletionTokens = index; ++ return result.drowseDiscoveryRequested(); ++ }); ++ expect(demanded).toEqual([false, false, false, false, true, false]); ++ result.drowseReadoutTarget = undefined; ++ expect(result.drowseDiscoveryRequested()).toBe(true); ++}); ++ ++test("skipped replay discovery avoids lens GPU work without a token probe", async () => { ++ const result = pipeline(); ++ result.curRoundDrowseCompletionTokens = 1; ++ result.drowseReadoutStart = 4; ++ result.drowseProbeKindHost = new Uint32Array(8); ++ await result.computeDrowseJlensProbabilities(tensor(), tensor()); ++ expect(result.tvm.beginScope).not.toHaveBeenCalled(); ++ result.drowseProbeKindHost[0] = 3; ++ await expect( ++ result.computeDrowseJlensProbabilities(tensor(), tensor()), ++ ).rejects.toThrow("J-lens probability runtime is unavailable"); ++}); ++ ++test("skipped replay discovery avoids SAE feature discovery", async () => { ++ const result = pipeline(); ++ result.curRoundDrowseCompletionTokens = 1; ++ result.drowseReadoutStart = 4; ++ result.drowseSaeReadoutActive = true; ++ result.drowseSaeDictionary = { activation: "relu", chunks: [] }; ++ result.drowseSaeReadoutAccumulate = jest.fn(); ++ await result.computeDrowseSaeTopFeatures(tensor()); ++ expect(result.tvm.beginScope).not.toHaveBeenCalled(); ++ expect(result.drowseSaeReadoutAccumulate).not.toHaveBeenCalled(); ++}); diff --git a/tests/drowse.test.ts b/tests/drowse.test.ts new file mode 100644 index 0000000..452db04 @@ -10388,7 +10887,7 @@ index 43b9e95..c0efb9a 100644 const engine = createEngineWithMultiplePipelines(); await expect( diff --git a/tests/generation_config.test.ts b/tests/generation_config.test.ts -index e48b225..129d5ed 100644 +index e48b225..2242e71 100644 --- a/tests/generation_config.test.ts +++ b/tests/generation_config.test.ts @@ -5,6 +5,33 @@ import { @@ -10425,7 +10924,27 @@ index e48b225..129d5ed 100644 test("High-level unsupported fields", () => { expect(() => { const genConfig: GenerationConfig = { -@@ -74,6 +101,21 @@ describe("Check generation config illegal values", () => { +@@ -44,11 +71,17 @@ describe("Check generation config illegal values", () => { + expect(() => { + const genConfig: GenerationConfig = { + logprobs: true, +- top_logprobs: 6, ++ top_logprobs: -1, + max_tokens: 10, + }; + postInitAndCheckGenerationConfigValues(genConfig); +- }).toThrow("Make sure 0 < top_logprobs <= 5."); ++ }).toThrow("top_logprobs"); ++ }); ++ ++ test("top_logprobs supports full-vocabulary requests", () => { ++ const genConfig: GenerationConfig = { logprobs: true, top_logprobs: 262144 }; ++ postInitAndCheckGenerationConfigValues(genConfig); ++ expect(genConfig.top_logprobs).toBe(262144); + }); + + test("top_logprobs set without setting logprobs", () => { +@@ -74,6 +107,21 @@ describe("Check generation config illegal values", () => { }); describe("Check generation post init", () => { @@ -10641,16 +11160,27 @@ index a7cf3ed..ef9c512 100644 + expect(retValue.get).not.toHaveBeenCalledWith(3); +}); diff --git a/tests/llm_chat_pipeline.test.ts b/tests/llm_chat_pipeline.test.ts -index 5138c4e..7b39b64 100644 +index 5138c4e..9a17c13 100644 --- a/tests/llm_chat_pipeline.test.ts +++ b/tests/llm_chat_pipeline.test.ts -@@ -1,4 +1,4 @@ +@@ -1,4 +1,15 @@ -import { LLMChatPipeline } from "../src/llm_chat"; +import { LLMChatPipeline, sampleDrowseTopKTopP } from "../src/llm_chat"; ++ ++test("retains the requested alternatives through the full candidate pool", () => { ++ const probabilities = new Float32Array(4096).fill(1 / 4096); ++ const ids = Int32Array.from({ length: 4096 }, (_, i) => i); ++ for (const count of [0, 5, 33, 257, 4096, 262144]) { ++ const result = sampleDrowseTopKTopP(probabilities, ids, 1, 4096, 0.5, [], count); ++ expect(result.topLogprobs).toHaveLength(Math.min(count, 4096)); ++ expect(result.argmax).toEqual({ token_id: 0, logprob: Math.log(1 / 4096) }); ++ expect(result.sampledTokenId).toBe(2048); ++ } ++}); import { MinValueError } from "../src/error"; import { Role } from "../src/config"; import { jest, test, expect, beforeEach } from "@jest/globals"; -@@ -66,6 +66,96 @@ beforeEach(() => { +@@ -66,6 +77,96 @@ beforeEach(() => { compileJSONSchemaMock.mockClear(); }); @@ -10747,7 +11277,7 @@ index 5138c4e..7b39b64 100644 type PipelineLike = LLMChatPipeline & Record; function createPipeline(): PipelineLike { -@@ -85,6 +175,8 @@ function createPipeline(): PipelineLike { +@@ -85,6 +186,8 @@ function createPipeline(): PipelineLike { } as any; pipeline["config"] = {} as any; pipeline["outputIds"] = []; @@ -10756,7 +11286,16 @@ index 5138c4e..7b39b64 100644 pipeline["appearedTokensFreq"] = new Map(); pipeline["stopTokens"] = []; pipeline["stopStr"] = []; -@@ -167,12 +259,16 @@ test("processNextToken appends tokens until stop string reached", () => { +@@ -101,6 +204,8 @@ function createPipeline(): PipelineLike { + pipeline["contextWindowSize"] = 16; + pipeline["slidingWindowSize"] = -1; + pipeline["filledKVCacheLength"] = 0; ++ pipeline["drowseCachedInputIds"] = []; ++ pipeline["resetKVCache"] = jest.fn(() => { pipeline["drowseCachedInputIds"] = []; }); + pipeline["outputMessage"] = ""; + pipeline["curRoundLatencyBreakdown"] = { + logitProcessorTime: [], +@@ -167,12 +272,16 @@ test("processNextToken appends tokens until stop string reached", () => { max_tokens: 5, }); expect(pipeline["stopTriggered"]).toBe(false); @@ -10773,7 +11312,7 @@ index 5138c4e..7b39b64 100644 }); test("processNextToken respects max_tokens and updates token frequency", () => { -@@ -215,15 +311,45 @@ test("prefillStep adds thinking reply header when thinking disabled", async () = +@@ -215,15 +324,45 @@ test("prefillStep adds thinking reply header when thinking disabled", async () = pipeline["tokenizer"].encode = jest.fn(() => Int32Array.from([9, 9])); await pipeline.prefillStep("hello", Role.user, undefined, { enable_thinking: false, @@ -10820,7 +11359,7 @@ index 5138c4e..7b39b64 100644 test("prefillStep appends standard reply header when thinking enabled", async () => { const pipeline = preparePrefillPipeline(); pipeline["tokenizer"].encode = jest.fn(() => Int32Array.from([2])); -@@ -236,6 +362,121 @@ test("prefillStep appends standard reply header when thinking enabled", async () +@@ -236,6 +375,121 @@ test("prefillStep appends standard reply header when thinking enabled", async () ).not.toHaveBeenCalled(); }); @@ -10942,10 +11481,50 @@ index 5138c4e..7b39b64 100644 test("prefillStep reuses grammar matcher when schema unchanged", async () => { const pipeline = preparePrefillPipeline(); const matcher = { reset: jest.fn(), dispose: jest.fn() }; -@@ -285,6 +526,39 @@ test("getInputData uses cached prompts when KV cache filled", async () => { - expect(pipeline["conversation"].getPromptArrayLastRound).toHaveBeenCalled(); +@@ -273,16 +527,68 @@ test("prefillStep compiles custom grammar when response type is grammar", async + expect(compileGrammarMock).toHaveBeenCalledWith("root ::= WORD"); }); +-test("getInputData uses cached prompts when KV cache filled", async () => { ++test("chat reuse includes every uncached token and turn separator", async () => { + const pipeline = createPipeline(); +- pipeline["tokenizer"].encode = jest.fn(() => Int32Array.from([1])); +- pipeline["conversation"].config.system_prefix_token_ids = undefined; +- pipeline["filledKVCacheLength"] = 0; +- await (pipeline as any).getInputData(); +- expect(pipeline["conversation"].getPromptArray).toHaveBeenCalled(); +- pipeline["filledKVCacheLength"] = 1; +- await (pipeline as any).getInputData(); +- expect(pipeline["conversation"].getPromptArrayLastRound).toHaveBeenCalled(); ++ pipeline["conversation"].config.system_prefix_token_ids = [2]; ++ pipeline["tokenizer"].encode = jest.fn(() => Int32Array.from([10, 20, 21, 30, 40])); ++ pipeline["filledKVCacheLength"] = 3; ++ pipeline["drowseCachedInputIds"] = [2, 10, 20]; ++ const result = await (pipeline as any).getInputData(); ++ expect(result.slice(0, 2)).toEqual([[[21, 30, 40]], 3]); ++ expect(pipeline["resetKVCache"]).not.toHaveBeenCalled(); ++ expect(pipeline["conversation"].getPromptArrayLastRound).not.toHaveBeenCalled(); ++ pipeline["contextWindowSize"] = 5; ++ await expect((pipeline as any).getInputData()).rejects.toThrow(); ++}); ++ ++test.each([[2, 99], [2], null, [2, 10, 20]])( ++ "chat reuse resets for a changed, untracked, or nonextending prefix %j", ++ async (cached) => { ++ const pipeline = createPipeline(); ++ pipeline["conversation"].config.system_prefix_token_ids = [2]; ++ pipeline["tokenizer"].encode = jest.fn(() => Int32Array.from([10, 20])); ++ pipeline["filledKVCacheLength"] = cached?.length === 3 ? 3 : 2; ++ pipeline["drowseCachedInputIds"] = cached; ++ const result = await (pipeline as any).getInputData(); ++ expect(result.slice(0, 2)).toEqual([[[2, 10, 20]], 3]); ++ expect(pipeline["resetKVCache"]).toHaveBeenCalledTimes(1); ++ expect(pipeline["filledKVCacheLength"]).toBe(0); ++ expect(pipeline["tvm"].beginScope).toHaveBeenCalledTimes(1); ++ expect(pipeline["tvm"].endScope).toHaveBeenCalledTimes(1); ++ }, ++); ++ +test("text completion uses only its explicit tokenizer prefix and counts it", async () => { + const pipeline = createPipeline(); + pipeline["conversation"].isTextCompletion = true; @@ -10977,11 +11556,30 @@ index 5138c4e..7b39b64 100644 + pipeline["fullVocabSize"] = 100; + pipeline["config"].drowse_completion_prefix_token_ids = prefix as any; + await expect((pipeline as any).getInputData()).rejects.toThrow("valid vocabulary token IDs"); -+}); -+ + }); + test("processNextToken ignores eos when requested", () => { - const pipeline = createPipeline(); - pipeline["stopTokens"] = [1]; +@@ -370,3 +676,20 @@ describe("computeImageEmbedSize", () => { + ); + }); + }); ++ ++ ++test("bounded sampler readback preserves distribution, forced support, and RNG mapping", () => { ++ const probabilities = Float32Array.from({ length: 2048 }, (_, index) => (2048 - index) / 2098176); ++ const ids = Int32Array.from({ length: 2048 }, (_, index) => index); ++ for (const topK of [1, 7, 1024, 2048]) { ++ for (const topP of [0, 0.1, 0.9, 1]) { ++ for (const draw of [0, 0.1, 0.5, 0.999999]) { ++ const selected = [0, 6, 1023, 2047]; ++ expect(sampleDrowseTopKTopP(probabilities.slice(0, topK), ids.slice(0, topK), topP, topK, draw, selected)) ++ .toEqual(sampleDrowseTopKTopP(probabilities, ids, topP, topK, draw, selected)); ++ } ++ } ++ } ++ expect(sampleDrowseTopKTopP(probabilities.slice(0, 1), ids.slice(0, 1), 0, 1024, 0, [0, 7])) ++ .toEqual(sampleDrowseTopKTopP(probabilities, ids, 0, 1024, 0, [0, 7])); ++}); diff --git a/tests/web_worker_handler.test.ts b/tests/web_worker_handler.test.ts index 9b04efa..1482f3b 100644 --- a/tests/web_worker_handler.test.ts @@ -11495,3 +12093,143 @@ index 9b04efa..1482f3b 100644 + "decodeDrowseTokens", + ]); +}); +diff --git a/tvm-direct-upload.mjs b/tvm-direct-upload.mjs +new file mode 100644 +index 0000000..3316eab +--- /dev/null ++++ b/tvm-direct-upload.mjs +@@ -0,0 +1,45 @@ ++import { createHash } from "node:crypto"; ++ ++const runtimeSha256 = "71cc97f20b962c9f88a3c29ca684504df2f69af72f49ad7a089d9e2136b90d16"; ++const recordLine = "const rec = shardRecords[j];"; ++ ++export function canDirectUploadTensor(rec) { ++ return rec.format === "raw" || ++ (rec.format === "f32-to-bf16" && rec.dtype !== "float32"); ++} ++ ++export async function uploadRawTensor(tvm, rec, buffer, device) { ++ const array = tvm.withNewScope(() => ++ tvm.detachFromCurrentScope(tvm.empty(rec.shape, rec.dtype, device)), ++ ); ++ try { ++ array.copyFromRawBytes(new Uint8Array(buffer, rec.byteOffset, rec.nbytes)); ++ await device.sync(); ++ tvm.tensorCacheUpdate(rec.name, array, false); ++ } finally { ++ array.dispose(); ++ } ++} ++ ++export function patchTensorCacheLoader(code) { ++ if (createHash("sha256").update(code).digest("hex") !== runtimeSha256 || ++ code.split(recordLine).length !== 2) { ++ throw new Error("The pinned TVM runtime changed; review the direct-upload patch before building."); ++ } ++ const branch = `${recordLine} ++ if (device.deviceType === DeviceStrToEnum.webgpu && canDirectUploadTensor(rec)) { ++ yield uploadRawTensor(this, rec, buffer, device); ++ continue; ++ }`; ++ return `${canDirectUploadTensor.toString()}\n${uploadRawTensor.toString()}\n${code.replace(recordLine, branch)}`; ++} ++ ++export function directUploadPlugin() { ++ return { ++ name: "drowse-tvm-direct-upload", ++ transform(code, id) { ++ if (!id.replaceAll("\\", "/").endsWith("/@mlc-ai/web-runtime/lib/index.js")) return null; ++ return { code: patchTensorCacheLoader(code), map: null }; ++ }, ++ }; ++} +diff --git a/tvm-direct-upload.test.mjs b/tvm-direct-upload.test.mjs +new file mode 100644 +index 0000000..5b9375a +--- /dev/null ++++ b/tvm-direct-upload.test.mjs +@@ -0,0 +1,83 @@ ++import assert from "node:assert/strict"; ++import { readFile } from "node:fs/promises"; ++import test from "node:test"; ++import { canDirectUploadTensor, uploadRawTensor, patchTensorCacheLoader, directUploadPlugin } from "./tvm-direct-upload.mjs"; ++ ++for (const [format, dtype, expected] of [ ++ ["raw", "float32", true], ++ ["raw", "uint32", true], ++ ["f32-to-bf16", "uint32", true], ++ ["f32-to-bf16", "float16", true], ++ ["f32-to-bf16", "float32", false], ++ ["unknown", "float16", false], ++]) { ++ test(`${format}/${dtype} retains the storage decoder when needed`, () => { ++ assert.equal(canDirectUploadTensor({ format, dtype }), expected); ++ }); ++} ++ ++function fixture(failAt) { ++ const calls = []; ++ const buffer = Uint8Array.from([9, 8, 7, 6, 1, 2, 3, 4, 5, 6, 7, 8]).buffer; ++ const rec = { name: "weight", shape: [2], dtype: "uint32", format: "raw", byteOffset: 4, nbytes: 8 }; ++ const step = (name) => { ++ calls.push(name); ++ if (failAt === name) throw new Error(name); ++ }; ++ const device = { async sync() { step("sync"); } }; ++ const array = { ++ copyFromRawBytes(bytes) { ++ step("copy"); ++ assert.equal(bytes.buffer, buffer); ++ assert.equal(bytes.byteOffset, 4); ++ assert.deepEqual([...bytes], [1, 2, 3, 4, 5, 6, 7, 8]); ++ }, ++ dispose() { step("dispose"); }, ++ }; ++ const tvm = { ++ withNewScope(fn) { return fn(); }, ++ detachFromCurrentScope(value) { return value; }, ++ empty(shape, dtype, target) { ++ step("allocate"); ++ assert.deepEqual(shape, rec.shape); ++ assert.equal(dtype, rec.dtype); ++ assert.equal(target, device); ++ return array; ++ }, ++ tensorCacheUpdate(name, value, override) { ++ step("cache"); ++ assert.equal(name, "weight"); ++ assert.equal(value, array); ++ assert.equal(override, false); ++ }, ++ }; ++ return { tvm, rec, buffer, device, calls }; ++} ++ ++test("uploads the original shard view and synchronizes before cache ownership transfer", async () => { ++ const f = fixture(); ++ await uploadRawTensor(f.tvm, f.rec, f.buffer, f.device); ++ assert.deepEqual(f.calls, ["allocate", "copy", "sync", "cache", "dispose"]); ++}); ++ ++for (const failAt of ["copy", "sync", "cache"]) { ++ test(`disposes the detached tensor after ${failAt} failure`, async () => { ++ const f = fixture(failAt); ++ await assert.rejects(uploadRawTensor(f.tvm, f.rec, f.buffer, f.device), new RegExp(failAt)); ++ assert.equal(f.calls.at(-1), "dispose"); ++ assert.equal(f.calls.filter((call) => call === "dispose").length, 1); ++ if (failAt !== "cache") assert.ok(!f.calls.includes("cache")); ++ }); ++} ++ ++test("patches only the pinned dependency and keeps CPU/conversion fallback intact", async () => { ++ const source = await readFile(new URL("./node_modules/@mlc-ai/web-runtime/lib/index.js", import.meta.url), "utf8"); ++ const result = patchTensorCacheLoader(source); ++ assert.match(result, /device\.deviceType === DeviceStrToEnum\.webgpu && canDirectUploadTensor\(rec\)/); ++ const originalTail = source.slice(source.indexOf("const rec = shardRecords[j];") + "const rec = shardRecords[j];".length); ++ assert.ok(result.endsWith(originalTail)); ++ assert.throws(() => patchTensorCacheLoader(source + "\n"), /pinned TVM runtime changed/); ++ assert.throws(() => patchTensorCacheLoader(result), /pinned TVM runtime changed/); ++ assert.equal(directUploadPlugin().transform(source, "/unrelated/index.js"), null); ++ assert.equal(directUploadPlugin().transform(source, "/node_modules/@mlc-ai/web-runtime/lib/index.js").code, result); ++}); diff --git a/browser-runtime/import-provider-instruments.py b/browser-runtime/import-provider-instruments.py index e995fd6e..236d9629 100644 --- a/browser-runtime/import-provider-instruments.py +++ b/browser-runtime/import-provider-instruments.py @@ -44,10 +44,17 @@ def main() -> None: def create_jlens_pack(args, model: dict) -> None: - checkpoint = torch.load(args.jlens_checkpoint, map_location="cpu", weights_only=False) + checkpoint = torch.load(args.jlens_checkpoint, map_location="cpu", weights_only=True) raw_layers = checkpoint.get("J") if isinstance(checkpoint, dict) else None if not isinstance(raw_layers, dict) or not raw_layers: raise SystemExit("provider J-lens checkpoint does not contain a J layer dictionary") + prompt_counts = [checkpoint[key] for key in ("n_prompts", "prompts_fitted") if key in checkpoint] + if not prompt_counts or any( + type(count) is not int or count <= 0 or count != prompt_counts[0] + for count in prompt_counts + ): + raise SystemExit("provider J-lens checkpoint has no consistent positive prompt count") + prompt_count = prompt_counts[0] layers: dict[str, torch.Tensor] = {} provider_layers = sorted(int(layer) for layer in raw_layers) layer_ids = select_jlens_layers( @@ -68,7 +75,6 @@ def create_jlens_pack(args, model: dict) -> None: save_file(layers, tensor_path) tensor_digest = sha256(tensor_path) checkpoint_digest = sha256(args.jlens_checkpoint) - prompt_count = int(checkpoint.get("n_prompts", checkpoint.get("prompts_fitted", 278))) manifest = { "format_version": 6, "method": "provider_jacobian_lens", diff --git a/browser-runtime/mlc_q4_torch.py b/browser-runtime/mlc_q4_torch.py index 045dfa31..6958dc88 100644 --- a/browser-runtime/mlc_q4_torch.py +++ b/browser-runtime/mlc_q4_torch.py @@ -295,8 +295,10 @@ def transformers_state_dict(directory: Path) -> tuple[dict[str, torch.Tensor], d quantization = chat.get("quantization") if architecture not in {"gemma3_text", "llama", "qwen3", "qwen3_5"} or not isinstance(raw_config, dict): raise ValueError("only the pinned Gemma 3, Llama, Qwen3, and Qwen3.5 q4 browser architectures are supported") - if quantization not in {"q4f16_1", "q4f32_1"}: - raise ValueError("only q4f16_1 and q4f32_1 browser weights are supported") + if quantization not in {"q4f16_1", "q4f32_1"} and not ( + quantization == "q0f32" and architecture == "gemma3_text" + ): + raise ValueError("only q4f16_1, q4f32_1, and Gemma q0f32 browser weights are supported") if architecture == "gemma3_text": text_config = raw_config.get("text_config") if not isinstance(text_config, dict): @@ -305,7 +307,7 @@ def transformers_state_dict(directory: Path) -> tuple[dict[str, torch.Tensor], d **text_config, "vocab_size": raw_config.get("vocab_size"), "context_window_size": raw_config.get("context_window_size", text_config.get("context_window_size")), - "sliding_window_size": raw_config.get("sliding_window_size", text_config.get("sliding_window_size")), + "sliding_window_size": text_config.get("sliding_window_size", text_config.get("sliding_window")), } source_prefix = "language_model." else: @@ -313,13 +315,14 @@ def transformers_state_dict(directory: Path) -> tuple[dict[str, torch.Tensor], d source_prefix = "" cache = MlcTensorCache(directory) direct_dtype = np.float16 if quantization == "q4f16_1" else np.float32 + matrix = cache.q4 if quantization != "q0f32" else lambda name: direct(cache, f"{name}.weight", np.float32) if architecture == "qwen3_5": return qwen35_state_dict(cache, config, direct_dtype), { "architecture": architecture, "quantization": quantization, **config, **special_token_config(chat), } state: dict[str, torch.Tensor] = {} - embedding = cache.q4(f"{source_prefix}model.embed_tokens") + embedding = matrix(f"{source_prefix}model.embed_tokens") state["model.embed_tokens.weight"] = embedding state["lm_head.weight"] = embedding hidden_size = int(config["hidden_size"]) @@ -343,25 +346,25 @@ def transformers_state_dict(directory: Path) -> tuple[dict[str, torch.Tensor], d cache, f"{source}.post_feedforward_layernorm.weight", direct_dtype ) for projection, width in (("q", q_width), ("k", kv_width), ("v", kv_width)): - value = cache.q4(f"{source}.self_attn.{projection}_proj") + value = matrix(f"{source}.self_attn.{projection}_proj") if tuple(value.shape) != (width, hidden_size): raise ValueError(f"MLC Gemma {projection.upper()} projection shape is invalid at layer {layer}") state[f"{target}.self_attn.{projection}_proj.weight"] = value else: fused_attention = "qkv_proj" if architecture == "llama" else "c_attn" - qkv = cache.q4(f"{source}.self_attn.{fused_attention}") + qkv = matrix(f"{source}.self_attn.{fused_attention}") if tuple(qkv.shape) != (q_width + 2 * kv_width, hidden_size): raise ValueError(f"MLC fused QKV shape is invalid at layer {layer}") state[f"{target}.self_attn.q_proj.weight"] = qkv[:q_width] state[f"{target}.self_attn.k_proj.weight"] = qkv[q_width : q_width + kv_width] state[f"{target}.self_attn.v_proj.weight"] = qkv[q_width + kv_width :] - state[f"{target}.self_attn.o_proj.weight"] = cache.q4(f"{source}.self_attn.o_proj") - gate_up = cache.q4(f"{source}.mlp.gate_up_proj") + state[f"{target}.self_attn.o_proj.weight"] = matrix(f"{source}.self_attn.o_proj") + gate_up = matrix(f"{source}.mlp.gate_up_proj") if tuple(gate_up.shape) != (2 * intermediate, hidden_size): raise ValueError(f"MLC fused gate/up shape is invalid at layer {layer}") state[f"{target}.mlp.gate_proj.weight"] = gate_up[:intermediate] state[f"{target}.mlp.up_proj.weight"] = gate_up[intermediate:] - state[f"{target}.mlp.down_proj.weight"] = cache.q4(f"{source}.mlp.down_proj") + state[f"{target}.mlp.down_proj.weight"] = matrix(f"{source}.mlp.down_proj") if architecture in {"gemma3_text", "qwen3"}: state[f"{target}.self_attn.q_norm.weight"] = direct( cache, f"{source}.self_attn.q_norm.weight", direct_dtype @@ -470,12 +473,15 @@ def build_transformers_model(directory: Path, device: str = "cpu") -> torch.nn.M kwargs = {} layer_types = kwargs.get("layer_types") if not isinstance(layer_types, list) or len(layer_types) != common["num_hidden_layers"]: - pattern = int(kwargs.get("_sliding_window_pattern", 6)) + pattern = int(config.get("sliding_window_pattern", kwargs.get("sliding_window_pattern", kwargs.get("_sliding_window_pattern", 6)))) layer_types = [ "full_attention" if (layer + 1) % pattern == 0 else "sliding_attention" for layer in range(common["num_hidden_layers"]) ] rope_theta = float(config["position_embedding_base"]) + local_rope_theta = float(config.get("rope_local_base_freq", kwargs.get("rope_local_base_freq", 10_000))) + global_rope = {"rope_type": "default", "rope_theta": rope_theta} + global_rope.update(config.get("rope_scaling") or kwargs.get("rope_scaling") or {}) model_config = Gemma3TextConfig( **common, max_position_embeddings=int(config["context_window_size"]), @@ -485,8 +491,8 @@ def build_transformers_model(directory: Path, device: str = "cpu") -> torch.nn.M sliding_window=int(config["sliding_window_size"]), layer_types=layer_types, rope_parameters={ - "full_attention": {"rope_type": "default", "rope_theta": rope_theta}, - "sliding_attention": {"rope_type": "default", "rope_theta": rope_theta}, + "full_attention": global_rope, + "sliding_attention": {"rope_type": "default", "rope_theta": local_rope_theta}, }, ) model_type = Gemma3ForCausalLM @@ -499,6 +505,7 @@ def build_transformers_model(directory: Path, device: str = "cpu") -> torch.nn.M raise ValueError( f"MLC q4 state does not close the Transformers model: missing={missing}, unexpected={unexpected}" ) + materialize_rotary_embeddings(model) for module in model.modules(): for name, buffer in tuple(module.named_buffers(recurse=False)): if not buffer.is_meta: @@ -508,12 +515,6 @@ def build_transformers_model(directory: Path, device: str = "cpu") -> torch.nn.M common["hidden_size"] ** 0.5, dtype=model_dtype, ) - elif name.endswith("inv_freq"): - inverse_frequency = 1.0 / ( - float(config.get("position_embedding_base", config.get("rope_theta"))) - ** (torch.arange(0, int(config["head_dim"]), 2, dtype=torch.float32) / int(config["head_dim"])) - ) - module._buffers[name] = inverse_frequency remaining_meta = [name for name, value in model.named_buffers() if value.is_meta] if remaining_meta: raise ValueError(f"MLC q4 model has unmaterialized buffers: {remaining_meta}") @@ -528,6 +529,15 @@ def build_transformers_model(directory: Path, device: str = "cpu") -> torch.nn.M return model +def materialize_rotary_embeddings(module: torch.nn.Module) -> None: + for name, child in tuple(module.named_children()): + if child.__class__.__name__.endswith("RotaryEmbedding"): + with torch.device("cpu"): + setattr(module, name, type(child)(child.config)) + else: + materialize_rotary_embeddings(child) + + def replace_rms_norms(module: torch.nn.Module) -> None: for name, child in tuple(module.named_children()): if child.__class__.__name__.endswith("RMSNorm"): diff --git a/browser-runtime/runtime-feasibility-evidence.json b/browser-runtime/runtime-feasibility-evidence.json deleted file mode 100644 index 1cead509..00000000 --- a/browser-runtime/runtime-feasibility-evidence.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "./runtime-feasibility-evidence.schema.json", - "schemaVersion": 3, - "status": "feasibility-required", - "polytheticRevision": null, - "gates": { - "gemmaTinyFp32Parity": null, - "llamaTinyFp32Parity": null, - "qwenTinyFp32Parity": null, - "gemmaProductionQ4Parity": null, - "smolProductionQ4Parity": null, - "qwenProductionQ4Parity": null, - "gemmaLongPrefill": null, - "runtimeLifecycle": null - } -} diff --git a/browser-runtime/runtime-lock-identity-v1.json b/browser-runtime/runtime-lock-identity-v1.json index e4016584..ce08ebc6 100644 --- a/browser-runtime/runtime-lock-identity-v1.json +++ b/browser-runtime/runtime-lock-identity-v1.json @@ -1,4 +1,4 @@ { "schemaVersion": 1, - "runtimeLockIdentitySha256": "1d18977b500de0e5ed57a54d58cb37a830f9d39328f7be5018095f3dfa33a96c" + "runtimeLockIdentitySha256": "ebdc5521d9206dc907bac7896fd52ec288cb5ce1dcfb5783111eba1a1a84bddc" } diff --git a/browser-runtime/runtime-lock.json b/browser-runtime/runtime-lock.json index 3ec48dc8..03b447db 100644 --- a/browser-runtime/runtime-lock.json +++ b/browser-runtime/runtime-lock.json @@ -6,7 +6,7 @@ "hookAbi": "post-block-residual-v4", "exactReadoutAbi": "exact-readout-v1", "toolchain": { - "forkManifestSha256": "8f87f73b71c531a2d5cef027ea258a550d4d4aff114ece21c69dc6a97accab97", + "forkManifestSha256": "8fa48dcb02c4b393603622be25af3ca4a7f97a97f521de81de33d6c623b666a3", "mlcLlmFork": { "repository": "https://github.com/a9lim/mlc-llm-polythetic", "commit": null @@ -16,10 +16,10 @@ "commit": null }, "webLlmPackage": { - "path": "browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.34.tgz", - "sha256": "4ba44a095d021ae46351594efcd317e248ab47f443a1bf102abd86cd8dbfd03d", + "path": "browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.38.tgz", + "sha256": "2bc5a703205eaaf547cfd6344d80ae0a4b44b931f66d487b3cc69495320a0995", "name": "@drowse/web-llm", - "version": "0.2.84-drowse.34", + "version": "0.2.84-drowse.38", "repository": "https://github.com/a9lim/web-llm-polythetic", "sourceCommit": null }, diff --git a/browser-runtime/validate_mlc_q4_parity.py b/browser-runtime/validate_mlc_q4_parity.py index fcfa8090..952e69e1 100644 --- a/browser-runtime/validate_mlc_q4_parity.py +++ b/browser-runtime/validate_mlc_q4_parity.py @@ -17,6 +17,7 @@ "smolProductionQ4Parity": "smollm2-360m-instruct", "qwenProductionQ4Parity": "qwen3-1.7b", } +PARITY_MODEL_IDS = {*EVIDENCE_MODEL_IDS.values(), "gemma3-1b-instruct", "gemma3-4b-instruct"} SMOL_NAMED_ROLE_INPUT_IDS = [ 1, 9690, @@ -261,7 +262,7 @@ def load_capture_metadata( if set(metadata) - allowed or not required.issubset(metadata) or metadata["schema_version"] != 3: raise ValueError("browser residual fixture has an invalid schema") if ( - metadata["model_id"] not in set(EVIDENCE_MODEL_IDS.values()) + metadata["model_id"] not in PARITY_MODEL_IDS or not valid_sha256(metadata["runtime_identity_sha256"]) or not valid_sha256(metadata["residual_sha256"]) or not valid_sha256(metadata["rank_one_control_residual_sha256"]) @@ -532,10 +533,12 @@ def steering_delta_cosine( def cosine(left: np.ndarray, right: np.ndarray) -> float: + left = np.asarray(left, dtype=np.float64).reshape(-1) + right = np.asarray(right, dtype=np.float64).reshape(-1) denominator = float(np.linalg.norm(left) * np.linalg.norm(right)) if denominator <= 1e-12: raise ValueError("rank-one steering produced no measurable residual delta") - return float(np.dot(left.reshape(-1), right.reshape(-1)) / denominator) + return float(np.clip(np.dot(left, right) / denominator, -1.0, 1.0)) def select_device(model_directory: Path, requested: str) -> str: diff --git a/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.32.tgz b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.32.tgz deleted file mode 100644 index 5917fd26..00000000 Binary files a/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.32.tgz and /dev/null differ diff --git a/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.36.tgz b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.36.tgz new file mode 100644 index 00000000..b45d5d65 Binary files /dev/null and b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.36.tgz differ diff --git a/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.37.tgz b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.37.tgz new file mode 100644 index 00000000..2d915780 Binary files /dev/null and b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.37.tgz differ diff --git a/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.38.tgz b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.38.tgz new file mode 100644 index 00000000..098c3b62 Binary files /dev/null and b/browser-runtime/vendor/drowse-web-llm-0.2.84-drowse.38.tgz differ diff --git a/docs/PYTHON_PRESERVATION_AUDIT.md b/docs/PYTHON_PRESERVATION_AUDIT.md deleted file mode 100644 index 5856f463..00000000 --- a/docs/PYTHON_PRESERVATION_AUDIT.md +++ /dev/null @@ -1,97 +0,0 @@ -# Python preservation audit - -Checked on 2026-09-06 against original Saklas 5.3.0 at -`e32e368b3b08626b47b54e39e0042c37ae27023e`, using the current `dev` working tree. -The working tree already contained the Drowse rename, browser runtime, and -Python improvements. This audit preserves those changes. Compatibility here -means the original capabilities under Drowse names, as requested; old import, -command, and URL aliases are outside the contract. - -## What remains available - -All 119 original Python modules have counterparts in `drowse/`. A snapshot -captured by importing the unmodified original package verifies these original -surfaces against the current implementation: - -- 81 public exports, 329 callable signatures, and 65 properties. -- 53 CLI parser paths, covering all eight verbs: `serve`, `manifold`, `pack`, - `experiment`, `config`, `template`, `lens`, and `sae`. -- 86 HTTP/WebSocket method-and-path entries, normalized for the rename. - -The signature check exercises original positional and keyword call forms and -checks unchanged optional defaults. It permits additive capabilities. These -checks are in `tests/test_python_preservation.py`; the baseline contract and -artifacts written by original Saklas live in `tests/fixtures/saklas_v5_3/`. - -| Capability | Current Python surface and verification | -| --- | --- | -| Generation and steering | `DrowseSession`, streaming, stateless/stateful generation, expressions, ablation, and hook cleanup; unit tests and real-model MPS tests | -| Extraction and manifolds | Original extraction, authored/discover fitting, composition, monitoring, transfer, and comparison modules retained; unit tests and real-model discover/fit/steer pipeline | -| Templates and experiments | Original template scoring and experiment CLI/API surfaces retained and covered by the non-GPU suite | -| Jacobian/R lenses | Fitting, readout, atoms, probes/gates, decomposition, and source lifecycle retained; unit tests plus the Jacobian-lens GPU suite | -| SAEs | Local training and external-source lifecycle, steering, and instrumentation retained; unit tests and installed SAE-Lens registry checks; gated real-release smoke not run | -| Artifacts | Original Profile, LoomTree, and baked manifold files load; original baked directions survive installation; GGUF tests run with the optional dependency installed | -| Server | OpenAI chat/completions, Ollama chat/generate, and native WebSocket generation exercised against an installed wheel and a real model | -| Dashboard | Default build installs `HttpRuntimeClient`; hosted WebGPU build remains separate; the packaged default dashboard runs with `navigator.gpu` disabled | - -Resolving every public Python export imports neither `drowse.server`, -`drowse.web`, nor FastAPI. A regression test enforces this boundary. Python -operation does not require Node, a browser, or WebGPU. `create_app(web=False)` -and the CLI's `--no-web` surface remain available. - -## Regressions repaired - -1. **Original conversation loading:** migrate the original version key before - the file loader checks required fields, matching the existing dictionary - loader's behavior. -2. **Original manifold reuse:** recognize renamed predecessor sidecars as stale - fits that can be regenerated. Original baked v10 artifacts, which have no - corpus to refit, accept the exact predecessor field set with an unknown - context-binding proof. No proof is invented; other schema/version damage is - still rejected, and source bytes remain unchanged. -3. **Prompt pooling:** trim template suffix whitespace only when it follows a - closing special token. Legitimate trailing assistant-content whitespace - remains part of the pooled span. -4. **Published manifold discovery:** search original Saklas/Polythetic tags as - well as the current Drowse tag, deduplicating within the original result cap. -5. **Python distribution assets:** package the complete default dashboard tree, - including the theme initializer and icons; serve icon/social directories as - files. The packaging check now detects omissions shared by both wheel and - sdist, and missing icons return 404 instead of the SPA document. -6. **Python dashboard autosave:** accept the Python tree's explicit null session - ID while retaining model matching and rejection of missing or conflicting - session IDs. The snapshot regression uses the original Python tree fixture. - -Also corrected two blocked browser-corpus candidate algorithm identifiers and -the existing test typing/lint failures exposed by the project checks. Runtime -test thresholds and package version were not relaxed or changed. - -## Verification - -Commands use the project's Python 3.12 environment on Apple Silicon macOS. - -| Check | Result | -| --- | --- | -| `.venv/bin/pytest -q -m 'not gpu'` | 3,751 passed, 18 skipped, 50 deselected | -| MPS `test_smoke.py`, `test_session.py`, `test_jlens_gpu.py` | 42 passed, 1 skipped; public SmolLM2-360M-Instruct and the lens suite's small model fixtures | -| MPS generation lifecycle/concurrency suite | 5 passed; state recovery after exceptions and concurrent-generation rejection verified | -| Final Python preservation regressions | 10 passed | -| Ruff across the checkout | Passed | -| Pyright using the project interpreter | 0 errors; 1 existing dynamic script-import warning in `test_hosted_jlens.py` | -| Generated REST type check | Current | -| Default and hosted frontend checks; runtime tests | Passed; conversation snapshot/library tests rerun after the autosave fix | -| Default and hosted builds | Passed; build isolation passed for both | -| Wheel and sdist build; package isolation | Passed; all 971 default dashboard files present and matching | -| Installed wheel outside the checkout | Public imports, static asset MIME types, OpenAI/Ollama generation, OpenAI SSE, native WebSocket generation passed | -| Packaged dashboard in Chromium, WebGPU disabled | Generation, autosave, backup download, and restore passed; restored nodes and token metadata matched the saved snapshot; no page errors or failed requests | - -The 18 non-GPU skips are uncached representative-tokenizer drift checks with -downloads disabled. The real-model suite's one skip is a pre-existing obsolete -monitor-based ablation assertion; the other steering/ablation tests ran. -CUDA, all model families and Python versions, gated SAE/model downloads, and a -fresh real-device hosted-WebGPU matrix were not exercised. Passing interface -and regression checks does not establish identical numerical outputs for every -model and hardware combination. - -Changes remain local on `dev`; no version bump, commit, push, or deployment was -performed by this audit. diff --git a/docs/manifold-validation-2026-09-05.md b/docs/manifold-validation-2026-09-05.md deleted file mode 100644 index bae7ed5d..00000000 --- a/docs/manifold-validation-2026-09-05.md +++ /dev/null @@ -1,37 +0,0 @@ -# Manifold steering validation — 2026-09-05 - -## Repairs - -- **Cross-layer geometry:** periodic coordinates now use circular means, and sphere coordinates use an embedded-vector mean. Ordinary coordinates retain their weighted arithmetic mean. Previously, phases 0.99 and 0.01 averaged to 0.50: the opposite side of the circle. The repair covers browser readouts, native full/lean monitor readings, and gate scalars. -- **Ambiguous means:** when embedded directions cancel, the aggregate retains the highest-weight observed layer (first on a tie). This is a deterministic representative, not a confident estimate of a unique mean. Per-layer readings remain available. -- **Fit cost:** explicitly selected PCA returns after the PCA candidate is evaluated. It no longer computes unused spectral embeddings and curved RBF candidates. Automatic selection is unchanged; no wall-clock speedup is claimed. -- **UI accuracy:** zero residual no longer implies a flat manifold. Flat/curved labels use attached artifact metadata; absent metadata is shown as generic geometry. - -## Verification - -- 301 native tests across topology, manifold math, monitor, steering, gates, probe sessions, and geometry replay passed. -- Rust fitting tests and strict Clippy passed. Rebuilt hosted WASM assets pass the reproducibility check. -- Browser regressions cover periodic seams, rotation, weighted and ambiguous means, sphere poles, missing layer buffers, readout/gate agreement, abrupt warm-start jumps, and zero-strength identity. -- Browser fitting, activation-spool recovery, worker cancellation/crashes, coordinator, provenance, and WASM golden checks passed. -- Python type/lint checks and Svelte type checking passed. -- Geometry UI tests passed in Chromium and WebKit, including known-curved versus unknown metadata, keyboard layer selection, and light/dark layouts at 320px and 1280px. Generated screenshots were inspected. Native and hosted dashboard builds passed (existing large-chunk warnings remain). - -### Real-model numerical smoke test - -`scripts/check_manifold_model.py` uses cached SmolLM2-360M-Instruct on the Mac GPU, with real residual activations at layer 16. It tests flat and controlled curved injection at strengths 0, +0.3, and −0.3. Outputs remained finite; zero strength preserved baseline within numerical tolerance; removing each hook restored baseline exactly. Both nonzero signs changed logits. - -The circle is constructed in a real activation frame: this checks numerical integration, not discovery of a semantic circle. It does not establish generation quality, calibrated membership, or generalization to other models. - -Run with: - -```sh -.venv/bin/python scripts/check_manifold_model.py --device mps -``` - -## Remaining boundaries - -Hosted automatic topology discovery remains explicitly disabled in `browserModelBackend.ts`. Linear PCA and explicitly authored geometry remain supported. Passing synthetic topology tests is not sufficient evidence to release automatic semantic shape detection. - -Before enabling that feature, validate topology selection on held-out, real-model corpora, including noisy flat data and negative controls. Check stability across resampling and layer subsets; expose inconclusive evidence rather than forcing a shape label. Residual and membership describe fit to the supplied artifact, not proof of a globally correct manifold. - -The full browser runtime command currently stops at an unrelated SAE source-metadata deep-equality assertion in `drowse-web-llm-backend.test.mjs`: actual metadata includes optional `model_layers` and `description_source` keys with undefined values, while the expected object omits them. Remaining manifold tests were run separately; the entire runtime suite is not claimed green. diff --git a/docs/research/interp-avenues-2026-07.md b/docs/research/interp-avenues-2026-07.md deleted file mode 100644 index 9b9bc518..00000000 --- a/docs/research/interp-avenues-2026-07.md +++ /dev/null @@ -1,269 +0,0 @@ -# Interpretability avenues beyond probes / J-lens / SAEs - -*Research digest, 2026-07-12. Three parallel literature sweeps (workspace/null-space; -planning/latent reasoning; introspection/causal methods), synthesized against the -drowse stack. Verification: most load-bearing items were fetched at the primary -source by the sweep agents; items marked [snippet] were search-verified only.* - -## The taxonomy: four kinds of "unvocalized" - -The "subconscious" framing decomposes into four empirically distinct objects: - -1. **Not-yet-vocalized (plans).** Content the model holds about future output — - rhyme targets, planned paragraphs, pre-committed answers. Readable, sometimes - causally load-bearing. -2. **Never-vocalized but workspace-visible.** Latent hops (Dallas→Texas→Austin), - internal beliefs diverging from stated answers, eval-awareness, premature - commitment. Probe-readable; absent from the text. Drowse probes already read - this class partially. -3. **Sub-report-threshold (the subliminal band).** Injected/present content that - shifts behavior while the model's self-report denies it. The report bottleneck - is a *trained gate*, not absent signal. -4. **Workspace-dark (the complement).** The ~93% of concept-vector variance - outside J-space. Constraint from the workspace paper's own clamping - experiment: its causal effects route through *re-derivation into* J-space - (complement swaps: 5% success alone, 0% with J-space clamped) — the complement - is the preconscious feed, not a parallel channel to output. - -Drowse's current stack reads (2) well, (1) not at all, (3) only from the -injection side, (4) only as the residual of `jspace_decompose`. Causal -attribution (patching-family) is a missing *leg*, orthogonal to all four. - ---- - -## Tier 1 — open niches we have the machinery for - -### 1. Subliminal-band psychophysics (experiment; ~zero new infra) - -**Confirmed open**: nobody has published the quantitative object — a per-concept -curve of behavior-shift threshold vs self-report threshold, with the gap as the -measured "subconscious margin." - -- Behavior threshold: α-sweep a steering term, measure `score_choices` - distribution shift (KL/Bhattacharyya vs unsteered — soft, not argmax). -- Report threshold: scored self-report ("do you notice an injected thought?") - via `score_choices` over yes/no; score *detection*, not identification — - report content confabulates (Lederman & Mahowald, arXiv:2603.05414). -- Act 2 (causal): the report gate is a circuit — early "evidence carrier" - features suppress a default-"no" gate (Macar et al., arXiv:2603.21396). - Ablating refusal directions boosts detection +53%, a trained bias vector +75%. - Our `!` operator can move the report threshold while the behavior threshold - stays — measure the band shrink. -- Act 3 (monitor dissociation): Qwen-32B shows a mid-layer latent detection - signal *attenuated before sampling* while the output denies injection - (Pearson-Vogel et al., arXiv:2602.20031; mechanism-informed prompting raises - verbal detection 0.3%→39.9%). Our monitor can read the latent signal live - against the verbal denial. -- Controls to design in: Singh/Linzen/Ravfogel (arXiv:2605.26242) — models may - be generic anomaly detectors, not privileged introspectors; need input-level - vs activation-level intervention discrimination. Also strength-without-source - (arXiv:2512.12411): magnitude sensing is early-layer and dissociated from - content ID. - -### 2. J-lens complement instrumentation + sleeper steering (small infra + experiment) - -**Confirmed open**: the workspace paper is 6 days old (2026-07-06); no published -probe/steer study of the complement exists. "Sleeper directions" (delayed-effect -steering) explicitly unclaimed. - -- Numbers (fetched from transformer-circuits.pub/2026/workspace/): median 6–7% - of concept-vector variance in J-space (~93% outside); 10–15% for two-hop - intermediates; J-space ≤~10% of total activation variance at any layer. -- Formalization warning (LW thread — Bushnaq, Linsefors): J-space is the set of - *sparse non-negative combinations* of lens vectors — a cone, not a subspace, - and the span can be ~full-rank. "Complement" must be defined as - low-conductance-under-J_l (SVD of J_l → per-layer conductance spectrum) or - pursuit-residual (1 − the share `jspace_decompose` already computes). -- Channel ideas: a `:silent` sibling of `:fraction` — whitened mass of h in the - low-conductance subspace of J_l (raw norm is rogue-dominated; the whitener is - our specialty). Plus downstream-connectivity salience (Circuits Update May - 2026: connectivity predicts steerability better than activation descriptors) — - a vocabulary-free importance measure for complement directions. -- Sleeper experiment: `|`-project a steering term against its own J-space - pursuit approximation, inject, and watch the live lens aggregate for *delayed* - workspace emergence. The clamping result predicts effect-only-via-re-derivation - — so the measurable is incubation latency + transformation, not a parallel - path. Prior art for complement-constrained steering exists but with X ≠ - J-space: Head-Masked Nullspace Steering (arXiv:2604.10326), AlphaSteer - (arXiv:2506.07022). -- Replication assets: `anthropics/jacobian-lens` (official companion code, HF - decoders); Neuronpedia hosts an interactive J-lens (Qwen3.6-27B); - `solarkyle/jspace-lenses` on HF has fitted lenses for **Gemma 4 E4B / 12B / - 12B-abliterated / 26B-MoE** — cross-check targets for our own fits. [snippet] - -### 3. Plan / future readout (medium infra) - -- **Cheapest**: ParaScopes continuation transplant (Pochinkov et al., - arXiv:2511.00180) — transplant the `\n\n`-boundary-token residual into a fresh - context and let the model regenerate the *planned paragraph*. No training; we - have full generation control. Loom-native as a token drilldown. -- **Deeper**: cross-position Jacobian lens `J_l^{(k)} = E[∂h_{final,t+k}/∂h_{l,t}]` - — rides the existing jlens VJP machinery (different probe positions, same - backward infra). Consensus plan-carrying sites: line/paragraph boundary tokens - (Biology paper; arXiv:2605.07984 [snippet]; arXiv:2601.20164 [snippet]). -- **Pre-CoT commitment probe**: linear probes on pre-CoT residuals predict the - final answer at ~0.9 AUC and steering them flips answers >50% of the time - (arXiv:2603.01437 [snippet]) — the model commits, then rationalizes. Shaped - exactly like a gateable drowse channel. -- Anthropic thread: Latent Planning Emerges with Scale (Hanna & Ameisen, ICLR - 2026, arXiv:2604.12493) — planning scales with size, steering can *strengthen* - it. Where's the Plan (arXiv:2605.07984 [snippet]): future-rhyme is decodable - everywhere but only Gemma-3-27B *causally relies* on it (layer-~30 handoff, - ~5 attention heads). Decodable ≠ used — a future readout needs a patching - validation leg. Planning is also inconsistent (arXiv:2508.18098: Gemma-2-2B - improvises poems) — want a planning-vs-improvising discriminator channel. -- Latent thought content is *distributional* — superposition of search frontiers - (arXiv:2505.12514) — so the readout should be soft/set-valued, not argmax. - ---- - -## Tier 2 — strong experiments, mostly existing infra - -### 4. Belief-vs-statement probes ("knows more than it shows") - -- Question-only correctness direction: linear probes on the pre-generation state - predict eventual answer correctness, generalize OOD, peak mid-layer, beat - verbalized confidence (arXiv:2509.10625) — internal P(IK) before any token; a - natural probe gate ("only trust generations where the correctness coordinate - is high"). Known blind spot: math/logic (confidently wrong). -- Truth/belief directions: 2-D truth subspace (Bürger et al., NeurIPS 2024); - belief probes predict retraction (arXiv:2505.16170 [snippet]); truth directions - generalize across logical transformations (arXiv:2506.00823 [snippet]). -- Eval-awareness cluster: probes separate test-vs-deploy framing - (arXiv:2507.01786), steering can suppress awareness (arXiv:2510.20487); - "unverbalized eval awareness" is the exact phenomenon, name and all. -- Deception is *multi-directional* — type-matched probes beat a universal one by - 3× margin (arXiv:2602.01425); a probe roster/manifold, not an axis. Fits the - drowse manifold thesis directly. - -### 5. CoT-faithfulness instrumentation - -We already have the `thinking`/`response` triggers and committed thinking. -- Measure probe-trajectory divergence between thinking and response segments; - compare which better predicts the final answer distribution. -- Rationalization detector: activation probes catch motivated reasoning even - when the CoT text is rationalized (arXiv:2603.17199 [snippet]); steering-induced - flips get rationalized by subsequent CoT (arXiv:2604.01202 [snippet]). -- Reasoning models verbalize hints they used ~25–39% of the time; RL-hacking - verbalized <2% (Chen et al., arXiv:2505.05410). Anthropic decoded deliberately - ROT-13-obfuscated CoT with logit-lens-class tools unsupervised (Fang & Marks, - arXiv:2512.01222) — lens machinery can recover hidden reasoning streams. - -### 6. The causal leg: attribution verb - -All drowse reads are correlational. Cheapest-reliable causal localization, 2026: -- **RelP** (arXiv:2508.21258): attribution patching with LRP coefficients at - identical cost (2 fwd + 1 bwd); correlation with true activation patching on - GPT-2 IOI MLPs goes 0.006 (AtP) → 0.956. -- **HVP reliability check** (arXiv:2606.09899): per-estimate trust score + one - extra backward to remove leading-order error. -- Pipeline: AtP*/RelP sweep → HVP flags → direct patching on survivors. The - jlens fit already owns the backward-pass machinery. Would give drowse a - `attribute`-shaped verb and a causal validation leg for every probe/steering - claim (including the future-readout and complement work above). - ---- - -## Tier 3 — worth knowing, lower priority - -- **Attention-side reads**: attention *probes* (learned pooling over token - activations; production-grade at GDM for Gemini misuse monitoring, - arXiv:2601.11516) are the 2026 growth area — attention as probe architecture, - not as signal. ACC++ (arXiv:2602.13483): single-forward QK-subspace causal - signals. KV-cache trait probing: genuinely open, nobody's done it, speculative - value. HeadVis (Transformer Circuits 2026) for head-function hypothesis - generation. -- **Model diffing**: narrow finetuning leaves readable traces in first-token - activation diffs on unrelated text (arXiv:2510.13900) — the cheap method; - crosscoders/transcoder-adapters (arXiv:2602.20904) the heavy one. Relevant - when comparing finetuned variants, not for live sessions. -- **Trained verbalization heads**: LatentQA (arXiv:2412.08686), Predictive - Concept Decoders (arXiv:2512.15712), Introspection Adapters - (arXiv:2604.16812; SOTA on AuditBench, catches encrypted-finetune attacks) — - the "ask the residual stream questions in English" alternative to hand-built - lenses. Training-side; heavier than drowse's fit-an-artifact model. -- **Endogenous steering resistance** (arXiv:2602.06941): Llama-3.3-70B recovers - mid-generation from misaligned steering while it's still active — dedicated - consistency-checking circuits, scale-dependent. Directly relevant to drowse - steering practice; worth checking whether gemma-4-12b fights our injections. -- **Premature commitment** (arXiv:2606.22936): cross-run hidden-state - convergence at a fixed early step predicts behavioral consistency (monitor - AUROC up to 0.97), orthogonal to correctness — a hidden settling event. - -## Standing caveats (field-level) - -- **SAE vindication-and-then-some**: on synthetic ground truth SAEs recover 9% - of true features while reporting 71% explained variance; random baselines - match trained SAEs on interpretability/probing/editing (arXiv:2602.14111). - GDM formally deprioritized SAE research (Mar 2025). SAE dark matter: >90% of - error norm is linearly predictable; the nonlinear core is scale-*constant* - (arXiv:2410.14670). The a9 position ("sorta obsolete") is now the published - consensus — but the same paper family warns all reconstruction metrics - overstate coverage. -- **Three kinds of dark** (synthesis): vocabulary-artifact dark (W-space content - the single-token lens can't name — Eleos commentary's W-space vs J-space; - multi-token lenses would recover it), wrongly-shaped dark (multi-dimensional / - nonlinear features — Engels ×2; *our curved-manifold machinery is the - designed tool for exactly this*), and irreducible dark (scale-constant - nonlinear SAE error + attribution-graph error nodes). -- **Metacognitive space is low-dimensional** (arXiv:2505.13763): models can - monitor/control only a small subspace of their own state — most internal - state is structurally unreportable. The complement of the metacognitive space - is another candidate operationalization of "subconscious." -- **Probes are adversarially evadable** (Neural Chameleons, arXiv:2512.11949): - finetuning to evade benign probes generalizes zero-shot to unseen safety - monitors. The "hostile telepaths" concern (LW): training against a lens - pushes computation into the complement — which is an argument *for* building - complement instrumentation now. -- **Subliminal learning caveat**: the Nature-published effect (Cloud et al.) - may be substantially a LoRA artifact — disappears under full finetuning - (arXiv:2606.00831); channel location determines auditability - (arXiv:2606.22019). - -## Parked: Vogel's Qwen introspection result through the J-lens (2026-07-12) - -Vogel, "Small Models Can Introspect, Too" (vgel.me/posts/qwen-introspection/): -Qwen2.5-Coder-32B, repeng PCA concept vectors ("cat"/"bread") injected via the -KV cache of earlier turns (layers 18–33), steering removed before the detection -question; introspection measured as steered-vs-unsteered logit shift on yes/no -(informative architecture prompt: +0.372% → +52.3% "yes" shift; Lorem-Ipsum and -wrong-location controls fail, so not a generic yes-bias). Logit lens over all 64 -layers: a "yes" signal hill at layers 46–52 (only steered + informed prompt), a -broader hill 52–62 (present even unsteered), and strong suppression of "yes" in -the final two layers. Precursor/companion to the Latent Introspection paper -(arXiv:2602.20031). - -The J-lens redo is more informative for a specific reason: it discriminates two -suppression mechanisms the logit lens conflates. -- **(a) Active gating**: the mid-stack detection signal is workspace-transmitted - (high p_l for the yes/detection tokens through the band) and then killed late - — the Macar et al. default-"no" gate acting on workspace content. -- **(b) Never transmitted**: the mid-stack hill is a breadcrumb — logit-lens - visible but low J-conductance throughout; the "final-layer suppression" is - then an artifact of premature decoding, not a gate. -Distinguishing (a) from (b) is exactly the workspace-vs-complement question -from avenue #2 above — the two parked threads converge. - -Practical notes for the eventual run: near the final layers J_l converges to -the raw unembedding row, so J-lens ≈ logit lens exactly where Vogel saw the -suppression — the informative delta is the 46–62 hills, i.e. the late-band -region. Fit the lens through the late layers: both the per-layer readout and -the aggregate cover every requested fitted layer. "yes"/"no" are -single tokens, so `jlens/yes`-style readout probes apply directly, and gate -scalars already ride the readout channel. Open question for the harness: vgel's -injection is KV-cache-persistent (steer turn 1, ask unsteered in turn 2) — -check what drowse's conversational path preserves across generate calls before -designing the replication. - -## Speculative footnote (marked as such) - -The clamping result operationalizes a psychodynamic stack with unusual fidelity: -workspace = access consciousness; plan representations = preconscious -(retrievable on demand); the complement = unconscious *whose only route to -speech is re-derivation into workspace form* — influence through transformation -into acceptable content, never directly. The introspection gate (default-"no", -trained by post-training, ablatable) is then a literal repression mechanism, -and the +53%/+75% elicitation results are the band moving under intervention. -Not load-bearing for any experiment above; but the subliminal-band experiment -and the sleeper-direction experiment are, jointly, a test of how far the -analogy actually carries. diff --git a/docs/runtime-audit-2026-09-06.md b/docs/runtime-audit-2026-09-06.md deleted file mode 100644 index e54006a1..00000000 --- a/docs/runtime-audit-2026-09-06.md +++ /dev/null @@ -1,57 +0,0 @@ -# Runtime and lifecycle audit — 2026-09-06 - -Local audit of manifold fitting, steering, probes, replay, generation, Loom, persistence, and model-family integration. Existing worktree changes were preserved. No dependency upgrades, version bump, commit, push, or deployment was performed. - -## Repairs - -| Area | Reproduced problem and repair | -| --- | --- | -| Fitting capture cleanup | Affine-worker failure or cancellation could leave committed activation captures behind. Cleanup now covers that boundary, including cancellation after the last layer. Explicit capture retention also works when authored sigma fitting is disabled. | -| Preference subscriptions | Async bootstrap discarded the persistence effect's disposer. The mounted workbench now owns a single persistence subscription and clears its pending write on disposal. | -| Replay queue | Pending token readouts were unbounded even though settled results were capped. The queue now admits at most 96 pending jobs, retains deduplication and interactive priority, and rejects overflow with a retry message. Synchronous transport failures release the active slot; finished jobs clear progress listeners. | -| Probe refresh | Out-of-order list responses could overwrite newer state, erase attachments, or resurrect detached probes. Request and mutation revisions prevent stale commits. Failed refreshes preserve known probes; unchanged catalogs no longer invalidate readouts. Lens and SAE roster mutations now invalidate their own replay caches as geometry already did. | -| Re-fit experience | Duplicate clicks are ignored, typed cancellation is informational, and successful fits refresh the catalog, probe roster, vector metadata, and open diagnostics. Old inspector responses cannot overwrite new diagnostics. Late probe attachments cannot close a different drawer. | -| New-chat reset | An explicit reset previously removed incompatible autosaves but restored compatible ones. Reset now clears only the selected model's current autosave regardless of compatibility. Named saved chats use a separate store. | -| Loom identity | Every freshly loaded tree previously started with the literal root ID `root`. New chats therefore collided in the saved-conversation lookup, triggering stale-revision autosave failures. Fresh roots now have unique IDs. Restored tree identities are unchanged. | -| Build verification | Hosted-shell assertions still expected retired landing-page copy. Description validation now uses the canonical metadata source, and the local-compute assertion matches the current rendered promise. | - -The probe refresh, retained-capture failure, compatible-session reset, and fresh-root collision regressions failed before their respective repairs and passed afterward. - -## Automated verification - -- Full Python suite: **3,789 passed, 20 skipped**, 11 warnings, 17m16s. No Python engine code was changed in this audit. -- Full browser runtime suite: passed after the final runtime changes. Includes authoritative Loom, generation, hybrid-cache contracts, steering compiler/kernel parity, instrument replay, storage, worker cancellation, fitting coordination, and artifact provenance tests. -- New lifecycle tests: 100 persistence mount/unmount cycles; single-owner replacement; pending-write cleanup; out-of-order probe responses; attach/detach races; unchanged-catalog cache reuse; 500 replay-queue overflow attempts; cancellation/invalidation; synchronous transport recovery; duplicate fits; re-fit diagnostics races. -- Rust fitting suite: **38 passed**, including golden fixtures, allocation ceilings, and adversarial topology/coordinate cases. -- Hosted fitting WASM reproducibility check: passed. -- Svelte checking: **0 errors, 0 warnings**. Theme, runtime-boundary, interface-policy, backup, metadata, and lifecycle checks passed. -- Native dashboard and hosted production builds: passed. Existing large-chunk warnings remain. -- Hosted build isolation and preview-shell verification: passed. -- Hosted release tooling/preflight tests and runtime/distribution lock validation: passed. Lock validation used the existing HEAD revision; it does not certify or deploy the uncommitted application changes. -- `npm audit`: **0 reported vulnerabilities**, including development dependencies. -- Python dependency consistency (`pip check`): passed. - -## Live model checks - -The browser checks used the locally built app and real installed model weights, not the fake runtime. Each of the four base-model families started a new conversation, generated, saved separately, and returned to the chat list after unloading. - -| Model | Observed result | -| --- | --- | -| Pythia 70M Deduped Base / GPT-NeoX | 24-token completion; separate new-chat autosave with the older named chat still present. An additional run with `default/welcoming.detached` steering and a live probe produced finite per-layer readings and a bounded 60-reading history. | -| GPT-2 Base | 24-token completion, followed by a sibling generation in Loom: 3 turns, 1 fork, 48 generated tokens. | -| Qwen 3.5 2B Base / hybrid architecture | 24-token completions; an active longer generation stopped at 40 tokens; a subsequent 24-token generation completed successfully. | -| Gemma 3 1B PT | 24-token completion and autosave. Raw output included `` markers. This is a runtime/integration pass, not a clean-text or semantic-quality pass; output was not silently filtered. | -| SmolLM2-360M-Instruct / native MPS | `scripts/check_manifold_model.py --device mps` passed six flat/controlled-curved injection checks at 0 and ±0.3. Outputs stayed finite; zero strength matched baseline within tolerance; removing each hook restored baseline exactly. | - -The native curved fixture is constructed in a real activation frame. It verifies numerical integration, not discovery of a semantic manifold or calibrated steering quality. - -The four browser runs remain in Your chats as `QA Sep 6 — Pythia`, `QA Sep 6 — GPT-2`, `QA Sep 6 — Qwen`, and `QA Sep 6 — Gemma`. The five pre-existing saved chats remained listed separately; the QA model was unloaded at the end. - -## Boundaries - -- This is not proof that the entire application is bug-free or leak-free. Resource cleanup was checked through ownership, queue, worker, storage, and repeated-lifecycle regressions; no long-duration GPU/JS heap-retention profile was performed. -- Live browser checks cover the four installed base-model families on this Mac/browser. Other model variants, platforms, mobile memory pressure, device loss, and all optional SAE/J-lens combinations were not exhaustively exercised with real weights in this pass. -- Full real-model browser authoring/re-fitting across every family was not run. Fitting was covered by coordinator/worker/storage regressions, WASM/Rust parity, and the native real-activation smoke test. -- Twenty Python tests were skipped; those are not counted as passes. Passing tests do not establish semantic manifold validity or output quality. -- Several pinned packages have newer registry releases (including Svelte, Vite, TypeScript, React, Playwright, and Three.js). No blanket upgrades were made: zero audit findings is not equivalent to using every latest version, and compiler/runtime changes require their own compatibility pass. -- No remote code-review service was available. Review was local, with the reported tests and live checks. diff --git a/domain-name-candidates-round-2.csv b/domain-name-candidates-round-2.csv deleted file mode 100644 index 48f9d9fc..00000000 --- a/domain-name-candidates-round-2.csv +++ /dev/null @@ -1,201 +0,0 @@ -rank,name,domain,url,theme,rationale,backronym_sketch,status,first_year_usd,renewal_usd,premium,checked_at -1,psyche,psyche.tools,https://psyche.tools,cognitive science,Directly signals mind and psychology; warm rather than clinical.,Probing Subspaces to Yield Cognitive Hidden-state Explanations,available standard live registrar,9.78,29.35,no,2026-08-27 -2,affect,affect.tools,https://affect.tools,feeling/psychology,Canonical emotion term and a verb meaning to change: a strong double meaning.,Activation Feature Fitting for Explainable Concept Tuning,available standard live registrar,9.78,29.35,no,2026-08-27 -3,slant,slant.tools,https://slant.tools,steering/control,"A directional bias or interpretive angle; short, tactile, and steerable.",Subspace Lenses for Activation Navigation and Tuning,available standard live registrar,9.78,29.35,no,2026-08-27 -4,drowsy,drowsy.tools,https://drowsy.tools,sleep/dream,"The closest new sibling to Drowse: liminal, stateful, and memorable.","Directional Readout and Observation for Workspace Steering, Yield-aware",available standard live registrar,9.78,29.35,no,2026-08-27 -5,pensive,pensive.tools,https://pensive.tools,sleep/dream,"Thoughtful, introspective, and emotionally colored.",Probing Embeddings and Neural Subspaces for Interpretable Vector Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -6,appraisal,appraisal.tools,https://appraisal.tools,cognitive science,A core emotion-theory term for how a system evaluates a situation.,"Activation Probing and Projection for Representation Analysis, Interpretation, Steering, Alignment, and Layers",available standard live registrar,9.78,29.35,no,2026-08-27 -7,affordance,affordance.tools,https://affordance.tools,cognitive science,A canonical cognitive-science term for possible actions and control.,"Activation Feature Fitting for Output Representation, Direction, Analysis, Navigation, Control, and Editing",available standard live registrar,9.78,29.35,no,2026-08-27 -8,arousal,arousal.tools,https://arousal.tools,feeling/psychology,A core affect dimension and a measurable activation state.,"Activation Readout for Output Understanding, Steering, and Layers",available standard live registrar,9.78,29.35,no,2026-08-27 -9,inward,inward.tools,https://inward.tools,steering/control,Suggests opening a model and looking within.,Interpreting Neural Workspaces for Activation Readout and Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -10,heed,heed.tools,https://heed.tools,steering/control,Attention and behavioral steering compressed into one compact verb.,Hidden-state Evaluation for Editing and Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -11,sentiment,sentiment.tools,https://sentiment.tools,feeling/psychology,"Immediately legible as affect, evaluation, and model measurement.",Subspace Editing of Neural Traits through Interpretable Manifold Evaluation and Neural Tracking,available standard live registrar,9.78,29.35,no,2026-08-27 -12,dreamy,dreamy.tools,https://dreamy.tools,sleep/dream,"Soft, stateful, and close to the tone that made Drowse work.","Directional Representation Editing and Manifold Analysis, Yield-aware",available standard live registrar,9.78,29.35,no,2026-08-27 -13,attitude,attitude.tools,https://attitude.tools,feeling/psychology,Both a mental stance and an orientation in space.,"Activation Traits Traced through Interpretable Tuning, Understanding, Direction, and Editing",available standard live registrar,9.78,29.35,no,2026-08-27 -14,binding,binding.tools,https://binding.tools,cognitive science,A cognitive-science problem and a literal operation on representations.,Basis Interpretation for Neural Direction Injection and Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -15,anchoring,anchoring.tools,https://anchoring.tools,cognitive science,A cognitive bias and a geometric control metaphor.,Activation Navigation and Concept Hidden-state Observation for Representation Injection and Neural Guidance,available standard live registrar,9.78,29.35,no,2026-08-27 -16,polarity,polarity.tools,https://polarity.tools,steering/control,"Fits bipolar concepts, activation axes, and emotional valence.","Probing Output Layers for Activation Representation Interpretation, Tuning, and Yield",available standard live registrar,9.78,29.35,no,2026-08-27 -17,mellow,mellow.tools,https://mellow.tools,sleep/dream,Friendly affective tone with an implicit modulation metaphor.,Manifold Editing with Layerwise Lenses for Output Watching,available standard live registrar,9.78,29.35,no,2026-08-27 -18,slumber,slumber.tools,https://slumber.tools,sleep/dream,"Drowse-adjacent, substantial, and easy to remember.","Subspace Lenses for Understanding Model Behavior, Editing, and Readout",available standard live registrar,9.78,29.35,no,2026-08-27 -19,emergence,emergence.tools,https://emergence.tools,cognitive science,Names the phenomenon interpretability tries to make legible.,"Editing Model Embeddings for Representation Geometry, Evaluation, Neural Control, and Explainability",available standard live registrar,9.78,29.35,no,2026-08-27 -20,enaction,enaction.tools,https://enaction.tools,cognitive science,A real cognitive-science term connecting cognition and action.,"Editing Neural Activations for Concept Tuning, Interpretation, Output Navigation",available standard live registrar,9.78,29.35,no,2026-08-27 -21,feeling,feeling.tools,https://feeling.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Features Editing Embeddings Layerwise Interpretation Neural Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -22,spirit,spirit.tools,https://spirit.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Steering Probing Interpretation Readout Injection Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -23,meaning,meaning.tools,https://meaning.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Manifolds Editing Activation Neural Interpretation Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -24,conscience,conscience.tools,https://conscience.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Concepts Observation Neural Steering Cognition Interpretation Editing Navigation Control Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -25,silence,silence.tools,https://silence.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Steering Interpretation Layerwise Editing Neural Concepts Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -26,awaken,awaken.tools,https://awaken.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Activation Workspace Analysis Kernels Editing Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -27,rouse,rouse.tools,https://rouse.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Readout Observation Unified Steering Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -28,rudder,rudder.tools,https://rudder.tools,steering/control,A natural metaphor for directional control and activation shaping.,Readout Unified Direction Detection Editing Representation,available standard live registrar,9.78,29.35,no,2026-08-27 -29,incline,incline.tools,https://incline.tools,steering/control,A natural metaphor for directional control and activation shaping.,Interpretation Neural Concepts Layerwise Injection Navigation Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -30,heading,heading.tools,https://heading.tools,steering/control,A natural metaphor for directional control and activation shaping.,Hidden-states Editing Activation Direction Interpretation Neural Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -31,approach,approach.tools,https://approach.tools,steering/control,A natural metaphor for directional control and activation shaping.,Activation Probing Projection Readout Observation Analysis Concepts Hidden-states,available standard live registrar,9.78,29.35,no,2026-08-27 -32,direction,direction.tools,https://direction.tools,steering/control,A natural metaphor for directional control and activation shaping.,Direction Interpretation Readout Editing Concepts Traits Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -33,calibrate,calibrate.tools,https://calibrate.tools,steering/control,A natural metaphor for directional control and activation shaping.,Concepts Activation Layerwise Interpretation Behavior Readout Analysis Traits Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -34,regulate,regulate.tools,https://regulate.tools,steering/control,A natural metaphor for directional control and activation shaping.,Readout Editing Geometry Unified Layerwise Activation Traits Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -35,modulate,modulate.tools,https://modulate.tools,steering/control,A natural metaphor for directional control and activation shaping.,Manifolds Observation Direction Unified Layerwise Activation Traits Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -36,smooth,smooth.tools,https://smooth.tools,steering/control,A natural metaphor for directional control and activation shaping.,Steering Manifolds Observation Output Traits Hidden-states,available standard live registrar,9.78,29.35,no,2026-08-27 -37,poised,poised.tools,https://poised.tools,steering/control,A natural metaphor for directional control and activation shaping.,Probing Observation Interpretation Steering Editing Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -38,centered,centered.tools,https://centered.tools,steering/control,A natural metaphor for directional control and activation shaping.,Concepts Editing Neural Traits Embeddings Readout Evaluation Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -39,balanced,balanced.tools,https://balanced.tools,steering/control,A natural metaphor for directional control and activation shaping.,Behavior Activation Layerwise Analysis Neural Concepts Editing Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -40,shaped,shaped.tools,https://shaped.tools,steering/control,A natural metaphor for directional control and activation shaping.,Steering Hidden-states Activation Probing Editing Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -41,angled,angled.tools,https://angled.tools,steering/control,A natural metaphor for directional control and activation shaping.,Activation Neural Geometry Layerwise Editing Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -42,slanted,slanted.tools,https://slanted.tools,steering/control,A natural metaphor for directional control and activation shaping.,Steering Layerwise Activation Neural Traits Editing Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -43,drawn,drawn.tools,https://drawn.tools,steering/control,A natural metaphor for directional control and activation shaping.,Direction Readout Activation Workspace Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -44,belief,belief.tools,https://belief.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Behavior Editing Layerwise Interpretation Embeddings Features,available standard live registrar,9.78,29.35,no,2026-08-27 -45,fear,fear.tools,https://fear.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Features Editing Activation Readout,available standard live registrar,9.78,29.35,no,2026-08-27 -46,doubt,doubt.tools,https://doubt.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Direction Observation Unified Behavior Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -47,anger,anger.tools,https://anger.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Neural Geometry Editing Readout,available standard live registrar,9.78,29.35,no,2026-08-27 -48,excitement,excitement.tools,https://excitement.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Editing eXplainability Concepts Interpretation Traits Embeddings Manifolds Evaluation Neural Tokens,available standard live registrar,9.78,29.35,no,2026-08-27 -49,affection,affection.tools,https://affection.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Features Fitting Editing Concepts Traits Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -50,gentle,gentle.tools,https://gentle.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Geometry Editing Neural Traits Layerwise Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -51,anxious,anxious.tools,https://anxious.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Neural eXplainability Interpretation Observation Unified Steering,available standard live registrar,9.78,29.35,no,2026-08-27 -52,illusion,illusion.tools,https://illusion.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Layerwise Latents Unified Steering Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -53,confidence,confidence.tools,https://confidence.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Concepts Observation Neural Features Interpretation Direction Editing Navigation Cognition Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -54,eager,eager.tools,https://eager.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Editing Activation Geometry Embeddings Readout,available standard live registrar,9.78,29.35,no,2026-08-27 -55,aspect,aspect.tools,https://aspect.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Steering Probing Editing Concepts Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -56,discernment,discernment.tools,https://discernment.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Direction Interpretation Steering Concepts Editing Readout Neural Manifolds Embeddings Navigation Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -57,examine,examine.tools,https://examine.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Activation Manifolds Interpretation Neural Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -58,determine,determine.tools,https://determine.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Direction Editing Traits Embeddings Readout Manifolds Interpretation Neural Evaluation,available standard live registrar,9.78,29.35,no,2026-08-27 -59,consider,consider.tools,https://consider.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Neural Steering Interpretation Direction Editing Readout,available standard live registrar,9.78,29.35,no,2026-08-27 -60,expression,expression.tools,https://expression.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Probing Readout Embeddings Steering Subspaces Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -61,effort,effort.tools,https://effort.tools,steering/control,A natural metaphor for directional control and activation shaping.,Editing Features Fitting Observation Readout Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -62,ethos,ethos.tools,https://ethos.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing Traits Hidden-states Observation Steering,available standard live registrar,9.78,29.35,no,2026-08-27 -63,cluster,cluster.tools,https://cluster.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Concepts Layerwise Unified Steering Traits Editing Readout,available standard live registrar,9.78,29.35,no,2026-08-27 -64,density,density.tools,https://density.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Direction Editing Neural Steering Interpretation Traits Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -65,fraction,fraction.tools,https://fraction.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Features Readout Activation Concepts Traits Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -66,dimension,dimension.tools,https://dimension.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Direction Interpretation Manifolds Editing Neural Steering Injection Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -67,fall,fall.tools,https://fall.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Features Activation Layerwise Latents,available standard live registrar,9.78,29.35,no,2026-08-27 -68,carry,carry.tools,https://carry.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Concepts Activation Readout Representation Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -69,lift,lift.tools,https://lift.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Layerwise Interpretation Features Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -70,alive,alive.tools,https://alive.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Layerwise Interpretation Vectors Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -71,bent,bent.tools,https://bent.tools,steering/control,A natural metaphor for directional control and activation shaping.,Behavior Editing Neural Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -72,pole,pole.tools,https://pole.tools,steering/control,A natural metaphor for directional control and activation shaping.,Probing Observation Layerwise Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -73,alone,alone.tools,https://alone.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Layerwise Observation Neural Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -74,darkness,darkness.tools,https://darkness.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Direction Activation Readout Kernels Neural Editing Steering Subspaces,available standard live registrar,9.78,29.35,no,2026-08-27 -75,asleep,asleep.tools,https://asleep.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Activation Steering Layerwise Editing Embeddings Probing,available standard live registrar,9.78,29.35,no,2026-08-27 -76,creep,creep.tools,https://creep.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Concepts Readout Editing Embeddings Probing,available standard live registrar,9.78,29.35,no,2026-08-27 -77,forget,forget.tools,https://forget.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Features Observation Readout Geometry Editing Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -78,chunking,chunking.tools,https://chunking.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Hidden-states Unified Neural Kernels Interpretation Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -79,conditioning,conditioning.tools,https://conditioning.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Neural Direction Interpretation Traits Injection Output Navigation Inference Nodes Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -80,auditory,auditory.tools,https://auditory.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Unified Direction Interpretation Traits Observation Readout Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -81,computational,computational.tools,https://computational.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Manifolds Probing Unified Traits Activation Tokens Interpretation Output Neural Analysis Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -82,connectionist,connectionist.tools,https://connectionist.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Neural Navigation Editing Cognition Traits Interpretation Output Nodes Injection Steering Tokens,available standard live registrar,9.78,29.35,no,2026-08-27 -83,bayesian,bayesian.tools,https://bayesian.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Behavior Activation Yield-aware Editing Steering Interpretation Analysis Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -84,avoidance,avoidance.tools,https://avoidance.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Vectors Observation Interpretation Direction Analysis Neural Concepts Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -85,absorption,absorption.tools,https://absorption.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Behavior Steering Observation Readout Probing Traits Interpretation Output Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -86,boredom,boredom.tools,https://boredom.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Behavior Observation Readout Editing Direction Output Manifolds,available standard live registrar,9.78,29.35,no,2026-08-27 -87,choices,choices.tools,https://choices.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Hidden-states Observation Interpretation Cognition Editing Steering,available standard live registrar,9.78,29.35,no,2026-08-27 -88,associative,associative.tools,https://associative.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Steering Subspaces Observation Concepts Interpretation Analysis Traits Injection Vectors Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -89,attentional,attentional.tools,https://attentional.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Traits Tokens Editing Neural Tuning Interpretation Observation Navigation Analysis Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -90,affective,affective.tools,https://affective.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Features Fitting Editing Concepts Traits Interpretation Vectors Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -91,confabulation,confabulation.tools,https://confabulation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Neural Features Activation Behavior Unified Layerwise Analysis Traits Interpretation Output Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -92,categorization,categorization.tools,https://categorization.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Activation Traits Editing Geometry Observation Readout Interpretation Zero-shot Analysis Tokens Injection Output Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -93,adaptation,adaptation.tools,https://adaptation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Direction Analysis Probing Traits Affect Tokens Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -94,aftereffect,aftereffect.tools,https://aftereffect.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Features Traits Editing Readout Embeddings Fitting Frames Evaluation Concepts Tokens,available standard live registrar,9.78,29.35,no,2026-08-27 -95,closure,closure.tools,https://closure.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Layerwise Observation Steering Unified Readout Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -96,calmness,calmness.tools,https://calmness.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Concepts Activation Layerwise Manifolds Neural Editing Steering Subspaces,available standard live registrar,9.78,29.35,no,2026-08-27 -97,dread,dread.tools,https://dread.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Direction Readout Editing Activation Detection,available standard live registrar,9.78,29.35,no,2026-08-27 -98,comfort,comfort.tools,https://comfort.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Concepts Observation Manifolds Features Output Readout Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -99,fascination,fascination.tools,https://fascination.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Features Activation Steering Concepts Interpretation Neural Analysis Traits Injection Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -100,attentive,attentive.tools,https://attentive.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Traits Tokens Editing Neural Tuning Interpretation Vectors Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -101,behavioral,behavioral.tools,https://behavioral.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Behavior Editing Hidden-states Activation Vectors Interpretation Observation Readout Analysis Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -102,experiential,experiential.tools,https://experiential.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Probing Embeddings Readout Interpretation Evaluation Neural Traits Injection Activation Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -103,expressive,expressive.tools,https://expressive.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Probing Readout Embeddings Steering Subspaces Interpretation Vectors Evaluation,available standard live registrar,9.78,29.35,no,2026-08-27 -104,directional,directional.tools,https://directional.tools,steering/control,A natural metaphor for directional control and activation shaping.,Direction Interpretation Readout Editing Concepts Traits Injection Observation Neural Activation Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -105,controllable,controllable.tools,https://controllable.tools,steering/control,A natural metaphor for directional control and activation shaping.,Concepts Observation Neural Traits Readout Output Layerwise Latents Activation Behavior Lenses Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -106,explainable,explainable.tools,https://explainable.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Editing eXplainability Probing Layerwise Activation Interpretation Neural Analysis Behavior Latents Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -107,coherent,coherent.tools,https://coherent.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Concepts Observation Hidden-states Editing Readout Embeddings Neural Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -108,calibrated,calibrated.tools,https://calibrated.tools,steering/control,A natural metaphor for directional control and activation shaping.,Concepts Activation Layerwise Interpretation Behavior Readout Analysis Traits Editing Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -109,dreaming,dreaming.tools,https://dreaming.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Direction Readout Editing Activation Manifolds Interpretation Neural Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -110,aligning,aligning.tools,https://aligning.tools,steering/control,A natural metaphor for directional control and activation shaping.,Activation Layerwise Interpretation Geometry Neural Injection Navigation Guidance,available standard live registrar,9.78,29.35,no,2026-08-27 -111,attending,attending.tools,https://attending.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Traits Tokens Editing Neural Direction Interpretation Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -112,interoception,interoception.tools,https://interoception.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Neural Traits Editing Readout Observation Concepts Embeddings Probing Tokens Injection Output Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -113,inhibition,inhibition.tools,https://inhibition.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Neural Hidden-states Injection Behavior Inference Traits Instruments Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -114,excitation,excitation.tools,https://excitation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Concepts Interpretation Traits Activation Tokens Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -115,habituation,habituation.tools,https://habituation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Hidden-states Activation Behavior Interpretation Traits Unified Analysis Tokens Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -116,interference,interference.tools,https://interference.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Neural Traits Editing Readout Features Embeddings Representation Evaluation Navigation Concepts Explainability,available standard live registrar,9.78,29.35,no,2026-08-27 -117,discrimination,discrimination.tools,https://discrimination.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Direction Interpretation Steering Concepts Readout Injection Manifolds Inference Neural Activation Traits Instruments Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -118,generalization,generalization.tools,https://generalization.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Geometry Editing Neural Embeddings Readout Activation Layerwise Interpretation Zero-shot Analysis Traits Injection Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -119,feedforward,feedforward.tools,https://feedforward.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Features Editing Embeddings Direction Fitting Observation Readout Workspace Activation Representation Detection,available standard live registrar,9.78,29.35,no,2026-08-27 -120,computation,computation.tools,https://computation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Manifolds Probing Unified Traits Activation Tokens Interpretation Output Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -121,categorizing,categorizing.tools,https://categorizing.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Activation Traits Editing Geometry Observation Readout Interpretation Zero-shot Injection Neural Guidance,available standard live registrar,9.78,29.35,no,2026-08-27 -122,expectation,expectation.tools,https://expectation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Probing Embeddings Concepts Traits Activation Tokens Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -123,exploitation,exploitation.tools,https://exploitation.tools,steering/control,A natural metaphor for directional control and activation shaping.,Editing eXplainability Probing Layerwise Observation Interpretation Traits Activation Tokens Injection Output Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -124,metacognitive,metacognitive.tools,https://metacognitive.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Manifolds Editing Traits Activation Concepts Observation Geometry Neural Interpretation Tokens Injection Vectors Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -125,episodic,episodic.tools,https://episodic.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing Probing Interpretation Steering Observation Direction Injection Concepts,available standard live registrar,9.78,29.35,no,2026-08-27 -126,explicit,explicit.tools,https://explicit.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Probing Layerwise Interpretation Concepts Injection Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -127,excitatory,excitatory.tools,https://excitatory.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Concepts Interpretation Traits Activation Tokens Observation Readout Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -128,bottomup,bottomup.tools,https://bottomup.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Behavior Observation Traits Tokens Output Manifolds Unified Probing,available standard live registrar,9.78,29.35,no,2026-08-27 -129,allostasis,allostasis.tools,https://allostasis.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Layerwise Latents Observation Steering Traits Analysis Subspaces Interpretation Signals,available standard live registrar,9.78,29.35,no,2026-08-27 -130,dominance,dominance.tools,https://dominance.tools,steering/control,A natural metaphor for directional control and activation shaping.,Direction Observation Manifolds Interpretation Neural Activation Navigation Concepts Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -131,ecological,ecological.tools,https://ecological.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing Concepts Observation Layerwise Output Geometry Interpretation Cognition Activation Latents,available standard live registrar,9.78,29.35,no,2026-08-27 -132,constructivism,constructivism.tools,https://constructivism.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Neural Steering Traits Readout Unified Cognition Tokens Interpretation Vectors Injection Subspaces Manifolds,available standard live registrar,9.78,29.35,no,2026-08-27 -133,behaviorism,behaviorism.tools,https://behaviorism.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Behavior Editing Hidden-states Activation Vectors Interpretation Observation Readout Injection Steering Manifolds,available standard live registrar,9.78,29.35,no,2026-08-27 -134,cognitivism,cognitivism.tools,https://cognitivism.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Geometry Neural Interpretation Traits Injection Vectors Inference Steering Manifolds,available standard live registrar,9.78,29.35,no,2026-08-27 -135,functionalism,functionalism.tools,https://functionalism.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Features Unified Neural Concepts Traits Interpretation Observation Navigation Activation Layerwise Injection Steering Manifolds,available standard live registrar,9.78,29.35,no,2026-08-27 -136,awareness,awareness.design,https://awareness.design,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Workspace Analysis Readout Editing Neural Embeddings Steering Subspaces,available standard live registrar,10.81,46.86,no,2026-08-27 -137,reason,reason.wiki,https://reason.wiki,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Readout Editing Activation Steering Observation Neural,available standard live registrar,2.06,26.26,no,2026-08-27 -138,mood,mood.science,https://mood.science,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Manifolds Observation Output Direction,available standard live registrar,10.79,10.79,no,2026-08-27 -139,attention,attention.software,https://attention.software,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Traits Tokens Editing Neural Tuning Interpretation Observation Navigation,available standard live registrar,15.96,33.47,no,2026-08-27 -140,apprehension,apprehension.tools,https://apprehension.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Probing Projection Readout Editing Hidden-states Embeddings Neural Steering Interpretation Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -141,association,association.tools,https://association.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Steering Subspaces Observation Concepts Interpretation Analysis Traits Injection Output Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -142,cognizance,cognizance.tools,https://cognizance.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Geometry Neural Interpretation Zero-shot Activation Navigation Cognition Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -143,argument,argument.tools,https://argument.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Readout Geometry Unified Manifolds Editing Neural Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -144,appearance,appearance.tools,https://appearance.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Probing Projection Editing Analysis Readout Affect Neural Concepts Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -145,chunk,chunk.tools,https://chunk.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Hidden-states Unified Neural Kernels,available standard live registrar,9.78,29.35,no,2026-08-27 -146,assumption,assumption.tools,https://assumption.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Steering Subspaces Unified Manifolds Probing Traits Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -147,believing,believing.tools,https://believing.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Behavior Editing Layerwise Interpretation Embeddings Vectors Injection Neural Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -148,assertion,assertion.tools,https://assertion.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Steering Subspaces Editing Readout Traits Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -149,accommodation,accommodation.tools,https://accommodation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Concepts Cognition Observation Manifolds Monitoring Output Direction Analysis Traits Interpretation Orthogonalization Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -150,acting,acting.tools,https://acting.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Concepts Traits Interpretation Neural Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -151,caring,caring.tools,https://caring.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Concepts Activation Readout Interpretation Neural Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -152,acquaintance,acquaintance.tools,https://acquaintance.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Concepts Quantitative Unified Analysis Interpretation Neural Traits Affect Navigation Cognition Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -153,imagining,imagining.tools,https://imagining.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Manifolds Activation Geometry Injection Neural Inference Navigation Guidance,available standard live registrar,9.78,29.35,no,2026-08-27 -154,portrayal,portrayal.tools,https://portrayal.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Probing Observation Readout Traits Representation Activation Yield-aware Analysis Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -155,aptitude,aptitude.tools,https://aptitude.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Probing Traits Interpretation Tokens Unified Direction Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -156,fallacy,fallacy.tools,https://fallacy.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Features Activation Layerwise Latents Analysis Concepts Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -157,argumentation,argumentation.tools,https://argumentation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Readout Geometry Unified Manifolds Editing Neural Traits Analysis Tokens Interpretation Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -158,extrapolation,extrapolation.tools,https://extrapolation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing eXplainability Traits Readout Activation Probing Observation Layerwise Analysis Tokens Interpretation Output Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -159,envisage,envisage.tools,https://envisage.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Editing Neural Vectors Interpretation Steering Activation Geometry Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -160,alertness,alertness.tools,https://alertness.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Layerwise Editing Readout Traits Neural Embeddings Steering Subspaces,available standard live registrar,9.78,29.35,no,2026-08-27 -161,description,description.tools,https://description.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Direction Editing Steering Concepts Readout Interpretation Probing Traits Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -162,anima,anima.tools,https://anima.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Neural Interpretation Manifolds Analysis,available standard live registrar,9.78,29.35,no,2026-08-27 -163,hallucination,hallucination.tools,https://hallucination.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Hidden-states Activation Layerwise Latents Unified Concepts Interpretation Neural Analysis Traits Injection Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -164,inferring,inferring.tools,https://inferring.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Neural Features Editing Readout Representation Injection Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -165,animus,animus.tools,https://animus.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Neural Interpretation Manifolds Unified Steering,available standard live registrar,9.78,29.35,no,2026-08-27 -166,counsel,counsel.tools,https://counsel.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Unified Neural Steering Editing Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -167,interpreting,interpreting.tools,https://interpreting.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Interpretation Neural Traits Editing Readout Probing Representation Embeddings Tokens Injection Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -168,guiding,guiding.tools,https://guiding.tools,steering/control,A natural metaphor for directional control and activation shaping.,Geometry Unified Interpretation Direction Injection Neural Guidance,available standard live registrar,9.78,29.35,no,2026-08-27 -169,ascertain,ascertain.tools,https://ascertain.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Steering Concepts Editing Readout Traits Analysis Interpretation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -170,emphasis,emphasis.tools,https://emphasis.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Editing Manifolds Probing Hidden-states Activation Steering Interpretation Subspaces,available standard live registrar,9.78,29.35,no,2026-08-27 -171,composition,composition.tools,https://composition.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Concepts Observation Manifolds Probing Output Steering Interpretation Traits Injection Orthogonalization Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -172,careful,careful.tools,https://careful.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Concepts Activation Readout Editing Features Unified Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -173,representation,representation.tools,https://representation.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Readout Editing Probing Representation Embeddings Steering Evaluation Neural Traits Activation Tokens Interpretation Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -174,yearning,yearning.tools,https://yearning.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Yield-aware Editing Activation Readout Neural Interpretation Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -175,sensory,sensory.tools,https://sensory.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Steering Editing Neural Subspaces Observation Readout Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -176,reinforcement,reinforcement.tools,https://reinforcement.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Readout Editing Interpretation Neural Features Observation Representation Concepts Embeddings Manifolds Evaluation Navigation Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -177,retrieval,retrieval.tools,https://retrieval.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Readout Editing Traits Representation Interpretation Embeddings Vectors Activation Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 -178,reflective,reflective.tools,https://reflective.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Readout Editing Features Layerwise Embeddings Concepts Traits Interpretation Vectors Evaluation,available standard live registrar,9.78,29.35,no,2026-08-27 -179,brightness,brightness.tools,https://brightness.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Behavior Readout Interpretation Geometry Hidden-states Traits Neural Editing Steering Subspaces,available standard live registrar,9.78,29.35,no,2026-08-27 -180,anguish,anguish.tools,https://anguish.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Neural Geometry Unified Interpretation Steering Hidden-states,available standard live registrar,9.78,29.35,no,2026-08-27 -181,agony,agony.tools,https://agony.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Geometry Observation Neural Yield-aware,available standard live registrar,9.78,29.35,no,2026-08-27 -182,astonishment,astonishment.tools,https://astonishment.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Steering Traits Observation Neural Interpretation Subspaces Hidden-states Manifolds Editing Navigation Tokens,available standard live registrar,9.78,29.35,no,2026-08-27 -183,arouse,arouse.tools,https://arouse.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Readout Observation Unified Steering Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -184,aversion,aversion.tools,https://aversion.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Vectors Editing Readout Steering Interpretation Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -185,adrift,adrift.tools,https://adrift.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Direction Readout Interpretation Features Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -186,angst,angst.tools,https://angst.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Neural Geometry Steering Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -187,acquisition,acquisition.tools,https://acquisition.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Activation Concepts Quantitative Unified Interpretation Steering Injection Traits Inference Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -188,ambition,ambition.tools,https://ambition.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Manifolds Behavior Interpretation Traits Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -189,aspiration,aspiration.tools,https://aspiration.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Activation Steering Probing Interpretation Readout Analysis Traits Injection Observation Neural,available standard live registrar,9.78,29.35,no,2026-08-27 -190,agreement,agreement.tools,https://agreement.tools,mechanistic interpretability,"Maps naturally to representations, probes, geometry, or model readout.",Activation Geometry Readout Editing Embeddings Manifolds Evaluation Neural Traits,available standard live registrar,9.78,29.35,no,2026-08-27 -191,definition,definition.tools,https://definition.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Direction Editing Features Interpretation Neural Injection Traits Inference Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -192,adjustment,adjustment.tools,https://adjustment.tools,steering/control,A natural metaphor for directional control and activation shaping.,Activation Direction Jacobian Unified Steering Traits Manifolds Editing Neural Tokens,available standard live registrar,9.78,29.35,no,2026-08-27 -193,sensitization,sensitization.tools,https://sensitization.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Steering Editing Neural Subspaces Interpretation Traits Injection Zero-shot Activation Tokens Inference Observation Navigation,available standard live registrar,9.78,29.35,no,2026-08-27 -194,bound,bound.tools,https://bound.tools,steering/control,A natural metaphor for directional control and activation shaping.,Behavior Observation Unified Neural Direction,available standard live registrar,9.78,29.35,no,2026-08-27 -195,considering,considering.tools,https://considering.tools,cognitive science,A recognized cognitive-science or psychology term with a direct product connection.,Concepts Observation Neural Steering Interpretation Direction Editing Readout Injection Navigation Geometry,available standard live registrar,9.78,29.35,no,2026-08-27 -196,ownership,ownership.tools,https://ownership.tools,steering/control,A natural metaphor for directional control and activation shaping.,Observation Workspace Neural Editing Readout Steering Hidden-states Interpretation Probing,available standard live registrar,9.78,29.35,no,2026-08-27 -197,daydream,daydream.tools,https://daydream.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Direction Activation Yield-aware Detection Readout Editing Analysis Manifolds,available standard live registrar,9.78,29.35,no,2026-08-27 -198,dreamlike,dreamlike.tools,https://dreamlike.tools,sleep/dream,Drowse-adjacent language for liminal cognition and model state.,Direction Readout Editing Activation Manifolds Layerwise Interpretation Kernels Embeddings,available standard live registrar,9.78,29.35,no,2026-08-27 -199,assure,assure.tools,https://assure.tools,steering/control,A natural metaphor for directional control and activation shaping.,Activation Steering Subspaces Unified Readout Editing,available standard live registrar,9.78,29.35,no,2026-08-27 -200,bashful,bashful.tools,https://bashful.tools,feeling/psychology,"A familiar human term for affect, stance, or inner state.",Behavior Activation Steering Hidden-states Features Unified Layerwise,available standard live registrar,9.78,29.35,no,2026-08-27 diff --git a/domain-name-candidates.csv b/domain-name-candidates.csv deleted file mode 100644 index b55879a0..00000000 --- a/domain-name-candidates.csv +++ /dev/null @@ -1,201 +0,0 @@ -rank,name,domain,url,theme,meaning,backronym,status,annual_usd,initial_years,initial_checkout_usd,renewal_usd,com_status,checked_at -1,monody,monody.ai,https://monody.ai,sound,A composition having a single melodic line.,"Manifold Observation for Neural Output Direction, Yield-aware",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -2,dimity,dimity.ai,https://dimity.ai,craft,A light strong fabric with woven stripes or squares.,Directional Interpretation and Manifold Injection for Trait Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -3,brayer,brayer.ai,https://brayer.ai,language,"A hand printing tool, in the US often a roller, used to spread a thin even layer of ink. Earl...",Behavior Readout and Analysis for Yield-aware Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -4,pavane,pavane.ai,https://pavane.ai,sound,"A moderately slow, courtly processional dance in duple time/meter.",Probe Analysis of Vector Activations in Neural Embeddings,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -5,rundel,rundel.ai,https://rundel.ai,water,A small stream; a runlet.,"Representation Understanding and Neural Direction Editing, Layerwise",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -6,cleome,cleome.ai,https://cleome.ai,flora,Any flowering plant in the genus Cleome.,"Concept-Layer Exploration, Observation, Monitoring, and Editing",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -7,hyssop,hyssop.ai,https://hyssop.ai,flora,"Any of several aromatic bushy herbs, of the genus Hyssopus, native to Southern Europe and onc...","Hidden-state Yield, Subspace Steering, Observation, and Probing",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -8,joyance,joyance.ai,https://joyance.ai,feeling,"Enjoyment, joy, delight.","Jacobian Observation for Yield-aware Activation, Neural Control, and Editing",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -9,fernery,fernery.ai,https://fernery.ai,land,A specialized garden for the cultivation and display of ferns.,"Feature Exploration and Readout for Neural Embedding Representation, Yield-aware",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -10,borage,borage.ai,https://borage.ai,flora,"Borago officinalis, a Mediterranean plant with rough, cucumber-flavored leaves and stems, use...",Behavior Observation and Representation Analysis for Guided Editing,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -11,spathe,spathe.ai,https://spathe.ai,flora,"A large bract that envelops or subtends a whole inflorescence, typically a spadix.",Subspace Probing and Trait Hidden-state Editing,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -12,doline,doline.ai,https://doline.ai,land,"A depression (basin, hollow) in karstic terrain/limestone.",Directional Observation of Latent Inference in Neural Embeddings,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -13,argali,argali.ai,https://argali.ai,land,"Ovis ammon, the largest wild sheep, which roams the highlands of Central Asia.",Activation Representation Geometry for Adaptive Language Intervention,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -14,visile,visile.ai,https://visile.ai,mind,Someone whose mental imagery consists of pictures.,Vector Interpretation of Subspaces in Layerwise Embeddings,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -15,muskeg,muskeg.ai,https://muskeg.ai,flora,A terrain composed of peat bog with tussocky meadow and woody vegetation including spruce.,"Manifold Understanding, Steering, Kernel Exploration, and Geometry",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -16,digram,digram.ai,https://digram.ai,language,A digraph (combination of two letters),Directional Interpretability and Geometry for Representation-Aware Models,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -17,smilax,smilax.ai,https://smilax.ai,flora,Any member of the Smilax genus of greenbriers.,Subspace Monitoring and Injection for Layerwise Activation eXploration,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -18,dittany,dittany.ai,https://dittany.ai,flora,"A labiate plant of species Origanum dictamnus, formerly renowned for its medicinal properties...",Directional Interpretability for Trait Tuning and Neural Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -19,odonate,odonate.ai,https://odonate.ai,fauna,Any carnivorous insect of the order Odonata; a dragonfly or damselfly.,"Observation-Driven Output Navigation for Activation, Trait, and Embedding",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -20,albite,albite.ai,https://albite.ai,earth,"A plagioclase feldspar, the first member of the Albite-Anorthite solid solution series.","Activation-Layer Basis for Interpretability, Traits, and Editing",available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -21,illite,illite.ai,https://illite.ai,earth,A micaceous phyllosilicate clay mineral with aggregates of grey or white monoclinic crystals.,Interpretability Layer Layer Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -22,augite,augite.ai,https://augite.ai,earth,"A variety of pyroxene, usually of a black or dark green color, occurring in igneous rocks, su...",Activation Unified Geometry Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -23,barite,barite.ai,https://barite.ai,earth,"A mineral, barium sulphate, with the chemical formula BaSO₄.",Behavior Activation Representation Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -24,raffia,raffia.ai,https://raffia.ai,craft,"A fibrous material used for tying plants, originating from the leaves of raffia palm trees (g...",Representation Activation Feature Feature Interpretability Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -25,dunite,dunite.ai,https://dunite.ai,earth,A type of igneous rock with a coarse-grained or phaneritic texture.,Direction Unified Neural Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -26,tenter,tenter.ai,https://tenter.ai,geometry,A framework upon which cloth is stretched and dried.,Trait Embedding Neural Trait Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -27,coteau,coteau.ai,https://coteau.ai,land,A hilly upland including the divide between two valleys.,Concept Observation Trait Embedding Activation Unified,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -28,blenny,blenny.ai,https://blenny.ai,fauna,"A true blenny, any of various marine fishes from the suborder Blennioidei or order Blenniifor...",Behavior Layer Embedding Neural Neural Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -29,aucuba,aucuba.ai,https://aucuba.ai,flora,Any of several decorative evergreen shrubs of the genus Aucuba.,Activation Unified Concept Unified Behavior Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -30,hypnum,hypnum.ai,https://hypnum.ai,flora,Any member of the genus Hypnum of mosses.,Hidden-state Yield Probe Neural Unified Manifold,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -31,boronia,boronia.ai,https://boronia.ai,flora,"Any of several aromatic herbs, of the genus Boronia, used in perfumery.",Behavior Observation Representation Observation Neural Interpretability Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -32,kainite,kainite.ai,https://kainite.ai,earth,"An evaporite, consisting of magnesium sulphate and potassium chloride with the chemical formu...",Kernel Activation Interpretability Neural Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -33,goyle,goyle.ai,https://goyle.ai,land,A ravine or other depression.,Geometry Observation Yield Layer Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -34,amadou,amadou.ai,https://amadou.ai,flora,"A spongy, flammable substance prepared from bracket fungi, formerly used as a styptic and as...",Activation Manifold Activation Direction Observation Unified,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -35,byssus,byssus.ai,https://byssus.ai,flora,The long fine silky filaments excreted by several mollusks (particularly Pinna nobilis) by wh...,Behavior Yield Steering Steering Unified Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -36,crewel,crewel.ai,https://crewel.ai,craft,"Worsted yarn, slackly twisted, used for embroidery.",Concept Representation Embedding Workbench Embedding Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -37,achene,achene.ai,https://achene.ai,flora,"A small, dry, indehiscent fruit, containing a single seed, as in the buttercup.",Activation Concept Hidden-state Embedding Neural Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -38,chital,chital.ai,https://chital.ai,geometry,"a large spotted deer, of genus Axis, native to India and Sri Lanka",Concept Hidden-state Interpretability Trait Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -39,tusche,tusche.ai,https://tusche.ai,language,A black liquid used in lithography for drawing and painting and in etching and the silk-scree...,Trait Unified Steering Concept Hidden-state Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -40,peahen,peahen.ai,https://peahen.ai,fauna,A female peafowl.,Probe Embedding Activation Hidden-state Embedding Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -41,fragor,fragor.ai,https://fragor.ai,light,A loud and sudden sound; the report of anything bursting; a crash.,Feature Representation Activation Geometry Observation Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -42,deutzia,deutzia.ai,https://deutzia.ai,flora,"Any of a group of cultivated shrubs, of the genus Deutzia, having white or pink flowers",Direction Embedding Unified Trait Zeroing Interpretability Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -43,pocosin,pocosin.ai,https://pocosin.ai,land,"A low, wooded swamp in (especially coastal) Eastern Maryland, Virginia or the Carolinas; a pa...",Probe Observation Concept Observation Steering Interpretability Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -44,marais,marais.ai,https://marais.ai,land,"A marsh; a marshy area, one intermittently covered with water, particularly in Louisiana, or...",Manifold Activation Representation Activation Interpretability Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -45,ligure,ligure.ai,https://ligure.ai,earth,"A gemstone, supposed to have been a form of agate",Layer Interpretability Geometry Unified Representation Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -46,pollan,pollan.ai,https://pollan.ai,water,"A freshwater fish, Coregonus pollan, resembling a herring",Probe Observation Layer Layer Activation Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -47,ratite,ratite.ai,https://ratite.ai,fauna,"A member of a diverse group of mostly large, running, flightless birds that lack keels on the...",Representation Activation Trait Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -48,nullah,nullah.ai,https://nullah.ai,water,"A stream-bed, ravine, or other watercourse; a drain for rain or floodwater.",Neural Unified Layer Layer Activation Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -49,lakelet,lakelet.ai,https://lakelet.ai,water,A small lake.,Layer Activation Kernel Embedding Layer Embedding Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -50,lappet,lappet.ai,https://lappet.ai,fauna,"A small decorative fold or flap, especially of lace or muslin, in a garment or headdress.",Layer Activation Probe Probe Embedding Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -51,coccid,coccid.ai,https://coccid.ai,fauna,Any of very many scale insects (including mealybugs) of the superfamily Coccoidea; especially...,Concept Observation Concept Concept Interpretability Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -52,podzol,podzol.ai,https://podzol.ai,instrument,The typical soil of coniferous or boreal forests.,Probe Observation Direction Zeroing Observation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -53,chlorite,chlorite.ai,https://chlorite.ai,earth,"A dark green mineral resembling serpentine, being a mixed silicate of magnesium, iron and alu...",Concept Hidden-state Layer Observation Representation Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -54,orcinol,orcinol.ai,https://orcinol.ai,signal,"A natural phenolic organic compound that occurs in many species of lichen, used in the produc...",Observation Representation Concept Interpretability Neural Observation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -55,claypan,claypan.ai,https://claypan.ai,sky,A compact stratum of partially permeable material rich in clay.,Concept Layer Activation Yield Probe Activation Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -56,pondage,pondage.ai,https://pondage.ai,water,The water in a reservoir.,Probe Observation Neural Direction Activation Geometry Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -57,mudstone,mudstone.ai,https://mudstone.ai,earth,A fine-grained sedimentary rock whose original constituents were clays or muds.,Manifold Unified Direction Steering Trait Observation Neural Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -58,musicale,musicale.ai,https://musicale.ai,sound,"A musical entertainment, usually private and typically involving classical music",Manifold Unified Steering Interpretability Concept Activation Layer Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -59,orotund,orotund.ai,https://orotund.ai,mind,"Of a voice: characterized by clarity, fullness, smoothness, and strength of sound; hence, of...",Observation Representation Observation Trait Unified Neural Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -60,subword,subword.ai,https://subword.ai,geometry,A portion of a word (fixed-size group of bits).,Steering Unified Behavior Workbench Observation Representation Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -61,anapest,anapest.ai,https://anapest.ai,sound,"In qualitative meter, a metrical foot consisting of three syllables, the first two unstressed...",Activation Neural Activation Probe Embedding Steering Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -62,cubeb,cubeb.ai,https://cubeb.ai,flora,"One of the berries of this plant, used as a condiment.",Concept Unified Behavior Embedding Behavior,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -63,bedeck,bedeck.ai,https://bedeck.ai,feeling,"To deck, ornament, or adorn",Behavior Embedding Direction Embedding Concept Kernel,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -64,herber,herber.ai,https://herber.ai,flora,A garden in which herbs and vegetables are grown; a herbarium,Hidden-state Embedding Representation Behavior Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -65,launce,launce.ai,https://launce.ai,mind,"sand eel, sand lance, fish of the family Ammodytidae",Layer Activation Unified Neural Concept Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -66,chanal,chanal.ai,https://chanal.ai,flora,thorny shrub or small tree common in central argentina having small orange or yellow flowers...,Concept Hidden-state Activation Neural Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -67,curtal,curtal.ai,https://curtal.ai,geometry,An early type of bassoon.,Concept Unified Representation Trait Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -68,irtysh,irtysh.ai,https://irtysh.ai,water,"A major river in Siberia, Russia and Kazakhstan.",Interpretability Representation Trait Yield Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -69,ganoid,ganoid.ai,https://ganoid.ai,fauna,"Having ganoid scales or plates, as a fish; specifically, of or pertaining to the Ganoidei.",Geometry Activation Neural Observation Interpretability Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -70,marish,marish.ai,https://marish.ai,land,A marsh.,Manifold Activation Representation Interpretability Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -71,irtish,irtish.ai,https://irtish.ai,water,an asian river; tributary of the ob river,Interpretability Representation Trait Interpretability Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -72,gadoid,gadoid.ai,https://gadoid.ai,fauna,Any fish of the family Gadidae,Geometry Activation Direction Observation Interpretability Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -73,gabert,gabert.ai,https://gabert.ai,navigation,"A lighter, or vessel for inland navigation.",Geometry Activation Behavior Embedding Representation Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -74,marshy,marshy.ai,https://marshy.ai,land,"Of, or resembling a marsh; boggy.",Manifold Activation Representation Steering Hidden-state Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -75,herbage,herbage.ai,https://herbage.ai,flora,Herbs collectively.,Hidden-state Embedding Representation Behavior Activation Geometry Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -76,dirge,dirge.ai,https://dirge.ai,sound,A mournful poem or piece of music composed or performed as a memorial to a deceased person.,Direction Interpretability Representation Geometry Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -77,huerta,huerta.ai,https://huerta.ai,land,The area of Murcia and Valencia with fertile ground.,Hidden-state Unified Embedding Representation Trait Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -78,nosegay,nosegay.ai,https://nosegay.ai,flora,"A small bunch of fragrant flowers or herbs tied in a bundle, often presented as a gift; noseg...",Neural Observation Steering Embedding Geometry Activation Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -79,ipomoea,ipomoea.ai,https://ipomoea.ai,flora,"Any of various twining plants of the genus Ipomoea with showy monopetalous flowers, including...",Interpretability Probe Observation Manifold Observation Embedding Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -80,ogive,ogive.ai,https://ogive.ai,geometry,The curve of a cumulative distribution function.,Observation Geometry Interpretability Vector Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -81,norther,norther.ai,https://norther.ai,sky,"A strong north wind, a wind blowing from the north.",Neural Observation Representation Trait Hidden-state Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -82,marline,marline.ai,https://marline.ai,sky,"A light all-purpose cord commonly used to bind the end of a larger rope, to prevent fraying.",Manifold Activation Representation Layer Interpretability Neural Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -83,polje,polje.ai,https://polje.ai,geometry,An extensive depression having a flat floor and steep walls but no outflowing surface stream...,Probe Observation Layer Jacobian Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -84,isere,isere.ai,https://isere.ai,water,a river in southeastern france; a tributary of the rhone,Interpretability Steering Embedding Representation Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -85,osmunda,osmunda.ai,https://osmunda.ai,flora,"A fern of the genus Osmunda, especially the royal fern, Osmunda regalis.",Observation Steering Manifold Unified Neural Direction Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -86,moorhen,moorhen.ai,https://moorhen.ai,fauna,"Any of various medium-sized water birds of the genus Gallinula, of the rail family, that feed...",Manifold Observation Observation Representation Hidden-state Embedding Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -87,biphase,biphase.ai,https://biphase.ai,signal,A method of transmitting binary data that avoids problems associated with long strings of one...,Behavior Interpretability Probe Hidden-state Activation Steering Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -88,sylvite,sylvite.ai,https://sylvite.ai,earth,"An evaporite, consisting of potassium chloride KCl, also found in fumaroles.",Steering Yield Layer Vector Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -89,alunite,alunite.ai,https://alunite.ai,earth,"A gray whitish, water-soluble mineral, potassium aluminium sulphate; the natural source of al...",Activation Layer Unified Neural Interpretability Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -90,binodal,binodal.ai,https://binodal.ai,geometry,Having two nodes,Behavior Interpretability Neural Observation Direction Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -91,pluteus,pluteus.ai,https://pluteus.ai,flora,The free-swimming larvae of echinoderms.,Probe Layer Unified Trait Embedding Unified Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -92,amniote,amniote.ai,https://amniote.ai,fauna,Any of the Amniota group of vertebrates having an amnion during the development of the embryo...,Activation Manifold Neural Interpretability Observation Trait Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -93,hemiola,hemiola.ai,https://hemiola.ai,sound,The articulation of two bars in triple time as if they were three bars in duple time.,Hidden-state Embedding Manifold Interpretability Observation Layer Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -94,leeside,leeside.ai,https://leeside.ai,land,"The side of something that provides the most shelter from some prevailing force such as wind,...",Layer Embedding Embedding Steering Interpretability Direction Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -95,amorpha,amorpha.ai,https://amorpha.ai,flora,Any species of the genus Amorpha of leguminous shrubs.,Activation Manifold Observation Representation Probe Hidden-state Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -96,knaur,knaur.ai,https://knaur.ai,geometry,A knot or burl in a tree.,Kernel Neural Activation Unified Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -97,alcidae,alcidae.ai,https://alcidae.ai,fauna,web-footed diving seabirds of northern seas: auks; puffins; guillemots; murres; etc.,Activation Layer Concept Interpretability Direction Activation Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -98,woodsia,woodsia.ai,https://woodsia.ai,flora,Any of the genus Woodsia of ferns.,Workbench Observation Observation Direction Steering Interpretability Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -99,plagal,plagal.ai,https://plagal.ai,sound,Designating a mode lying a perfect fourth below the authentic form.,Probe Layer Activation Geometry Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -100,demoss,demoss.ai,https://demoss.ai,flora,To remove moss from.,Direction Embedding Manifold Observation Steering Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -101,graben,graben.ai,https://graben.ai,land,"An elongated block of the Earth's crust, bounded by faults, that has dropped relative to the...",Geometry Representation Activation Behavior Embedding Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -102,pyrene,pyrene.ai,https://pyrene.ai,earth,A polycyclic aromatic hydrocarbon containing four fused benzene rings; first isolated from co...,Probe Yield Representation Embedding Neural Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -103,biscay,biscay.ai,https://biscay.ai,water,A sea area corresponding to the Bay of Biscay.,Behavior Interpretability Steering Concept Activation Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -104,pommel,pommel.ai,https://pommel.ai,craft,A rounded knob or handle.,Probe Observation Manifold Manifold Embedding Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -105,ramage,ramage.ai,https://ramage.ai,feeling,"wildness, spirit, courage, ferocity",Representation Activation Manifold Activation Geometry Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -106,reamer,reamer.ai,https://reamer.ai,craft,A device for rendering citrus juice.,Representation Embedding Activation Manifold Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -107,cowpea,cowpea.ai,https://cowpea.ai,flora,"Any of the plants in the species Vigna unguiculata, including the black-eyed pea.",Concept Observation Workbench Probe Embedding Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -108,rachis,rachis.ai,https://rachis.ai,geometry,The central shaft of a feather.,Representation Activation Concept Hidden-state Interpretability Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -109,marler,marler.ai,https://marler.ai,land,A laborer in a marlpit.,Manifold Activation Representation Layer Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -110,windle,windle.ai,https://windle.ai,flora,"An old English measure of corn, half a bushel.",Workbench Interpretability Neural Direction Layer Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -111,pelage,pelage.ai,https://pelage.ai,fauna,"Fur, hair, or any other form of the coat of a mammal.",Probe Embedding Layer Activation Geometry Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -112,acinus,acinus.ai,https://acinus.ai,flora,"One of the small grains or drupelets which make up some kinds of fruit, as the blackberry, ra...",Activation Concept Interpretability Neural Unified Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -113,juncus,juncus.ai,https://juncus.ai,land,Any plant of the genus Juncus (the rushes).,Jacobian Unified Neural Concept Unified Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -114,anuran,anuran.ai,https://anuran.ai,fauna,"Any amphibian of the order Anura; a frog, a toad.",Activation Neural Unified Representation Activation Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -115,laffer,laffer.ai,https://laffer.ai,geometry,A comedy.,Layer Activation Feature Feature Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -116,dodder,dodder.ai,https://dodder.ai,flora,"To shake or tremble as one moves, especially as of old age or childhood; to totter.",Direction Observation Direction Direction Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -117,towage,towage.ai,https://towage.ai,navigation,The act of towing.,Trait Observation Workbench Activation Geometry Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -118,yeasty,yeasty.ai,https://yeasty.ai,feeling,Having or resembling yeast.,Yield Embedding Activation Steering Trait Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -119,drowse,drowse.ai,https://drowse.ai,motion,"An act, or a state, of being drowsy or sleepy.",Direction Representation Observation Workbench Steering Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -120,moorer,moorer.ai,https://moorer.ai,land,The person who moors a vessel,Manifold Observation Observation Representation Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -121,calcar,calcar.ai,https://calcar.ai,flora,A spur-like projection.,Concept Activation Layer Concept Activation Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -122,chiloe,chiloe.ai,https://chiloe.ai,land,the largest chilean island and the only one to be settled; located off south-central chile,Concept Hidden-state Interpretability Layer Observation Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -123,lascar,lascar.ai,https://lascar.ai,fauna,"A sailor from India or Southeast Asia, especially as serving on a European ship.",Layer Activation Steering Concept Activation Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -124,cimbri,cimbri.ai,https://cimbri.ai,land,"An ancient tribe that invaded southern Europe between 113 and 101 BCE, generally thought to h...",Concept Interpretability Manifold Behavior Representation Interpretability,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -125,cannel,cannel.ai,https://cannel.ai,craft,A bituminous coal that burns brightly with much smoke.,Concept Activation Neural Neural Embedding Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -126,unhewn,unhewn.ai,https://unhewn.ai,earth,Not hewn.,Unified Neural Hidden-state Embedding Workbench Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -127,meader,meader.ai,https://meader.ai,land,A mower.,Manifold Embedding Activation Direction Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -128,bayamo,bayamo.ai,https://bayamo.ai,sky,A violent storm in the Caribbean.,Behavior Activation Yield Activation Manifold Observation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -129,mulley,mulley.ai,https://mulley.ai,land,A hornless or polled animal.,Manifold Unified Layer Layer Embedding Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -130,cichlid,cichlid.ai,https://cichlid.ai,fauna,"Any of many tropical fish, of the family Cichlidae, popular as aquarium fish.",Concept Interpretability Concept Hidden-state Layer Interpretability Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -131,crepis,crepis.ai,https://crepis.ai,geometry,A plant of the genus Crepis in the family Compositae.,Concept Representation Embedding Probe Interpretability Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -132,logwood,logwood.ai,https://logwood.ai,flora,"A tree of species Haematoxylum campechianum, in the legume family, of great economic importan...",Layer Observation Geometry Workbench Observation Observation Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -133,ligula,ligula.ai,https://ligula.ai,fauna,"A strap or strap-shaped object, especially such a development in plants or insects.",Layer Interpretability Geometry Unified Layer Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -134,pirrie,pirrie.ai,https://pirrie.ai,sky,A strong gale.,Probe Interpretability Representation Representation Interpretability Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -135,shoran,shoran.ai,https://shoran.ai,signal,Acronym of short-range navigation.,Steering Hidden-state Observation Representation Activation Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -136,woggle,woggle.ai,https://woggle.ai,craft,"A Boy Scout's neckerchief clasp or slide, originally a loop or ring of leather.",Workbench Observation Geometry Geometry Layer Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -137,bedder,bedder.ai,https://bedder.ai,land,A property with a specified number of bedrooms.,Behavior Embedding Direction Direction Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -138,fungia,fungia.ai,https://fungia.ai,flora,Any member of the coral genus Fungia.,Feature Unified Neural Geometry Interpretability Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -139,bejuco,bejuco.ai,https://bejuco.ai,flora,"Any climbing woody vine of the tropics with the habit of a liana; in the Philippines, especia...",Behavior Embedding Jacobian Unified Concept Observation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -140,sharee,sharee.ai,https://sharee.ai,mind,A person with whom something is shared.,Steering Hidden-state Activation Representation Embedding Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -141,toneme,toneme.ai,https://toneme.ai,sound,A phoneme in a language that uses different tones for different meanings.,Trait Observation Neural Embedding Manifold Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -142,bharal,bharal.ai,https://bharal.ai,fauna,"A blue sheep, being any species of the genus Pseudois, goatlike bovids of the Himalayas and w...",Behavior Hidden-state Activation Representation Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -143,podger,podger.ai,https://podger.ai,craft,"A tool in the form of a short commonly-tapered metal rod, principally used to align holes in...",Probe Observation Direction Geometry Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -144,piecer,piecer.ai,https://piecer.ai,craft,Someone or something that pieces.,Probe Interpretability Embedding Concept Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -145,piggle,piggle.ai,https://piggle.ai,craft,A long-handled fork for mixing or digging.,Probe Interpretability Geometry Geometry Layer Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -146,pushrod,pushrod.ai,https://pushrod.ai,navigation,A rod in a piston engine that actuates rocker arms above the cylinder head.,Probe Unified Steering Hidden-state Representation Observation Direction,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -147,benzoin,benzoin.ai,https://benzoin.ai,flora,"A resinous substance, dry and brittle, obtained from Styrax benzoin, a tree of Sumatra, Java,...",Behavior Embedding Neural Zeroing Observation Interpretability Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -148,cowslip,cowslip.ai,https://cowslip.ai,flora,"A low-growing plant, Primula veris, with yellow flowers.",Concept Observation Workbench Steering Layer Interpretability Probe,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -149,finfish,finfish.ai,https://finfish.ai,fauna,"Clipped compound of finned fish, as in e.g. ray-finned fish; used to distinguish them from sh...",Feature Interpretability Neural Feature Interpretability Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -150,bycatch,bycatch.ai,https://bycatch.ai,fauna,Any fish (or other creatures) that are not targeted as a catch but are unintentionally caught...,Behavior Yield Concept Activation Trait Concept Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -151,isocost,isocost.ai,https://isocost.ai,geometry,A curve that represents a combination of various inputs that cost the same.,Interpretability Steering Observation Concept Observation Steering Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -152,oblast,oblast.ai,https://oblast.ai,geometry,A region or province in Slavic or Slavic-influenced countries.,Observation Behavior Layer Activation Steering Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -153,onlap,onlap.ai,https://onlap.ai,instrument,The phenomenon of successively younger rock strata extending progressively further across an...,Observation Neural Layer Activation Probe,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -154,mordent,mordent.ai,https://mordent.ai,sound,An ornament consisting of a single alternation between a given pitch and the one immediately...,Manifold Observation Representation Direction Embedding Neural Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -155,garfish,garfish.ai,https://garfish.ai,fauna,"Any fish of the needlefish family Belonidae, with a long narrow body and needle-shaped jaws,...",Geometry Activation Representation Feature Interpretability Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -156,frisket,frisket.ai,https://frisket.ai,language,A thin frame in a printing press that holds the sheet of paper in position and acts as a mask.,Feature Representation Interpretability Steering Kernel Embedding Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -157,mazurka,mazurka.ai,https://mazurka.ai,sound,"A Polish folk dance in triple time, usually moderately fast, containing a heavy accent on the...",Manifold Activation Zeroing Unified Representation Kernel Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -158,catboat,catboat.ai,https://catboat.ai,craft,"A sailing boat with a single sail, usually rigged on a gaff spar, used for fishing in New Eng...",Concept Activation Trait Behavior Observation Activation Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -159,dunnock,dunnock.ai,https://dunnock.ai,fauna,"A small European and Asian passerine bird, Prunella modularis; the hedge sparrow or hedge war...",Direction Unified Neural Neural Observation Concept Kernel,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -160,lenslet,lenslet.ai,https://lenslet.ai,instrument,A small lens that is part of an array used to generate illumination of uniform intensity,Layer Embedding Neural Steering Layer Embedding Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -161,batfish,batfish.ai,https://batfish.ai,fauna,"Any of several spade-shaped, laterally compressed, reef-dwelling tropical fish of the genus P...",Behavior Activation Trait Feature Interpretability Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -162,clitic,clitic.ai,https://clitic.ai,language,"A morpheme that functions like a word, but never appears as an independent word, instead bein...",Concept Layer Interpretability Trait Interpretability Concept,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -163,calcic,calcic.ai,https://calcic.ai,earth,"Of, pertaining to, or derived from calcium or lime.",Concept Activation Layer Concept Interpretability Concept,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -164,armlet,armlet.ai,https://armlet.ai,water,A band worn on the arm for ornamental or identification purposes.,Activation Representation Manifold Layer Embedding Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -165,faunal,faunal.ai,https://faunal.ai,fauna,Pertaining to animals.,Feature Activation Unified Neural Activation Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -166,arapaho,arapaho.ai,https://arapaho.ai,fauna,A member of a Native American people of Wyoming and Oklahoma.,Activation Representation Activation Probe Activation Hidden-state Observation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -167,ovine,ovine.ai,https://ovine.ai,fauna,An animal from the genus Ovis; a sheep.,Observation Vector Interpretability Neural Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -168,muggy,muggy.ai,https://muggy.ai,sky,"Humid, or hot and humid.",Manifold Unified Geometry Geometry Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -169,syrupy,syrupy.ai,https://syrupy.ai,feeling,Overly sweet.,Steering Yield Representation Unified Probe Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -170,mense,mense.ai,https://mense.ai,feeling,Decency; propriety; civility.,Manifold Embedding Neural Steering Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -171,aerator,aerator.ai,https://aerator.ai,craft,"A device which mixes air with a substance, particularly soil or a liquid.",Activation Embedding Representation Activation Trait Observation Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -172,grampus,grampus.ai,https://grampus.ai,fauna,A killer whale (Orcinus orca).,Geometry Representation Activation Manifold Probe Unified Steering,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -173,morceau,morceau.ai,https://morceau.ai,sound,A small bit; a morsel or snippet.,Manifold Observation Representation Concept Embedding Activation Unified,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -174,smidgen,smidgen.ai,https://smidgen.ai,instrument,"Chiefly in the form a smidgen of: a very small amount or quantity; a bit, a trace.",Steering Manifold Interpretability Direction Geometry Embedding Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -175,souse,souse.ai,https://souse.ai,mind,To immerse in liquid; to steep or drench.,Steering Observation Unified Steering Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -176,elsen,elsen.ai,https://elsen.ai,craft,"An awl, a pointed tool.",Embedding Layer Steering Embedding Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -177,sahul,sahul.ai,https://sahul.ai,water,"The continent that contains the islands of Australia, New Guinea, and Tasmania, especially du...",Steering Activation Hidden-state Unified Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -178,apocope,apocope.ai,https://apocope.ai,sound,The loss or omission of a sound or syllable from the end of a word.,Activation Probe Observation Concept Observation Probe Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -179,holdall,holdall.ai,https://holdall.ai,language,A large bag for carrying belongings while travelling.,Hidden-state Observation Layer Direction Activation Layer Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -180,spindel,spindel.ai,https://spindel.ai,craft,The rod made from the above used in the spinning of wool and other natural fibres.,Steering Probe Interpretability Neural Direction Embedding Layer,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -181,alosa,alosa.ai,https://alosa.ai,fauna,shad,Activation Layer Observation Steering Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -182,lurcher,lurcher.ai,https://lurcher.ai,fauna,A type of crossbreed dog ― a cross between a sighthound and any other breed or the offspring...,Layer Unified Representation Concept Hidden-state Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -183,abrader,abrader.ai,https://abrader.ai,craft,Something that abrades; a tool or machine for abrading.,Activation Behavior Representation Activation Direction Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -184,pantile,pantile.ai,https://pantile.ai,earth,"A type of interlocking roof tile with a rounded under and over, giving it an elongated S-shap...",Probe Activation Neural Trait Interpretability Layer Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -185,piglike,piglike.ai,https://piglike.ai,fauna,Resembling or characteristic of a pig.,Probe Interpretability Geometry Layer Interpretability Kernel Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -186,pallene,pallene.ai,https://pallene.ai,sky,A moon of Saturn.,Probe Activation Layer Layer Embedding Neural Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -187,terebra,terebra.ai,https://terebra.ai,fauna,"The ovipositor of a female hymenopteran, that pierces.",Trait Embedding Representation Embedding Behavior Representation Activation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -188,suckler,suckler.ai,https://suckler.ai,fauna,Any animal that suckles its young; a mammal.,Steering Unified Concept Kernel Layer Embedding Representation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -189,roneo,roneo.ai,https://roneo.ai,language,A copying machine using stencils; a mimeograph.,Representation Observation Neural Embedding Observation,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -190,mercery,mercery.ai,https://mercery.ai,craft,The goods in which a mercer deals.,Manifold Embedding Representation Concept Embedding Representation Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -191,untruth,untruth.ai,https://untruth.ai,feeling,A lie or falsehood.,Unified Neural Trait Representation Unified Trait Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -192,berain,berain.ai,https://berain.ai,sky,To rain upon; wet with rain; moisten.,Behavior Embedding Representation Activation Interpretability Neural,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -193,vapory,vapory.ai,https://vapory.ai,sky,Resembling vapor; vaporous.,Vector Activation Probe Observation Representation Yield,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -194,buttock,buttock.ai,https://buttock.ai,sky,Each of the two large fleshy halves of the posterior part of the body between the base of the...,Behavior Unified Trait Trait Observation Concept Kernel,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -195,tlingit,tlingit.ai,https://tlingit.ai,language,A member of an Indian people from the coastal regions of Alaska and British Columbia.,Trait Layer Interpretability Neural Geometry Interpretability Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -196,sbornik,sbornik.ai,https://sbornik.ai,language,A collection of manuscripts; an anthology.,Steering Behavior Observation Representation Neural Interpretability Kernel,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -197,tarnish,tarnish.ai,https://tarnish.ai,sky,"Oxidation or discoloration, especially of a decorative metal exposed to air.",Trait Activation Representation Neural Interpretability Steering Hidden-state,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -198,hasidim,hasidim.ai,https://hasidim.ai,feeling,sect of orthodox jews who follow the mosaic law strictly,Hidden-state Activation Steering Interpretability Direction Interpretability Manifold,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -199,cacique,cacique.ai,https://cacique.ai,fauna,"A local political leader in Latin America, Spain, or the Philippines.",Concept Activation Concept Interpretability Quantitative Unified Embedding,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 -200,unhurt,unhurt.ai,https://unhurt.ai,sound,Not hurt; unharmed or unscathed,Unified Neural Hidden-state Unified Representation Trait,available standard live registrar,82.70,2,165.40,82.70,unavailable,2026-08-27 diff --git a/domain-name-recommendations-2026-09-05-round-3.json b/domain-name-recommendations-2026-09-05-round-3.json deleted file mode 100644 index 79bf5991..00000000 --- a/domain-name-recommendations-2026-09-05-round-3.json +++ /dev/null @@ -1,704 +0,0 @@ -{ - "recommendations": [ - { - "rank": 1, - "name": "Lunomi", - "slug": "lunomi", - "pronunciation": "loo-NOH-mee", - "rationale": "Soft, memorable, and slightly lunar; my strongest overall pick.", - "domain": "lunomi.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=lunomi.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "Existing musician/creator use and an unrelated Polish trading company.", - "existing_use_source": "https://ko-fi.com/lunomi/" - }, - { - "rank": 2, - "name": "Nimela", - "slug": "nimela", - "pronunciation": "nih-MEL-ah", - "rationale": "Gentle and compact; works equally well for an app or a library.", - "domain": "nimela.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=nimela.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 3, - "name": "Quiet Tide", - "slug": "quiettide", - "pronunciation": "quiet tide", - "rationale": "A natural metaphor for subtly steering a model’s behavior.", - "domain": "quiettide.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=quiettide.ai", - "category": "English compound", - "origin": "Quiet Tide", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 4, - "name": "Inner Vale", - "slug": "innervale", - "pronunciation": "inner vale", - "rationale": "Suggests an interior landscape waiting to be explored.", - "domain": "innervale.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=innervale.ai", - "category": "English compound", - "origin": "Inner Vale", - "origin_url": "", - "existing_use_note": "Existing fictional-place uses and company names.", - "existing_use_source": "https://www.innervale.com/" - }, - { - "rank": 5, - "name": "Domaso", - "slug": "domaso", - "pronunciation": "DOH-mah-zoh", - "rationale": "A Lake Como village name with a warm, unhurried sound.", - "domain": "domaso.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=domaso.ai", - "category": "place name", - "origin": "Lake Como, Italy", - "origin_url": "https://www.northlakecomo.net/uploads/EnTravelguide-upload.pdf", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 6, - "name": "Somori", - "slug": "somori", - "pronunciation": "soh-MOR-ee", - "rationale": "Rounded and restful; has the feel of a small creative studio.", - "domain": "somori.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=somori.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 7, - "name": "Open Fern", - "slug": "openfern", - "pronunciation": "open fern", - "rationale": "Unfolding structure; a good image for making hidden things visible.", - "domain": "openfern.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=openfern.ai", - "category": "English compound", - "origin": "Open Fern", - "origin_url": "", - "existing_use_note": "Existing company-directory use.", - "existing_use_source": "https://www.lgr.co.uk/Directory/?letter=F" - }, - { - "rank": 8, - "name": "Paper Tide", - "slug": "papertide", - "pronunciation": "paper tide", - "rationale": "Language in motion; literary without sounding academic.", - "domain": "papertide.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=papertide.ai", - "category": "English compound", - "origin": "Paper Tide", - "origin_url": "", - "existing_use_note": "Name appears as a customer/example business on an AI-email-marketing site; existence of a separate active company not established.", - "existing_use_source": "https://hiremara.com/" - }, - { - "rank": 9, - "name": "Lumella", - "slug": "lumella", - "pronunciation": "loo-MEL-ah", - "rationale": "Luminous and melodic; especially strong as a visual identity.", - "domain": "lumella.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=lumella.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "Existing beauty-store and diagnostic-brand uses; domain availability does not establish exclusive name rights.", - "existing_use_source": "https://lumella.net/" - }, - { - "rank": 10, - "name": "Silver Moss", - "slug": "silvermoss", - "pronunciation": "silver moss", - "rationale": "Soft nature imagery with a slight metallic, technical edge.", - "domain": "silvermoss.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=silvermoss.ai", - "category": "English compound", - "origin": "Silver Moss", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 11, - "name": "Norali", - "slug": "norali", - "pronunciation": "nor-AH-lee", - "rationale": "Airy, balanced, and easy to use in ordinary conversation.", - "domain": "norali.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=norali.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 12, - "name": "Ostuni", - "slug": "ostuni", - "pronunciation": "os-TOO-nee", - "rationale": "An Italian town name; crisp, sunny, and distinctive.", - "domain": "ostuni.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=ostuni.ai", - "category": "place name", - "origin": "Puglia, Italy", - "origin_url": "https://www.italia.it/en/puglia/brindisi/ostuni", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 13, - "name": "Kind Muse", - "slug": "kindmuse", - "pronunciation": "kind muse", - "rationale": "Warm and creative; a good fit for shaping model personality.", - "domain": "kindmuse.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=kindmuse.ai", - "category": "English compound", - "origin": "Kind Muse", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 14, - "name": "Soft Current", - "slug": "softcurrent", - "pronunciation": "soft current", - "rationale": "Subtle influence and continuous flow; closely fits steering.", - "domain": "softcurrent.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=softcurrent.ai", - "category": "English compound", - "origin": "Soft Current", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 15, - "name": "Moon Cove", - "slug": "mooncove", - "pronunciation": "moon cove", - "rationale": "A quiet place to explore; compact and visually evocative.", - "domain": "mooncove.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=mooncove.ai", - "category": "English compound", - "origin": "Moon Cove", - "origin_url": "", - "existing_use_note": "Existing Minecraft-server and production-company uses.", - "existing_use_source": "https://rsq.productions/privacy-policy/" - }, - { - "rank": 16, - "name": "Nolemi", - "slug": "nolemi", - "pronunciation": "noh-LEM-ee", - "rationale": "Friendly and fluid; could support a personable little mascot.", - "domain": "nolemi.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=nolemi.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "Appears as a user-created character name on an AI platform, not as the platform brand.", - "existing_use_source": "https://shapes.inc/nolemi" - }, - { - "rank": 17, - "name": "Clear Meadow", - "slug": "clearmeadow", - "pronunciation": "clear meadow", - "rationale": "Open terrain and visibility; a gentle interpretability metaphor.", - "domain": "clearmeadow.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=clearmeadow.ai", - "category": "English compound", - "origin": "Clear Meadow", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 18, - "name": "Siluna", - "slug": "siluna", - "pronunciation": "sih-LOO-nah", - "rationale": "Smooth and moonlike; graceful when spoken aloud.", - "domain": "siluna.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=siluna.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "Existing music and lighting-product uses; siluna.world also has a landing page.", - "existing_use_source": "https://siluna.world/" - }, - { - "rank": 19, - "name": "Light Grove", - "slug": "lightgrove", - "pronunciation": "light grove", - "rationale": "A branching space illuminated from within.", - "domain": "lightgrove.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=lightgrove.ai", - "category": "English compound", - "origin": "Light Grove", - "origin_url": "", - "existing_use_note": "Existing fictional location in Enderal.", - "existing_use_source": "https://wiki.en.sureai.net/Enderal%3ALightgrove" - }, - { - "rank": 20, - "name": "Roseto", - "slug": "roseto", - "pronunciation": "roh-ZEH-toh", - "rationale": "From Roseto degli Abruzzi; rounded, warm, and elegant.", - "domain": "roseto.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=roseto.ai", - "category": "place name", - "origin": "Roseto degli Abruzzi, Italy", - "origin_url": "https://www.visitroseto.it/en/discover/", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 21, - "name": "Soft Moss", - "slug": "softmoss", - "pronunciation": "soft moss", - "rationale": "Tactile and welcoming; easy to remember after hearing once.", - "domain": "softmoss.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=softmoss.ai", - "category": "English compound", - "origin": "Soft Moss", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 22, - "name": "Gold Fern", - "slug": "goldfern", - "pronunciation": "gold fern", - "rationale": "Simple, bright, and easy to turn into a recognizable symbol.", - "domain": "goldfern.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=goldfern.ai", - "category": "English compound", - "origin": "Gold Fern", - "origin_url": "", - "existing_use_note": "Existing real-estate and mining-consulting uses.", - "existing_use_source": "https://www.goldfern.com.au/" - }, - { - "rank": 23, - "name": "Enoli", - "slug": "enoli", - "pronunciation": "eh-NOH-lee", - "rationale": "Short, flowing, and adaptable beyond the initial product.", - "domain": "enoli.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=enoli.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "Existing corporate-services organization and personal-name uses.", - "existing_use_source": "https://enoli.net/" - }, - { - "rank": 24, - "name": "Blue Hollow", - "slug": "bluehollow", - "pronunciation": "blue hollow", - "rationale": "Hidden depth; a strong fit for an exploratory visual interface.", - "domain": "bluehollow.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=bluehollow.ai", - "category": "English compound", - "origin": "Blue Hollow", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 25, - "name": "Fable Cove", - "slug": "fablecove", - "pronunciation": "fable cove", - "rationale": "A small home for language, stories, and different voices.", - "domain": "fablecove.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=fablecove.ai", - "category": "English compound", - "origin": "Fable Cove", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 26, - "name": "Bormio", - "slug": "bormio", - "pronunciation": "BOR-myoh", - "rationale": "An Italian Alpine town name; compact and sturdy.", - "domain": "bormio.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=bormio.ai", - "category": "place name", - "origin": "Italian Alps", - "origin_url": "https://www.bormio.eu/en", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 27, - "name": "Amber Muse", - "slug": "ambermuse", - "pronunciation": "amber muse", - "rationale": "Warm color and creative influence; polished without being cold.", - "domain": "ambermuse.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=ambermuse.ai", - "category": "English compound", - "origin": "Amber Muse", - "origin_url": "", - "existing_use_note": "Existing jewelry brand.", - "existing_use_source": "https://ambermuse.lt/" - }, - { - "rank": 28, - "name": "Sorumi", - "slug": "sorumi", - "pronunciation": "soh-ROO-mee", - "rationale": "A soft, rhythmic name with a friendly character.", - "domain": "sorumi.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=sorumi.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 29, - "name": "Ponza", - "slug": "ponza", - "pronunciation": "PON-tsah", - "rationale": "An Italian island name; short, lively, and distinctive.", - "domain": "ponza.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=ponza.ai", - "category": "place name", - "origin": "Island in Italy", - "origin_url": "https://www.visitponza.it/en/discover-ponza-2/", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 30, - "name": "Mellow Tide", - "slug": "mellowtide", - "pronunciation": "mellow tide", - "rationale": "Relaxed movement; approachable and pleasant to say.", - "domain": "mellowtide.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=mellowtide.ai", - "category": "English compound", - "origin": "Mellow Tide", - "origin_url": "", - "existing_use_note": "Existing musician use and trademark-journal mentions; legal scope not assessed.", - "existing_use_source": "https://music.apple.com/us/artist/mellowtide/1768055740" - }, - { - "rank": 31, - "name": "Moon Moss", - "slug": "moonmoss", - "pronunciation": "moon moss", - "rationale": "A slightly strange natural image with strong visual potential.", - "domain": "moonmoss.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=moonmoss.ai", - "category": "English compound", - "origin": "Moon Moss", - "origin_url": "", - "existing_use_note": "Food-product trademark use surfaced; legal status/scope not assessed.", - "existing_use_source": "https://ttabvue.uspto.gov/ttabvue-92091396-CAN-1.pdf" - }, - { - "rank": 32, - "name": "Tameli", - "slug": "tameli", - "pronunciation": "tah-MEL-ee", - "rationale": "Gentle consonants and a clear three-syllable rhythm.", - "domain": "tameli.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=tameli.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 33, - "name": "Still Cove", - "slug": "stillcove", - "pronunciation": "still cove", - "rationale": "A calm workspace; quiet and self-contained.", - "domain": "stillcove.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=stillcove.ai", - "category": "English compound", - "origin": "Still Cove", - "origin_url": "", - "existing_use_note": "An exact-name trademark application surfaced for an e-commerce company; legal scope not assessed.", - "existing_use_source": "https://trademarks.justia.com/983/52/stillcove-98352747.html" - }, - { - "rank": 34, - "name": "Light Moss", - "slug": "lightmoss", - "pronunciation": "light moss", - "rationale": "Small points of illumination; delicate and unusual.", - "domain": "lightmoss.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=lightmoss.ai", - "category": "English compound", - "origin": "Light Moss", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 35, - "name": "Tropea", - "slug": "tropea", - "pronunciation": "troh-PEH-ah", - "rationale": "A Calabrian town name; flowing and sunlit.", - "domain": "tropea.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=tropea.ai", - "category": "place name", - "origin": "Calabria, Italy", - "origin_url": "https://calabriastraordinaria.it/en/destinations/tropea-the-pearl-of-the-tyrrhenian-sea", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 36, - "name": "Fable Fern", - "slug": "fablefern", - "pronunciation": "fable fern", - "rationale": "Language and unfolding forms; playful alliteration.", - "domain": "fablefern.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=fablefern.ai", - "category": "English compound", - "origin": "Fable Fern", - "origin_url": "", - "existing_use_note": "Existing bookshop and invitation-studio uses.", - "existing_use_source": "https://www.fablefernbookshop.com/pages/contact-us" - }, - { - "rank": 37, - "name": "Norumi", - "slug": "norumi", - "pronunciation": "noh-ROO-mee", - "rationale": "Rounded and companionable; good for a personable product.", - "domain": "norumi.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=norumi.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "Existing cat-related shop use.", - "existing_use_source": "https://heynorumi.com/" - }, - { - "rank": 38, - "name": "Silver Glow", - "slug": "silverglow", - "pronunciation": "silver glow", - "rationale": "Illumination with a restrained, slightly futuristic feel.", - "domain": "silverglow.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=silverglow.ai", - "category": "English compound", - "origin": "Silver Glow", - "origin_url": "", - "existing_use_note": "Existing typeface and music uses.", - "existing_use_source": "https://www.myfonts.com/collections/silverglow-font-balpirick/" - }, - { - "rank": 39, - "name": "Bloom Cove", - "slug": "bloomcove", - "pronunciation": "bloom cove", - "rationale": "A sheltered place for ideas and personalities to develop.", - "domain": "bloomcove.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=bloomcove.ai", - "category": "English compound", - "origin": "Bloom Cove", - "origin_url": "", - "existing_use_note": "Existing online-store uses.", - "existing_use_source": "https://www.merchantgenius.io/shop/url/bloomcove.shop" - }, - { - "rank": 40, - "name": "Locarno", - "slug": "locarno", - "pronunciation": "loh-KAR-noh", - "rationale": "A Swiss lakeside city name; established and substantial.", - "domain": "locarno.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=locarno.ai", - "category": "place name", - "origin": "Ticino, Switzerland", - "origin_url": "https://www.ascona-locarno.com/en/explore/locarno", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 41, - "name": "Gentle Tide", - "slug": "gentletide", - "pronunciation": "gentle tide", - "rationale": "Small, deliberate changes; an intuitive steering association.", - "domain": "gentletide.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=gentletide.ai", - "category": "English compound", - "origin": "Gentle Tide", - "origin_url": "", - "existing_use_note": "Existing retreat-business use.", - "existing_use_source": "https://linktr.ee/gentletide" - }, - { - "rank": 42, - "name": "Moss Lane", - "slug": "mosslane", - "pronunciation": "moss lane", - "rationale": "A path through something living; grounded and approachable.", - "domain": "mosslane.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=mosslane.ai", - "category": "English compound", - "origin": "Moss Lane", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 43, - "name": "Ikumi", - "slug": "ikumi", - "pronunciation": "ee-KOO-mee", - "rationale": "Compact and rhythmic; friendly enough for everyday use.", - "domain": "ikumi.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=ikumi.ai", - "category": "sound-led name", - "origin": "Selected for its sound; no foreign-language translation or first-ever coinage claimed.", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 44, - "name": "Fable Moon", - "slug": "fablemoon", - "pronunciation": "fable moon", - "rationale": "Dreamlike and literary; broad room for a visual identity.", - "domain": "fablemoon.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=fablemoon.ai", - "category": "English compound", - "origin": "Fable Moon", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 45, - "name": "Varallo", - "slug": "varallo", - "pronunciation": "vah-RAHL-loh", - "rationale": "A Piedmont town name; melodic, with a confident ending.", - "domain": "varallo.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=varallo.ai", - "category": "place name", - "origin": "Piedmont, Italy", - "origin_url": "https://www.italia.it/en/piedmont/varallo", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 46, - "name": "Mist Lake", - "slug": "mistlake", - "pronunciation": "mist lake", - "rationale": "Hidden depth gradually becoming visible.", - "domain": "mistlake.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=mistlake.ai", - "category": "English compound", - "origin": "Mist Lake", - "origin_url": "", - "existing_use_note": "Existing Codex color-theme name.", - "existing_use_source": "https://www.dexthemes.com/mistlake/dark" - }, - { - "rank": 47, - "name": "Bright Muse", - "slug": "brightmuse", - "pronunciation": "bright muse", - "rationale": "Clear, optimistic, and immediately easy to understand.", - "domain": "brightmuse.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=brightmuse.ai", - "category": "English compound", - "origin": "Bright Muse", - "origin_url": "", - "existing_use_note": "Japanese company name surfaced in a commercial-disclosure page; business type not resolved.", - "existing_use_source": "https://utage-system.com/p/kMKZthBOukj5" - }, - { - "rank": 48, - "name": "Posada", - "slug": "posada", - "pronunciation": "poh-SAH-dah", - "rationale": "A Sardinian village name; welcoming and easy to say.", - "domain": "posada.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=posada.ai", - "category": "place name", - "origin": "Sardinia, Italy", - "origin_url": "https://www.sardegnaturismo.it/en/explore/posada?language=en-gb", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 49, - "name": "Merry Bloom", - "slug": "merrybloom", - "pronunciation": "merry bloom", - "rationale": "Cheerful and playful; suited to a less formal product voice.", - "domain": "merrybloom.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=merrybloom.ai", - "category": "English compound", - "origin": "Merry Bloom", - "origin_url": "", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - }, - { - "rank": 50, - "name": "Sulmona", - "slug": "sulmona", - "pronunciation": "sool-MOH-nah", - "rationale": "An Abruzzo town name; sonorous and distinctive.", - "domain": "sulmona.ai", - "registrar_url": "https://porkbun.com/checkout/search?q=sulmona.ai", - "category": "place name", - "origin": "Abruzzo, Italy", - "origin_url": "https://turismo.comune.sulmona.aq.it/", - "existing_use_note": "No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.", - "existing_use_source": "" - } - ] -} diff --git a/domain-name-registry-checks-2026-09-05-round-3.json b/domain-name-registry-checks-2026-09-05-round-3.json deleted file mode 100644 index 43234ff8..00000000 --- a/domain-name-registry-checks-2026-09-05-round-3.json +++ /dev/null @@ -1,1202 +0,0 @@ -[ - { - "name": "lunomi", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/lunomi.ai", - "checked_at_utc": "2026-09-05T21:56:50.171349+00:00" - }, - { - "name": "lunomi", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/lunomi/json", - "checked_at_utc": "2026-09-05T21:56:50.157474+00:00" - }, - { - "name": "lunomi", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/lunomi", - "checked_at_utc": "2026-09-05T21:56:50.217407+00:00" - }, - { - "name": "sorumi", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/sorumi.ai", - "checked_at_utc": "2026-09-05T21:56:50.321206+00:00" - }, - { - "name": "sorumi", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/sorumi/json", - "checked_at_utc": "2026-09-05T21:56:50.344345+00:00" - }, - { - "name": "sorumi", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/sorumi", - "checked_at_utc": "2026-09-05T21:56:50.494922+00:00" - }, - { - "name": "norumi", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/norumi.ai", - "checked_at_utc": "2026-09-05T21:56:50.880035+00:00" - }, - { - "name": "norumi", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/norumi/json", - "checked_at_utc": "2026-09-05T21:56:50.960609+00:00" - }, - { - "name": "norumi", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/norumi", - "checked_at_utc": "2026-09-05T21:56:51.134006+00:00" - }, - { - "name": "nimela", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/nimela.ai", - "checked_at_utc": "2026-09-05T21:56:51.150725+00:00" - }, - { - "name": "nimela", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/nimela/json", - "checked_at_utc": "2026-09-05T21:56:51.172988+00:00" - }, - { - "name": "nimela", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/nimela", - "checked_at_utc": "2026-09-05T21:56:51.342903+00:00" - }, - { - "name": "nolemi", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/nolemi.ai", - "checked_at_utc": "2026-09-05T21:56:51.309303+00:00" - }, - { - "name": "nolemi", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/nolemi/json", - "checked_at_utc": "2026-09-05T21:56:51.325262+00:00" - }, - { - "name": "nolemi", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/nolemi", - "checked_at_utc": "2026-09-05T21:56:51.550944+00:00" - }, - { - "name": "siluna", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/siluna.ai", - "checked_at_utc": "2026-09-05T21:56:52.061549+00:00" - }, - { - "name": "siluna", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/siluna/json", - "checked_at_utc": "2026-09-05T21:56:52.121651+00:00" - }, - { - "name": "siluna", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/siluna", - "checked_at_utc": "2026-09-05T21:56:52.294524+00:00" - }, - { - "name": "somori", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/somori.ai", - "checked_at_utc": "2026-09-05T21:56:52.268209+00:00" - }, - { - "name": "somori", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/somori/json", - "checked_at_utc": "2026-09-05T21:56:52.302736+00:00" - }, - { - "name": "somori", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/somori", - "checked_at_utc": "2026-09-05T21:56:52.526761+00:00" - }, - { - "name": "tameli", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/tameli.ai", - "checked_at_utc": "2026-09-05T21:56:53.238088+00:00" - }, - { - "name": "tameli", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/tameli/json", - "checked_at_utc": "2026-09-05T21:56:53.292528+00:00" - }, - { - "name": "tameli", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/tameli", - "checked_at_utc": "2026-09-05T21:56:53.469986+00:00" - }, - { - "name": "lumella", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/lumella.ai", - "checked_at_utc": "2026-09-05T21:56:54.084744+00:00" - }, - { - "name": "lumella", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/lumella/json", - "checked_at_utc": "2026-09-05T21:56:54.109139+00:00" - }, - { - "name": "lumella", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/lumella", - "checked_at_utc": "2026-09-05T21:56:54.364743+00:00" - }, - { - "name": "enoli", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/enoli.ai", - "checked_at_utc": "2026-09-05T21:56:54.285527+00:00" - }, - { - "name": "enoli", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/enoli/json", - "checked_at_utc": "2026-09-05T21:56:54.305565+00:00" - }, - { - "name": "enoli", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/enoli", - "checked_at_utc": "2026-09-05T21:56:54.518484+00:00" - }, - { - "name": "norali", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/norali.ai", - "checked_at_utc": "2026-09-05T21:56:54.479674+00:00" - }, - { - "name": "norali", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/norali/json", - "checked_at_utc": "2026-09-05T21:56:54.549248+00:00" - }, - { - "name": "norali", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/norali", - "checked_at_utc": "2026-09-05T21:56:54.723529+00:00" - }, - { - "name": "ikumi", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/ikumi.ai", - "checked_at_utc": "2026-09-05T21:56:56.132803+00:00" - }, - { - "name": "ikumi", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/ikumi/json", - "checked_at_utc": "2026-09-05T21:56:56.192391+00:00" - }, - { - "name": "ikumi", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/ikumi", - "checked_at_utc": "2026-09-05T21:56:56.381808+00:00" - }, - { - "name": "domaso", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/domaso.ai", - "checked_at_utc": "2026-09-05T21:56:57.831854+00:00" - }, - { - "name": "domaso", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/domaso/json", - "checked_at_utc": "2026-09-05T21:56:57.852386+00:00" - }, - { - "name": "domaso", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/domaso", - "checked_at_utc": "2026-09-05T21:56:58.084034+00:00" - }, - { - "name": "ostuni", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/ostuni.ai", - "checked_at_utc": "2026-09-05T21:56:58.026782+00:00" - }, - { - "name": "ostuni", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/ostuni/json", - "checked_at_utc": "2026-09-05T21:56:58.083827+00:00" - }, - { - "name": "ostuni", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/ostuni", - "checked_at_utc": "2026-09-05T21:56:58.267206+00:00" - }, - { - "name": "roseto", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/roseto.ai", - "checked_at_utc": "2026-09-05T21:56:58.653273+00:00" - }, - { - "name": "roseto", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/roseto/json", - "checked_at_utc": "2026-09-05T21:56:58.665867+00:00" - }, - { - "name": "roseto", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/roseto", - "checked_at_utc": "2026-09-05T21:56:58.898995+00:00" - }, - { - "name": "bormio", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/bormio.ai", - "checked_at_utc": "2026-09-05T21:56:58.847865+00:00" - }, - { - "name": "bormio", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/bormio/json", - "checked_at_utc": "2026-09-05T21:56:58.885196+00:00" - }, - { - "name": "bormio", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/bormio", - "checked_at_utc": "2026-09-05T21:56:59.109943+00:00" - }, - { - "name": "locarno", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/locarno.ai", - "checked_at_utc": "2026-09-05T21:56:59.068746+00:00" - }, - { - "name": "locarno", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/locarno/json", - "checked_at_utc": "2026-09-05T21:56:59.075293+00:00" - }, - { - "name": "locarno", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/locarno", - "checked_at_utc": "2026-09-05T21:56:59.322426+00:00" - }, - { - "name": "ponza", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/ponza.ai", - "checked_at_utc": "2026-09-05T21:56:59.262671+00:00" - }, - { - "name": "ponza", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/ponza/json", - "checked_at_utc": "2026-09-05T21:56:59.281974+00:00" - }, - { - "name": "ponza", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/ponza", - "checked_at_utc": "2026-09-05T21:56:59.494306+00:00" - }, - { - "name": "tropea", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/tropea.ai", - "checked_at_utc": "2026-09-05T21:56:59.454465+00:00" - }, - { - "name": "tropea", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/tropea/json", - "checked_at_utc": "2026-09-05T21:56:59.517343+00:00" - }, - { - "name": "tropea", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/tropea", - "checked_at_utc": "2026-09-05T21:56:59.692092+00:00" - }, - { - "name": "varallo", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/varallo.ai", - "checked_at_utc": "2026-09-05T21:56:59.860113+00:00" - }, - { - "name": "varallo", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/varallo/json", - "checked_at_utc": "2026-09-05T21:56:59.944154+00:00" - }, - { - "name": "varallo", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/varallo", - "checked_at_utc": "2026-09-05T21:57:00.126685+00:00" - }, - { - "name": "sulmona", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/sulmona.ai", - "checked_at_utc": "2026-09-05T21:57:00.127741+00:00" - }, - { - "name": "sulmona", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/sulmona/json", - "checked_at_utc": "2026-09-05T21:57:00.166347+00:00" - }, - { - "name": "sulmona", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/sulmona", - "checked_at_utc": "2026-09-05T21:57:00.392975+00:00" - }, - { - "name": "posada", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/posada.ai", - "checked_at_utc": "2026-09-05T21:57:00.511442+00:00" - }, - { - "name": "posada", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/posada/json", - "checked_at_utc": "2026-09-05T21:57:00.603023+00:00" - }, - { - "name": "posada", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/posada", - "checked_at_utc": "2026-09-05T21:57:00.770247+00:00" - }, - { - "name": "quiettide", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/quiettide.ai", - "checked_at_utc": "2026-09-05T21:57:00.750167+00:00" - }, - { - "name": "quiettide", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/quiettide/json", - "checked_at_utc": "2026-09-05T21:57:00.796531+00:00" - }, - { - "name": "quiettide", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/quiettide", - "checked_at_utc": "2026-09-05T21:57:00.977232+00:00" - }, - { - "name": "softmoss", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/softmoss.ai", - "checked_at_utc": "2026-09-05T21:57:01.366685+00:00" - }, - { - "name": "softmoss", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/softmoss/json", - "checked_at_utc": "2026-09-05T21:57:01.421555+00:00" - }, - { - "name": "softmoss", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/softmoss", - "checked_at_utc": "2026-09-05T21:57:01.606231+00:00" - }, - { - "name": "stillcove", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/stillcove.ai", - "checked_at_utc": "2026-09-05T21:57:02.195958+00:00" - }, - { - "name": "stillcove", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/stillcove/json", - "checked_at_utc": "2026-09-05T21:57:02.309794+00:00" - }, - { - "name": "stillcove", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/stillcove", - "checked_at_utc": "2026-09-05T21:57:02.451825+00:00" - }, - { - "name": "innervale", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/innervale.ai", - "checked_at_utc": "2026-09-05T21:57:02.631763+00:00" - }, - { - "name": "innervale", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/innervale/json", - "checked_at_utc": "2026-09-05T21:57:02.672409+00:00" - }, - { - "name": "innervale", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/innervale", - "checked_at_utc": "2026-09-05T21:57:02.812267+00:00" - }, - { - "name": "bluehollow", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/bluehollow.ai", - "checked_at_utc": "2026-09-05T21:57:03.202864+00:00" - }, - { - "name": "bluehollow", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/bluehollow/json", - "checked_at_utc": "2026-09-05T21:57:03.276237+00:00" - }, - { - "name": "bluehollow", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/bluehollow", - "checked_at_utc": "2026-09-05T21:57:03.420224+00:00" - }, - { - "name": "lightgrove", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/lightgrove.ai", - "checked_at_utc": "2026-09-05T21:57:03.389886+00:00" - }, - { - "name": "lightgrove", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/lightgrove/json", - "checked_at_utc": "2026-09-05T21:57:03.488448+00:00" - }, - { - "name": "lightgrove", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/lightgrove", - "checked_at_utc": "2026-09-05T21:57:03.652799+00:00" - }, - { - "name": "mooncove", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/mooncove.ai", - "checked_at_utc": "2026-09-05T21:57:04.035031+00:00" - }, - { - "name": "mooncove", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/mooncove/json", - "checked_at_utc": "2026-09-05T21:57:04.045478+00:00" - }, - { - "name": "mooncove", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/mooncove", - "checked_at_utc": "2026-09-05T21:57:04.277975+00:00" - }, - { - "name": "mosslane", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/mosslane.ai", - "checked_at_utc": "2026-09-05T21:57:04.995754+00:00" - }, - { - "name": "mosslane", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/mosslane/json", - "checked_at_utc": "2026-09-05T21:57:05.059004+00:00" - }, - { - "name": "mosslane", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/mosslane", - "checked_at_utc": "2026-09-05T21:57:05.228996+00:00" - }, - { - "name": "mistlake", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/mistlake.ai", - "checked_at_utc": "2026-09-05T21:57:05.399941+00:00" - }, - { - "name": "mistlake", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/mistlake/json", - "checked_at_utc": "2026-09-05T21:57:05.463026+00:00" - }, - { - "name": "mistlake", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/mistlake", - "checked_at_utc": "2026-09-05T21:57:05.658331+00:00" - }, - { - "name": "kindmuse", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/kindmuse.ai", - "checked_at_utc": "2026-09-05T21:57:06.384128+00:00" - }, - { - "name": "kindmuse", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/kindmuse/json", - "checked_at_utc": "2026-09-05T21:57:06.408081+00:00" - }, - { - "name": "kindmuse", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/kindmuse", - "checked_at_utc": "2026-09-05T21:57:06.651840+00:00" - }, - { - "name": "mellowtide", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/mellowtide.ai", - "checked_at_utc": "2026-09-05T21:57:07.234403+00:00" - }, - { - "name": "mellowtide", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/mellowtide/json", - "checked_at_utc": "2026-09-05T21:57:07.247975+00:00" - }, - { - "name": "mellowtide", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/mellowtide", - "checked_at_utc": "2026-09-05T21:57:07.482919+00:00" - }, - { - "name": "bloomcove", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/bloomcove.ai", - "checked_at_utc": "2026-09-05T21:57:07.445556+00:00" - }, - { - "name": "bloomcove", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/bloomcove/json", - "checked_at_utc": "2026-09-05T21:57:07.444341+00:00" - }, - { - "name": "bloomcove", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/bloomcove", - "checked_at_utc": "2026-09-05T21:57:07.722726+00:00" - }, - { - "name": "fablecove", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/fablecove.ai", - "checked_at_utc": "2026-09-05T21:57:07.641637+00:00" - }, - { - "name": "fablecove", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/fablecove/json", - "checked_at_utc": "2026-09-05T21:57:07.669838+00:00" - }, - { - "name": "fablecove", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/fablecove", - "checked_at_utc": "2026-09-05T21:57:07.875289+00:00" - }, - { - "name": "papertide", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/papertide.ai", - "checked_at_utc": "2026-09-05T21:57:08.276941+00:00" - }, - { - "name": "papertide", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/papertide/json", - "checked_at_utc": "2026-09-05T21:57:08.283956+00:00" - }, - { - "name": "papertide", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/papertide", - "checked_at_utc": "2026-09-05T21:57:08.518338+00:00" - }, - { - "name": "goldfern", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/goldfern.ai", - "checked_at_utc": "2026-09-05T22:03:47.121113+00:00" - }, - { - "name": "goldfern", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/goldfern/json", - "checked_at_utc": "2026-09-05T22:03:47.074654+00:00" - }, - { - "name": "goldfern", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/goldfern", - "checked_at_utc": "2026-09-05T22:03:47.156335+00:00" - }, - { - "name": "silvermoss", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/silvermoss.ai", - "checked_at_utc": "2026-09-05T22:03:47.265741+00:00" - }, - { - "name": "silvermoss", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/silvermoss/json", - "checked_at_utc": "2026-09-05T22:03:47.317822+00:00" - }, - { - "name": "silvermoss", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/silvermoss", - "checked_at_utc": "2026-09-05T22:03:47.408031+00:00" - }, - { - "name": "fablefern", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/fablefern.ai", - "checked_at_utc": "2026-09-05T22:03:47.463754+00:00" - }, - { - "name": "fablefern", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/fablefern/json", - "checked_at_utc": "2026-09-05T22:03:47.521486+00:00" - }, - { - "name": "fablefern", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/fablefern", - "checked_at_utc": "2026-09-05T22:03:47.628154+00:00" - }, - { - "name": "merrybloom", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/merrybloom.ai", - "checked_at_utc": "2026-09-05T22:03:47.647306+00:00" - }, - { - "name": "merrybloom", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/merrybloom/json", - "checked_at_utc": "2026-09-05T22:03:47.733840+00:00" - }, - { - "name": "merrybloom", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/merrybloom", - "checked_at_utc": "2026-09-05T22:03:47.915941+00:00" - }, - { - "name": "brightmuse", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/brightmuse.ai", - "checked_at_utc": "2026-09-05T22:03:47.852305+00:00" - }, - { - "name": "brightmuse", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/brightmuse/json", - "checked_at_utc": "2026-09-05T22:03:47.914214+00:00" - }, - { - "name": "brightmuse", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/brightmuse", - "checked_at_utc": "2026-09-05T22:03:48.103241+00:00" - }, - { - "name": "moonmoss", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/moonmoss.ai", - "checked_at_utc": "2026-09-05T22:03:48.080878+00:00" - }, - { - "name": "moonmoss", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/moonmoss/json", - "checked_at_utc": "2026-09-05T22:03:48.088846+00:00" - }, - { - "name": "moonmoss", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/moonmoss", - "checked_at_utc": "2026-09-05T22:03:48.384300+00:00" - }, - { - "name": "ambermuse", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/ambermuse.ai", - "checked_at_utc": "2026-09-05T22:03:48.264974+00:00" - }, - { - "name": "ambermuse", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/ambermuse/json", - "checked_at_utc": "2026-09-05T22:03:48.325109+00:00" - }, - { - "name": "ambermuse", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/ambermuse", - "checked_at_utc": "2026-09-05T22:03:48.518858+00:00" - }, - { - "name": "clearmeadow", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/clearmeadow.ai", - "checked_at_utc": "2026-09-05T22:03:48.507748+00:00" - }, - { - "name": "clearmeadow", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/clearmeadow/json", - "checked_at_utc": "2026-09-05T22:03:48.579206+00:00" - }, - { - "name": "clearmeadow", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/clearmeadow", - "checked_at_utc": "2026-09-05T22:03:48.742532+00:00" - }, - { - "name": "openfern", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/openfern.ai", - "checked_at_utc": "2026-09-05T22:03:48.689174+00:00" - }, - { - "name": "openfern", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/openfern/json", - "checked_at_utc": "2026-09-05T22:03:48.800979+00:00" - }, - { - "name": "openfern", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/openfern", - "checked_at_utc": "2026-09-05T22:03:48.937953+00:00" - }, - { - "name": "silverglow", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/silverglow.ai", - "checked_at_utc": "2026-09-05T22:03:48.945948+00:00" - }, - { - "name": "silverglow", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/silverglow/json", - "checked_at_utc": "2026-09-05T22:03:49.014729+00:00" - }, - { - "name": "silverglow", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/silverglow", - "checked_at_utc": "2026-09-05T22:03:49.201611+00:00" - }, - { - "name": "softcurrent", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/softcurrent.ai", - "checked_at_utc": "2026-09-05T22:03:49.160559+00:00" - }, - { - "name": "softcurrent", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/softcurrent/json", - "checked_at_utc": "2026-09-05T22:03:49.223130+00:00" - }, - { - "name": "softcurrent", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/softcurrent", - "checked_at_utc": "2026-09-05T22:03:49.424356+00:00" - }, - { - "name": "lightmoss", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/lightmoss.ai", - "checked_at_utc": "2026-09-05T22:03:49.389966+00:00" - }, - { - "name": "lightmoss", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/lightmoss/json", - "checked_at_utc": "2026-09-05T22:03:49.405083+00:00" - }, - { - "name": "lightmoss", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/lightmoss", - "checked_at_utc": "2026-09-05T22:03:49.632760+00:00" - }, - { - "name": "gentletide", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/gentletide.ai", - "checked_at_utc": "2026-09-05T22:03:49.577366+00:00" - }, - { - "name": "gentletide", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/gentletide/json", - "checked_at_utc": "2026-09-05T22:03:49.632608+00:00" - }, - { - "name": "gentletide", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/gentletide", - "checked_at_utc": "2026-09-05T22:03:49.857249+00:00" - }, - { - "name": "fablemoon", - "registry": "rdap", - "http_status": 404, - "summary": null, - "url": "https://rdap.identitydigital.services/rdap/domain/fablemoon.ai", - "checked_at_utc": "2026-09-05T22:03:49.817335+00:00" - }, - { - "name": "fablemoon", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/fablemoon/json", - "checked_at_utc": "2026-09-05T22:03:49.840200+00:00" - }, - { - "name": "fablemoon", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/fablemoon", - "checked_at_utc": "2026-09-05T22:03:50.076221+00:00" - } -] diff --git a/domain-name-screening-2026-09-05-cognition.csv b/domain-name-screening-2026-09-05-cognition.csv deleted file mode 100644 index 036bd4f1..00000000 --- a/domain-name-screening-2026-09-05-cognition.csv +++ /dev/null @@ -1,640 +0,0 @@ -domain,registrar_status,premium,registration_usd_per_year,renewal_usd_per_year,registrar_timestamp -aatos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -aava.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -accorto.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -adarme.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -adentro.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -adumbral.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -aflora.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -agnoia.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -ahndung.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -ahnen.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -ahnung.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -aisti.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -aistia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -ajatus.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -akari.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -alar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -alento.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -alethe.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -alethea.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -alidade.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -alula.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -alveus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -anfract.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -anima.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -animo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -animus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -aning.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -apercu.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -aperio.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -areola.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -areole.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -armilla.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -asola.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -asomar.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -asomo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -assioma.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -atinar.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -atino.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -atisba.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -atisbo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -aureole.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -auroral.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -avistar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -axon.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -azimuth.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -bifold.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -bosquejo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -bract.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -bracteal.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -brote.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -brujula.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -calice.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -calyce.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -calyx.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -candent.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -candor.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -catkin.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -catopta.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -cauce.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -cauces.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -caustic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -caustics.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -celaje.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -cernere.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -cernis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -cerno.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -chiarore.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -clarear.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -clartes.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -cogito.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -corolla.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -corollae.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -corymb.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -cyme.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -cymose.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -dedans.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -deepview.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -dendron.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -denken.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -denker.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -dentro.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -destello.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -desvela.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -desvelo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -deuten.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -deuter.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -devaneio.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -devoile.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -devoiler.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -dianoia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -diaphan.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -dimora.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -diopter.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -dioptra.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -dioptre.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -disvelo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -doxa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -eclaire.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -eclat.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -eclore.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -eidetic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -eidola.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -eidolon.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -eidos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -eikasia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -einblick.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -elava.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -elicere.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -elicit.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -elicite.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -elucide.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -emoi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -endon.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -energeia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -energein.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -energeo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -enfold.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -engram.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -engrama.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -ennoia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -ensejo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -ensoul.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -entender.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -entrevu.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -envers.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -epinoia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -esbozo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -esprit.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -eveil.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -evince.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -evolute.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -facet.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -facetia.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -facetiae.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -faden.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -falte.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -falten.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -fanal.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -fascial.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -fascicle.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -feinsinn.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -feixe.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -fibril.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -figura.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -filar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -filo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -filose.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -filum.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -fleuron.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -floret.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -folio.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -forma.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -fresta.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -frond.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -frondlet.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -fulgur.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -geodesic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -geodesy.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -germen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -glia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -glimt.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -glod.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -glossa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -glossal.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -glotta.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -glume.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -gnosis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -gyri.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -gyrus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -hajime.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -havainto.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -havaita.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -hazama.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -hebra.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -helming.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -hibari.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -hibiki.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -hilar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -hilvan.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -hinata.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -hizashi.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -hohde.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -horama.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -hotaru.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -hyle.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -illume.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -imago.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -inblick.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -infold.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -inhere.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -innen.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -innside.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -innsikt.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -innsyn.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -inscape.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -inspect.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -insyn.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -intento.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -intima.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -intimo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -intone.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -intrace.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -intuito.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -intus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -involute.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -inward.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -iridal.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -irides.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -iridic.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -isocline.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -isogon.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -isogone.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -isophote.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -isopleth.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -kagami.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -kagero.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -kajastus.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -kajava.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -kajo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -kajota.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -kasanari.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -kasane.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -katse.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -keel.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -keim.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -kenning.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -kenspeck.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -kielo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -kioku.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -kirei.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -klarna.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -kodama.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -kohaku.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -kokoro.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -komorebi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -kotoba.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -krinein.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -kuulas.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -kuulto.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -laine.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -lamella.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -lamina.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -lanka.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -lanthorn.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -latebra.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -latebrae.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -latens.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -lateo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -lauschen.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -legato.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -lemma.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -lexeme.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -ligula.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -ligule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -limbus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -limen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -limina.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -limner.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -limpid.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -lisiere.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -ljus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -logia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -loimu.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -lucarne.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -lucency.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -lucent.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -lucern.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -lucerna.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -lucida.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -lucidez.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -lucido.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -luciole.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -lucule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -lueur.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -lueurs.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -luff.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -luffing.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -luisant.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -lumen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -lumet.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -lumina.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -luminate.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -lunula.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -lunule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -luoto.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -luova.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -lysa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -madobe.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -madori.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -manabi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -manabu.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -matassa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -medula.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -mens.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -mentis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -merism.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -metanoia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -michi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -mieli.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -minamo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -miolo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -mirada.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -mirino.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -mizuki.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -moira.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -moire.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -morula.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -mueca.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -muesca.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -murmure.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -nacre.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -nacrous.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -nagare.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -nagori.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -nervio.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -nervure.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -nesso.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -neurite.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -neurula.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -nitido.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -nitore.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -nodo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -noein.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -noema.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -noeron.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -noesis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -noetic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -noetos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -nosco.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -notum.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -noumen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -noumena.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -noverim.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -nuage.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -nuance.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -nuancer.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -nucleo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -ogee.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -ogive.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -oiva.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -oivallus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -oivaltaa.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -oivata.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -olhar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -olho.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -omoi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -omote.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -opalin.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -opalina.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -opaline.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -opsis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -orama.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -ordire.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -ordito.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -oriel.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -orlare.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -otear.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -ousia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -palea.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -pateo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -pelucid.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -pensar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -pensare.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -pensato.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -pensee.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -penser.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -pensiero.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -penumbra.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -percee.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -perspic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -phaino.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -phare.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -phares.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -pharos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -phasis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -phonic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -phren.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -phrena.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -phronema.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -phronis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -piega.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -pieghe.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -pinna.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -pinnule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -pleat.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -pliant.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -plica.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -plicae.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -plicate.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -pliegue.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -pliure.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -portato.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -profilo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -prosody.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -punoa.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -punos.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -purl.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -purlin.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -purling.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -radula.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -raggio.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -raison.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -raita.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -ramal.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -ramus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -rasgo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -rastro.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -raum.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -raunen.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -ravel.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -reflet.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -reflets.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -refocus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -refold.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -relance.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -releve.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -relief.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -relume.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -rendija.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -replat.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -repli.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -resorte.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -retalho.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -retazo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -retazos.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -rete.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -rethread.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -retia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -reticle.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -retune.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -reveal.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -reveil.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -revelar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -revers.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -ricalco.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -ricamo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -rilievo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -rill.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -rimple.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -ripple.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -risalto.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -risvolto.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -rubato.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -ruche.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -ruched.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -ruching.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -rucking.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -rudder.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -runnel.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -saber.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -saperi.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sapient.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -sapore.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -satori.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -sbircio.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -schau.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -scorcio.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -scull.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -sema.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -seme.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -sememe.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -semina.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -semino.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -semion.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -senno.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -sensa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -sensio.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -senso.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -sensum.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -senti.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -sentic.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -sentio.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -sentir.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -sentire.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -serein.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sesgar.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -sesgo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -sesudo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -sguardo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -shiori.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -shirabe.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -shiru.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -shirube.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -shirushi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -shizuku.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -sikt.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -sillage.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sinn.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -sinueux.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sisalla.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -sisin.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -sisus.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -sken.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -skimra.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -skimte.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -slue.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -sluice.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -snodo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -solmu.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -soma.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -somite.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -sonance.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -sonant.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -sonda.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sondeo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -songe.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -songes.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sonhar.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -sonho.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -sonoro.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -sopro.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -soral.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -sorus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -spola.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -spore.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -sporule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -spuren.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -stipule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -subrosa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -sugata.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -sulci.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -sulcus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -sutil.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -svelare.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -svelato.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -svelo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -synlig.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -talamo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -tankar.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -tanke.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -taxis.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -tela.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -tellur.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:09 -tenere.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -tenuto.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -tepala.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -tepaline.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -tesela.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -tessere.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -textum.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -theoria.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -thole.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -tholing.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -thymos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -thyrse.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -thyrsus.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -tiller.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -tillered.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -tonos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -traccia.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -tracer.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -tracery.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -trama.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -trame.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -tramer.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -trameur.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -transom.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -trasluz.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:11 -traspare.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -trazo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -tremolo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -tropos.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -tsubomi.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -tsumugi.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -tsuzuri.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -tuck.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -tuft.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -tufted.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:17 -tuike.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -tuiki.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -tyda.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -tydelig.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -tyding.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -udito.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -umbel.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -umbra.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -umbral.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -uncoil.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unfurl.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unlace.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unmask.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unmesh.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unmute.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unseam.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unskein.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unspool.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -untwine.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -unweave.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -unweft.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:02 -usva.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -utsuro.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -utsuwa.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -vagen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -vaisto.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -valaise.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -valkea.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -valo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -varco.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -varde.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -variare.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -varse.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -varsel.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -vava.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -vedo.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -veduta.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:19 -veering.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -veille.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -veilleur.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:31 -velamen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -velar.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -velina.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:25 -veludo.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -velum.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:50 -venula.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -venule.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:56 -veva.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -vevna.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -vietti.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -vire.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -viri.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -visao.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -visto.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -voluta.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -volute.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -vyer.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:43 -vyyhti.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:30 -wispish.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -wissen.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:37 -wistful.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -wistly.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -witan.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -witling.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -witting.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -yawing.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:16:15 -yohaku.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -yosuga.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -yukari.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 -yukue.ai,AVAILABLE,0,82.7,82.7,2026-09-05 22:14:37 -yurai.ai,UNAVAILABLE,0,82.7,82.7,2026-09-05 22:15:24 diff --git a/domain-name-screening-2026-09-05-round-2.csv b/domain-name-screening-2026-09-05-round-2.csv deleted file mode 100644 index a4e45229..00000000 --- a/domain-name-screening-2026-09-05-round-2.csv +++ /dev/null @@ -1,801 +0,0 @@ -"domain","result","type","ts","premium","price","renewal" -"dawdle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dawdler.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dally.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dilly.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"pootle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"tootle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"tootler.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"noodle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"noodler.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"noodling.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"natter.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"prattle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"patter.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"patten.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"jotter.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"jotting.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"jottings.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"mutter.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"mutterer.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"mumbled.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"mumbly.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"mumbler.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"gibber.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"babble.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"babbler.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"burble.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"burbly.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"warbling.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fleeting.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"flitting.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"flitter.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"flutter.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"flurry.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"flurried.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"froth.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"frothy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"frolic.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"frisky.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"frizzle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"frizzy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"frippery.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"trinket.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"bauble.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"bijou.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"doodad.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"doodler.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"doodling.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"riffle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"riffling.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"riffler.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"tinkerer.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"tinkling.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"tinkle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dinkum.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dinky.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"diddly.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fiddly.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fidget.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fidgety.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"scooch.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squish.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squishy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squidge.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squeezy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squeak.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squeaky.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"squeal.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"snuggle.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"snugly.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"snugger.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"snoozy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"snoozer.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dozy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dozing.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dozer.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"drowsing.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"napping.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"napper.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"nappy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"snooze.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"sleepy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"sleepily.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"slumbery.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dreamer.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dreamful.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dreamily.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dreamy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dreamt.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"dreamlike.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fanciful.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fancy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fancied.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"whimsy.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"whims.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"whim.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"whimlet.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"whimful.ai","AVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"fancify.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"wishful.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"wist.ai","UNAVAILABLE","registration","2026-09-05 15:28:02","0","8270","8270" -"lantern.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"lamplight.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"candle.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"candor.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"candid.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"canny.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"candlelit.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"glowworm.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"glowlight.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"stargaze.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"starglow.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"starlet.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"starry.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"starlight.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"moonrise.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"moonbeam.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"moonlight.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sunbeam.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sunburst.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sundial.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sundog.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sunspot.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sunward.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"sundown.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"daylight.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"daybreak.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"dayglow.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"daystar.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"daydreams.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"dreamwork.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"dreamscape.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"dreamland.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"dreamtime.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"lullaby.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"lull.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"lulling.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"hush.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"hushed.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"hushful.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"quietly.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"quietude.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"stillness.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"stilling.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"still.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"softest.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"softer.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"softly.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"softy.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"gentler.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"gently.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"tenderly.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"tender.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"gentleness.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"velvet.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"velvety.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"satiny.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"silky.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"plush.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"plushy.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"fleecy.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"fleece.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"woolly.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"woolen.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"woollen.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"cottony.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"cotton.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"gossamer.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"gauzy.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"diaphane.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"diaphany.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"gauzily.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"feathery.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"feather.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"feathered.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"downwind.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"windward.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"wayfinder.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"waymark.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"waypost.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"signpost.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"guidepost.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"handrail.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"handhold.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"foothold.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"handloom.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"handwork.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"handbell.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"handsel.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"foothill.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"firelight.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"fireglow.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"fireside.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"hearth.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"hearthside.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"hearthrug.ai","AVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"kindling.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"ember.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"embers.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"emberglow.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"cinder.ai","UNAVAILABLE","registration","2026-09-05 15:29:06","0","8270","8270" -"persimmon.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"pawpaw.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"papaya.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"guava.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"quince.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"loquat.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"kumquat.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"apricot.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nectarine.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sweetness.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sweetly.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sweetpea.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"honeypot.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"honeybun.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"honeybee.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"honeycomb.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"honeyed.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jammed.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jammies.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jammy.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jello.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jellies.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jellied.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jelly.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"gumdrops.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"gumdrop.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"trifling.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"trifles.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"trifle.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"taffy.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"tidbits.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"tidbit.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"morsels.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"morsel.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nubbin.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nubbins.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nibbler.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"niblet.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nibbles.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nibble.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"bonbons.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"bonbon.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"truffler.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"truffles.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"truffle.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dimpled.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dimply.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dimples.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dimple.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dumplings.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dumpling.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"puddings.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"pudding.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crumbles.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crumbly.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crumb.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crumbs.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"croutons.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crouton.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sprinkles.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sprinkle.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"drizzling.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"drizzle.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dollops.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"dollop.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"molasses.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"marmalade.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"souffle.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"syllable.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sorbet.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"sherbet.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"granita.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"popcorn.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"flapjack.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"marzipan.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"tapioca.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"semolina.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"orzo.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"risotto.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"pottage.ai","AVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"polenta.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"porridge.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"shortcake.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"curd.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"custard.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"praline.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"meringue.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"nougat.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"fudge.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"toffee.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"treacle.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"butter.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"buttery.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crumby.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"crumble.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"biscotti.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"biscuit.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"brioche.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"scone.ai","UNAVAILABLE","registration","2026-09-05 15:36:19","0","8270","8270" -"jaunty.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"wryly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"airily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"breezily.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"breezy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"blithe.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"blithely.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"playful.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puckish.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"impish.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"droll.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"drollery.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"wry.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"wily.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"coyly.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"curious.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"oddly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"oddity.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quirky.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quirk.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quibble.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quibbler.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quip.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quippy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"quipping.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"wit.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"witty.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"wittily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"whimsyful.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"winsome.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"perky.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"perkily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cheeky.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cheery.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cheerily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"chirpy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"chirr.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"chirrup.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"chirrupy.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"chirping.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"peppy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"spry.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"sprightly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"lively.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"livelier.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"merrily.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"merry.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"mirth.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"mirthful.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"jolly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"jollity.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"jollily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"jovial.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"jovially.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"sassy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"sassily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"feisty.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"spunky.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"feistier.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"spiffy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"spiff.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"spiffing.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"nifty.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"niftier.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"natty.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"nattier.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"nimbly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"dainty.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"daintily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"dapper.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"dapperly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"dandy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"dandily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"snug.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"snuggly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cosy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cozy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cozily.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cozying.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cuddly.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cuddles.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"cuddling.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"fluffy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"fluffily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puffy.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puffily.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puffball.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puffballs.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puffery.ai","AVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"puffling.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"peep.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"peek.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"peeking.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"peeper.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"peephole.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"porthole.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"spyglass.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"lookout.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"looksee.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"looker.ai","UNAVAILABLE","registration","2026-09-05 15:36:01","0","8270","8270" -"onlooker.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"keyhole.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"skylight.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"sunroom.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"windchime.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"windup.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"windmill.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"pinwheel.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"whirligig.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"whirly.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"whirling.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"gleeful.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"gleefully.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"giddy.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"giddily.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"giggly.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"giggle.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"giggling.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"giggler.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"twiddly.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"twiddler.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"twiddling.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"waggish.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"waggle.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"waggly.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"wiggly.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"wriggly.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"wriggler.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"nuthatch.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"waxwing.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"wagtail.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"cuckoo.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"peewit.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"peewee.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"wren.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"humming.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"blackcap.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"beech.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"beechnut.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"hazelnut.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"chestnut.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"acorn.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"hazel.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"nutmeg.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"mynah.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"myna.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"songbird.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"jackdaw.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"magpie.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"jaybird.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"sparrow.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"swallow.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"swift.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"swiftlet.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"warbler.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"wagtails.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"kinglet.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"redpoll.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"crossbill.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"dotterel.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"godwit.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"bluebird.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"blackbird.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"tealight.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"coot.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"moorhen.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"bunting.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"goldcrest.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"firecrest.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"chaffinch.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"bullfinch.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"finch.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"finches.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"firkin.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"furrow.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"furlong.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"farthing.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"faraway.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"nearish.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"nearby.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"afar.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"yesteryear.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"yestereve.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"erstwhile.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"sometime.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"hither.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"hence.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"henceforth.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"haply.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"hapless.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"happy.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"glad.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"gladsome.ai","AVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"gladly.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"gladness.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"aplomb.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"verve.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"fervor.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"fervour.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"ardor.ai","UNAVAILABLE","registration","2026-09-05 15:37:06","0","8270","8270" -"outward.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"innermost.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"within.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"beneath.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"underlay.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"underside.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"underlit.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"overlook.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"foresight.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"hindsight.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"sleuth.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"reveal.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"revealer.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"disclose.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"disclosure.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"untell.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"latent.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"latently.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"tacitly.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unvoiced.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"voicing.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unsay.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"retold.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"relit.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"recasting.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"inflected.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"inflects.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"incline.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"inclined.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"intone.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"intoned.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"attuned.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"detune.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"tunable.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"tuneful.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"tuner.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"undertow.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"undergo.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"underglow.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"interlay.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"interlap.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"intermix.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"interplay.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"innerly.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"outmost.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"outlier.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"outliers.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"outcrop.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"outcrops.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"offcut.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"offcuts.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"cutaway.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"cutout.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"cutline.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"cutback.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"cutwork.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"crosscut.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"crossway.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"crossways.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"crosswind.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"sidewind.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"sidelight.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"sidewise.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"sideways.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"edgewise.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"endwise.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"insightfully.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"openwork.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"openmind.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"openminded.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"openhand.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unfold.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unfolding.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unfolded.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unrolled.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"uncoiled.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unlaced.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"untwisted.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unwoven.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unweft.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unpicking.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unpicked.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unspooled.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unraveled.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unravelled.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unknotted.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unwinding.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unwound.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unmuffle.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unmuffled.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unfazed.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unruffled.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unhushed.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"uncloak.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"uncloaked.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unveiled.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unveiling.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unclasp.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unclasped.ai","AVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unlock.ai","UNAVAILABLE","registration","2026-09-05 15:38:26","0","8270","8270" -"unlocked.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unlatch.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unlatched.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unseal.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unsealed.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unstitch.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unstitched.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"undoing.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"undone.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unbound.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unfurled.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unfetter.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"unfettered.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rethink.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rethought.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reframed.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rework.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reworked.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"remold.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"remould.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reshape.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reshaped.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reshaper.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"recode.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"recoded.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rewired.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rewire.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rewoven.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"refitted.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"refolded.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"refocus.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"refocused.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"readjust.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"realign.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"realigned.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reorder.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"retint.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reroute.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rerouted.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"retrace.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"retraced.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"retracing.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"redirect.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reorient.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reoriented.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rethinker.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"rethinks.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tinting.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tint.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"shade.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"shading.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"shaded.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tone.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"toned.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"temper.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tempering.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tamber.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"telltale.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tattler.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tellable.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"legible.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"legibly.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"readable.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"readably.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"seeable.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"viewable.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"viewless.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"viewed.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"viewer.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"glimpse.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"glimpsed.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"glean.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"gleaner.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"gleaned.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reveries.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"revering.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"reverent.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"daydreamer.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"dreaming.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"lucid.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"limpidly.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"numinous.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"noumenal.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"quale.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"quiddity.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"quiddler.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"eidos.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"eidola.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"monad.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"dyad.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"triad.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"tetrad.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"pentad.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"ennead.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"heptad.ai","AVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"sextet.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"octet.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"nonet.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"septet.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"sevenfold.ai","UNAVAILABLE","registration","2026-09-05 15:39:16","0","8270","8270" -"moonglow.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"moondust.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"moonbow.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sunshower.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sunblind.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"moonward.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sunwise.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sunray.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sunrays.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sunlamp.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"suntime.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"dewfall.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"dewily.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"daylily.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowbell.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowdrop.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowcap.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowbank.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowflake.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowdrift.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowmelt.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowfall.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowbird.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sundew.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"bellflower.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"snowberry.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"cloudberry.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"cloudlet.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"cloudlets.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"foglet.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"haze.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"hazy.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"hazily.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"misted.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"misting.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"mistlike.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"mothy.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"mothwing.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"mothlike.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"fireflies.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"glowfly.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"glowmoth.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"fireweed.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"foxglove.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"foxfire.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"foxtail.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"heather.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"heath.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"heathery.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"gorse.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"gorget.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"gorsy.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"fernery.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"fernlike.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"ferny.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"bramble.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"brambly.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"briar.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"brier.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"briary.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"reedy.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"reedlike.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"sedgy.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rushy.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rushlet.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rills.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"runnels.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rindle.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rillet.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"freshets.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"streamlet.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"brooklet.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"brooklets.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"brookside.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rivulet.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"rivery.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"riverlet.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"flowlet.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"flowstone.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"flowage.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"floe.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"floes.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"floater.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"floaty.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"afloat.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"adrift.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"drifter.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"drifting.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"drifted.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"drifty.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"waft.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wafting.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wafted.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wafture.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wisp.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wisps.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wispy.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wispily.ai","AVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"wispen.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" -"zephyr.ai","UNAVAILABLE","registration","2026-09-05 15:41:01","0","8270","8270" - diff --git a/domain-name-screening-2026-09-05.csv b/domain-name-screening-2026-09-05.csv deleted file mode 100644 index 560ee137..00000000 --- a/domain-name-screening-2026-09-05.csv +++ /dev/null @@ -1,595 +0,0 @@ -domain,result,type,ts,premium,price,renewal -drowse.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -unspool.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -unfurl.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -splay.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -thrum.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -twill.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -weft.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -purl.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -skein.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -nock.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -yaw.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -skirl.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -furl.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -glint.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -gleam.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -glimmer.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -limen.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -liminal.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -noema.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -noesis.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -qualia.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -engram.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -eidetic.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -reverie.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -musing.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -musingly.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -inward.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -slumber.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -drowsy.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -pensive.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -daydream.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -drift.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -ripple.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -rill.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -runnel.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -eddy.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -freshet.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -shoal.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -tarn.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -tor.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -whorl.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -volute.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -gnomon.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -alidade.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -reticle.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -lenslet.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -prism.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -caustic.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -parallax.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -moire.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -umbra.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -penumbra.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -aureole.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -lucent.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -nacre.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -opaline.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -vireo.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -pipit.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dunlin.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -linnet.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dipper.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -lapwing.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -tern.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -sable.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -fennec.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -stoat.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -civet.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dormouse.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dunnock.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -borage.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -brayer.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dimity.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -doline.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -cannel.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -mullion.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -muntin.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -lintel.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -soffit.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -bevel.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -chamfer.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dado.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -rabbet.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -tenon.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -dowel.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -spindle.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -bobbin.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -shuttle.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -heddle.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -treadle.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -lilt.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -legato.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -rubato.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -timbre.ai,UNAVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -mordent.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -hemiola.ai,AVAILABLE,registration,2026-09-05 15:05:12,0,8270,8270 -unweave.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -untwine.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -untwist.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -uncoil.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unlace.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -untuck.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unpick.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unbind.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unwind.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unravel.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unroll.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unmask.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unshade.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -uncloud.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -undrape.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -unveil.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -untold.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -untangle.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -refold.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -refit.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -reframe.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -retune.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -attune.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -inflect.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -deflect.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -refract.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -diffract.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -cleave.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -swerve.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -veer.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -yawl.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -tiller.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -rudder.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -capstan.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -clew.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -luff.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -leeway.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -lee.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -helm.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -halyard.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -yonder.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -glade.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -bower.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -bracken.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -sorrel.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -sedge.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -rushes.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -teasel.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -yarrow.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -catkin.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -samara.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -samphire.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -vetch.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -clover.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -bluebell.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -cowslip.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -woodlark.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -skylark.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -redstart.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -redwing.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -sandpiper.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -turnstone.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -avocet.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -veery.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -pewee.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -wigeon.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -teal.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -siskin.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -fulmar.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -curlew.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -plover.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -petrel.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -merganser.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -larkspur.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -firefly.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -mayfly.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -caddis.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -damselfly.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -dapple.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -stipple.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -fleck.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -speckle.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -freckle.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -mottle.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -ripplets.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -billow.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -billowy.ai,AVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -silken.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -satin.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -velour.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -voile.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -calico.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -cambric.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -muslin.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -damask.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -brocade.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -poplin.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -taffeta.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -tulle.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -gauze.ai,UNAVAILABLE,registration,2026-09-05 15:07:45,0,8270,8270 -gloss.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -glim.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -glisten.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -shimmer.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -flicker.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -waver.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -quiver.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -shiver.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -tremor.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -quaver.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -warble.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -murmur.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -mumble.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -rustle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -susurr.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -sough.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -whisper.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -whither.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -thither.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -inmost.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -inly.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -inwardly.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unthought.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unbidden.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unspoken.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unsaid.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unsung.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unshown.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unseen.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -unlit.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -relight.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -limpid.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -pellucid.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -lucidity.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -lucidly.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -placid.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -wistful.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -wistfully.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -wonderment.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -pondering.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -ponder.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -brood.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -dreamlet.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -daylit.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -sunlit.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -moony.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -moonlit.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -moonlet.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -gloam.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -gloaming.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -dawning.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -duskily.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -vesper.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -vespers.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -crepuscle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -crepuscular.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -eventide.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -evenfall.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -auroral.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -nacrous.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -pearly.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -pearlescent.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -opalescent.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -shimmery.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -gleamy.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -glinty.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -glimmery.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -spangle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -spangled.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -twinkle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -twinkly.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -twilit.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -starlit.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -starling.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -linnets.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -finchlet.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -nestle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -nestling.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -nuzzle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -nuzzly.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -downy.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -fledge.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -fledged.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -fledgling.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -fluff.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -flume.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -spume.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -brume.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -brumous.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -rime.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -rimy.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -hoarfrost.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -frostlet.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -dewlap.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -dewdrop.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -dewlet.ai,AVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -dewy.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -mistle.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -misty.ai,UNAVAILABLE,registration,2026-09-05 15:08:49,0,8270,8270 -conation.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -conative.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -enactive.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -enaction.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -afford.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -noetic.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -noumen.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -noumena.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -appercept.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -deictic.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -deixis.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sememe.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -alloseme.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -intension.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -construal.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -inhere.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -inhese.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -qualic.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -eidolon.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ectype.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ectypal.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ideatum.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ideate.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ideant.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -cogent.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -conatus.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -conflate.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -gestalt.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -apperceive.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -insight.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -retrodict.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -precept.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -percept.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -percip.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -intuent.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sapient.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sentient.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sensate.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sentire.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sentic.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -nescient.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sublimen.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -sublimate.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -subtext.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -subword.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -undertone.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -overtone.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -toneme.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -phoneme.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -prosody.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -caesura.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -spondee.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -trochee.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -iamb.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -anapest.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -scansion.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -elision.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ellipsis.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -dexis.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -dictum.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -dicta.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -glossa.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -lexis.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -lemma.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -glossol.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -glossing.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -recast.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -revoice.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -reweave.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -redraft.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -rescore.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -retell.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -scumble.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -frisket.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -scrim.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -tracery.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -tessera.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -graver.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -burin.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -gouge.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -etcher.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -etching.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -hatchery.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -duotone.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -tritone.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -halftone.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -tinter.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -tintype.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -grisaille.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -encaustic.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -impasto.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -pentimento.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -intaglio.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -finial.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -arris.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -cove.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -coving.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ogee.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -ogive.ai,AVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -torus.ai,UNAVAILABLE,registration,2026-09-05 15:11:07,0,8270,8270 -twiddle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -tweak.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -fiddle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wiggle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wobble.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wriggle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wrangle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wangle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wheedle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -coaxer.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -cajole.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -caress.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -tussle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -ruffle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -rumple.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -crumple.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pleat.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -plait.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -plisse.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -unpleat.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -unknit.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -unknot.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -unbraid.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -unblend.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -unthread.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -threadlet.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -yarnlet.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -tassel.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -bobble.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -bobbly.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pommel.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -gimbal.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -fulcrum.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pawl.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -ratchet.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -cogwheel.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pinion.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -bevelled.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -whittle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -whittler.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -spokeshave.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -spicule.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -splint.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -splinter.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -sloyd.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -adze.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -awl.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -bodkin.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -thimble.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -gimlet.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -gouger.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -auger.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -wherry.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -skerry.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -skiff.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -coracle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -coble.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -dinghy.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -dory.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pram.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -punt.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -scull.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -sculler.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -scuttle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -scupper.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -sprit.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -sprig.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -twiglet.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -leaflet.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -bract.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -bractlet.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -umbel.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -cyme.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -corymb.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -raceme.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -panicle.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -glume.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -awn.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -aril.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -husk.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -frond.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -foliole.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pinna.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -lamina.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -lamella.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -lamellar.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -petiole.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -stipule.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -isotone.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -isoline.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -isopleth.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -isobar.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -isobath.ai,AVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -isogon.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -dyadic.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -sheaf.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -sheave.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -lissome.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -lissom.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -pliant.ai,UNAVAILABLE,registration,2026-09-05 15:12:11,0,8270,8270 -ramify.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -ramose.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -ramous.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -pleach.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -coppice.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -pollard.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -bough.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -bole.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -burl.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -burr.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -onlap.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -offlap.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -drumlin.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -kettle.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -kame.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -esker.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -moraine.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -arete.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -cirque.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dell.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dingle.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dint.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dent.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -tatter.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -tattered.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -drape.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -drapery.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swathe.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swath.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swatch.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swatchy.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swaddle.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swish.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swoosh.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swoop.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swoon.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -saunter.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -gambol.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -gambit.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -gambrel.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -amble.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -ambler.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -ramble.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -rambler.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -meander.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -wander.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -wanderer.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -wayward.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -wayworn.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -sidle.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -sidestep.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -sidelong.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -oblique.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -slantwise.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -askew.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -skew.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -slant.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -swerver.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -nudger.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -softie.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -mellow.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -mallow.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -muggy.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -marshy.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -smidgen.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -smidge.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dabble.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dabber.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dabster.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dappled.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dappler.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -ruddle.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -raddle.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -dittany.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -tansy.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -madder.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -weld.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -woad.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -burdock.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -comfrey.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -chervil.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -chive.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -savory.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -burnet.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -betony.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -woodruff.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -vervain.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -speedwell.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -harebell.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -eyebright.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -bugle.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -fleabane.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -fleawort.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -sepal.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -tepal.ai,AVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -stamen.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -anther.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -filament.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -pistil.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 -ovule.ai,UNAVAILABLE,registration,2026-09-05 15:13:58,0,8270,8270 diff --git a/domain-name-shortlist-2026-09-05-cognition.csv b/domain-name-shortlist-2026-09-05-cognition.csv deleted file mode 100644 index 94254d9a..00000000 --- a/domain-name-shortlist-2026-09-05-cognition.csv +++ /dev/null @@ -1,21 +0,0 @@ -rank,name,domain,letters,pronunciation,language,meaning,project_fit,editorial_note,meaning_source,registrar,registrar_status,premium,registration_usd_per_year,minimum_initial_years,calculated_initial_usd_before_tax,renewal_usd_per_year,minimum_renewal_years,checked_at_utc,purchase_link,rdap_http_status,pypi_http_status,npm_http_status,existing_use_note,existing_use_source -1,Nitore,nitore.ai,6,nee-TOH-reh,Italian,"Clarity, brilliance, polish.","A precise, elegant name for making model internals intelligible.","Best overall balance of sound, brevity, and purpose.",https://www.treccani.it/vocabolario/nitore/,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=nitore.ai,404,404,404,No obvious exact-name AI/software product surfaced in the bounded web screen. Surname and account-name uses exist., -2,Sisin,sisin.ai,5,SEE-sin,Finnish,Innermost.,"The shortest, most direct expression of looking inside a model.","Five letters, two syllables, and an unusually exact thematic fit.",https://en.wiktionary.org/wiki/sisin,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=sisin.ai,404,404,404,SISIN also appears as an acronym for a Bolivian public-investment information system; no exact-name AI workbench surfaced.,https://www.contraloria.gob.bo/wp-content/uploads/2025/03/GATIC-AUD-2024-001.pdf -3,Asomar,asomar.ai,6,ah-soh-MAR,Spanish,To appear or come into view.,Hidden patterns becoming visible through probes and readouts.,Warm and spacious; especially suited to a visual exploration product.,https://www.larousse.com/en/dictionaries/spanish-english/asomar/3441,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=asomar.ai,404,404,404,Existing communications consultancy and maritime-association uses. No exact-name AI workbench surfaced.,https://asomar.es/en/elementor-1425/ -4,Unskein,unskein.ai,7,un-SKAYN,English,To unwind a skein; to unfurl.,Untangling distributed representations into understandable threads.,Strongest English metaphor; spelling is less familiar than its sound.,https://en.wiktionary.org/wiki/unskein,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=unskein.ai,404,404,404,No obvious exact-name software product surfaced; literary uses exist., -5,Merism,merism.ai,6,MAIR-iz-um,"English, from Greek","A whole expressed through contrasting parts, such as high and low.",An unusually close match to concept poles and the space between them.,Most conceptually specific; a little more academic than the first four.,https://en.wiktionary.org/wiki/merism,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=merism.ai,404,404,404,A community-oriented landing page and company-directory entries use Merism. No exact-name AI workbench surfaced.,https://merism.org/ -6,Svelare,svelare.ai,7,zveh-LAH-reh,Italian,To reveal or unveil.,A direct statement of the interpretability mission.,Elegant and active; the initial sv sound needs one introduction for English speakers.,https://dictionary.cambridge.org/dictionary/italian-english/svelare,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=svelare.ai,404,404,404,No obvious exact-name AI/software product surfaced in the bounded web screen., -7,Ricalco,ricalco.ai,7,ree-KAHL-koh,Italian,Tracing or a copy produced by tracing.,Following the outlines and paths of internal model behavior.,"Crisp, rhythmic, and more instrument-like in tone.",https://www.treccani.it/vocabolario/ricalco/,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=ricalco.ai,404,404,404,Ricalco appears descriptively in drawing-software titles; no clear standalone exact-name AI brand surfaced.,https://apps.apple.com/it/app/ar-drawing-schizzo-ricalco/id6760111809 -8,Deuten,deuten.ai,6,DOY-tuhn,German,To interpret or read signs.,Turning hidden measurements into something understandable.,Compact and serious; eu is pronounced oy in German.,https://dictionary.cambridge.org/dictionary/german-english/deuten,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=deuten.ai,404,404,404,No obvious exact-name AI/software product surfaced in the bounded web screen., -9,Falte,falte.ai,5,FAHL-tuh,German,"A fold, crease, or wrinkle.",A simple geometric image for folded representation spaces.,Five letters and two syllables; a strong geometric identity.,https://www.collinsdictionary.com/dictionary/german-english/falte,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=falte.ai,404,404,404,Common word and surname uses; no exact-name AI/software brand surfaced in the bounded screen., -10,Punoa,punoa.ai,5,POO-noh-ah,Finnish,To weave or plait.,Composing steering directions and following the model's intertwined features.,"Soft, distinctive, and only five letters.",https://livingdictionaries.app/finnish/entry/80b77ce8-860d-42b3-8d8c-6b1080623ea2,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=punoa.ai,404,404,404,Also a place name and surname; no obvious exact-name AI/software product surfaced.,https://en.wikipedia.org/wiki/Punoa -11,Havaita,havaita.ai,7,HAH-vy-tah,Finnish,"To perceive, observe, detect, or notice.",Almost a definition of what the probing instruments let you do.,A precise perception word with a clear three-syllable rhythm.,https://en.wiktionary.org/wiki/havaita,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=havaita.ai,404,404,404,No obvious exact-name AI/software product surfaced in the bounded web screen., -12,Udito,udito.ai,5,oo-DEE-toh,Italian,Hearing; the sense of hearing.,A metaphor for listening to otherwise inaccessible internal signals.,"Short, warm, and immediately speakable.",https://www.collinsdictionary.com/dictionary/italian-english/udito,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=udito.ai,404,404,404,An unrelated hearing-care clinic uses Udito.,https://www.udito.pl/ -13,Skimte,skimte.ai,6,SHIM-teh,Norwegian,To glimpse or discern faintly.,Catching a glimpse of the hidden activity behind an answer.,Compact and distinctive; Norwegian ski here sounds like shi.,https://dictionary.cambridge.org/dictionary/norwegian-english/skimte,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=skimte.ai,404,404,404,No obvious exact-name AI/software product surfaced in the bounded web screen., -14,Ordire,ordire.ai,6,or-DEE-reh,Italian,To set up the warp of a fabric; also to weave or plot.,Preparing the threads from which model behavior is composed.,Memorable and purposeful; the plotting sense is a tonal consideration.,https://www.treccani.it/vocabolario/ordire/,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=ordire.ai,404,404,404,No obvious exact-name AI/software product surfaced; the ordinary word also means to hatch a plot., -15,Risvolto,risvolto.ai,8,reez-VOHL-toh,Italian,"A turned-back fold; figuratively, a less visible aspect or implication.",Revealing the other side of a model response.,"The longest option at eight letters, but a strong three-syllable word.",https://www.treccani.it/vocabolario/risvolto_%28Sinonimi-e-Contrari%29/,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=risvolto.ai,404,404,404,Existing fashion/boutique usage; no obvious exact-name AI/software product surfaced.,https://it.wikipedia.org/wiki/Risvolto -16,Rimple,rimple.ai,6,RIM-puhl,English,"A fold, wrinkle, or ripple.",Small changes moving through a curved internal landscape.,One of the easiest to say; playful and tactile.,https://www.merriam-webster.com/dictionary/rimple,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=rimple.ai,404,404,200,"The exact npm name is already a JavaScript library. Kept as a domain-available option, with a developer-namespace collision.",https://github.com/xiechao06/rimple -17,Retazo,retazo.ai,6,reh-TAH-soh,Spanish,"A fragment, remnant, or snippet.",Small pieces of activity used to understand a larger representation.,Strong consonants and a clear three-syllable rhythm; guide uses Latin American pronunciation.,https://www.spanishdict.com/translate/el%20retazo?langFrom=es,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=retazo.ai,404,404,404,"Existing design/retail uses and Retazo Digital, a web/app-services brand.",https://bucle.io/servicios/ -18,Venula,venula.ai,6,VEN-yoo-lah,Latin-derived anatomical word,A small vein.,An organic metaphor for pathways and flows inside a complex system.,Soft and biological; less literal about AI than the leading names.,https://en.wiktionary.org/wiki/venula,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=venula.ai,404,404,404,Personal-name uses surfaced; no obvious exact-name AI/software product., -19,Wispish,wispish.ai,7,WIS-pish,English,Resembling a wisp; wispy.,"Faint, fleeting patterns becoming visible in a live model.",Light and memorable; more atmospheric than technical.,https://www.merriam-webster.com/dictionary/wispish,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=wispish.ai,404,404,404,No obvious exact-name AI/software product surfaced in the bounded web screen., -20,Purling,purling.ai,7,PUR-ling,English,Knitting in purl stitch; also softly murmuring or flowing.,Connects the project's threads with its continuous stream of activations.,"Gentle, tactile, and familiar to say.",https://www.merriam-webster.com/dictionary/purl,Porkbun,AVAILABLE,0,82.70,2,165.40,82.70,2,2026-09-05T22:21:02.871842+00:00,https://porkbun.com/checkout/search?q=purling.ai,404,404,404,Purling is an established luxury chess/art-games brand; no exact-name AI workbench surfaced.,https://www.purlingartgames.com/our-story diff --git a/domain-name-shortlist-2026-09-05-round-2.csv b/domain-name-shortlist-2026-09-05-round-2.csv deleted file mode 100644 index ec574596..00000000 --- a/domain-name-shortlist-2026-09-05-round-2.csv +++ /dev/null @@ -1,22 +0,0 @@ -"rank","name","domain","pronunciation","rationale","registrar_status","premium","registration_annual_usd","renewal_annual_usd","minimum_term_years","two_year_arithmetic_estimate_usd","price_note","registrar_checked_at_utc","registry_http_status","registry_checked_at_utc","pypi_http_status","npm_http_status","registrar_url","dictionary_url","collision_note","collision_sources" -"1","puckish","puckish.ai","PUCK-ish","Mischievous and playful; a strong match for experimenting with model personalities.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.412907+00:00","404","404","https://porkbun.com/checkout/search?q=puckish.ai","https://www.merriam-webster.com/dictionary/puckish","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"2","underlit","underlit.ai","UN-der-lit","Light beneath the surface; an evocative metaphor for inspecting model internals.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.580275+00:00","404","404","https://porkbun.com/checkout/search?q=underlit.ai","https://www.collinsdictionary.com/us/dictionary/english/underlit","Exact title of a small 2024 game-jam game. This is an existing software use.","https://mathix94.itch.io/underlit" -"3","unmuffle","unmuffle.ai","un-MUFF-ul","Free hidden signals from what obscures them; the clearest interpretability metaphor.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.402976+00:00","404","404","https://porkbun.com/checkout/search?q=unmuffle.ai","https://www.merriam-webster.com/dictionary/unmuffle","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"4","retint","retint.ai","ree-TINT","Change the shade of something; a compact metaphor for steering model behavior.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.776075+00:00","404","404","https://porkbun.com/checkout/search?q=retint.ai","https://www.collinsdictionary.com/us/english-language-learning/retint","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"5","uncoiled","uncoiled.ai","un-KOYLD","Complex structure opened out so it can be explored.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:22.130940+00:00","404","404","https://porkbun.com/checkout/search?q=uncoiled.ai","https://www.merriam-webster.com/dictionary/uncoil","Also used as a music release title and in mathematical terminology; no exact software brand surfaced in the limited search.","https://arxiv.org/abs/2302.12782" -"6","intoned","intoned.ai","in-TOHND","Voice, tone, and expression; a natural association with language.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.951294+00:00","404","404","https://porkbun.com/checkout/search?q=intoned.ai","https://dictionary.cambridge.org/us/dictionary/english/intoned","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"7","unlaced","unlaced.ai","un-LAYST","Opened and loosened; tactile, memorable, and easy to spell.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.979209+00:00","404","404","https://porkbun.com/checkout/search?q=unlaced.ai","https://www.merriam-webster.com/dictionary/unlace","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"8","fancied","fancied.ai","FAN-seed","Imagined possibilities; creative and slightly whimsical.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:22.502473+00:00","404","404","https://porkbun.com/checkout/search?q=fancied.ai","https://www.merriam-webster.com/dictionary/fancied","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"9","honeyed","honeyed.ai","HUN-eed","A warm, pleasant voice; particularly apt for tone and persona steering.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:21.800927+00:00","404","404","https://porkbun.com/checkout/search?q=honeyed.ai","https://dictionary.cambridge.org/us/dictionary/english/honeyed","Existing creative studio name and adjective in the app title Honeyed Legends Myths. Its literal meaning can also imply insincere sweetness.","https://thehoneyedcollective.com/honeyed-studios/ https://apps.apple.com/hk/app/honeyed-legends-myths/id6761210848" -"10","brambly","brambly.ai","BRAM-blee","Tangled, branching growth; a visual identity for exploring branching conversations.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:24.186052+00:00","404","404","https://porkbun.com/checkout/search?q=brambly.ai","https://www.merriam-webster.com/dictionary/brambly","Strong association with Brambly Hedge, a children's book series. No exact standalone software brand surfaced in the limited search.","" -"11","fernery","fernery.ai","FUR-nuh-ree","A place where ferns grow; a quiet, organic name with strong visual possibilities.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:24.374968+00:00","404","404","https://porkbun.com/checkout/search?q=fernery.ai","https://www.merriam-webster.com/dictionary/fernery","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"12","hazily","hazily.ai","HAY-zih-lee","Half-visible patterns and uncertain impressions; soft and atmospheric.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:24.308602+00:00","404","404","https://porkbun.com/checkout/search?q=hazily.ai","https://www.oxfordlearnersdictionaries.com/us/definition/english/hazily","Has a deliberate ambiguity/uncertainty connotation. No exact software brand surfaced in the limited search.","https://www.oxfordlearnersdictionaries.com/us/definition/english/hazily" -"13","dozing","dozing.ai","DOH-zing","Dormant potential and dreamlike states; gentle and easy to remember.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:23.041226+00:00","404","404","https://porkbun.com/checkout/search?q=dozing.ai","https://www.merriam-webster.com/dictionary/doze","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"14","riverlet","riverlet.ai","RIV-er-let","A little river; a natural metaphor for branching streams of generation.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:24.562185+00:00","404","404","https://porkbun.com/checkout/search?q=riverlet.ai","https://www.merriam-webster.com/dictionary/riverlet","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"15","dimpled","dimpled.ai","DIM-puld","Small contours in a surface; friendly, tactile, and suggestive of geometry.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:23.402872+00:00","404","404","https://porkbun.com/checkout/search?q=dimpled.ai","https://www.oxfordlearnersdictionaries.com/definition/english/dimpled","Existing technical phrase Dimpled Manifold Model in ML research; this is not an exact standalone product-name match.","https://arxiv.org/abs/2106.10151" -"16","wafting","wafting.ai","WAF-ting","Gentle movement in a direction; a soft metaphor for activation steering.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:24.482564+00:00","404","404","https://porkbun.com/checkout/search?q=wafting.ai","https://www.merriam-webster.com/dictionary/waft","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"17","satiny","satiny.ai","SAT-in-ee","Smooth and tactile; a polished, approachable brand.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:22.870864+00:00","404","404","https://porkbun.com/checkout/search?q=satiny.ai","https://www.oxfordlearnersdictionaries.com/us/definition/english/satiny","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"18","wittily","wittily.ai","WIT-ih-lee","Clever expression; an upbeat name for a language-focused tool.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:23.233657+00:00","404","404","https://porkbun.com/checkout/search?q=wittily.ai","https://www.oxfordlearnersdictionaries.com/us/definition/english/wittily","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"19","giddily","giddily.ai","GID-ih-lee","Excitement and discovery; playful and buoyant.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:23.032894+00:00","404","404","https://porkbun.com/checkout/search?q=giddily.ai","https://www.oxfordlearnersdictionaries.com/us/definition/english/giddily","No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.","" -"20","blithely","blithely.ai","BLYTHE-lee","Carefree and cheerful; a light, literary personality.","AVAILABLE","0","82.70","82.70","2","165.40","About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.","2026-09-05 15:45:52","404","2026-09-05T15:42:22.138639+00:00","404","404","https://porkbun.com/checkout/search?q=blithely.ai","https://www.oxfordlearnersdictionaries.com/us/definition/english/blithely","Can mean cheerfully or carelessly; pronunciation has a voiced th. No exact software brand surfaced in the limited search.","https://www.oxfordlearnersdictionaries.com/us/definition/english/blithely" - diff --git a/domain-name-shortlist-2026-09-05-round-3.csv b/domain-name-shortlist-2026-09-05-round-3.csv deleted file mode 100644 index 6d3df615..00000000 --- a/domain-name-shortlist-2026-09-05-round-3.csv +++ /dev/null @@ -1,51 +0,0 @@ -rank,name,slug,pronunciation,rationale,domain,registrar_url,category,origin,origin_url,existing_use_note,existing_use_source,availability,premium,registration_usd_per_year,renewal_usd_per_year,minimum_term_years,checked_at_utc -1,Lunomi,lunomi,loo-NOH-mee,"Soft, memorable, and slightly lunar; my strongest overall pick.",lunomi.ai,https://porkbun.com/checkout/search?q=lunomi.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,Existing musician/creator use and an unrelated Polish trading company.,https://ko-fi.com/lunomi/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -2,Nimela,nimela,nih-MEL-ah,Gentle and compact; works equally well for an app or a library.,nimela.ai,https://porkbun.com/checkout/search?q=nimela.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -3,Quiet Tide,quiettide,quiet tide,A natural metaphor for subtly steering a model’s behavior.,quiettide.ai,https://porkbun.com/checkout/search?q=quiettide.ai,English compound,Quiet Tide,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -4,Inner Vale,innervale,inner vale,Suggests an interior landscape waiting to be explored.,innervale.ai,https://porkbun.com/checkout/search?q=innervale.ai,English compound,Inner Vale,,Existing fictional-place uses and company names.,https://www.innervale.com/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -5,Domaso,domaso,DOH-mah-zoh,"A Lake Como village name with a warm, unhurried sound.",domaso.ai,https://porkbun.com/checkout/search?q=domaso.ai,place name,"Lake Como, Italy",https://www.northlakecomo.net/uploads/EnTravelguide-upload.pdf,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -6,Somori,somori,soh-MOR-ee,Rounded and restful; has the feel of a small creative studio.,somori.ai,https://porkbun.com/checkout/search?q=somori.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -7,Open Fern,openfern,open fern,Unfolding structure; a good image for making hidden things visible.,openfern.ai,https://porkbun.com/checkout/search?q=openfern.ai,English compound,Open Fern,,Existing company-directory use.,https://www.lgr.co.uk/Directory/?letter=F,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -8,Paper Tide,papertide,paper tide,Language in motion; literary without sounding academic.,papertide.ai,https://porkbun.com/checkout/search?q=papertide.ai,English compound,Paper Tide,,Name appears as a customer/example business on an AI-email-marketing site; existence of a separate active company not established.,https://hiremara.com/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -9,Lumella,lumella,loo-MEL-ah,Luminous and melodic; especially strong as a visual identity.,lumella.ai,https://porkbun.com/checkout/search?q=lumella.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,Existing beauty-store and diagnostic-brand uses; domain availability does not establish exclusive name rights.,https://lumella.net/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -10,Silver Moss,silvermoss,silver moss,"Soft nature imagery with a slight metallic, technical edge.",silvermoss.ai,https://porkbun.com/checkout/search?q=silvermoss.ai,English compound,Silver Moss,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -11,Norali,norali,nor-AH-lee,"Airy, balanced, and easy to use in ordinary conversation.",norali.ai,https://porkbun.com/checkout/search?q=norali.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -12,Ostuni,ostuni,os-TOO-nee,"An Italian town name; crisp, sunny, and distinctive.",ostuni.ai,https://porkbun.com/checkout/search?q=ostuni.ai,place name,"Puglia, Italy",https://www.italia.it/en/puglia/brindisi/ostuni,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -13,Kind Muse,kindmuse,kind muse,Warm and creative; a good fit for shaping model personality.,kindmuse.ai,https://porkbun.com/checkout/search?q=kindmuse.ai,English compound,Kind Muse,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -14,Soft Current,softcurrent,soft current,Subtle influence and continuous flow; closely fits steering.,softcurrent.ai,https://porkbun.com/checkout/search?q=softcurrent.ai,English compound,Soft Current,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -15,Moon Cove,mooncove,moon cove,A quiet place to explore; compact and visually evocative.,mooncove.ai,https://porkbun.com/checkout/search?q=mooncove.ai,English compound,Moon Cove,,Existing Minecraft-server and production-company uses.,https://rsq.productions/privacy-policy/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -16,Nolemi,nolemi,noh-LEM-ee,Friendly and fluid; could support a personable little mascot.,nolemi.ai,https://porkbun.com/checkout/search?q=nolemi.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,"Appears as a user-created character name on an AI platform, not as the platform brand.",https://shapes.inc/nolemi,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -17,Clear Meadow,clearmeadow,clear meadow,Open terrain and visibility; a gentle interpretability metaphor.,clearmeadow.ai,https://porkbun.com/checkout/search?q=clearmeadow.ai,English compound,Clear Meadow,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -18,Siluna,siluna,sih-LOO-nah,Smooth and moonlike; graceful when spoken aloud.,siluna.ai,https://porkbun.com/checkout/search?q=siluna.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,Existing music and lighting-product uses; siluna.world also has a landing page.,https://siluna.world/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -19,Light Grove,lightgrove,light grove,A branching space illuminated from within.,lightgrove.ai,https://porkbun.com/checkout/search?q=lightgrove.ai,English compound,Light Grove,,Existing fictional location in Enderal.,https://wiki.en.sureai.net/Enderal%3ALightgrove,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -20,Roseto,roseto,roh-ZEH-toh,"From Roseto degli Abruzzi; rounded, warm, and elegant.",roseto.ai,https://porkbun.com/checkout/search?q=roseto.ai,place name,"Roseto degli Abruzzi, Italy",https://www.visitroseto.it/en/discover/,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -21,Soft Moss,softmoss,soft moss,Tactile and welcoming; easy to remember after hearing once.,softmoss.ai,https://porkbun.com/checkout/search?q=softmoss.ai,English compound,Soft Moss,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -22,Gold Fern,goldfern,gold fern,"Simple, bright, and easy to turn into a recognizable symbol.",goldfern.ai,https://porkbun.com/checkout/search?q=goldfern.ai,English compound,Gold Fern,,Existing real-estate and mining-consulting uses.,https://www.goldfern.com.au/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -23,Enoli,enoli,eh-NOH-lee,"Short, flowing, and adaptable beyond the initial product.",enoli.ai,https://porkbun.com/checkout/search?q=enoli.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,Existing corporate-services organization and personal-name uses.,https://enoli.net/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -24,Blue Hollow,bluehollow,blue hollow,Hidden depth; a strong fit for an exploratory visual interface.,bluehollow.ai,https://porkbun.com/checkout/search?q=bluehollow.ai,English compound,Blue Hollow,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -25,Fable Cove,fablecove,fable cove,"A small home for language, stories, and different voices.",fablecove.ai,https://porkbun.com/checkout/search?q=fablecove.ai,English compound,Fable Cove,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -26,Bormio,bormio,BOR-myoh,An Italian Alpine town name; compact and sturdy.,bormio.ai,https://porkbun.com/checkout/search?q=bormio.ai,place name,Italian Alps,https://www.bormio.eu/en,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -27,Amber Muse,ambermuse,amber muse,Warm color and creative influence; polished without being cold.,ambermuse.ai,https://porkbun.com/checkout/search?q=ambermuse.ai,English compound,Amber Muse,,Existing jewelry brand.,https://ambermuse.lt/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -28,Sorumi,sorumi,soh-ROO-mee,"A soft, rhythmic name with a friendly character.",sorumi.ai,https://porkbun.com/checkout/search?q=sorumi.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -29,Ponza,ponza,PON-tsah,"An Italian island name; short, lively, and distinctive.",ponza.ai,https://porkbun.com/checkout/search?q=ponza.ai,place name,Island in Italy,https://www.visitponza.it/en/discover-ponza-2/,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -30,Mellow Tide,mellowtide,mellow tide,Relaxed movement; approachable and pleasant to say.,mellowtide.ai,https://porkbun.com/checkout/search?q=mellowtide.ai,English compound,Mellow Tide,,Existing musician use and trademark-journal mentions; legal scope not assessed.,https://music.apple.com/us/artist/mellowtide/1768055740,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -31,Moon Moss,moonmoss,moon moss,A slightly strange natural image with strong visual potential.,moonmoss.ai,https://porkbun.com/checkout/search?q=moonmoss.ai,English compound,Moon Moss,,Food-product trademark use surfaced; legal status/scope not assessed.,https://ttabvue.uspto.gov/ttabvue-92091396-CAN-1.pdf,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -32,Tameli,tameli,tah-MEL-ee,Gentle consonants and a clear three-syllable rhythm.,tameli.ai,https://porkbun.com/checkout/search?q=tameli.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -33,Still Cove,stillcove,still cove,A calm workspace; quiet and self-contained.,stillcove.ai,https://porkbun.com/checkout/search?q=stillcove.ai,English compound,Still Cove,,An exact-name trademark application surfaced for an e-commerce company; legal scope not assessed.,https://trademarks.justia.com/983/52/stillcove-98352747.html,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -34,Light Moss,lightmoss,light moss,Small points of illumination; delicate and unusual.,lightmoss.ai,https://porkbun.com/checkout/search?q=lightmoss.ai,English compound,Light Moss,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -35,Tropea,tropea,troh-PEH-ah,A Calabrian town name; flowing and sunlit.,tropea.ai,https://porkbun.com/checkout/search?q=tropea.ai,place name,"Calabria, Italy",https://calabriastraordinaria.it/en/destinations/tropea-the-pearl-of-the-tyrrhenian-sea,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -36,Fable Fern,fablefern,fable fern,Language and unfolding forms; playful alliteration.,fablefern.ai,https://porkbun.com/checkout/search?q=fablefern.ai,English compound,Fable Fern,,Existing bookshop and invitation-studio uses.,https://www.fablefernbookshop.com/pages/contact-us,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -37,Norumi,norumi,noh-ROO-mee,Rounded and companionable; good for a personable product.,norumi.ai,https://porkbun.com/checkout/search?q=norumi.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,Existing cat-related shop use.,https://heynorumi.com/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -38,Silver Glow,silverglow,silver glow,"Illumination with a restrained, slightly futuristic feel.",silverglow.ai,https://porkbun.com/checkout/search?q=silverglow.ai,English compound,Silver Glow,,Existing typeface and music uses.,https://www.myfonts.com/collections/silverglow-font-balpirick/,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -39,Bloom Cove,bloomcove,bloom cove,A sheltered place for ideas and personalities to develop.,bloomcove.ai,https://porkbun.com/checkout/search?q=bloomcove.ai,English compound,Bloom Cove,,Existing online-store uses.,https://www.merchantgenius.io/shop/url/bloomcove.shop,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -40,Locarno,locarno,loh-KAR-noh,A Swiss lakeside city name; established and substantial.,locarno.ai,https://porkbun.com/checkout/search?q=locarno.ai,place name,"Ticino, Switzerland",https://www.ascona-locarno.com/en/explore/locarno,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -41,Gentle Tide,gentletide,gentle tide,"Small, deliberate changes; an intuitive steering association.",gentletide.ai,https://porkbun.com/checkout/search?q=gentletide.ai,English compound,Gentle Tide,,Existing retreat-business use.,https://linktr.ee/gentletide,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -42,Moss Lane,mosslane,moss lane,A path through something living; grounded and approachable.,mosslane.ai,https://porkbun.com/checkout/search?q=mosslane.ai,English compound,Moss Lane,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -43,Ikumi,ikumi,ee-KOO-mee,Compact and rhythmic; friendly enough for everyday use.,ikumi.ai,https://porkbun.com/checkout/search?q=ikumi.ai,sound-led name,Selected for its sound; no foreign-language translation or first-ever coinage claimed.,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -44,Fable Moon,fablemoon,fable moon,Dreamlike and literary; broad room for a visual identity.,fablemoon.ai,https://porkbun.com/checkout/search?q=fablemoon.ai,English compound,Fable Moon,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -45,Varallo,varallo,vah-RAHL-loh,"A Piedmont town name; melodic, with a confident ending.",varallo.ai,https://porkbun.com/checkout/search?q=varallo.ai,place name,"Piedmont, Italy",https://www.italia.it/en/piedmont/varallo,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -46,Mist Lake,mistlake,mist lake,Hidden depth gradually becoming visible.,mistlake.ai,https://porkbun.com/checkout/search?q=mistlake.ai,English compound,Mist Lake,,Existing Codex color-theme name.,https://www.dexthemes.com/mistlake/dark,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -47,Bright Muse,brightmuse,bright muse,"Clear, optimistic, and immediately easy to understand.",brightmuse.ai,https://porkbun.com/checkout/search?q=brightmuse.ai,English compound,Bright Muse,,Japanese company name surfaced in a commercial-disclosure page; business type not resolved.,https://utage-system.com/p/kMKZthBOukj5,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -48,Posada,posada,poh-SAH-dah,A Sardinian village name; welcoming and easy to say.,posada.ai,https://porkbun.com/checkout/search?q=posada.ai,place name,"Sardinia, Italy",https://www.sardegnaturismo.it/en/explore/posada?language=en-gb,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -49,Merry Bloom,merrybloom,merry bloom,Cheerful and playful; suited to a less formal product voice.,merrybloom.ai,https://porkbun.com/checkout/search?q=merrybloom.ai,English compound,Merry Bloom,,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z -50,Sulmona,sulmona,sool-MOH-nah,An Abruzzo town name; sonorous and distinctive.,sulmona.ai,https://porkbun.com/checkout/search?q=sulmona.ai,place name,"Abruzzo, Italy",https://turismo.comune.sulmona.aq.it/,No clear same-name AI/software product surfaced in the bounded searches; this is not an exhaustive name or trademark search.,,AVAILABLE,0,82.7,82.7,2,2026-09-05T22:04:16.175Z diff --git a/domain-name-shortlist-2026-09-05.csv b/domain-name-shortlist-2026-09-05.csv deleted file mode 100644 index 8184b3fb..00000000 --- a/domain-name-shortlist-2026-09-05.csv +++ /dev/null @@ -1,21 +0,0 @@ -rank,name,domain,pronunciation,rationale,status,premium,registration_annual_usd,renewal_annual_usd,minimum_term_years,two_year_estimate_usd,price_note,registrar_checked_at_utc,registry_http_status,registry_checked_at_utc,registrar_url,pypi_http_status,npm_http_status,collision_note,sources -1,Unknit,unknit.ai,un-NIT,Undo intertwined strands; a clear metaphor for disentangling model representations.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.221927+00:00,https://porkbun.com/checkout/search?q=unknit.ai,404,404,No obvious exact-name AI product found; PyPI and npm lookups returned 404.,https://www.merriam-webster.com/dictionary/unknit -2,Billowy,billowy.ai,BIL-oh-ee,"Flowing, changing shapes; soft and memorable for exploring model behavior.",AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.230158+00:00,https://porkbun.com/checkout/search?q=billowy.ai,404,404,A footwear retailer and other unrelated businesses use the word; no obvious exact-name AI product found.,https://billowyshop.com/policies/legal-notice -3,Borage,borage.ai,BOR-ij,"A blue, star-flowered herb; a distinctive botanical identity with room to grow.",AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.520455+00:00,https://porkbun.com/checkout/search?q=borage.ai,404,404,No obvious exact-name AI/software product found; PyPI and npm lookups returned 404., -4,Drowse,drowse.ai,DROWZ (rhymes with cows),"A liminal mental state; the strongest short, atmospheric option.",AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.426276+00:00,https://porkbun.com/checkout/search?q=drowse.ai,200,404,"Existing Drowse sleep-sound apps and a PyPI REST client. Excellent sound, but not an unused software name.",https://apps.apple.com/us/app/drowse-sleep-sounds-mixer/id6760371927 | https://play.google.com/store/apps/details?id=be.studio3020.drowse | https://pypi.org/project/drowse/ -5,Unpleat,unpleat.ai,un-PLEET,Unfold hidden structure; a compact metaphor for opening up model geometry.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.631992+00:00,https://porkbun.com/checkout/search?q=unpleat.ai,404,404,No obvious exact-name AI/software product found; a real but less common verb.,https://en.wiktionary.org/wiki/unpleat -6,Toneme,toneme.ai,TOH-neem,A meaningful tone unit in language; connects language with subtle behavioral differences.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.700109+00:00,https://porkbun.com/checkout/search?q=toneme.ai,404,404,An unrelated ToneMe GitHub repository surfaced; the exact PyPI and npm lookups returned 404.,https://www.merriam-webster.com/dictionary/toneme | https://github.com/leihuayi/ToneMe/releases -7,Tepal,tepal.ai,TEE-puhl,"A petal-like flower part; five letters and a compact, organic identity.",AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.842199+00:00,https://porkbun.com/checkout/search?q=tepal.ai,404,404,No obvious exact-name AI/software product found. The botanical word also permits TEP-uhl.,https://www.dictionary.com/browse/tepal -8,Smidgen,smidgen.ai,SMID-jin,A tiny amount; a friendly metaphor for fine-grained steering adjustments.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:55.928373+00:00,https://porkbun.com/checkout/search?q=smidgen.ai,404,200,"Existing npm IOTA CLI, Go text-editor component, and inventory-management project. Not an unused software name.",https://github.com/bitfinexcom/smidgen | https://pkg.go.dev/github.com/sedwards2009/smidgen | https://github.com/Smidgen-Inventory-Management -9,Unshown,unshown.ai,un-SHOHN,The parts normally hidden; direct and relevant to model inspection.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.024054+00:00,https://porkbun.com/checkout/search?q=unshown.ai,404,404,An unrelated UnShown game exists; no obvious exact-name AI workbench found.,https://www.collinsdictionary.com/dictionary/english/unshown | https://pix3ldev.itch.io/un-shown -10,Doline,doline.ai,DOH-leen,A natural basin; an evocative name for exploring a model's internal landscape.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.113911+00:00,https://porkbun.com/checkout/search?q=doline.ai,404,404,"A less familiar geological word, with a sinkhole association. No obvious exact-name AI/software product found.",https://www.collinsdictionary.com/dictionary/english/doline -11,Scumble,scumble.ai,SKUM-buhl,A painting technique that softens color through layers; fits subtle trait modulation.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.196470+00:00,https://porkbun.com/checkout/search?q=scumble.ai,404,404,"Also a novel title, a Discworld drink, and an established multilabel-learning metric acronym. Distinctive, but the opening sound may be polarizing.",https://arxiv.org/abs/1802.05033 | https://en.wikipedia.org/wiki/Scumble -12,Brayer,brayer.ai,BRAY-er,A printmaker's ink roller; a tactile tool for applying controlled changes.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.308401+00:00,https://porkbun.com/checkout/search?q=brayer.ai,200,404,The exact PyPI name is already a Pydantic desktop-form library. Brayer is also used by an appliance brand and as a surname.,https://pypi.org/project/brayer/ | https://brayer.ru/ -13,Coving,coving.ai,KOH-ving,A curved transition between surfaces; a quiet geometric metaphor.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.389044+00:00,https://porkbun.com/checkout/search?q=coving.ai,404,404,A common architectural and graphics term; no obvious exact-name AI product found.,https://www.sidefx.com/media/uploads/tutorial/H12_%20lessons/Light%20Shade%20Rendering/lsr_m07.pdf -14,Harebell,harebell.ai,HAIR-bell,A delicate blue wildflower; an approachable visual identity with a clear image.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.526489+00:00,https://porkbun.com/checkout/search?q=harebell.ai,404,404,"No obvious exact-name AI/software product found. Eight letters, but only two familiar syllables.",https://www.oxfordlearnersdictionaries.com/definition/english/harebell -15,Dimity,dimity.ai,DIM-ih-tee,A woven fabric; a soft name for a workbench that combines many traits.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.618358+00:00,https://porkbun.com/checkout/search?q=dimity.ai,404,404,Existing activity-and-mood diary app and UK consultancy. Exact PyPI and npm lookups returned 404.,https://apps.apple.com/au/app/dimity-activity-mood-diary/id6791005508 | https://find-and-update.company-information.service.gov.uk/company/15070128 -16,Sculler,sculler.ai,SKUL-er,Someone who rows with two oars; a concrete metaphor for directional control.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.717792+00:00,https://porkbun.com/checkout/search?q=sculler.ai,404,404,Digital Sculler is a content/AI tutorial brand; no obvious exact-name AI workbench found. Sounds like skull-er.,https://digitalsculler.com/ -17,Ruddle,ruddle.ai,RUD-uhl,Red ochre used for marking; fits highlighting and tracing hidden activity.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.795483+00:00,https://porkbun.com/checkout/search?q=ruddle.ai,404,200,An npm SVG-icon collection already uses the exact name. Surname uses also appear.,https://www.npmjs.com/package/ruddle -18,Isobath,isobath.ai,EYE-so-bath,A line connecting equal depths; a precise metaphor for mapping internal geometry.,AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.915056+00:00,https://porkbun.com/checkout/search?q=isobath.ai,200,404,The exact PyPI name is already a bathymetry GUI. More technical than the leading names.,https://pypi.org/project/isobath/ -19,Mordent,mordent.ai,MOR-dunt,"A quick musical turn around a note; suggests small, deliberate changes in output.",AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:56.996637+00:00,https://porkbun.com/checkout/search?q=mordent.ai,404,404,An older music-score authoring tool uses the name. The exact PyPI and npm lookups returned 404.,https://dcgi.fel.cvut.cz/en/theses/2013/rejthedv/ -20,Shimmery,shimmery.ai,SHIM-er-ee,"Subtle changes in light; suited to a visual, exploratory product identity.",AVAILABLE,0,82.70,82.70,2,165.40,"Two-year estimate is twice the displayed annual rate, not a completed checkout quote; taxes or transaction calculation can differ.",2026-09-05 15:19:17 UTC,404,2026-09-05T15:19:57.102097+00:00,https://porkbun.com/checkout/search?q=shimmery.ai,404,404,No obvious exact-name AI/software product found. Eight letters and less technical than the other choices., diff --git a/domain-registrar-evidence-2026-09-05-cognition.json b/domain-registrar-evidence-2026-09-05-cognition.json deleted file mode 100644 index 97b7987d..00000000 --- a/domain-registrar-evidence-2026-09-05-cognition.json +++ /dev/null @@ -1,1613 +0,0 @@ -{ - "registrar": "Porkbun", - "endpoint": "https://porkbun.com/api/domains/getChecks", - "checked_at_utc": "2026-09-05T22:21:02.871842+00:00", - "pending": 0, - "results": [ - { - "id": "1821297503", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "nitore.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297504", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "sisin.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297505", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "asomar.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297506", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "unskein.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297507", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "rimple.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297508", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "svelare.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297509", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "merism.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297510", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "ricalco.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297511", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "deuten.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297512", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "falte.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297513", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "havaita.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297514", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "punoa.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297515", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "udito.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297516", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "skimte.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297517", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "ordire.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297518", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "retazo.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297519", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "venula.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297520", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "wispish.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297521", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "risvolto.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821297522", - "check_id": "87decbdd4d56f2a8f75b354a2d54eb0e118d3c09eefe9cccd5d83734584f18bb", - "domain": "purling.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:21:00", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - } - ], - "independent_registry_and_package_checks": [ - { - "name": "nitore", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.296621+00:00" - }, - { - "name": "sisin", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.313048+00:00" - }, - { - "name": "asomar", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.515429+00:00" - }, - { - "name": "unskein", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.497444+00:00" - }, - { - "name": "rimple", - "rdap": { - "status": 404 - }, - "pypi": { - "status": 404 - }, - "npm": { - "status": 200, - "description": "[API](https://xiechao06.github.io/rimple).", - "url": "https://github.com/xiechao06/rimple#readme" - }, - "checked_at": "2026-09-05T22:21:01.055674+00:00" - }, - { - "name": "svelare", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.714019+00:00" - }, - { - "name": "merism", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.708476+00:00" - }, - { - "name": "ricalco", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:00.915307+00:00" - }, - { - "name": "deuten", - "rdap": { - "status": 404 - }, - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.387498+00:00" - }, - { - "name": "falte", - "rdap": { - "status": 404 - }, - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.553130+00:00" - }, - { - "name": "havaita", - "rdap": { - "status": 404 - }, - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.714865+00:00" - }, - { - "name": "punoa", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.598430+00:00" - }, - { - "name": "udito", - "rdap": { - "status": 404 - }, - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:02.266851+00:00" - }, - { - "name": "skimte", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.783409+00:00" - }, - { - "name": "ordire", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.958397+00:00" - }, - { - "name": "retazo", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:01.989130+00:00" - }, - { - "name": "venula", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:02.157937+00:00" - }, - { - "name": "wispish", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:02.191379+00:00" - }, - { - "name": "risvolto", - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "rdap": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:02.366384+00:00" - }, - { - "name": "purling", - "rdap": { - "status": 404 - }, - "pypi": { - "status": 404 - }, - "npm": { - "status": 404 - }, - "checked_at": "2026-09-05T22:21:02.819240+00:00" - } - ], - "price_note": "Annual quotes. Two-year registration and renewal minimum. Initial amount is calculated, not a checkout total. Taxes and checkout adjustments may apply." -} \ No newline at end of file diff --git a/domain-registrar-evidence-2026-09-05-round-2.json b/domain-registrar-evidence-2026-09-05-round-2.json deleted file mode 100644 index 8352ae42..00000000 --- a/domain-registrar-evidence-2026-09-05-round-2.json +++ /dev/null @@ -1,2262 +0,0 @@ -{ - "project": "Polythetic", - "round": 2, - "checked_date": "2026-09-05", - "screened_unique_new_domains": 799, - "final_count": 20, - "method": "Live Porkbun exact-domain registration checks, final pending=0; RDAP used independently as preliminary corroboration; public PyPI/npm and limited web collision searches.", - "pricing_source": "https://porkbun.com/tld/ai", - "shortlist": [ - { - "rank": 1, - "name": "puckish", - "domain": "puckish.ai", - "pronunciation": "PUCK-ish", - "rationale": "Mischievous and playful; a strong match for experimenting with model personalities.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.412907+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=puckish.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/puckish", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 2, - "name": "underlit", - "domain": "underlit.ai", - "pronunciation": "UN-der-lit", - "rationale": "Light beneath the surface; an evocative metaphor for inspecting model internals.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.580275+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=underlit.ai", - "dictionary_url": "https://www.collinsdictionary.com/us/dictionary/english/underlit", - "collision_note": "Exact title of a small 2024 game-jam game. This is an existing software use.", - "collision_sources": "https://mathix94.itch.io/underlit" - }, - { - "rank": 3, - "name": "unmuffle", - "domain": "unmuffle.ai", - "pronunciation": "un-MUFF-ul", - "rationale": "Free hidden signals from what obscures them; the clearest interpretability metaphor.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.402976+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=unmuffle.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/unmuffle", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 4, - "name": "retint", - "domain": "retint.ai", - "pronunciation": "ree-TINT", - "rationale": "Change the shade of something; a compact metaphor for steering model behavior.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.776075+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=retint.ai", - "dictionary_url": "https://www.collinsdictionary.com/us/english-language-learning/retint", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 5, - "name": "uncoiled", - "domain": "uncoiled.ai", - "pronunciation": "un-KOYLD", - "rationale": "Complex structure opened out so it can be explored.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:22.130940+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=uncoiled.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/uncoil", - "collision_note": "Also used as a music release title and in mathematical terminology; no exact software brand surfaced in the limited search.", - "collision_sources": "https://arxiv.org/abs/2302.12782" - }, - { - "rank": 6, - "name": "intoned", - "domain": "intoned.ai", - "pronunciation": "in-TOHND", - "rationale": "Voice, tone, and expression; a natural association with language.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.951294+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=intoned.ai", - "dictionary_url": "https://dictionary.cambridge.org/us/dictionary/english/intoned", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 7, - "name": "unlaced", - "domain": "unlaced.ai", - "pronunciation": "un-LAYST", - "rationale": "Opened and loosened; tactile, memorable, and easy to spell.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.979209+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=unlaced.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/unlace", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 8, - "name": "fancied", - "domain": "fancied.ai", - "pronunciation": "FAN-seed", - "rationale": "Imagined possibilities; creative and slightly whimsical.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:22.502473+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=fancied.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/fancied", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 9, - "name": "honeyed", - "domain": "honeyed.ai", - "pronunciation": "HUN-eed", - "rationale": "A warm, pleasant voice; particularly apt for tone and persona steering.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:21.800927+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=honeyed.ai", - "dictionary_url": "https://dictionary.cambridge.org/us/dictionary/english/honeyed", - "collision_note": "Existing creative studio name and adjective in the app title Honeyed Legends Myths. Its literal meaning can also imply insincere sweetness.", - "collision_sources": "https://thehoneyedcollective.com/honeyed-studios/ https://apps.apple.com/hk/app/honeyed-legends-myths/id6761210848" - }, - { - "rank": 10, - "name": "brambly", - "domain": "brambly.ai", - "pronunciation": "BRAM-blee", - "rationale": "Tangled, branching growth; a visual identity for exploring branching conversations.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:24.186052+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=brambly.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/brambly", - "collision_note": "Strong association with Brambly Hedge, a children's book series. No exact standalone software brand surfaced in the limited search.", - "collision_sources": "" - }, - { - "rank": 11, - "name": "fernery", - "domain": "fernery.ai", - "pronunciation": "FUR-nuh-ree", - "rationale": "A place where ferns grow; a quiet, organic name with strong visual possibilities.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:24.374968+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=fernery.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/fernery", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 12, - "name": "hazily", - "domain": "hazily.ai", - "pronunciation": "HAY-zih-lee", - "rationale": "Half-visible patterns and uncertain impressions; soft and atmospheric.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:24.308602+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=hazily.ai", - "dictionary_url": "https://www.oxfordlearnersdictionaries.com/us/definition/english/hazily", - "collision_note": "Has a deliberate ambiguity/uncertainty connotation. No exact software brand surfaced in the limited search.", - "collision_sources": "https://www.oxfordlearnersdictionaries.com/us/definition/english/hazily" - }, - { - "rank": 13, - "name": "dozing", - "domain": "dozing.ai", - "pronunciation": "DOH-zing", - "rationale": "Dormant potential and dreamlike states; gentle and easy to remember.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:23.041226+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=dozing.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/doze", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 14, - "name": "riverlet", - "domain": "riverlet.ai", - "pronunciation": "RIV-er-let", - "rationale": "A little river; a natural metaphor for branching streams of generation.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:24.562185+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=riverlet.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/riverlet", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 15, - "name": "dimpled", - "domain": "dimpled.ai", - "pronunciation": "DIM-puld", - "rationale": "Small contours in a surface; friendly, tactile, and suggestive of geometry.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:23.402872+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=dimpled.ai", - "dictionary_url": "https://www.oxfordlearnersdictionaries.com/definition/english/dimpled", - "collision_note": "Existing technical phrase Dimpled Manifold Model in ML research; this is not an exact standalone product-name match.", - "collision_sources": "https://arxiv.org/abs/2106.10151" - }, - { - "rank": 16, - "name": "wafting", - "domain": "wafting.ai", - "pronunciation": "WAF-ting", - "rationale": "Gentle movement in a direction; a soft metaphor for activation steering.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:24.482564+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=wafting.ai", - "dictionary_url": "https://www.merriam-webster.com/dictionary/waft", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 17, - "name": "satiny", - "domain": "satiny.ai", - "pronunciation": "SAT-in-ee", - "rationale": "Smooth and tactile; a polished, approachable brand.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:22.870864+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=satiny.ai", - "dictionary_url": "https://www.oxfordlearnersdictionaries.com/us/definition/english/satiny", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 18, - "name": "wittily", - "domain": "wittily.ai", - "pronunciation": "WIT-ih-lee", - "rationale": "Clever expression; an upbeat name for a language-focused tool.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:23.233657+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=wittily.ai", - "dictionary_url": "https://www.oxfordlearnersdictionaries.com/us/definition/english/wittily", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 19, - "name": "giddily", - "domain": "giddily.ai", - "pronunciation": "GID-ih-lee", - "rationale": "Excitement and discovery; playful and buoyant.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:23.032894+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=giddily.ai", - "dictionary_url": "https://www.oxfordlearnersdictionaries.com/us/definition/english/giddily", - "collision_note": "No exact standalone software brand surfaced in the limited web search; not a comprehensive clearance.", - "collision_sources": "" - }, - { - "rank": 20, - "name": "blithely", - "domain": "blithely.ai", - "pronunciation": "BLYTHE-lee", - "rationale": "Carefree and cheerful; a light, literary personality.", - "registrar_status": "AVAILABLE", - "premium": 0, - "registration_annual_usd": "82.70", - "renewal_annual_usd": "82.70", - "minimum_term_years": 2, - "two_year_arithmetic_estimate_usd": "165.40", - "price_note": "About USD 165 upfront before tax. Annualized prices; actual checkout rounding/fees can differ.", - "registrar_checked_at_utc": "2026-09-05 15:45:52", - "registry_http_status": 404, - "registry_checked_at_utc": "2026-09-05T15:42:22.138639+00:00", - "pypi_http_status": 404, - "npm_http_status": 404, - "registrar_url": "https://porkbun.com/checkout/search?q=blithely.ai", - "dictionary_url": "https://www.oxfordlearnersdictionaries.com/us/definition/english/blithely", - "collision_note": "Can mean cheerfully or carelessly; pronunciation has a voiced th. No exact software brand surfaced in the limited search.", - "collision_sources": "https://www.oxfordlearnersdictionaries.com/us/definition/english/blithely" - } - ], - "registrar": { - "fetched_at_utc": "2026-09-05T15:46:56.143Z", - "pending": 0, - "results": [ - { - "id": "1819946217", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "puckish.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946218", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "underlit.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946219", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "unmuffle.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946220", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "retint.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946221", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "uncoiled.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946222", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "intoned.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946223", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "unlaced.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946224", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "fancied.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946225", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "honeyed.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946226", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "brambly.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946227", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "fernery.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946228", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "hazily.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946229", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "dozing.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946230", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "riverlet.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946231", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "dimpled.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946232", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "wafting.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946233", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "satiny.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946234", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "wittily.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946235", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "giddily.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819946236", - "check_id": "7b78721024776c5806c19529a7b6a173cd631b650b887d50e55fc2493dcc0400", - "domain": "blithely.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:45:52", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - } - ] - }, - "registry_checks": [ - { - "domain": "puckish.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/puckish.ai", - "checked_at": "2026-09-05T15:42:21.412907+00:00" - }, - { - "domain": "unmuffle.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/unmuffle.ai", - "checked_at": "2026-09-05T15:42:21.402976+00:00" - }, - { - "domain": "underlit.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/underlit.ai", - "checked_at": "2026-09-05T15:42:21.580275+00:00" - }, - { - "domain": "retint.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/retint.ai", - "checked_at": "2026-09-05T15:42:21.776075+00:00" - }, - { - "domain": "honeyed.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/honeyed.ai", - "checked_at": "2026-09-05T15:42:21.800927+00:00" - }, - { - "domain": "intoned.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/intoned.ai", - "checked_at": "2026-09-05T15:42:21.951294+00:00" - }, - { - "domain": "unlaced.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/unlaced.ai", - "checked_at": "2026-09-05T15:42:21.979209+00:00" - }, - { - "domain": "uncoiled.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/uncoiled.ai", - "checked_at": "2026-09-05T15:42:22.130940+00:00" - }, - { - "domain": "blithely.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/blithely.ai", - "checked_at": "2026-09-05T15:42:22.138639+00:00" - }, - { - "domain": "fancied.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/fancied.ai", - "checked_at": "2026-09-05T15:42:22.502473+00:00" - }, - { - "domain": "satiny.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/satiny.ai", - "checked_at": "2026-09-05T15:42:22.870864+00:00" - }, - { - "domain": "giddily.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/giddily.ai", - "checked_at": "2026-09-05T15:42:23.032894+00:00" - }, - { - "domain": "dozing.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/dozing.ai", - "checked_at": "2026-09-05T15:42:23.041226+00:00" - }, - { - "domain": "wittily.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/wittily.ai", - "checked_at": "2026-09-05T15:42:23.233657+00:00" - }, - { - "domain": "dimpled.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/dimpled.ai", - "checked_at": "2026-09-05T15:42:23.402872+00:00" - }, - { - "domain": "brambly.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/brambly.ai", - "checked_at": "2026-09-05T15:42:24.186052+00:00" - }, - { - "domain": "hazily.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/hazily.ai", - "checked_at": "2026-09-05T15:42:24.308602+00:00" - }, - { - "domain": "fernery.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/fernery.ai", - "checked_at": "2026-09-05T15:42:24.374968+00:00" - }, - { - "domain": "wafting.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/wafting.ai", - "checked_at": "2026-09-05T15:42:24.482564+00:00" - }, - { - "domain": "riverlet.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/riverlet.ai", - "checked_at": "2026-09-05T15:42:24.562185+00:00" - } - ], - "package_checks": [ - { - "name": "puckish", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/puckish/json", - "checked_at": "2026-09-05T15:42:02.920318+00:00" - }, - { - "name": "puckish", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/puckish", - "checked_at": "2026-09-05T15:42:02.972686+00:00" - }, - { - "name": "unmuffle", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/unmuffle/json", - "checked_at": "2026-09-05T15:42:02.906954+00:00" - }, - { - "name": "unmuffle", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/unmuffle", - "checked_at": "2026-09-05T15:42:03.152707+00:00" - }, - { - "name": "underlit", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/underlit/json", - "checked_at": "2026-09-05T15:42:03.128953+00:00" - }, - { - "name": "underlit", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/underlit", - "checked_at": "2026-09-05T15:42:03.192937+00:00" - }, - { - "name": "retint", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/retint/json", - "checked_at": "2026-09-05T15:42:03.353068+00:00" - }, - { - "name": "retint", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/retint", - "checked_at": "2026-09-05T15:42:03.551209+00:00" - }, - { - "name": "honeyed", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/honeyed/json", - "checked_at": "2026-09-05T15:42:03.562864+00:00" - }, - { - "name": "honeyed", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/honeyed", - "checked_at": "2026-09-05T15:42:03.659840+00:00" - }, - { - "name": "intoned", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/intoned/json", - "checked_at": "2026-09-05T15:42:03.752683+00:00" - }, - { - "name": "intoned", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/intoned", - "checked_at": "2026-09-05T15:42:03.827707+00:00" - }, - { - "name": "unlaced", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/unlaced/json", - "checked_at": "2026-09-05T15:42:03.820972+00:00" - }, - { - "name": "unlaced", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/unlaced", - "checked_at": "2026-09-05T15:42:04.006906+00:00" - }, - { - "name": "uncoiled", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/uncoiled/json", - "checked_at": "2026-09-05T15:42:04.005607+00:00" - }, - { - "name": "uncoiled", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/uncoiled", - "checked_at": "2026-09-05T15:42:04.088088+00:00" - }, - { - "name": "blithely", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/blithely/json", - "checked_at": "2026-09-05T15:42:04.205825+00:00" - }, - { - "name": "blithely", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/blithely", - "checked_at": "2026-09-05T15:42:04.236938+00:00" - }, - { - "name": "fancied", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/fancied/json", - "checked_at": "2026-09-05T15:42:04.695449+00:00" - }, - { - "name": "fancied", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/fancied", - "checked_at": "2026-09-05T15:42:04.920587+00:00" - }, - { - "name": "satiny", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/satiny/json", - "checked_at": "2026-09-05T15:42:05.335176+00:00" - }, - { - "name": "satiny", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/satiny", - "checked_at": "2026-09-05T15:42:05.443389+00:00" - }, - { - "name": "giddily", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/giddily/json", - "checked_at": "2026-09-05T15:42:05.495877+00:00" - }, - { - "name": "giddily", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/giddily", - "checked_at": "2026-09-05T15:42:05.568508+00:00" - }, - { - "name": "dozing", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/dozing/json", - "checked_at": "2026-09-05T15:42:05.639405+00:00" - }, - { - "name": "dozing", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/dozing", - "checked_at": "2026-09-05T15:42:05.742658+00:00" - }, - { - "name": "wittily", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/wittily/json", - "checked_at": "2026-09-05T15:42:05.933220+00:00" - }, - { - "name": "wittily", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/wittily", - "checked_at": "2026-09-05T15:42:06.008464+00:00" - }, - { - "name": "dimpled", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/dimpled/json", - "checked_at": "2026-09-05T15:42:06.076615+00:00" - }, - { - "name": "dimpled", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/dimpled", - "checked_at": "2026-09-05T15:42:06.205594+00:00" - }, - { - "name": "brambly", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/brambly/json", - "checked_at": "2026-09-05T15:42:07.318064+00:00" - }, - { - "name": "brambly", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/brambly", - "checked_at": "2026-09-05T15:42:07.437433+00:00" - }, - { - "name": "hazily", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/hazily/json", - "checked_at": "2026-09-05T15:42:07.499164+00:00" - }, - { - "name": "hazily", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/hazily", - "checked_at": "2026-09-05T15:42:07.549409+00:00" - }, - { - "name": "fernery", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/fernery/json", - "checked_at": "2026-09-05T15:42:07.635495+00:00" - }, - { - "name": "fernery", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/fernery", - "checked_at": "2026-09-05T15:42:07.721123+00:00" - }, - { - "name": "wafting", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/wafting/json", - "checked_at": "2026-09-05T15:42:07.703879+00:00" - }, - { - "name": "wafting", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/wafting", - "checked_at": "2026-09-05T15:42:07.869120+00:00" - }, - { - "name": "riverlet", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/riverlet/json", - "checked_at": "2026-09-05T15:42:07.869327+00:00" - }, - { - "name": "riverlet", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/riverlet", - "checked_at": "2026-09-05T15:42:07.973324+00:00" - } - ] -} - diff --git a/domain-registrar-evidence-2026-09-05-round-3.json b/domain-registrar-evidence-2026-09-05-round-3.json deleted file mode 100644 index 74711f93..00000000 --- a/domain-registrar-evidence-2026-09-05-round-3.json +++ /dev/null @@ -1,3358 +0,0 @@ -{ - "registrar": "Porkbun", - "endpoint": "https://porkbun.com/api/domains/getChecks", - "pending": 0, - "results": [ - { - "id": "1821252899", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "lunomi.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252900", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "sorumi.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252901", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "norumi.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252902", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "nimela.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252903", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "nolemi.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252904", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "somori.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252905", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "tameli.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252906", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "lumella.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252907", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "enoli.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252908", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "norali.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252909", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "ikumi.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252910", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "siluna.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252911", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "domaso.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252912", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "ostuni.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252913", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "roseto.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252914", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "bormio.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252915", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "locarno.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252916", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "ponza.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252917", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "tropea.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252918", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "varallo.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252919", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "sulmona.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252920", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "posada.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252921", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "quiettide.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252922", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "softmoss.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252923", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "stillcove.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252924", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "innervale.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252925", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "bluehollow.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252926", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "lightgrove.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252927", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "mooncove.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252928", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "mosslane.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252929", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "mistlake.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252930", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "kindmuse.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252931", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "mellowtide.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252932", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "bloomcove.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252933", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "fablecove.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252934", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "papertide.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252935", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "goldfern.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252936", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "silvermoss.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252937", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "fablefern.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252938", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "merrybloom.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252939", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "brightmuse.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252940", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "moonmoss.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252941", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "ambermuse.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252942", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "clearmeadow.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252943", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "openfern.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252944", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "silverglow.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252945", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "softcurrent.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252946", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "lightmoss.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252947", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "gentletide.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1821252948", - "check_id": "7f44e4a00c7f5dc04a02593b469d5ba752f549cba1301dd954ec55d4f7dfceef", - "domain": "fablemoon.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 22:03:26", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - } - ], - "fetched_at_utc": "2026-09-05T22:04:16.175Z" -} diff --git a/domain-registrar-evidence-2026-09-05.json b/domain-registrar-evidence-2026-09-05.json deleted file mode 100644 index 20fe65ed..00000000 --- a/domain-registrar-evidence-2026-09-05.json +++ /dev/null @@ -1,1819 +0,0 @@ -{ - "settings": { - "hideUnavailable": null - }, - "results": [ - { - "id": "1819869402", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "unknit.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869403", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "billowy.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869404", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "borage.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869405", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "drowse.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869406", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "unpleat.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869407", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "toneme.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869408", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "tepal.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869409", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "smidgen.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869410", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "unshown.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869411", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "doline.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869412", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "scumble.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869413", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "brayer.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869414", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "coving.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869415", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "harebell.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869416", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "dimity.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869417", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "sculler.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869418", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "ruddle.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869419", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "isobath.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869420", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "mordent.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - }, - { - "id": "1819869421", - "check_id": "17995276fed71a1daea67a821a16e331b10c4995147eaae45d8f09c61b3be050", - "domain": "shimmery.ai", - "tld": "ai", - "result": "AVAILABLE", - "type": "registration", - "ts": "2026-09-05 15:19:17", - "weight": "0", - "extended": { - "bulkSearch": 1, - "resultType": null, - "discount": 0, - "premium": 0, - "price": "8270", - "pricing": { - "registryFees": { - "currency": "USD", - "amount": 8000, - "default-amount": 8000, - "exchangeRate": 1, - "USD": "8000" - }, - "registrarMarkup": { - "type": "flat", - "amount": "0", - "fixed": 0, - "markup": "0" - }, - "otherFees": [], - "totalOtherFees": "0", - "cost": 8000, - "customerPrice": 8000, - "grossMargin": 0, - "forceRetailPrice": null - }, - "typePricing": { - "registration": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "renewal": { - "ignoreLowerRenew": null, - "currentWholesale": "8000", - "premium": 0, - "price": "8270" - }, - "transfer": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - }, - "update": { - "ignoreLowerRenew": null, - "currentWholesale": "16000", - "premium": 0, - "price": "16509" - } - } - }, - "environment": "prod", - "reason": null, - "inCart": "0" - } - ], - "pending": 0, - "verification": { - "project": "Polythetic local mechanistic-interpretability and activation-steering workbench", - "pool_unique_domains": 594, - "registry_checks": [ - { - "domain": "unknit.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/unknit.ai", - "checked_at": "2026-09-05T15:19:55.221927+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/unknit.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "billowy.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/billowy.ai", - "checked_at": "2026-09-05T15:19:55.230158+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/billowy.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "borage.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/borage.ai", - "checked_at": "2026-09-05T15:19:55.520455+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/borage.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "drowse.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/drowse.ai", - "checked_at": "2026-09-05T15:19:55.426276+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/drowse.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "unpleat.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/unpleat.ai", - "checked_at": "2026-09-05T15:19:55.631992+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/unpleat.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "toneme.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/toneme.ai", - "checked_at": "2026-09-05T15:19:55.700109+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/toneme.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "tepal.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/tepal.ai", - "checked_at": "2026-09-05T15:19:55.842199+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/tepal.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "smidgen.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/smidgen.ai", - "checked_at": "2026-09-05T15:19:55.928373+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/smidgen.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "unshown.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/unshown.ai", - "checked_at": "2026-09-05T15:19:56.024054+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/unshown.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "doline.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/doline.ai", - "checked_at": "2026-09-05T15:19:56.113911+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/doline.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "scumble.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/scumble.ai", - "checked_at": "2026-09-05T15:19:56.196470+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/scumble.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "brayer.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/brayer.ai", - "checked_at": "2026-09-05T15:19:56.308401+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/brayer.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "coving.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/coving.ai", - "checked_at": "2026-09-05T15:19:56.389044+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/coving.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "harebell.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/harebell.ai", - "checked_at": "2026-09-05T15:19:56.526489+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/harebell.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "dimity.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/dimity.ai", - "checked_at": "2026-09-05T15:19:56.618358+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/dimity.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "sculler.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/sculler.ai", - "checked_at": "2026-09-05T15:19:56.717792+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/sculler.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "ruddle.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/ruddle.ai", - "checked_at": "2026-09-05T15:19:56.795483+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/ruddle.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "isobath.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/isobath.ai", - "checked_at": "2026-09-05T15:19:56.915056+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/isobath.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "mordent.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/mordent.ai", - "checked_at": "2026-09-05T15:19:56.996637+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/mordent.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - }, - { - "domain": "shimmery.ai", - "status_code": 404, - "url": "https://rdap.identitydigital.services/rdap/domain/shimmery.ai", - "checked_at": "2026-09-05T15:19:57.102097+00:00", - "response": "{\n \"rdapConformance\": [\n \"rdap_level_0\",\n \"icann_rdap_response_profile_1\",\n \"icann_rdap_technical_implementation_guide_1\"\n ],\n \"notices\": [\n {\n \"title\": \"Terms of Service\",\n \"description\": [\n \"Access to RDAP information is provided to assist persons in determining the contents of a domain name registration record in the registry database. The data in this record is provided by Identity Digital or, if the record pertains to a TLD not operated by Identity Digital, then the corresponding primary Registry Operator for informational purposes only, and neither Identity Digital nor the Registry Operator guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Identity Digital, a Registrar, or Registry Operator except as reasonably necessary to register domain names or modify existing registrations. When using the RDAP service, please consider the following: the RDAP service is not a replacement for standard EPP commands to the SRS service. RDAP is not considered authoritative for registered domain objects. The RDAP service may be scheduled for downtime during production or OT&E maintenance periods. Queries to the RDAP services are throttled. If too many queries are received from a single IP address within a specified time, the service will begin to reject further queries for a period of time to prevent disruption of RDAP service access. Abuse of the RDAP system through data mining is mitigated by detecting and limiting bulk query access from single sources. Where applicable, the presence of a [Non-Public Data] tag indicates that such data is not made publicly available due to applicable data privacy laws or requirements. Should you wish to contact the registrant, please refer to the RDAP records available through the registrar URL listed above. Access to non-public data may be provided, upon request, where it can be reasonably confirmed that the requester holds a specific legitimate interest and a proper legal basis for accessing the withheld data. Access to the data provided by Identity Digital can be requested by submitting a request via the form found at https://www.identity.digital/about/policies/whois-layered-access/ Identity Digital Inc. and, if applicable, the primary Registry Operators reserve the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.\"\n ],\n \"links\": [\n {\n \"value\": \"https://rdap.identitydigital.services/rdap/domain/shimmery.ai\",\n \"rel\": \"terms-of-service\",\n \"href\": \"https://www.identity.digital/policies/rdds-access-policy\",\n \"type\": \"text/html\"\n }\n ]\n }\n ],\n \"errorCode\": 404,\n \"title\": \"Object not found\",\n \"description\": [\n \"Object not found\"\n ],\n \"lang\": \"en\"\n}" - } - ], - "package_checks": [ - { - "name": "unknit", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/unknit/json", - "checked_at": "2026-09-05T15:19:56.893004+00:00" - }, - { - "name": "unknit", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/unknit", - "checked_at": "2026-09-05T15:19:56.851169+00:00" - }, - { - "name": "billowy", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/billowy/json", - "checked_at": "2026-09-05T15:19:56.915138+00:00" - }, - { - "name": "billowy", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/billowy", - "checked_at": "2026-09-05T15:19:57.008873+00:00" - }, - { - "name": "borage", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/borage/json", - "checked_at": "2026-09-05T15:19:57.093736+00:00" - }, - { - "name": "borage", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/borage", - "checked_at": "2026-09-05T15:19:57.043262+00:00" - }, - { - "name": "drowse", - "registry": "pypi", - "http_status": 200, - "summary": "Human readable slim REST client", - "url": "https://pypi.org/pypi/drowse/json", - "checked_at": "2026-09-05T15:19:57.102007+00:00" - }, - { - "name": "drowse", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/drowse", - "checked_at": "2026-09-05T15:19:57.199696+00:00" - }, - { - "name": "unpleat", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/unpleat/json", - "checked_at": "2026-09-05T15:19:57.339019+00:00" - }, - { - "name": "unpleat", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/unpleat", - "checked_at": "2026-09-05T15:19:57.265882+00:00" - }, - { - "name": "toneme", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/toneme/json", - "checked_at": "2026-09-05T15:19:57.402318+00:00" - }, - { - "name": "toneme", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/toneme", - "checked_at": "2026-09-05T15:19:57.429334+00:00" - }, - { - "name": "tepal", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/tepal/json", - "checked_at": "2026-09-05T15:19:57.554472+00:00" - }, - { - "name": "tepal", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/tepal", - "checked_at": "2026-09-05T15:19:57.554353+00:00" - }, - { - "name": "smidgen", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/smidgen/json", - "checked_at": "2026-09-05T15:19:57.612264+00:00" - }, - { - "name": "smidgen", - "registry": "npm", - "http_status": 200, - "summary": "IOTA CLI client", - "url": "https://registry.npmjs.org/smidgen", - "checked_at": "2026-09-05T15:19:57.710104+00:00" - }, - { - "name": "unshown", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/unshown/json", - "checked_at": "2026-09-05T15:19:57.742438+00:00" - }, - { - "name": "unshown", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/unshown", - "checked_at": "2026-09-05T15:19:57.779108+00:00" - }, - { - "name": "doline", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/doline/json", - "checked_at": "2026-09-05T15:19:57.925536+00:00" - }, - { - "name": "doline", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/doline", - "checked_at": "2026-09-05T15:19:57.886082+00:00" - }, - { - "name": "scumble", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/scumble/json", - "checked_at": "2026-09-05T15:19:57.963043+00:00" - }, - { - "name": "scumble", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/scumble", - "checked_at": "2026-09-05T15:19:58.041685+00:00" - }, - { - "name": "brayer", - "registry": "pypi", - "http_status": 200, - "summary": "Turn a Pydantic model into a desktop form: declare the shape, get a validated object back", - "url": "https://pypi.org/pypi/brayer/json", - "checked_at": "2026-09-05T15:19:58.041922+00:00" - }, - { - "name": "brayer", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/brayer", - "checked_at": "2026-09-05T15:19:58.110038+00:00" - }, - { - "name": "coving", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/coving/json", - "checked_at": "2026-09-05T15:19:58.253356+00:00" - }, - { - "name": "coving", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/coving", - "checked_at": "2026-09-05T15:19:58.185188+00:00" - }, - { - "name": "harebell", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/harebell/json", - "checked_at": "2026-09-05T15:19:58.325371+00:00" - }, - { - "name": "harebell", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/harebell", - "checked_at": "2026-09-05T15:19:58.457241+00:00" - }, - { - "name": "dimity", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/dimity/json", - "checked_at": "2026-09-05T15:19:58.448181+00:00" - }, - { - "name": "dimity", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/dimity", - "checked_at": "2026-09-05T15:19:58.568961+00:00" - }, - { - "name": "sculler", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/sculler/json", - "checked_at": "2026-09-05T15:19:58.653867+00:00" - }, - { - "name": "sculler", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/sculler", - "checked_at": "2026-09-05T15:19:58.589003+00:00" - }, - { - "name": "ruddle", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/ruddle/json", - "checked_at": "2026-09-05T15:19:58.757102+00:00" - }, - { - "name": "ruddle", - "registry": "npm", - "http_status": 200, - "summary": "Ruddle is a comprehensive collection of high-quality SVG icons designed to enhance web and app development. It offers an extensive array of icons suitable for various applications, ensuring seamless integration and visual consistency in your projects.", - "url": "https://registry.npmjs.org/ruddle", - "checked_at": "2026-09-05T15:19:58.725540+00:00" - }, - { - "name": "isobath", - "registry": "pypi", - "http_status": 200, - "summary": "A GUI tool for computing slope angles along depth contours from NetCDF bathymetry data", - "url": "https://pypi.org/pypi/isobath/json", - "checked_at": "2026-09-05T15:19:58.761096+00:00" - }, - { - "name": "isobath", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/isobath", - "checked_at": "2026-09-05T15:19:58.847977+00:00" - }, - { - "name": "mordent", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/mordent/json", - "checked_at": "2026-09-05T15:19:58.949423+00:00" - }, - { - "name": "mordent", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/mordent", - "checked_at": "2026-09-05T15:19:58.908036+00:00" - }, - { - "name": "shimmery", - "registry": "pypi", - "http_status": 404, - "summary": null, - "url": "https://pypi.org/pypi/shimmery/json", - "checked_at": "2026-09-05T15:19:59.021182+00:00" - }, - { - "name": "shimmery", - "registry": "npm", - "http_status": 404, - "summary": null, - "url": "https://registry.npmjs.org/shimmery", - "checked_at": "2026-09-05T15:19:59.173840+00:00" - } - ], - "minimum_term_source": "https://porkbun.com/tld/ai", - "pricing_source": "https://porkbun.com/products/domains", - "two_year_price_note": "Two times the advertised annual price is a budget estimate, not a completed checkout quote." - } -} diff --git a/drowse/cli/AGENTS.md b/drowse/cli/AGENTS.md index d9c1a663..a43b9b2a 100644 --- a/drowse/cli/AGENTS.md +++ b/drowse/cli/AGENTS.md @@ -159,7 +159,8 @@ discovery and download entirely. naturalness`. All default `None`/`False`; YAML fills unset values, session defaults (DLS on, compile and cuda-graphs off) win otherwise. - `_add_logit_args` — `--top-k-alts N`, the session default for - `SamplingConfig.return_top_k`. Enforced in `[0, 256]` by both CLI and YAML. + `SamplingConfig.return_top_k`. CLI and YAML require a nonnegative integer; + the sampler bounds the retained count by its actual candidate pool. On `serve` and `experiment fan`. - `_add_config_args` — `-c/--config PATH` (repeatable) and `-s/--strict`. @@ -191,7 +192,7 @@ visibility or skip the upload. The manifold compute verbs (`extract`, ## Per-verb flags **serve** — `model` (optional when YAML supplies it), `-q`, `-d`, `-p`, -`-H/--host` (`0.0.0.0`), `-P/--port` (`[1, 65535]`, 8000), `-S/--steer EXPR`, +`-H/--host` (`127.0.0.1`; non-loopback requires `--api-key` or `DROWSE_API_KEY`), `-P/--port` (`[1, 65535]`, 8000), `-S/--steer EXPR`, `-C/--cors ORIGIN` (repeatable), `-k/--api-key` (falls back to `$DROWSE_API_KEY`), `--no-web`, plus the injection, logit, and config blocks. diff --git a/drowse/cli/config_file.py b/drowse/cli/config_file.py index 98fef137..157c5048 100644 --- a/drowse/cli/config_file.py +++ b/drowse/cli/config_file.py @@ -203,12 +203,12 @@ def finite_number(key: str) -> float | None: # certainly meant a number). if isinstance(return_top_k_v, bool) or not isinstance(return_top_k_v, int): raise ConfigFileError( - f"{path}: return_top_k must be an integer in [0, 256] " + f"{path}: return_top_k must be a nonnegative integer " f"(got {type(return_top_k_v).__name__} {return_top_k_v!r})" ) - if return_top_k_v < 0 or return_top_k_v > 256: + if return_top_k_v < 0: raise ConfigFileError( - f"{path}: return_top_k out of range [0, 256] " + f"{path}: return_top_k must be nonnegative " f"(got {return_top_k_v!r})" ) diff --git a/drowse/cli/parsers.py b/drowse/cli/parsers.py index ae61420d..f4d0a41b 100644 --- a/drowse/cli/parsers.py +++ b/drowse/cli/parsers.py @@ -51,12 +51,12 @@ def _add_logit_args(p: argparse.ArgumentParser) -> None: distributional surfaces (drilldown logits tab, inline surprise tint, NodeCompareDrawer logit columns); ~60 KB/turn on the wire at K=8. Per-call ``SamplingConfig.return_top_k > 0`` overrides; K=0 inherits. - YAML equivalent: ``return_top_k:`` int in ``[0, 256]``. + YAML equivalent: ``return_top_k:`` nonnegative int. """ p.add_argument( - "--top-k-alts", dest="top_k_alts", type=_bounded_int(0, 256), + "--top-k-alts", dest="top_k_alts", type=_nonnegative_int, default=None, metavar="N", - help="Session default for top-K alternatives capture (0–256). " + help="Session default for top-K alternatives capture. " "0 (default) = chosen-token logprob only; N>0 ships top-N " "decoded alternatives per token for distributional surfaces. " "Unset = inherit YAML ``return_top_k:`` / session default.", @@ -212,7 +212,7 @@ def _build_serve_parser(parser: argparse.ArgumentParser) -> None: default=None, help="Probe categories: all, none, epistemic, alignment, register, cultural (default: all)", ) - parser.add_argument("-H", "--host", default="0.0.0.0", help="Bind address") + parser.add_argument("-H", "--host", default="127.0.0.1", help="Bind address (non-loopback requires an API key)") parser.add_argument( "-P", "--port", type=_bounded_int(1, 65535), default=8000, help="Bind port", diff --git a/drowse/cli/runners/serve.py b/drowse/cli/runners/serve.py index 30942465..1e4184c1 100644 --- a/drowse/cli/runners/serve.py +++ b/drowse/cli/runners/serve.py @@ -3,6 +3,7 @@ from __future__ import annotations import argparse +import os import sys from typing import Any, Sequence @@ -145,6 +146,13 @@ def _run_serve(args: argparse.Namespace) -> None: sys.exit(1) _pkg._load_effective_config(args) + from drowse.server.app import is_loopback_host + api_key = getattr(args, "api_key", None) + if api_key is None: + api_key = os.environ.get("DROWSE_API_KEY") + if not is_loopback_host(args.host) and not api_key: + print("drowse serve: non-loopback binding requires --api-key or DROWSE_API_KEY", file=sys.stderr) + sys.exit(2) if not args.model: print( "drowse serve: model required. Pass a HuggingFace repo id (e.g.\n" @@ -176,7 +184,7 @@ def _run_serve(args: argparse.Namespace) -> None: web_enabled = not getattr(args, "no_web", False) app = create_app(session, default_steering=default_steering, cors_origins=args.cors or None, - api_key=getattr(args, "api_key", None), + api_key=api_key, web=web_enabled) # The default probe roster — tagged concept axes plus every fitted bundled @@ -207,4 +215,6 @@ def _run_serve(args: argparse.Namespace) -> None: print(f"API docs: http://{args.host}:{args.port}/docs") if args.port != 11434: print("Tip: for drop-in Ollama compatibility, run with `--port 11434`.") - uvicorn.run(app, host=args.host, port=args.port, log_level="info") + from drowse.server.ws_stream import MAX_WS_MESSAGE_BYTES + uvicorn.run(app, host=args.host, port=args.port, log_level="info", + ws_max_size=MAX_WS_MESSAGE_BYTES) diff --git a/drowse/core/AGENTS.md b/drowse/core/AGENTS.md index 4883b712..84f67c9b 100644 --- a/drowse/core/AGENTS.md +++ b/drowse/core/AGENTS.md @@ -14,6 +14,13 @@ per-layer `subspace_inject` calls carrying an along/onto pair ## model.py +`load_model` and `DrowseSession.from_pretrained` default to repository Python +being disabled for configs, tokenizers, and model implementations. Explicit +`trust_remote_code=True` opts in; `None` honors `DROWSE_TRUST_REMOTE_CODE` +(`1`/`true`/`yes`/`on`), and explicit `False` overrides the environment. +Metadata-only resolution stays `False` regardless of that environment variable. +Native model implementations remain preferred even when custom code is trusted. + HF causal-LM loading and per-architecture wiring. `ArchProfile` / `_LAYER_ACCESSORS` map `model_type` → layer-list accessor (module-level `def`s, not lambdas); `_TESTED_ARCHS` gates a one-time `UserWarning` on an untested @@ -476,7 +483,11 @@ activation is the unit only when no metadata is cached (offline or unlisted feature), and `ScalarReading.unit` says which. Feature metadata is fetched lazily from Neuronpedia at validate/pin time and through a batch backfill the dashboard calls between generations — never inside the decode loop — and persists through -`io/sae.py::save_sae_feature_meta`. +`io/sae.py::save_sae_feature_meta`. Responses must match the model, source, +feature id and provider dictionary before entering the cache. A cached maximum +without a checked description still triggers a lookup. Network requests release +the instrument lock; publication verifies that the same backend, layer and +metadata cache remain active, so a late response cannot relabel a successor SAE. `sae_training.py::train_residual_sae` trains a native one-layer ReLU SAE from block-output token activations under model inference mode; decoder rows are @@ -1003,6 +1014,13 @@ routes flat (`raw=True`) generation; `supports_thinking` / (gpt-oss) and bracket (Mistral-3) fallbacks, and the `_ThinkState` machine plus `GenerationState` drive streaming. +Token decode tables are bounded to two entries and checked against the exact +live tokenizer, including added-token growth. Chat renders are bounded to 128 +entries and an 8 MiB estimated text/tensor budget; the key includes the live +template, special-token values, scene grammar, and model family. Both caches use +weak tokenizer references and release entries on tokenizer collection or session closure. +`DrowseSession.close()` also releases the reusable generation KV cache. + **Step identity.** The decode loop owns ONE `step_id` per forward — `len(generated_ids)` before that forward — and hands the same value to the capture sink (`step_callback`), the gate callback (`score_callback`), and the token tap @@ -1139,6 +1157,12 @@ writes one `capture_authored` loom mutation per populated channel, then runs the ordinary final-prompt sink. There is no second transformer forward. Captured authored rows are immutable — rerolls reuse their data. +`GenerationState.cancellation_scope(event)` binds cancellation to the current +worker thread and survives startup `reset()`. All decode and batch stop checks +use `is_stop_requested()`, combining this scope with explicit `session.stop()`. +`generate_stream.close()` joins its worker even before the first iterator read; +closing an old stream cannot signal a later generation. + **Jacobian-lens surface.** `session.jlens` validates sidecar/live-weight identity before loading, refreshes or evicts an already-resident lens when an external process replaces its generation, and verifies each layer's payload digest while @@ -1219,6 +1243,12 @@ blobs live in memory during streaming — `to_dict` omits them, `save` writes a sidecar. Mutators raise `MutationDuringGenerationError` (409) on conflict, `UnknownNodeError` (404) / `InvalidNodeOperationError` (400) otherwise. +`LoomTree.load` bounds the main JSON at 64 MiB and the decompressed token +sidecar at 256 MiB before JSON parsing. Invalid JSON and corrupt/truncated gzip +raise `LoomTreeError`. A positive integer `max_bytes=` overrides both per-file +limits for trusted large exports. These byte limits bound input expansion, not +the total memory used by parsed objects. Tree and sidecar remain format 2. + `loom_diff.py` — cross-branch diff primitives: `text_diff` (word-level via `difflib.SequenceMatcher` → aligned `DiffSpan`s), `readings_diff` (per-probe `Δ = b − a`, sorted by `abs(delta)`, carrying both originals so "moved" and diff --git a/drowse/core/generation.py b/drowse/core/generation.py index f1cddec3..081188f5 100644 --- a/drowse/core/generation.py +++ b/drowse/core/generation.py @@ -7,8 +7,9 @@ import threading import warnings from enum import IntEnum +from contextlib import contextmanager from typing import Any, Callable, cast -from weakref import WeakKeyDictionary +from weakref import ReferenceType, WeakKeyDictionary, ref import torch from transformers import PreTrainedModel, PreTrainedTokenizerBase @@ -73,7 +74,33 @@ def _get_eos_ids(model: PreTrainedModel, tokenizer: PreTrainedTokenizerBase) -> _TOKEN_TABLE_CACHE_MAX = 2 -_token_table_cache: dict[tuple[str, int, int], list[str | None]] = {} +_generation_cache_lock = threading.RLock() +_token_table_cache: dict[ + tuple[Any, ...], tuple[ReferenceType[Any], list[str | None]] +] = {} + + +def _forget_tokenizer_cache(reference: ReferenceType[Any]) -> None: + with _generation_cache_lock: + for cache in (_token_table_cache, _chat_input_cache): + for key, entry in list(cache.items()): + if entry[0] is reference: + del cache[key] + + +def clear_generation_caches(tokenizer: PreTrainedTokenizerBase) -> None: + with _generation_cache_lock: + for cache in (_token_table_cache, _chat_input_cache): + for key, entry in list(cache.items()): + if entry[0]() is tokenizer: + del cache[key] + + +def _tokenizer_cache_ref(tokenizer: PreTrainedTokenizerBase) -> ReferenceType[Any] | None: + try: + return ref(tokenizer, _forget_tokenizer_cache) + except TypeError: + return None def _get_token_table(tokenizer: PreTrainedTokenizerBase, vocab_size: int) -> list[str | None]: @@ -85,11 +112,15 @@ def _get_token_table(tokenizer: PreTrainedTokenizerBase, vocab_size: int) -> lis (replacement char U+FFFD) — these must be buffered and decoded together with subsequent tokens (e.g. multi-token emoji). """ - tok_key = (*_tok_key(tokenizer), int(vocab_size)) - cached = _token_table_cache.pop(tok_key, None) - if cached is not None: - _token_table_cache[tok_key] = cached - return cached + tok_key = ( + *_tok_key(tokenizer), int(vocab_size), id(tokenizer), + len(getattr(tokenizer, "added_tokens_encoder", {})), + ) + with _generation_cache_lock: + cached = _token_table_cache.pop(tok_key, None) + if cached is not None and cached[0]() is tokenizer: + _token_table_cache[tok_key] = cached + return cached[1] # batch_decode is orders of magnitude faster than per-id decode() # for large vocabs (150k+ tokens in modern models) — Rust-side loop # instead of a Python round-trip per entry. Chunked so that a single @@ -113,9 +144,13 @@ def _get_token_table(tokenizer: PreTrainedTokenizerBase, vocab_size: int) -> lis table[i] = s if '\ufffd' not in s else None except Exception: table[i] = '' - while len(_token_table_cache) >= _TOKEN_TABLE_CACHE_MAX: - _token_table_cache.pop(next(iter(_token_table_cache))) - _token_table_cache[tok_key] = table + reference = _tokenizer_cache_ref(tokenizer) + if reference is not None: + with _generation_cache_lock: + _token_table_cache.pop(tok_key, None) + while len(_token_table_cache) >= _TOKEN_TABLE_CACHE_MAX: + _token_table_cache.pop(next(iter(_token_table_cache))) + _token_table_cache[tok_key] = (reference, table) return table @@ -579,6 +614,7 @@ class GenerationState: def __init__(self): self.stop_requested = threading.Event() + self._cancellation = threading.local() self.token_queue: queue.SimpleQueue[Any] = queue.SimpleQueue() self.thinking_end_idx: int = 0 self.finish_reason: str = "stop" @@ -600,6 +636,19 @@ def __init__(self): def request_stop(self): self.stop_requested.set() + def is_stop_requested(self) -> bool: + owned = getattr(self._cancellation, "event", None) + return self.stop_requested.is_set() or (owned is not None and owned.is_set()) + + @contextmanager + def cancellation_scope(self, event: threading.Event): + previous = getattr(self._cancellation, "event", None) + self._cancellation.event = event + try: + yield + finally: + self._cancellation.event = previous + def reset(self): self.stop_requested.clear() self.token_queue = queue.SimpleQueue() @@ -647,18 +696,41 @@ def add(self, token_id: int) -> None: self.counts[pos].add_(1.0) -# Hand-rolled LRU for build_chat_input results. functools.lru_cache won't -# work cleanly because (a) we'd need every kwarg hashable (the tokenizer -# isn't reliably so across HF versions), and (b) the cached value is a -# torch.Tensor we want to ``.clone()`` on hit so callers can't mutate the -# cached buffer. Keyed on (id(tokenizer), system_prompt, frozen-tuple of -# chat, thinking, add_generation_prompt) — id(tokenizer) implicitly -# invalidates when a fresh tokenizer instance is loaded into a session. -# Sized to comfortably absorb the stateless prefill workload (one identical -# prefix repeated 800×) without bloating; small chat lists serialize -# cheaply to tuples so the per-lookup hash cost is negligible. +# Bound both prompt text and tensors, and release them with their tokenizer. +# Returned tensors are cloned so callers cannot mutate cached input ids. _CHAT_INPUT_CACHE_MAX = 128 -_chat_input_cache: dict[tuple[Any, ...], torch.Tensor] = {} +_CHAT_INPUT_CACHE_MAX_BYTES = 8 * 1024 * 1024 +_chat_input_cache: dict[ + tuple[Any, ...], tuple[ReferenceType[Any], torch.Tensor, int] +] = {} + + +def _chat_cache_key_bytes(value: Any) -> int: + if isinstance(value, str): + return 64 + 4 * len(value) + if isinstance(value, tuple): + return 64 + 8 * len(value) + sum(_chat_cache_key_bytes(v) for v in value) + return 64 + + +def _remember_chat_input( + tokenizer: PreTrainedTokenizerBase, key: tuple[Any, ...], tensor: torch.Tensor, +) -> None: + cost = _chat_cache_key_bytes(key) + tensor.numel() * tensor.element_size() + 128 + if cost > _CHAT_INPUT_CACHE_MAX_BYTES: + return + reference = _tokenizer_cache_ref(tokenizer) + if reference is None: + return + with _generation_cache_lock: + _chat_input_cache.pop(key, None) + total = sum(entry[2] for entry in _chat_input_cache.values()) + while _chat_input_cache and ( + len(_chat_input_cache) >= _CHAT_INPUT_CACHE_MAX + or total + cost > _CHAT_INPUT_CACHE_MAX_BYTES + ): + total -= _chat_input_cache.pop(next(iter(_chat_input_cache)))[2] + _chat_input_cache[key] = (reference, tensor, cost) def _chat_input_cache_key( @@ -669,8 +741,12 @@ def _chat_input_cache_key( add_generation_prompt: bool, gen_role: str | None = None, gen_seat: str = "assistant", - scene_mode: bool = False, + scene: "TurnGrammar | None" = None, + model_type: str | None = None, ) -> tuple[Any, ...]: + template = tokenizer.chat_template + if isinstance(template, dict): + template = tuple(sorted(template.items())) return ( id(tokenizer), system_prompt, @@ -682,7 +758,14 @@ def _chat_input_cache_key( add_generation_prompt, gen_role, gen_seat, - scene_mode, + repr(scene), + model_type, + template, + tuple( + (name, tuple(value) if isinstance(value, list) else value) + for name, value in sorted(getattr(tokenizer, "special_tokens_map", {}).items()) + ), + len(getattr(tokenizer, "added_tokens_encoder", {})), ) @@ -775,22 +858,16 @@ def build_chat_input( chat.extend(messages) has_labels = gen_role is not None or any(m.get("label") for m in chat) if getattr(tokenizer, "chat_template", None) is not None: - # Cache lookup: see _chat_input_cache docstring for invalidation - # semantics. Only the chat-template branch is cached — the - # base-model fallback is sub-ms and not worth complicating. - # Per-turn labels + ``gen_role`` participate in the key so role- - # tagged renders never collide with plain renders of the same chat. key = _chat_input_cache_key( tokenizer, chat, system_prompt, thinking, add_generation_prompt, gen_role, gen_seat, - scene is not None, + scene, model_type, ) - cached = _chat_input_cache.pop(key, None) - if cached is not None: - _chat_input_cache[key] = cached - # Return a clone — callers (notably ``_prepare_input``) ``.to`` - # device-move the tensor and would otherwise alias the cache. - return cached.clone() + with _generation_cache_lock: + cached = _chat_input_cache.pop(key, None) + if cached is not None and cached[0]() is tokenizer: + _chat_input_cache[key] = cached + return cached[1].clone() scene_result = _try_scene_render( tokenizer, chat, scene, thinking=thinking, @@ -799,9 +876,7 @@ def build_chat_input( gen_seat=gen_seat, ) if scene_result is not None: - if len(_chat_input_cache) >= _CHAT_INPUT_CACHE_MAX: - _chat_input_cache.pop(next(iter(_chat_input_cache))) - _chat_input_cache[key] = scene_result + _remember_chat_input(tokenizer, key, scene_result) return scene_result.clone() if gen_seat != "assistant": raise SceneRenderError( @@ -840,11 +915,7 @@ def build_chat_input( if isinstance(result, torch.Tensor) else cast(torch.Tensor, result["input_ids"]) # pyright: ignore[reportArgumentType, reportCallIssue] # transformers BatchEncoding stub lacks str-key subscript ) - # Insert into the LRU cache. Hits above move the entry to the end; - # popping the first key removes the least recently used render. - if len(_chat_input_cache) >= _CHAT_INPUT_CACHE_MAX: - _chat_input_cache.pop(next(iter(_chat_input_cache))) - _chat_input_cache[key] = tensor + _remember_chat_input(tokenizer, key, tensor) return tensor.clone() # Base model without chat template — the cast model's raw-marker # fallback (``render_scene_raw``): ``Label: text`` lines, seats free, @@ -1259,7 +1330,7 @@ def _decode_piece(tid: int) -> str | None: try: with torch.inference_mode(): for _ in range(config.max_new_tokens): - if state.stop_requested.is_set(): + if state.is_stop_requested(): state.finish_reason = "stop" # Stop fired while still inside a thinking phase: # anchor ``thinking_end_idx`` at the current position @@ -1449,61 +1520,55 @@ def _decode_piece(tid: int) -> str | None: [[forced_id]], device=device, dtype=cand_ids.dtype, ) - # ``cand_logp`` backs both the logprobs capture and the - # perplexity entropy. Compute it only when one of them needs - # it, and pay the entropy ``.item()`` host sync (one sync per - # token) only when a consumer actually wants perplexity — - # ``want_perplexity=False`` (e.g. stateless server streaming, - # which never surfaces per-token ppl) skips it entirely. want_ppl = want_perplexity and capture_sampler_stats + float_parts = [] + id_parts = [next_token.reshape(-1)] if logprobs is not None or want_ppl: cand_logp = cand_probs.clamp_min( torch.finfo(torch.float32).tiny, ).log() + if want_ppl: + float_parts.append((-(cand_probs * cand_logp)).sum().reshape(1)) + if logprobs is not None: + selected_logp = ( + cand_logp.index_select(0, chosen_pos) + if forced_in_pool else torch.log_softmax( + logits.float(), dim=-1, + )[0].index_select(0, next_token.reshape(-1)) + ) + float_parts.append(selected_logp) + if logprobs > 0: + masked = cand_logp.masked_fill(cand_probs <= 0, float("-inf")) + tlv, tpos = masked.topk(min(logprobs, cand_logp.numel())) + id_parts.append(cand_ids.index_select(0, tpos)) + float_parts.append(tlv) + if float_parts: + # Preserve integer IDs and fp32 bits in one host transfer. + ids = torch.cat(id_parts) + values = torch.cat(float_parts).float() + packed = torch.cat((ids, values.view(torch.int32).to(ids.dtype))).cpu() + host_ids = packed[:ids.numel()].tolist() + host_values = packed[ids.numel():].to(torch.int32).view(torch.float32).tolist() + token_id = int(host_ids[0]) + offset = 0 + if want_ppl: + current_perplexity = math.exp(host_values[offset]) + offset += 1 + else: + current_perplexity = None + if logprobs is not None: + chosen_logprob = float(host_values[offset]) + offset += 1 + if logprobs > 0: + top_alts = [ + TokenAlt(id=int(i), text=_decode_alt(int(i)), logprob=float(v)) + for i, v in zip(host_ids[1:], host_values[offset:], strict=True) + if math.isfinite(v) + ] else: - cand_logp = None - if want_ppl: - assert cand_logp is not None # set above when want_ppl - entropy_nats = float((-(cand_probs * cand_logp)).sum().item()) - current_perplexity = math.exp(entropy_nats) - else: - # Not computed this step. ``None`` is the contract every - # consumer types (``TokenEvent.perplexity: float | None``, - # the loom token row, the WS frame) and the value the - # degenerate no-forward case already carries; a NaN would - # read as a real measurement and is not valid JSON. + token_id = int(next_token.item()) current_perplexity = None - token_id = int(next_token.item()) - - if logprobs is not None: - assert cand_logp is not None - if forced_in_pool: - chosen_logprob = float(cand_logp[int(chosen_pos.item())].item()) - else: - chosen_logprob = float(torch.log_softmax( - logits.float(), dim=-1, - )[0, token_id].item()) - if logprobs > 0: - # Only surface in-support alternatives. Sub-top-p tail - # entries were zeroed in ``cand_probs`` and clamped to - # ``log(tiny)`` in ``cand_logp``; without this mask a - # request for more alts than the nucleus holds pads the - # list with tokens the sampler had zero probability of - # drawing (reported at ~-87 nats). Mask them to -inf, - # take the top-k, then drop any -inf the topk had to - # pad with — so a peaked step returns fewer than - # ``logprobs`` alts rather than out-of-support ones. - masked = cand_logp.masked_fill(cand_probs <= 0, float("-inf")) - tlv, tpos = masked.topk(min(logprobs, cand_logp.numel())) - keep = torch.isfinite(tlv) - tlv, tpos = tlv[keep], tpos[keep] - tli = cand_ids.index_select(0, tpos) - top_alts = [ - TokenAlt(id=int(i), text=_decode_alt(int(i)), logprob=float(v)) - for i, v in zip(tli.tolist(), tlv.tolist(), strict=True) - ] - if token_id in eos_ids: # Channel-based models (gpt-oss) use EOS tokens as # channel separators. For these models only, skip diff --git a/drowse/core/loom.py b/drowse/core/loom.py index f01487ae..aac18d56 100644 --- a/drowse/core/loom.py +++ b/drowse/core/loom.py @@ -35,11 +35,12 @@ import re import secrets import tempfile +import zlib from contextlib import suppress import threading import time from dataclasses import dataclass, field, fields -from typing import Any, Callable, Iterator, Literal, cast +from typing import Any, BinaryIO, Callable, Iterator, Literal, cast from drowse.core.errors import DrowseError # ``LoomMutated`` is defined in ``events`` (one module owns the bus's payload @@ -111,6 +112,16 @@ def user_message(self) -> tuple[int, str]: return (409, str(self) or self.__class__.__name__) +def _read_json_bounded(stream: BinaryIO | gzip.GzipFile, max_bytes: int, label: str) -> Any: + raw = stream.read(max_bytes + 1) + if len(raw) > max_bytes: + raise LoomTreeError(f"{label} exceeds the {max_bytes}-byte import limit") + try: + return json.loads(raw.decode("utf-8")) + except (UnicodeDecodeError, json.JSONDecodeError, RecursionError) as error: + raise LoomTreeError(f"{label} is invalid JSON") from error + + def _require_fields( data: dict[str, Any], required: frozenset[str], @@ -455,7 +466,7 @@ def _parse_recipe_modifier(value: str) -> Recipe: if number is not None: sampling_values[key] = number - _recipe_modifier_range(sampling_values, "temperature", 0.0, 2.0) + _recipe_modifier_range(sampling_values, "temperature", 0.0, None) _recipe_modifier_range(sampling_values, "top_p", 0.0, 1.0) _recipe_modifier_range(sampling_values, "top_k", 0, None) _recipe_modifier_range(sampling_values, "max_tokens", 1, None) @@ -780,6 +791,8 @@ def derive_seed_schedule(base_seed: int | None, n: int) -> list[int]: # Current-only loaders require these versions and every field written by the # corresponding schema; there is no implicit v1 or additive-field migration. TREE_FORMAT_VERSION = 2 +_TREE_MAX_LOAD_BYTES = 64 * 1024 * 1024 +_TOKEN_SIDECAR_MAX_LOAD_BYTES = 256 * 1024 * 1024 TOKEN_SIDECAR_FORMAT_VERSION = 2 @@ -1810,13 +1823,27 @@ def save(self, path: Any) -> None: write_json_atomic(out_path, data) @classmethod - def load(cls, path: Any, *, events: EventBus | None = None) -> "LoomTree": + def load( + cls, path: Any, *, events: EventBus | None = None, + max_bytes: int | None = None, + ) -> "LoomTree": + """Load a saved tree with bounded JSON and gzip expansion. + + Defaults to 64 MiB for the tree and 256 MiB for its expanded token + sidecar. ``max_bytes`` overrides both limits for trusted large exports. + """ from pathlib import Path from drowse.io.brand_migration import migrate_legacy_record + if max_bytes is not None and ( + type(max_bytes) is not int or max_bytes <= 0 + ): + raise ValueError("max_bytes must be a positive integer") in_path = Path(path) - with open(in_path, "r", encoding="utf-8") as f: - data = json.load(f) + with open(in_path, "rb") as f: + data = _read_json_bounded( + f, _TREE_MAX_LOAD_BYTES if max_bytes is None else max_bytes, "loom tree", + ) if not isinstance(data, dict): raise LoomTreeError("loom tree file must contain an object") data = migrate_legacy_record(data) @@ -1838,12 +1865,17 @@ def load(cls, path: Any, *, events: EventBus | None = None) -> "LoomTree": ) sidecar = in_path.parent / sidecar_name try: - with gzip.open(sidecar, "rt", encoding="utf-8") as f: - token_payload = json.load(f) + with gzip.GzipFile(sidecar, "rb") as f: + token_payload = _read_json_bounded( + f, _TOKEN_SIDECAR_MAX_LOAD_BYTES if max_bytes is None else max_bytes, + "token sidecar", + ) except FileNotFoundError as e: raise LoomTreeError( f"token sidecar declared but missing: {sidecar}" ) from e + except (gzip.BadGzipFile, EOFError, zlib.error) as error: + raise LoomTreeError("token sidecar is not a complete gzip file") from error if not isinstance(token_payload, dict): raise LoomTreeError("token sidecar must contain an object") _require_fields(token_payload, frozenset({"token_sidecar_format", "nodes"}), "token sidecar") diff --git a/drowse/core/model.py b/drowse/core/model.py index bb85d99e..67b4ac08 100644 --- a/drowse/core/model.py +++ b/drowse/core/model.py @@ -3,6 +3,7 @@ import hashlib import json import logging +import os import threading import warnings import weakref @@ -161,7 +162,7 @@ def model_source_fingerprint( effective_quantize = quantize if resolved_device == "cuda" else None resolved_load_dtype = _resolve_dtype(dtype, resolved_device) if config is None: - config = AutoConfig.from_pretrained(model_id, trust_remote_code=True) + config = AutoConfig.from_pretrained(model_id, trust_remote_code=False) resolved_commit = ( getattr(config, "_commit_hash", None) or getattr(getattr(config, "text_config", None), "_commit_hash", None) @@ -233,7 +234,7 @@ def config_model_shape(model_id: str) -> tuple[int, int]: Raises when the config declares neither, because a *guessed* layer count would silently widen or narrow a proof. """ - config = AutoConfig.from_pretrained(model_id) + config = AutoConfig.from_pretrained(model_id, trust_remote_code=False) text_config = getattr(config, "text_config", config) n_layers = getattr( text_config, "num_hidden_layers", getattr(text_config, "n_layer", None), @@ -936,6 +937,7 @@ def load_model( *, compile: bool = False, compile_mode: str = "default", + trust_remote_code: bool | None = None, on_progress: Callable[[str], None] | None = None, ) -> tuple[PreTrainedModel, PreTrainedTokenizerBase]: """Load a HuggingFace causal LM and its tokenizer. @@ -966,6 +968,8 @@ def load_model( would shape-recompile per decode step). ``"max-autotune"`` runs Triton autotune (long first-call latency, marginal gains for decode-shape workloads). + trust_remote_code: Permit repository Python only when explicitly True, + or when unset and DROWSE_TRUST_REMOTE_CODE is enabled. Defaults off. on_progress: Optional per-step status sink. The loader's own status goes to ``log.info``, which is invisible unless the embedding application configured logging — a library must not @@ -978,6 +982,10 @@ def load_model( ``OptimizedModule.__getattr__``, so ``get_layers`` and ``get_model_info`` continue to work. """ + if trust_remote_code is None: + trust_remote_code = os.environ.get("DROWSE_TRUST_REMOTE_CODE", "").strip().lower() in {"1", "true", "yes", "on"} + if type(trust_remote_code) is not bool: + raise ValueError("trust_remote_code must be a boolean") device = detect_device(device) if device == "mps": patch_torch_for_mps() @@ -985,7 +993,7 @@ def load_model( if on_progress is not None: on_progress(f"Device: {device}") - plan = _resolve_load_plan(model_id, quantize=quantize, device=device, dtype=dtype) + plan = _resolve_load_plan(model_id, quantize=quantize, device=device, dtype=dtype, trust_remote_code=trust_remote_code) tokenizer = AutoTokenizer.from_pretrained( model_id, **plan.tokenizer_kwargs, **plan.pin_kwargs, ) @@ -1034,6 +1042,7 @@ def _resolve_load_plan( quantize: str | None, device: str, dtype: torch.dtype | str | None, + trust_remote_code: bool = False, ) -> LoadPlan: """Decide how to load ``model_id``; read configs, never weights.""" resolved_dtype = _resolve_dtype(dtype, device) @@ -1043,7 +1052,7 @@ def _resolve_load_plan( # single pin, a mutable Hub branch can advance between independent # ``from_pretrained`` calls and leave caches stamped with config A over # weights B. Local paths carry no commit and remain path-hash identified. - probe_config = AutoConfig.from_pretrained(model_id, trust_remote_code=True) + probe_config = AutoConfig.from_pretrained(model_id, trust_remote_code=trust_remote_code) resolved_revision = ( getattr(probe_config, "_commit_hash", None) or getattr(getattr(probe_config, "text_config", None), "_commit_hash", None) @@ -1059,7 +1068,7 @@ def _resolve_load_plan( # so it fires for any mistralai/* repo (Mistral-Small, Ministral, etc.) and # third-party finetunes whose name carries the family. # https://huggingface.co/mistralai/Mistral-Small-3.1-24B-Instruct-2503/discussions/84 - tokenizer_kwargs: dict[str, Any] = {"trust_remote_code": True} + tokenizer_kwargs: dict[str, Any] = {"trust_remote_code": trust_remote_code} if "mistral" in model_id.lower(): tokenizer_kwargs["fix_mistral_regex"] = True @@ -1098,7 +1107,7 @@ def _resolve_load_plan( native_type = getattr(probe_config, "model_type", None) native_text_type = getattr(getattr(probe_config, "text_config", None), "model_type", None) - trust = not ( + trust = trust_remote_code and not ( (native_type and native_type in CONFIG_MAPPING) or (native_text_type and native_text_type in CONFIG_MAPPING) ) diff --git a/drowse/core/sampling.py b/drowse/core/sampling.py index 34633a32..a2b1d7f6 100644 --- a/drowse/core/sampling.py +++ b/drowse/core/sampling.py @@ -48,9 +48,8 @@ class SamplingConfig: # log_softmax (any ``on_token`` consumer or an explicit ``logprobs`` # request), so K=0 is the minimal-additive-cost default for the loom # path. ``K > 0`` additionally captures the top-K alternatives with - # decoded text per :class:`TokenAlt`. Clamped to ``[0, 256]`` in - # ``__post_init__`` — beyond 256 is data nobody can act on and bytes - # nobody wants on the wire. + # decoded text per :class:`TokenAlt`. The sampler bounds the count by + # its actual candidate pool; retaining many alternatives costs memory. return_top_k: int = 0 # Per-message role-substitution labels (roleplay scaffold). Like # ``seed``, these are per-call and recorded on the produced loom nodes @@ -86,17 +85,8 @@ def __post_init__(self) -> None: # it's a real runtime guard against lists slipping through. if self.stop is not None and not isinstance(self.stop, tuple): # pyright: ignore[reportUnnecessaryIsInstance] object.__setattr__(self, "stop", tuple(self.stop)) - # Clamp return_top_k into the supported range. We do this rather - # than raise because the field is exposed through both Python - # (kwarg) and YAML/CLI surfaces; clamping silently keeps the - # downstream engine math safe (slicing with a too-large K would - # ValueError on torch.topk) and matches the rest of the - # SamplingConfig discipline of preferring graceful coercion to - # raises at construction. if self.return_top_k < 0: object.__setattr__(self, "return_top_k", 0) - elif self.return_top_k > 256: - object.__setattr__(self, "return_top_k", 256) # Default sentinels used by merged_with — matches the dataclass defaults. _DEFAULTS = { diff --git a/drowse/core/session.py b/drowse/core/session.py index ed61093f..10f31e5c 100644 --- a/drowse/core/session.py +++ b/drowse/core/session.py @@ -320,7 +320,7 @@ def __call__( **kwargs: Any, ) -> Any: del scores, kwargs - stop = 1 if self._state.stop_requested.is_set() else 0 + stop = 1 if self._state.is_stop_requested() else 0 return input_ids.new_full((int(input_ids.shape[0]),), stop).bool() @@ -361,7 +361,7 @@ def _run_serial_generation_jobs( grid_rows.append(row) if on_result is not None: on_result(idx, result, row) - if stop_between_jobs and session._gen_state.stop_requested.is_set(): + if stop_between_jobs and session._gen_state.is_stop_requested(): break return RunSet(results, node_ids=node_ids, grid=grid_rows, kind=kind) @@ -866,6 +866,7 @@ def from_pretrained( compile: bool = False, compile_mode: str | None = None, cuda_graphs: bool = False, + trust_remote_code: bool | None = None, return_top_k: int = 0, on_progress: Callable[[str], None] | None = None, ) -> "DrowseSession": @@ -912,6 +913,10 @@ def from_pretrained( bundled concept fit the default probe roster still needs. Unset (the library default) constructs silently; the CLI passes a printing callback so a first ``drowse serve`` narrates instead of hanging. + + ``trust_remote_code`` defaults off unless DROWSE_TRUST_REMOTE_CODE is + enabled. Explicit True permits repository Python; explicit False + overrides the environment. Only opt in for code you trust. """ # Load WITHOUT compile so the StaticCache probe runs against the # bare nn.Module (probing through the OptimizedModule wrapper @@ -929,6 +934,7 @@ def from_pretrained( device=device, dtype=dtype, compile=False, + trust_remote_code=trust_remote_code, on_progress=on_progress, ) @@ -1094,13 +1100,10 @@ def __init__( # Session-level default for SamplingConfig.return_top_k. # Per-call value > 0 wins; per-call K=0 (the # SamplingConfig default) inherits this stored value via the - # composition in ``_generate_core``. Clamped on entry mirroring - # SamplingConfig.__post_init__ so out-of-range values from - # ``--top-k-alts`` or YAML don't reach the engine slice. + # composition in ``_generate_core``. The sampler bounds this by + # the actual candidate pool when capturing alternatives. if return_top_k < 0: return_top_k = 0 - elif return_top_k > 256: - return_top_k = 256 self._default_return_top_k: int = int(return_top_k) self._steering = SteeringManager() # CUDA-graphs / StaticCache routing. Probe @@ -3787,9 +3790,16 @@ def load_sae(self, release: str, *, layer: int | None = None) -> dict[str, Any]: validate_residual_width( backend, selected, int(self._model_info["hidden_dim"]), ) + source_info = { + "layer": selected, "width": width, + "revision": backend.revision, "fingerprint": backend.fingerprint, + "sae_id": backend.sae_ids_by_layer.get(str(selected)), + "repo_id": backend.repo_id, + "neuronpedia_id": backend.neuronpedia_ids_by_layer.get(str(selected)), + } feature_meta = ( {} if isinstance(backend, LocalSaeBackend) - else load_sae_feature_meta(self.model_id, release) + else load_sae_feature_meta(self.model_id, release, source=source_info) ) # Publish/validate the source binding before replacing the # session's resident runtime. A metadata failure must leave the @@ -3801,29 +3811,19 @@ def load_sae(self, release: str, *, layer: int | None = None) -> dict[str, Any]: self.model_id, "local", normalize_local_sae_name(release), ) else: - save_sae_metadata(self.model_id, release, { - "layer": selected, - "width": width, - "revision": backend.revision, - "fingerprint": backend.fingerprint, - "sae_id": backend.sae_ids_by_layer.get(str(selected)), - "repo_id": backend.repo_id, - "neuronpedia_id": backend.neuronpedia_ids_by_layer.get( - str(selected) - ), - }) - self._sae_backend = backend - self._sae_layer = selected - self._sae_width = width - self._sae_feature_meta = feature_meta - self._sae_instrument.live = None - self._sae_instrument.step_stash = None - self._sae_instrument.last_step_readings = None + save_sae_metadata(self.model_id, release, source_info) # Feature ids belong to the resident release; changing it evicts # stale directions and pinned probes rather than silently reusing ids. for name in [key for key in self._profiles if key.startswith("sae/")]: del self._profiles[name] with self._sae_instrument.state_lock: + self._sae_backend = backend + self._sae_layer = selected + self._sae_width = width + self._sae_feature_meta = feature_meta + self._sae_instrument.live = None + self._sae_instrument.step_stash = None + self._sae_instrument.last_step_readings = None for name in list(self._sae_instrument.probes): self._probe_hash_cache.pop(name, None) self._sae_instrument.probes.clear() @@ -3836,16 +3836,16 @@ def unload_sae(self) -> None: with self._model_exclusive( "unload_sae called while another model operation is in flight; retry shortly" ): - self._sae_backend = None - self._sae_layer = None - self._sae_width = None - self._sae_feature_meta = {} - self._sae_instrument.live = None - self._sae_instrument.step_stash = None - self._sae_instrument.last_step_readings = None for name in [key for key in self._profiles if key.startswith("sae/")]: del self._profiles[name] with self._sae_instrument.state_lock: + self._sae_backend = None + self._sae_layer = None + self._sae_width = None + self._sae_feature_meta = {} + self._sae_instrument.live = None + self._sae_instrument.step_stash = None + self._sae_instrument.last_step_readings = None for name in list(self._sae_instrument.probes): self._probe_hash_cache.pop(name, None) self._sae_instrument.probes.clear() @@ -3891,20 +3891,21 @@ def validate_sae_feature(self, feature_id: int | str) -> dict[str, Any]: idx = int(feature_id) except (TypeError, ValueError) as exc: raise SaeFeatureError(f"SAE feature id must be an integer: {feature_id!r}") from exc - _backend, layer, width = self._require_sae() + with self._sae_instrument.state_lock: + backend, layer, width = self._require_sae() + meta = self._sae_feature_meta.get(str(idx)) if not 0 <= idx < width: raise SaeFeatureError( f"SAE feature {idx} out of range [0, {width}) for layer {layer}" ) - meta = self._sae_feature_meta.get(str(idx)) - if meta is None or (meta.get("max_act") is None and not meta.get("checked")): + if meta is None or ( + (meta.get("max_act") is None or not meta.get("label")) and not meta.get("checked") + ): meta = self._fetch_sae_feature_meta(idx) or meta or {} - return { - "id": idx, - "label": meta.get("label"), - "layer": layer, - "max_act": meta.get("max_act"), - } + with self._sae_instrument.state_lock: + if self._sae_backend is not backend or self._sae_layer != layer: + raise SaeFeatureError("SAE source changed while loading feature metadata; try again") + return {"id": idx, "label": meta.get("label"), "layer": layer, "max_act": meta.get("max_act")} def _sae_label(self, feature_id: int) -> str | None: entry = self._sae_feature_meta.get(str(feature_id)) @@ -3930,11 +3931,13 @@ def _fetch_neuronpedia_feature(self, feature_id: int) -> dict[str, Any] | None: response always yields an entry — ``checked`` marks "we asked", so a feature with no Neuronpedia data isn't re-fetched on every validate. """ - info = self.sae_info or {} + with self._sae_instrument.state_lock: + info = self.sae_info or {} neuronpedia_id = info.get("neuronpedia_id") if not isinstance(neuronpedia_id, str) or "/" not in neuronpedia_id: return None import json + import math from urllib.parse import quote from huggingface_hub import get_session @@ -3946,14 +3949,26 @@ def _fetch_neuronpedia_feature(self, feature_id: int) -> dict[str, Any] | None: try: response = get_session().get( url, - timeout=2.0, + timeout=10.0, headers={"User-Agent": "drowse-sae-meta/1"}, ) response.raise_for_status() payload = json.loads(response.content) except Exception: return None - if not isinstance(payload, dict): + if ( + not isinstance(payload, dict) + or payload.get("modelId") != model + or payload.get("layer") != source + or str(payload.get("index")) != str(feature_id) + or not isinstance(payload.get("explanations"), list) + ): + return None + dictionary = payload.get("source") + if not isinstance(dictionary, dict) or any( + info.get(expected) is not None and dictionary.get(actual) != info[expected] + for expected, actual in (("repo_id", "hfRepoId"), ("sae_id", "saelensSaeId")) + ): return None label = None for row in payload.get("explanations", []) or []: @@ -3964,7 +3979,10 @@ def _fetch_neuronpedia_feature(self, feature_id: int) -> dict[str, Any] | None: label = description.strip() break max_act = payload.get("maxActApprox") - if not (isinstance(max_act, (int, float)) and float(max_act) > 0): + if not ( + isinstance(max_act, (int, float)) and not isinstance(max_act, bool) + and math.isfinite(max_act) and float(max_act) > 0 + ): max_act = None return { "label": label, @@ -3980,16 +3998,20 @@ def _fetch_sae_feature_meta(self, feature_id: int) -> dict[str, Any] | None: renders raw activations until metadata is cached (the dashboard backfills via :meth:`fetch_sae_feature_meta` between generations). """ + with self._sae_instrument.state_lock: + backend, layer, _width = self._require_sae() + metadata = self._sae_feature_meta + source = self.sae_info entry = self._fetch_neuronpedia_feature(feature_id) if entry is None: return None from drowse.io.sae import save_sae_feature_meta - self._sae_feature_meta[str(feature_id)] = entry - backend, _layer, _width = self._require_sae() - save_sae_feature_meta( - self.model_id, backend.release, self._sae_feature_meta, - ) + with self._sae_instrument.state_lock: + if self._sae_backend is not backend or self._sae_layer != layer or self._sae_feature_meta is not metadata: + return None + metadata[str(feature_id)] = entry + save_sae_feature_meta(self.model_id, backend.release, metadata, source=source) return entry def fetch_sae_feature_meta( @@ -4005,7 +4027,10 @@ def fetch_sae_feature_meta( silently dropped — the top-k can't produce one, so there is nothing to report). """ - backend, _layer, width = self._require_sae() + with self._sae_instrument.state_lock: + backend, layer, width = self._require_sae() + metadata = self._sae_feature_meta + source = self.sae_info seen: set[int] = set() wanted: list[int] = [] for raw in feature_ids: @@ -4013,9 +4038,10 @@ def fetch_sae_feature_meta( if not 0 <= idx < width or idx in seen: continue seen.add(idx) - entry = self._sae_feature_meta.get(str(idx)) + entry = metadata.get(str(idx)) if entry is None or ( - entry.get("max_act") is None and not entry.get("checked") + (entry.get("max_act") is None or not entry.get("label")) + and not entry.get("checked") ): wanted.append(idx) if wanted: @@ -4031,19 +4057,20 @@ def fetch_sae_feature_meta( if fetched: from drowse.io.sae import save_sae_feature_meta - self._sae_feature_meta.update(fetched) - save_sae_feature_meta( - self.model_id, backend.release, self._sae_feature_meta, - ) - self._refresh_sae_probe_meta(fetched) - return { - str(idx): { - "label": entry.get("label"), - "max_act": entry.get("max_act"), + with self._sae_instrument.state_lock: + if self._sae_backend is not backend or self._sae_layer != layer or self._sae_feature_meta is not metadata: + return {} + metadata.update(fetched) + save_sae_feature_meta(self.model_id, backend.release, metadata, source=source) + self._refresh_sae_probe_meta(fetched) + with self._sae_instrument.state_lock: + if self._sae_backend is not backend or self._sae_layer != layer or self._sae_feature_meta is not metadata: + return {} + return { + str(idx): {"label": entry.get("label"), "max_act": entry.get("max_act")} + for idx in sorted(seen) + if (entry := metadata.get(str(idx))) is not None } - for idx in sorted(seen) - if (entry := self._sae_feature_meta.get(str(idx))) is not None - } def _refresh_sae_probe_meta(self, fetched: dict[str, dict[str, Any]]) -> None: """Reflect newly fetched metadata onto attached feature probes. @@ -9815,6 +9842,7 @@ def generate_stream( result_holder: list[GenerationResult] = [] exc_holder: list[BaseException] = [] idx_counter = [0] + cancelled = threading.Event() def _push( text: str, is_thinking: bool, tid: int | None, lp: float | None, @@ -9861,19 +9889,20 @@ def _push( def _worker(): try: - result = self._generate_core( - input, - steering=steering, - sampling=sampling, - stateless=stateless, - raw=raw, - thinking=thinking, - on_token=consumer, - parent_node_id=parent_node_id, - recipe_override=recipe_override, - gen_seat=gen_seat, - append_same_role=append_same_role, - ) + with self._gen_state.cancellation_scope(cancelled): + result = self._generate_core( + input, + steering=steering, + sampling=sampling, + stateless=stateless, + raw=raw, + thinking=thinking, + on_token=consumer, + parent_node_id=parent_node_id, + recipe_override=recipe_override, + gen_seat=gen_seat, + append_same_role=append_same_role, + ) result_holder.append(result) except BaseException as e: exc_holder.append(e) @@ -9882,6 +9911,19 @@ def _worker(): worker = threading.Thread(target=_worker, daemon=True) worker.start() + finished = False + + def _finish() -> None: + nonlocal finished + if finished: + return + cancelled.set() + worker.join() + while not q.empty(): + q.get_nowait() + finished = True + if exc_holder and not result_holder: + raise exc_holder[0] def _events() -> Iterator[TokenEvent]: try: @@ -9891,10 +9933,7 @@ def _events() -> Iterator[TokenEvent]: break yield item finally: - self._gen_state.stop_requested.set() - worker.join() - if exc_holder and not result_holder: - raise exc_holder[0] + _finish() class _GenerationStream: def __init__(self, iterator: Iterator[TokenEvent]) -> None: @@ -9908,8 +9947,11 @@ def __next__(self) -> TokenEvent: def close(self) -> None: close = getattr(self._iterator, "close", None) - if callable(close): - close() + try: + if callable(close): + close() + finally: + _finish() @property def result(self) -> GenerationResult | None: @@ -10842,6 +10884,11 @@ def close(self) -> None: alongside the transient steering hooks, releasing their ``2 x n_layers x hidden_size`` of device buffers with them. """ + from drowse.core.generation import clear_generation_caches + + tokenizer = getattr(self, "_tokenizer", None) + if tokenizer is not None: + clear_generation_caches(tokenizer) self._steering.clear_all() self._steering.detach_compiled_offsets() self.detach_persistent_capture() @@ -10888,6 +10935,8 @@ def close(self) -> None: if cache is not None: cache.clear() self._prefix_cache = None + self._generation_static_cache = None + self._generation_static_cache_len = 0 self._whitener = None self._jlens = None self._jlens_identity = None diff --git a/drowse/io/AGENTS.md b/drowse/io/AGENTS.md index f49e80a5..54c80dd3 100644 --- a/drowse/io/AGENTS.md +++ b/drowse/io/AGENTS.md @@ -14,6 +14,13 @@ Three artifact families: the **manifold** (per-concept, the steering artifact), the **template** (slot + values + contexts), and the **per-model sources** (neutral/alignment caches, Jacobian lens, SAEs). +Metadata-only operations never execute model-repository Python. Lens fetch, +model shape/source probes, and offline fit-cache checks use +`trust_remote_code=False`; unsupported custom metadata fails closed. The actual +model-loading path is a separate, explicitly trusted operation. `HFError` +retains wrapped diagnostics in its exception chain, but `user_message()` hides +transport details that can contain signed URLs or credentials. + ## Shared primitives ### paths.py @@ -70,17 +77,25 @@ is and what to re-run, not which field the exact-set schema missed first. ### atomic.py / staging.py / shards.py -`atomic.py` — `write_bytes_atomic` / `write_json_atomic` stage to a -same-directory tempfile, `fsync`, then `os.replace` (same-dir staging is -required: `os.replace` is atomic only within a filesystem). `fsync_directory` -makes a directory entry durable. `artifact_lock` is the cross-process lock; +`atomic.py` — `write_bytes_atomic` / `write_json_atomic` stage to a unique, +owner-only same-directory tempfile (0600 on POSIX), `fsync`, then `os.replace` +and sync the parent directory. Exclusive temporary creation avoids predictable +staging symlinks and collisions between writers; failure cleanup removes only +that write's staging file. Existing files acquire the private mode when rewritten. +Same-directory staging keeps replacement on one filesystem. `fsync_directory` +is a best-effort durability barrier where directory syncing is supported. +`artifact_lock` is the cross-process lock; `ReleasableArtifactLock` lets a short cache transaction run inside a longer fit, and `artifact_process_lease` / `artifact_has_live_lease` protect mapped immutable shards after that lock is released (stale PID markers are reaped). +The in-process lock registry holds weak references; active owners and waiters +retain their lock. On-disk lock files stay stable for cross-process exclusion. `staging.py` — `stage_verify_swap`: recover a `.bak` when the destination is missing, wipe stale staging, build a fully validated `.staging/` tree, then promote (`target → .bak`, `.staging → target`) with best-effort restore. +Failed initial backup recovery stops before cleanup or building, preserving the +only good copy. A recovered installation still requires `force=True` to replace. `shards.py` — the immutable-generation primitive three per-model families share (the neutral and alignment caches in `alignment.py`, the local J-lens in @@ -620,8 +635,13 @@ is applied, `load_active_sae` the one place a selection resolves to `(release, provider_metadata)`. Under `models//sae/bindings` it stores the release/layer runtime binding plus the lazily fetched per-feature Neuronpedia metadata (`-features.json`, `{id: {label, max_act}}`, where `max_act` is -`maxActApprox` — the unit that normalizes the SAE strength channel to 0..1), both -at `SAE_RUNTIME_FORMAT_VERSION = 3`. Provider weights stay in the SAELens/Hugging +`maxActApprox` — the reference maximum for the SAE strength channel). Runtime +bindings use `SAE_RUNTIME_FORMAT_VERSION = 3`; feature metadata uses +`SAE_FEATURE_META_FORMAT_VERSION = 4` and records the exact layer, width, +revision, fingerprint, SAE id, repository and Neuronpedia source. A cache from +a different binding or an older unbound format is ignored. Prepared source +rows expose `description_source` when the provider supplies that identity. +Provider weights stay in the SAELens/Hugging Face cache. `sae_artifacts.py` owns Drowse-trained fp32 weights under `sae/local//` with their own manifest (`LOCAL_SAE_FORMAT_VERSION = 1`), and never writes into a provider cache. diff --git a/drowse/io/atomic.py b/drowse/io/atomic.py index 3797a5d0..51b6ed3b 100644 --- a/drowse/io/atomic.py +++ b/drowse/io/atomic.py @@ -2,12 +2,12 @@ A plain ``open(p, "w") + json.dump`` corrupts the file on SIGKILL or ENOSPC — the partial bytes remain at ``p`` with no signal to the loader. ``write_*`` -helpers here stage to ``.tmp`` in the same directory, ``flush()`` + -``fsync()``, then ``os.replace()`` the tempfile into place. Same-dir staging -is required: ``os.replace()`` is only atomic on the same filesystem, and -``tempfile.NamedTemporaryFile`` defaults to ``$TMPDIR`` which often isn't. +helpers here use private, unique staging files in the same directory, +``flush()`` + ``fsync()``, then ``os.replace()`` the tempfile into place. +Same-dir staging is required: ``os.replace()`` is only atomic on the same +filesystem. -A crash between the write and the replace leaves ``.tmp`` orphaned; +A crash between the write and the replace can leave a staging file orphaned; the next loader sees the prior good ```` (or no file at all on a first-time write). The orphan is harmless — it's outside the manifest's ``files`` map and doesn't affect integrity verification. @@ -16,16 +16,18 @@ import json import os +import tempfile import threading import uuid from contextlib import suppress from contextlib import contextmanager from pathlib import Path from typing import Any +from weakref import WeakValueDictionary _ARTIFACT_LOCKS_GUARD = threading.Lock() -_ARTIFACT_LOCKS: dict[Path, threading.RLock] = {} +_ARTIFACT_LOCKS: WeakValueDictionary[Path, threading.RLock] = WeakValueDictionary() _ARTIFACT_LOCK_STATE = threading.local() @@ -209,37 +211,25 @@ def artifact_has_live_lease(path: Path) -> bool: return live -def _temp_path(path: Path) -> Path: - """Return the same-directory staging path for ``path``. - - Uses ``.tmp`` when ``path`` has a suffix, ``.tmp`` - otherwise. Same parent directory in either case. - """ - suffix = path.suffix - if suffix: - return path.with_suffix(suffix + ".tmp") - return path.with_name(path.name + ".tmp") - - def write_bytes_atomic(path: Path, data: bytes) -> None: """Atomically write ``data`` to ``path``. - Stages to ``.tmp`` in the same directory, fsyncs the file, - then ``os.replace()``s into place. + Stages to a unique owner-only file in the same directory, fsyncs it, + then publishes with ``os.replace()`` and syncs the parent directory. """ path.parent.mkdir(parents=True, exist_ok=True) - tmp = _temp_path(path) - fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644) + fd, tmp_name = tempfile.mkstemp(prefix=f".{path.name[:40]}.", suffix=".tmp", dir=path.parent) + tmp = Path(tmp_name) try: with os.fdopen(fd, "wb") as f: f.write(data) f.flush() os.fsync(f.fileno()) - except BaseException: + os.replace(tmp, path) + fsync_directory(path.parent) + finally: with suppress(FileNotFoundError): tmp.unlink() - raise - os.replace(tmp, path) def fsync_directory(path: Path) -> None: diff --git a/drowse/io/hf.py b/drowse/io/hf.py index f9d7abfe..0f8a86ef 100644 --- a/drowse/io/hf.py +++ b/drowse/io/hf.py @@ -18,6 +18,8 @@ class HFError(RuntimeError, DrowseError): def user_message(self) -> tuple[int, str]: + if self.__cause__ is not None: + return (502, "Hugging Face operation failed") return (502, str(self) or self.__class__.__name__) diff --git a/drowse/io/lens_sources.py b/drowse/io/lens_sources.py index 2c3e4fbf..0e909533 100644 --- a/drowse/io/lens_sources.py +++ b/drowse/io/lens_sources.py @@ -637,7 +637,7 @@ def _resolve_model_for_fetch(model_id: str) -> tuple[str, int, int]: """The immutable model revision and dimensions a fetch validates against.""" from transformers import AutoConfig - config = AutoConfig.from_pretrained(model_id, trust_remote_code=True) + config = AutoConfig.from_pretrained(model_id, trust_remote_code=False) model_revision = _model_commit(config) if model_revision is None: raise ValueError( diff --git a/drowse/io/manifold_lifecycle.py b/drowse/io/manifold_lifecycle.py index 0e3e6a4a..7adaf79d 100644 --- a/drowse/io/manifold_lifecycle.py +++ b/drowse/io/manifold_lifecycle.py @@ -726,9 +726,9 @@ def preflight_manifold_fit_noop( try: from transformers import AutoConfig, AutoTokenizer - config = AutoConfig.from_pretrained(model_id, trust_remote_code=True) + config = AutoConfig.from_pretrained(model_id, trust_remote_code=False) model_type = getattr(config, "model_type", None) - tokenizer = AutoTokenizer.from_pretrained(model_id) + tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=False) except Exception: # Tokenizer/config resolution can raise anything the Hub or a custom # implementation chooses; every failure means "cannot prove". diff --git a/drowse/io/sae.py b/drowse/io/sae.py index 88e65dfb..90e0ce53 100644 --- a/drowse/io/sae.py +++ b/drowse/io/sae.py @@ -28,6 +28,7 @@ from drowse.io.source_registry import ActiveSourceRegistry SAE_RUNTIME_FORMAT_VERSION = 3 +SAE_FEATURE_META_FORMAT_VERSION = 4 SAE_SOURCE_FORMAT_VERSION = 1 _RUNTIME_FIELDS = { "layer", "width", "revision", "fingerprint", "sae_id", "repo_id", @@ -229,7 +230,16 @@ def _validate_feature_entry(value: Any) -> dict[str, Any] | None: return {"label": label, "max_act": None if max_act is None else float(max_act)} -def load_sae_feature_meta(model_id: str, release: str) -> dict[str, dict[str, Any]]: +def _feature_source( + model_id: str, release: str, source: dict[str, Any] | None, +) -> dict[str, Any] | None: + source = source if source is not None else load_sae_metadata(model_id, release) + return {key: source[key] for key in sorted(_RUNTIME_FIELDS)} if source is not None else None + + +def load_sae_feature_meta( + model_id: str, release: str, *, source: dict[str, Any] | None = None, +) -> dict[str, dict[str, Any]]: """Load the current ``{feature_id: {label, max_act}}`` metadata cache.""" path = sae_features_path(model_id, release) if not path.exists(): @@ -240,10 +250,11 @@ def load_sae_feature_meta(model_id: str, release: str) -> dict[str, dict[str, An return {} if ( not isinstance(payload, dict) - or set(payload) != {"format_version", "model_id", "release", "features"} - or payload["format_version"] != SAE_RUNTIME_FORMAT_VERSION + or set(payload) != {"format_version", "model_id", "release", "source", "features"} + or payload["format_version"] != SAE_FEATURE_META_FORMAT_VERSION or payload["model_id"] != model_id or payload["release"] != release + or payload["source"] != _feature_source(model_id, release, source) ): return {} features = payload["features"] @@ -263,6 +274,7 @@ def load_sae_feature_meta(model_id: str, release: str) -> dict[str, dict[str, An def save_sae_feature_meta( model_id: str, release: str, features: dict[str, dict[str, Any]], + *, source: dict[str, Any] | None = None, ) -> Path: normalized: dict[str, dict[str, Any]] = {} for key, value in features.items(): @@ -282,9 +294,10 @@ def save_sae_feature_meta( path = sae_features_path(model_id, release) with artifact_lock(path): write_json_atomic(path, { - "format_version": SAE_RUNTIME_FORMAT_VERSION, + "format_version": SAE_FEATURE_META_FORMAT_VERSION, "model_id": model_id, "release": release, + "source": _feature_source(model_id, release, source), "features": normalized, }) return path @@ -344,6 +357,14 @@ def list_sae_sources(model_id: str) -> list[dict[str, Any]]: metadata = load_sae_metadata(model_id, release) if metadata is None: continue + neuronpedia_id = metadata["neuronpedia_id"] + description_source = None + if isinstance(neuronpedia_id, str) and "/" in neuronpedia_id and metadata["repo_id"] and metadata["sae_id"]: + model, dictionary = neuronpedia_id.split("/", 1) + description_source = { + "model": model, "source": dictionary, + "repository": metadata["repo_id"], "saeId": metadata["sae_id"], + } rows.append({ "source": f"saelens:{release}", "kind": "saelens", @@ -356,5 +377,6 @@ def list_sae_sources(model_id: str) -> list[dict[str, Any]]: "path": str(path), "layer": metadata["layer"], "features": metadata["width"], + "description_source": description_source, }) return rows diff --git a/drowse/io/staging.py b/drowse/io/staging.py index c3a4d829..1cbebd3d 100644 --- a/drowse/io/staging.py +++ b/drowse/io/staging.py @@ -29,15 +29,17 @@ def stage_verify_swap( ``target -> .bak`` and ``.staging -> target`` with best-effort restore on failure. """ - if target_folder.exists() and not force: - raise make_error(f"{target_folder} exists; pass force=True to overwrite") - staging = target_folder.with_name(target_folder.name + ".staging") backup = target_folder.with_name(target_folder.name + ".bak") if not target_folder.exists() and backup.exists(): - with suppress(OSError): + try: backup.rename(target_folder) + except OSError as error: + raise make_error(f"{label}: could not recover the previous install ({error})") from error + + if target_folder.exists() and not force: + raise make_error(f"{target_folder} exists; pass force=True to overwrite") if staging.exists(): shutil.rmtree(staging) diff --git a/drowse/server/AGENTS.md b/drowse/server/AGENTS.md index 9c6a83ec..682fbe88 100644 --- a/drowse/server/AGENTS.md +++ b/drowse/server/AGENTS.md @@ -122,11 +122,27 @@ what carries data. app-level dependency over HTTP and WebSocket routes. `_require_auth` + `_check_bearer` gate HTTP; `ws_auth_ok(websocket)` runs **before** `websocket.accept()` (close 1008 on failure) and accepts either an -`Authorization: Bearer …` header or the browser-dashboard `?token=…` fallback, -since browser WebSocket constructors cannot set headers. Unset key = open -server. `DROWSE_STRICT_MODEL` (`1`/`true`/`yes`/`on`) 404s a `model` mismatch +`Authorization: Bearer …` header or a `drowse.auth.` +WebSocket subprotocol. The dashboard offers that credential alongside +`drowse.v1`; only `drowse.v1` is echoed in the handshake. Legacy `?token=…` +clients remain accepted, but `ws_auth_ok` removes token query entries before +Uvicorn access logging, including on rejection. Browser origins must +match the request origin or an explicit `cors_origins` entry; wildcard CORS +does not grant API or WebSocket access. Non-browser clients may omit Origin. Without +a key, the TCP peer must be loopback and HTTP/WS Host must be loopback or the +ASGI server address. In-process ASGI client labels are not network addresses. +IPv4-mapped loopback IPv6 peers are accepted. The CLI binds +loopback by default and requires a key for remote binds. `DROWSE_STRICT_MODEL` (`1`/`true`/`yes`/`on`) 404s a `model` mismatch across OpenAI and Ollama against `known_model_names`; unset accepts any name. +`_HttpSecurityMiddleware` authenticates private API requests before body parsing +while preserving the existing auth-error rendering. It checks browser origins +for all API methods and other mutations, bounds declared and streamed HTTP +bodies (64 MiB by default; `DROWSE_MAX_REQUEST_BYTES` or the explicit +`create_app(max_request_bytes=...)` override), sets API `no-store`, and applies +the dashboard CSP/framing/referrer/MIME/permission headers. It is pure ASGI so +streaming cancellation and worker ownership stay intact. + **Locking.** `acquire_session_lock(session)` is a bounded (`SESSION_LOCK_TIMEOUT_SECONDS = 300`) async context manager yielding `True`/`False`. Non-streaming handlers take it plainly; streaming handlers hold @@ -141,6 +157,10 @@ Ollama `{"error": ""}` under `/api/`, native `{"detail": ""}` under in the request's own envelope; `_on_http_exception` flattens a native `HTTPException.detail` to a **string** so `/drowse/v1/*` clients never have to guess between a string, a dict, and a list of pydantic errors. +Mapped filesystem errors have generic client messages while keeping their +status and local traceback. Wrapped `DrowseError` messages go through +`user_message()`; in particular, wrapped HF transport failures must not expose +signed URLs or upstream credentials in either JSON or SSE. ## Native tree conventions @@ -153,8 +173,15 @@ models stay protocol-specific. `refuse_if_busy(session)` is a non-blocking `gen_lock` probe → 409. It guards the mutating manifold routes and the profile bake: `session.lock` orders native mutations against each other, but an SSE fit or extract whose request was -cancelled leaves its worker thread — and the `gen_lock` — alive past the -cancel. +cancelled retains its worker thread and locks until the worker exits. +`finish_worker` shields cleanup from AnyIO and repeated asyncio cancellation. +`run_in_thread` owns blocking route workers until their real completion, including +JSON routes and background jobs. Job shutdown joins both fetch/load and fit/train +workers before marking them idle. OpenAI/Ollama create streaming workers only +under the session lock; token reads, non-streaming inference, and joins stay off +the ASGI loop. `ClosingStreamingResponse` closes iterators on send failures too. +Native progress callbacks are coalesced and keep bounded recent history (256 +messages for JSON/SSE); terminal frames never wait on an abandoned queue. **Status taxonomy.** @@ -356,7 +383,7 @@ single non-thread-safe command buffer. name/layer so the symmetric matrix costs one Woodbury apply per entry rather than one per pair. Missing whitener → 409; a pair it doesn't fully cover, or a name whose snapshot isn't ready, lands as `null`. -- `POST /extract` — `session.extract` in `asyncio.to_thread`, SSE or JSON (the +- `POST /extract` — `session.extract` through `run_in_thread`, SSE or JSON (the JSON branch also returns the collected `progress` lines). Body `{concept, baseline?, kind, custom_system?, sae?, role?, namespace?, force?}` — `kind` ∈ `abstract|concrete|custom` with `custom_system` required for @@ -503,7 +530,7 @@ before dispatch. needs its text, fork and prefill mutually exclusive) live in the model validators, so the schema is the single description of a well-formed frame; `PydanticCustomError` keeps those messages verbatim. -- `{type: "stop"}` — signals `session.stop()` mid-generation; a no-op when idle. +- `{type: "stop"}` — signals only its own worker mid-generation; a no-op when idle. `WSInputMessage` is `{role, content, label?}` — `label` is the per-turn cast label the scene stitcher renders into the constructed header, so a dashboard @@ -549,17 +576,21 @@ handler catches them explicitly. Pydantic rejections render as reported, not just the first, because `input` is a union whose real failure is the second branch error. Only an unexpected exception closes (1011). -**Concurrency.** One perpetual reader task owns `receive_json()` and feeds a -shared `incoming` queue — the underlying `websockets` `recv_in_progress` flag +**Concurrency.** One perpetual reader task owns `receive_text()` and feeds a +shared bounded `incoming` buffer (1 MiB/frame, 16 pending messages / 4 MiB) — the underlying `websockets` `recv_in_progress` flag makes overlapping receives a `RuntimeError`, so no other task reads the socket. -All sends go through one `asyncio.Lock`. `tree_mutated` events ride a +All sends go through one `asyncio.Lock` with a 30-second timeout. `tree_mutated` events ride a connection-level `LoomMutated` subscription forwarded by its own task, and `done` waits for its node's `finalize_assistant` delta to be forwarded first, -so a client never sees a completed-but-empty assistant node. Per generate turn -`generate_stream` runs in a worker thread, `on_token` bridges to asyncio via -`call_soon_threadsafe`, and the handler races the token queue against -`incoming` so an in-flight `stop` is honored without blocking; non-stop frames -mid-generation hold in a deferred deque and drain after the turn. +so a client never sees a completed-but-empty assistant node. Per generate turn, +`generate` / fork / prefill runs in a worker thread under a request-owned +`GenerationState.cancellation_scope`. `on_token` bridges to asyncio through a +bounded queue. Token and tree queues each allow 256 outstanding events, +including callbacks pending on the event loop; overflow disconnects the client. +The handler races token events against coalesced stop/disconnect controls; +non-stop frames remain in the same bounded FIFO until the turn ends. Disconnect +cancels queued requests and stops/joins only that connection's active worker; +closing an idle connection never stops another caller. `session.lock` is held for the full N-way batch so concurrent clients serialize FIFO; `n>1` fans siblings out serially under deterministic derived seeds, and an error inside one sibling aborts the rest of the fan. diff --git a/drowse/server/app.py b/drowse/server/app.py index 0bdd1dd7..c1c866c9 100644 --- a/drowse/server/app.py +++ b/drowse/server/app.py @@ -3,12 +3,17 @@ from __future__ import annotations import asyncio +import base64 +import hmac +import ipaddress import json +import logging import os import time import uuid from contextlib import asynccontextmanager from typing import TYPE_CHECKING, Any, AsyncIterator, Callable, cast +from urllib.parse import parse_qsl, urlencode, urlsplit if TYPE_CHECKING: from drowse.core.results import GenerationResult @@ -17,11 +22,12 @@ from fastapi.exception_handlers import http_exception_handler from fastapi.exceptions import RequestValidationError from fastapi.middleware.cors import CORSMiddleware -from fastapi.responses import JSONResponse, StreamingResponse +from fastapi.responses import JSONResponse from fastapi.security import HTTPBearer from pydantic import BaseModel, model_validator -from starlette.datastructures import Headers +from starlette.datastructures import Headers, MutableHeaders from starlette.exceptions import HTTPException as StarletteHTTPException +from starlette.types import ASGIApp, Message, Receive, Scope, Send from drowse.core.errors import DrowseError from drowse.core.session import ConcurrentGenerationError, GenerationStream, DrowseSession @@ -36,6 +42,9 @@ strict_model_enabled, ) from drowse.server.streaming import ( + ClosingStreamingResponse, + run_in_thread, + stream_events, probe_reading_aggregate, stream_finalizer, usage_dict, @@ -43,6 +52,7 @@ SESSION_LOCK_TIMEOUT_SECONDS = 300 +DEFAULT_MAX_REQUEST_BYTES = 64 * 1024 * 1024 #: Route-prefix discriminators for the three protocols served on one port. #: Each owns an error envelope: OpenAI ``{"error": {message, type, param, @@ -242,13 +252,59 @@ def _protocol_error(path: str, status: int, message: str) -> JSONResponse: _bearer = HTTPBearer(auto_error=False) +def is_loopback_host(host: str) -> bool: + if host.lower() == "localhost": + return True + try: + address = ipaddress.ip_address(host) + if isinstance(address, ipaddress.IPv6Address) and address.ipv4_mapped is not None: + address = address.ipv4_mapped + return address.is_loopback + except ValueError: + return False + + +def _origin(value: str) -> tuple[str, str, int] | None: + try: + parsed = urlsplit(value) + if ( + parsed.scheme not in {"http", "https"} or not parsed.hostname + or parsed.username is not None or parsed.password is not None + or parsed.path or parsed.query or parsed.fragment + or any(char.isspace() for char in value) or "\\" in value + ): + return None + port = parsed.port if parsed.port is not None else (443 if parsed.scheme == "https" else 80) + return parsed.scheme, parsed.hostname.lower(), port + except ValueError: + return None + + +def _local_host_ok(conn: Request | WebSocket) -> bool: + client = conn.scope.get("client") + if client: + try: + ipaddress.ip_address(client[0]) + except ValueError: + pass # In-process ASGI transports can use non-IP client labels. + else: + if not is_loopback_host(client[0]): + return False + hosts = conn.headers.getlist("host") + target = _origin("http://" + hosts[0]) if len(hosts) == 1 else None + if target is None: + return False + server = conn.scope.get("server") + return is_loopback_host(target[1]) or bool(server and target[1] == server[0].lower()) + + def _check_bearer(headers: Headers, expected: str) -> bool: """Return True iff a correct ``Authorization: Bearer `` header is present.""" auth = headers.get("authorization") or headers.get("Authorization") if not auth: return False scheme, _, token = auth.partition(" ") - return scheme.lower() == "bearer" and token == expected + return scheme.lower() == "bearer" and hmac.compare_digest(token.encode(), expected.encode()) def _require_auth(request: Request = None, # pyright: ignore[reportArgumentType] # FastAPI injects Request/WebSocket by type; None default is a sentinel, not a real argument @@ -266,6 +322,8 @@ def _require_auth(request: Request = None, # pyright: ignore[reportArgumentType return expected = getattr(conn.app.state, "api_key", None) if not expected: + if request is not None and not _local_host_ok(request): + raise HTTPException(403, "Untrusted host; configure an API key for remote access") return if request is None: # WS path: handler calls ws_auth_ok() before websocket.accept(). @@ -279,20 +337,107 @@ def _require_auth(request: Request = None, # pyright: ignore[reportArgumentType return -def ws_auth_ok(websocket: WebSocket) -> bool: - """Return True iff the WebSocket handshake carries valid bearer auth. +def _browser_origin_ok(conn: Request | WebSocket) -> bool: + origins = conn.headers.getlist("origin") + if origins: + origin = _origin(origins[0]) if len(origins) == 1 else None + hosts = conn.headers.getlist("host") + scheme = "https" if conn.scope["scheme"] in {"https", "wss"} else "http" + target = _origin(scheme + "://" + hosts[0]) if len(hosts) == 1 else None + allowed = conn.app.state.ws_origins + if origin is None or (origin != target and origin not in allowed): + return False + return True - Call this BEFORE ``websocket.accept()``. If it returns False, close the - handshake with ``await websocket.close(code=1008)``. - """ + +def ws_auth_ok(websocket: WebSocket) -> bool: + """Validate browser Origin and bearer auth before accepting a WebSocket.""" + query = parse_qsl(websocket.scope.get("query_string", b"").decode("latin-1"), keep_blank_values=True) + tokens = [value for name, value in query if name == "token"] + if tokens: + websocket.scope["query_string"] = urlencode([(name, value) for name, value in query if name != "token"]).encode() expected = getattr(websocket.app.state, "api_key", None) + if not expected and not _local_host_ok(websocket): + return False + if not _browser_origin_ok(websocket): + return False if not expected: return True if _check_bearer(websocket.headers, expected): return True - # Browser WebSocket constructors cannot attach Authorization headers. - # The bundled dashboard sends the same bearer value as ?token=... . - return websocket.query_params.get("token") == expected + credentials = [protocol.removeprefix("drowse.auth.") for protocol in websocket.scope.get("subprotocols", []) + if protocol.startswith("drowse.auth.")] + if credentials: + encoded = base64.urlsafe_b64encode(expected.encode()).rstrip(b"=") + return len(credentials) == 1 and hmac.compare_digest(credentials[0].encode(), encoded) + return len(tokens) == 1 and hmac.compare_digest(tokens[0].encode(), expected.encode()) + + +class _HttpSecurityMiddleware: + def __init__(self, app: ASGIApp, *, max_request_bytes: int) -> None: + self.app = app + self.max_request_bytes = max_request_bytes + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + if scope["type"] != "http": + await self.app(scope, receive, send) + return + request = Request(scope) + path = scope["path"] + private = path.startswith((NATIVE_PREFIX, OLLAMA_PREFIX, "/v1/")) + + async def secure_send(message: Message) -> None: + if message["type"] == "http.response.start": + headers = MutableHeaders(scope=message) + headers["X-Content-Type-Options"] = "nosniff" + headers["X-Frame-Options"] = "DENY" + headers["Referrer-Policy"] = "no-referrer" + headers["Permissions-Policy"] = "camera=(), microphone=(), geolocation=(), payment=(), usb=()" + headers["Content-Security-Policy"] = ( + "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; " + "img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' https://www.neuronpedia.org https://drowse.ai/api/contact; " + "frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'self'" + ) + if private: + headers["Cache-Control"] = "no-store" + await send(message) + + if private: + try: + _require_auth(request) + except HTTPException as exc: + handler = request.app.exception_handlers[StarletteHTTPException] + response = await handler(request, exc) + await response(scope, receive, secure_send) + return + try: + check_origin = private or scope["method"] not in {"GET", "HEAD", "OPTIONS"} + if check_origin and scope["method"] != "OPTIONS" and not _browser_origin_ok(request): + raise HTTPException(403, "Untrusted request origin") + lengths = request.headers.getlist("content-length") + if lengths: + if len(lengths) != 1 or not lengths[0].isascii() or not lengths[0].isdigit(): + raise HTTPException(400, "Invalid Content-Length") + length = lengths[0].lstrip("0") or "0" + if len(length) > len(str(self.max_request_bytes)) or int(length) > self.max_request_bytes: + raise HTTPException(413, "Request body too large") + except HTTPException as exc: + response = _protocol_error(path, exc.status_code, _detail_text(exc.detail)) + await response(scope, receive, secure_send) + return + + received = 0 + + async def limited_receive() -> Message: + nonlocal received + message = await receive() + if message["type"] == "http.request": + received += len(message.get("body", b"")) + if received > self.max_request_bytes: + raise HTTPException(413, "Request body too large") + return message + + await self.app(scope, limited_receive, secure_send) def _sampling_kwargs( @@ -407,7 +552,7 @@ def _render_logprobs_completions(result: GenerationResult, session: DrowseSessio async def _stream_generation( session: DrowseSession, - stream_iter: GenerationStream, rid: str, model_id: str, object_type: str, + stream_factory: Callable[[], GenerationStream], rid: str, model_id: str, object_type: str, format_delta: Callable[[Any], dict[str, Any]], empty_delta: dict[str, Any], include_usage: bool = False, role_delta: bool = False, request: Request | None = None, @@ -458,8 +603,10 @@ def _error_frames(status: int, message: str) -> list[str]: "choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": None}], } yield f"data: {json.dumps(chunk)}\n\n" + stream_iter = None try: - for event in stream_iter: + stream_iter = stream_factory() + async for event in stream_events(stream_iter): # Bail out if the client has hung up — close the inner # generator (handled in ``finally``) and stop spending the # GPU on tokens nobody is reading. @@ -498,8 +645,10 @@ def _error_frames(status: int, message: str) -> list[str]: # + join) on every exit — normal completion (no-op on an exhausted # generator), an in-band error, or an early client-disconnect # ``return`` — rather than leaving it to GC. - stream_iter.close() + if stream_iter is not None: + await run_in_thread(stream_iter.close) + assert stream_iter is not None last_result = stream_iter.result finish_reason, usage, mf_agg = stream_finalizer(session, last_result) final_choice: dict[str, Any] = { @@ -536,7 +685,12 @@ def create_app(session: DrowseSession, cors_origins: list[str] | None = None, api_key: str | None = None, *, - web: bool = False) -> FastAPI: + web: bool = False, + max_request_bytes: int | None = None) -> FastAPI: + if max_request_bytes is None: + max_request_bytes = int(os.environ.get("DROWSE_MAX_REQUEST_BYTES", DEFAULT_MAX_REQUEST_BYTES)) + if type(max_request_bytes) is not int or max_request_bytes <= 0: + raise ValueError("max_request_bytes must be a positive integer") app = FastAPI( title="drowse", description="OpenAI-compatible API with activation steering", @@ -546,6 +700,8 @@ def create_app(session: DrowseSession, app.state.default_steering = default_steering app.state.created_ts = int(time.time()) app.state.api_key = api_key if api_key is not None else os.environ.get("DROWSE_API_KEY") + app.state.ws_origins = {origin for value in (cors_origins or []) if (origin := _origin(value)) is not None} + app.add_middleware(_HttpSecurityMiddleware, max_request_bytes=max_request_bytes) # Generation serialization lives on ``session.lock`` (asyncio.Lock) # so both the OpenAI and Ollama route families share a single FIFO # queue. Requests wait rather than 409 on contention. @@ -560,6 +716,8 @@ def create_app(session: DrowseSession, @app.exception_handler(DrowseError) async def _on_drowse_error(request: Request, exc: DrowseError): + if exc.__cause__ is not None: + logging.getLogger("drowse.api").error("Request failed", exc_info=exc) status, msg = exc.user_message() return _protocol_error(request.url.path, status, msg) @@ -590,6 +748,17 @@ async def _on_http_exception(request: Request, exc: StarletteHTTPException): so a client had to guess. On ``/drowse/v1/*`` it is always a string; every other prefix keeps FastAPI's default rendering. """ + if isinstance(exc.__cause__, DrowseError): + _status, detail = exc.__cause__.user_message() + if exc.__cause__.__cause__ is not None: + logging.getLogger("drowse.api").error("Request failed", exc_info=exc.__cause__) + return _protocol_error(request.url.path, exc.status_code, detail) + if isinstance(exc.__cause__, OSError): + logging.getLogger("drowse.api").error("Filesystem request failed", exc_info=exc.__cause__) + detail = {404: "Requested artifact not found", 409: "An artifact already exists at the destination"}.get( + exc.status_code, "Filesystem operation failed. Check the server log for details.", + ) + return _protocol_error(request.url.path, exc.status_code, detail) response = await http_exception_handler(request, exc) detail = cast(object, exc.detail) if ( @@ -705,7 +874,7 @@ async def _run_blocking(req: _SamplingBase, prompt_or_messages: Any, *, raw: boo async with acquire_session_lock(session) as acquired: if not acquired: return _error(503, "Server busy", "server_error") - return session.generate(prompt_or_messages, raw=raw, **gen_kwargs).first + return (await run_in_thread(session.generate, prompt_or_messages, raw=raw, **gen_kwargs)).first @app.post("/v1/chat/completions") async def chat_completions(req: ChatCompletionRequest, request: Request): @@ -724,13 +893,14 @@ def _chat_delta(event: Any) -> dict[str, Any]: d["content"] = event.text return {"delta": d} - stream_iter = session.generate_stream( - messages, live_scores=False, live_readouts=False, **gen_kwargs, - ) + def stream_factory() -> GenerationStream: + return session.generate_stream( + messages, live_scores=False, live_readouts=False, **gen_kwargs, + ) include_usage = bool(req.stream_options and req.stream_options.include_usage) - return StreamingResponse( + return ClosingStreamingResponse( _stream_generation(session, - stream_iter, rid, model_id, + stream_factory, rid, model_id, "chat.completion.chunk", _chat_delta, {"delta": {}}, include_usage=include_usage, role_delta=True, request=request), @@ -774,14 +944,15 @@ async def completions(req: CompletionRequest, request: Request): gen_kwargs = _sampling_kwargs(req, app.state.default_steering) if req.stream: - stream_iter = session.generate_stream( - req.prompt, raw=True, live_scores=False, live_readouts=False, - **gen_kwargs, - ) + def stream_factory() -> GenerationStream: + return session.generate_stream( + req.prompt, raw=True, live_scores=False, live_readouts=False, + **gen_kwargs, + ) include_usage = bool(req.stream_options and req.stream_options.include_usage) - return StreamingResponse( + return ClosingStreamingResponse( _stream_generation(session, - stream_iter, rid, model_id, + stream_factory, rid, model_id, "text_completion", lambda e: {"text": e.text}, {"text": ""}, include_usage=include_usage, role_delta=False, request=request), diff --git a/drowse/server/background_job.py b/drowse/server/background_job.py index b7618cc3..06b9e277 100644 --- a/drowse/server/background_job.py +++ b/drowse/server/background_job.py @@ -30,12 +30,12 @@ import threading import time from collections.abc import Awaitable, Callable -from contextlib import suppress from typing import Any from fastapi import FastAPI, HTTPException from drowse.core.errors import DrowseError +from drowse.server.streaming import finish_worker JobBody = Callable[[], Awaitable[None]] ErrorHandler = Callable[[BaseException], None] @@ -148,7 +148,7 @@ def launch(self, body: JobBody, on_error: ErrorHandler) -> "asyncio.Task[None]": async def _runner() -> None: try: - await body() + await finish_worker(asyncio.ensure_future(body())) except Exception as exc: # noqa: BLE001 - routed to the per-job scrubber on_error(exc) finally: @@ -171,19 +171,14 @@ def request_cancel(self) -> dict[str, Any]: return self.status() async def stop(self) -> None: - """Shutdown-time stop: signal the event and await a cancellable job; - asyncio-cancel and drain an uncancellable one.""" + """Signal cooperative cancellation and join the actual job lifetime.""" task = self.task if self.cancellable: event = self.cancel_event if event is not None: event.set() - if task is not None and not task.done(): - await task - elif task is not None and not task.done(): - task.cancel() - with suppress(asyncio.CancelledError): - await task + if task is not None and not task.done(): + await finish_worker(task) def make_progress_hook( diff --git a/drowse/server/instrument_routes.py b/drowse/server/instrument_routes.py index 8b1a0ec1..f02dffcd 100644 --- a/drowse/server/instrument_routes.py +++ b/drowse/server/instrument_routes.py @@ -33,7 +33,6 @@ from __future__ import annotations -import asyncio import logging import math import re @@ -47,6 +46,7 @@ from drowse.core.jlens import LensNotFittedError, resolve_word_token from drowse.core.loom import InvalidNodeOperationError, UnknownNodeError from drowse.core.measurements import MeasurementsEnvelope +from drowse.server.streaming import run_in_thread from drowse.server.app import acquire_session_lock from drowse.server.background_job import ( BackgroundJob, @@ -392,6 +392,7 @@ async def _stop_lens_fit() -> None: async def _stop_sae_train() -> None: await sae_train_job.stop() + await sae_load_job.stop() app.router.on_shutdown.append(_stop_lens_fit) app.router.on_shutdown.append(_stop_sae_train) @@ -495,8 +496,8 @@ async def _activate_lens_source(source: str) -> list[int]: if not acquired: raise RuntimeError("session locked") session.lens.set_live(False) - await asyncio.to_thread(session.select_jlens_source, source) - state = await asyncio.to_thread(session.lens.set_live, True) + await run_in_thread(session.select_jlens_source, source) + state = await run_in_thread(session.lens.set_live, True) return list(state.layers or ()) # ===================================================================== @@ -542,7 +543,7 @@ async def instrument_live( if not acquired: raise HTTPException(503, "session locked") try: - state = await asyncio.to_thread( + state = await run_in_thread( instrument.set_live, body.enabled, **extras, ) except LensNotFittedError as e: @@ -576,7 +577,7 @@ async def _sae_sources() -> SourcesResponse: from drowse.core.sae import list_sae_releases from drowse.io.sae import list_sae_sources - rows = await asyncio.to_thread(list_sae_sources, session.model_id) + rows = await run_in_thread(list_sae_sources, session.model_id) sources = [ cast(InstrumentSourceJSON, { k: v for k, v in row.items() if k != "path" @@ -584,7 +585,7 @@ async def _sae_sources() -> SourcesResponse: for row in rows ] try: - releases = await asyncio.to_thread( + releases = await run_in_thread( list_sae_releases, session.model_id, ) except DrowseError as exc: @@ -666,7 +667,7 @@ async def _lens_fetch_body(body: LensFetchRequest) -> None: + ", ".join([NEURONPEDIA_BINDING, *sorted(WORKSPACE_ARMS)]) ) st["message"] = "fetching external lens into the Hugging Face cache…" - binding = await asyncio.to_thread( + binding = await run_in_thread( fetch_lens_source, session.model_id, body.source, @@ -700,7 +701,7 @@ async def _lens_fit_body( st = lens_fit_job.state st["message"] = f"streaming {body.prompts} corpus documents…" - docs, spec = await asyncio.to_thread( + docs, spec = await run_in_thread( stream_default_lens_corpus, body.prompts, cancel_event=lens_fit_job.cancel_event, @@ -710,7 +711,7 @@ async def _lens_fit_body( done_field="prompts_done", total_field="prompts_total", ) st["message"] = "fitting…" - await asyncio.to_thread( + await run_in_thread( session.fit_jlens, docs, corpus_spec=spec, @@ -726,7 +727,7 @@ async def _lens_fit_body( if acquired: st["live_layers"] = list( ( - await asyncio.to_thread(session.lens.set_live, True) + await run_in_thread(session.lens.set_live, True) ).layers or () ) st["message"] = "done" @@ -737,10 +738,10 @@ async def _sae_fetch_body(body: SaeFetchRequest, source: str, release: str) -> N async with acquire_session_lock(session) as acquired: if not acquired: raise RuntimeError("session locked") - info = await asyncio.to_thread( + info = await run_in_thread( session.load_sae, release, layer=body.layer, ) - await asyncio.to_thread(session.sae.set_live, True) + await run_in_thread(session.sae.set_live, True) st["info"] = info st["message"] = ( f"loaded {source} · live at L{info.get('layer')} " @@ -762,12 +763,12 @@ async def _sae_train_body(body: SaeTrainRequest, layer: int) -> None: st = sae_train_job.state n_docs = max(1, math.ceil(body.tokens / body.seq_len)) st["message"] = f"streaming {n_docs:,} corpus documents…" - docs, spec = await asyncio.to_thread(stream_default_lens_corpus, n_docs) + docs, spec = await run_in_thread(stream_default_lens_corpus, n_docs) on_progress = make_progress_hook( st, _TRAIN_PROGRESS_RE, done_field="tokens_done", total_field="tokens_total", ) - result = await asyncio.to_thread( + result = await run_in_thread( session.train_sae, body.name, docs, @@ -793,7 +794,7 @@ async def _sae_train_body(body: SaeTrainRequest, layer: int) -> None: try: async with acquire_session_lock(session) as acquired: if acquired: - await asyncio.to_thread(session.sae.set_live, True) + await run_in_thread(session.sae.set_live, True) except Exception: log.exception("could not auto-enable live SAE after training") @@ -1009,7 +1010,7 @@ async def instrument_token_readout( if not acquired: raise HTTPException(503, "session locked") try: - return await asyncio.to_thread( + return await run_in_thread( instrument.token_readout, node_id, raw_index, @@ -1077,7 +1078,7 @@ async def sae_features_metadata( if any(feature_id < 0 for feature_id in body.ids): raise HTTPException(400, "feature ids must be non-negative") try: - features = await asyncio.to_thread( + features = await run_in_thread( session.fetch_sae_feature_meta, body.ids, ) except DrowseError as exc: diff --git a/drowse/server/manifold_routes.py b/drowse/server/manifold_routes.py index 9a49d348..bc9dd7ad 100644 --- a/drowse/server/manifold_routes.py +++ b/drowse/server/manifold_routes.py @@ -13,7 +13,6 @@ """ from __future__ import annotations -import asyncio import logging import threading from pathlib import Path @@ -49,6 +48,7 @@ ) from drowse.io.paths import manifold_dir from drowse.io.templates import AmbiguousTemplateError, TemplateNotFoundError +from drowse.server.streaming import run_in_thread from drowse.server.app import acquire_session_lock from drowse.server.native_common import ( NativeRequest, @@ -525,6 +525,8 @@ def _install_error_frame(exc: Exception) -> dict[str, Any] | None: http_error = cast(HTTPException, exc) return {"message": str(http_error.detail), "code": "Conflict"} if isinstance(exc, (ManifoldInstallConflict, ManifoldHFError)): + if exc.__cause__ is not None: + log.error("manifold install failed", exc_info=exc) _status, message = exc.user_message() return {"message": message, "code": type(exc).__name__} if isinstance(exc, ImportError): @@ -708,7 +710,7 @@ async def merge_manifold(req: MergeManifoldRequest) -> ManifoldInfo: raise HTTPException(503, "session locked") refuse_if_busy(session) try: - folder = await asyncio.to_thread( + folder = await run_in_thread( merge_discover_manifolds, req.namespace, req.name, @@ -772,7 +774,7 @@ async def _job(on_progress: ProgressCallback) -> ManifoldInfo: # Under the session lock in both branches; the gen-lock probe has # to run before the worker thread starts writing the folder. refuse_if_busy(session) - return await asyncio.to_thread(_install, on_progress) + return await run_in_thread(_install, on_progress) return await sse_or_json( request, @@ -863,7 +865,7 @@ def _gen(on_progress: Callable[[str], None]) -> ManifoldInfo: return body async def _job(on_progress: ProgressCallback) -> ManifoldInfo: - return await asyncio.to_thread(_gen, on_progress) + return await run_in_thread(_gen, on_progress) def _format_error(e: Exception) -> dict[str, Any] | None: if isinstance(e, HTTPException): @@ -921,7 +923,7 @@ async def update_manifold( raise HTTPException(503, "session locked") refuse_if_busy(session) try: - await asyncio.to_thread( + await run_in_thread( update_manifold_folder, folder, description=req.description, @@ -966,7 +968,7 @@ async def delete_manifold( try: return cast( ManifoldDeleteResponse, - await asyncio.to_thread( + await run_in_thread( remove_manifold_folder, namespace, name, ), ) @@ -1012,7 +1014,7 @@ def _fit(on_progress: Callable[[str], None]) -> ManifoldInfo: return body async def _job(on_progress: ProgressCallback) -> ManifoldInfo: - return await asyncio.to_thread(_fit, on_progress) + return await run_in_thread(_fit, on_progress) return await sse_or_json( request, diff --git a/drowse/server/ollama.py b/drowse/server/ollama.py index 62a57c99..28502c30 100644 --- a/drowse/server/ollama.py +++ b/drowse/server/ollama.py @@ -29,7 +29,7 @@ probe_token_readings, strict_model_enabled, ) -from drowse.server.streaming import probe_reading_aggregate, stream_finalizer +from drowse.server.streaming import ClosingStreamingResponse, probe_reading_aggregate, run_in_thread, stream_events, stream_finalizer import hashlib import json @@ -40,7 +40,7 @@ from typing import Any from fastapi import FastAPI, HTTPException, Request -from fastapi.responses import JSONResponse, Response, StreamingResponse +from fastapi.responses import JSONResponse, Response from drowse.core.errors import DrowseError from drowse.core.results import GenerationResult @@ -436,7 +436,7 @@ async def api_pull(request: Request): async def _stream(): yield json.dumps({"status": "pulling manifest"}) + "\n" yield json.dumps({"status": "success"}) + "\n" - return StreamingResponse(_stream(), media_type="application/x-ndjson") + return ClosingStreamingResponse(_stream(), media_type="application/x-ndjson") @app.post("/api/push") async def api_push(): @@ -548,7 +548,7 @@ async def _run_and_build_chat_response( }, ) try: - result = session.generate(input_payload, raw=raw, **gen_kwargs).first + result = (await run_in_thread(session.generate, input_payload, raw=raw, **gen_kwargs)).first except ConcurrentGenerationError as e: raise HTTPException( status_code=409, detail="Generation already in progress", @@ -654,7 +654,7 @@ async def _stream_chat_or_generate( input_payload, raw=raw, live_scores=False, live_readouts=False, **gen_kwargs, ) - for event in stream_iter: + async for event in stream_events(stream_iter): # Bail out if the client has hung up — close the inner # generator (handled in ``finally``) and stop spending # the GPU on tokens nobody is reading. @@ -735,8 +735,8 @@ async def _stream_chat_or_generate( # (no-op on an exhausted generator), an in-band error, or # an early client-disconnect ``return`` — rather than # leaving it to GC. - assert stream_iter is not None - stream_iter.close() + if stream_iter is not None: + await run_in_thread(stream_iter.close) elapsed_ns = time.monotonic_ns() - start_ns assert stream_iter is not None @@ -783,7 +783,7 @@ async def api_chat(request: Request): # rewrite the response — we'd disconnect mid-stream. gen_kwargs, system = _resolve_options(body, app.state.default_steering) if body.get("stream", True): - return StreamingResponse( + return ClosingStreamingResponse( _stream_chat_or_generate( body, is_chat=True, gen_kwargs=gen_kwargs, system=system, request=request, @@ -800,7 +800,7 @@ async def api_generate(request: Request): _check_model_or_404(body) gen_kwargs, system = _resolve_options(body, app.state.default_steering) if body.get("stream", True): - return StreamingResponse( + return ClosingStreamingResponse( _stream_chat_or_generate( body, is_chat=False, gen_kwargs=gen_kwargs, system=system, request=request, diff --git a/drowse/server/profile_routes.py b/drowse/server/profile_routes.py index fc30c43a..cbe1ee72 100644 --- a/drowse/server/profile_routes.py +++ b/drowse/server/profile_routes.py @@ -10,13 +10,13 @@ from __future__ import annotations -import asyncio from typing import Any from fastapi import FastAPI, HTTPException, Request from fastapi.responses import Response from drowse.core.profile import Profile +from drowse.server.streaming import run_in_thread from drowse.server.app import acquire_session_lock from drowse.server.native_common import ( extraction_error_frame, @@ -384,7 +384,7 @@ def _run(on_progress: ProgressCallback) -> tuple[str, Any]: ) async def _job(on_progress: ProgressCallback) -> ExtractResponse: - canonical, profile = await asyncio.to_thread(_run, on_progress) + canonical, profile = await run_in_thread(_run, on_progress) registry_name = extract_registry_name(canonical, req.namespace) session.steer(registry_name, profile) return { @@ -434,7 +434,7 @@ async def bake_profile( # fingerprint mismatch, a merge that produced no tensor) is a # DrowseError and reaches the client as a 400 through the global # handler. - name, profile = await asyncio.to_thread( + name, profile = await run_in_thread( session.bake, req.name, req.expression, ) return profile_to_json(name, profile) diff --git a/drowse/server/response_models.py b/drowse/server/response_models.py index 50ef24bf..ac2a4431 100644 --- a/drowse/server/response_models.py +++ b/drowse/server/response_models.py @@ -693,6 +693,14 @@ class InstrumentsResponse(TypedDict): instruments: list[InstrumentFamilyBlock] +class SaeDescriptionSourceJSON(TypedDict): + model: str + source: str + repository: str + folder: NotRequired[str] + saeId: NotRequired[str] + + class InstrumentSourceJSON(TypedDict): """One usable artifact source (lens binding / SAE source row).""" @@ -708,6 +716,7 @@ class InstrumentSourceJSON(TypedDict): checkpoint: NotRequired[str] layer: NotRequired[int] features: NotRequired[int] + description_source: NotRequired[SaeDescriptionSourceJSON | None] class SaeReleaseJSON(TypedDict): diff --git a/drowse/server/sse.py b/drowse/server/sse.py index a4859943..866c9057 100644 --- a/drowse/server/sse.py +++ b/drowse/server/sse.py @@ -5,12 +5,14 @@ import asyncio import json import logging +import threading +from collections import deque from collections.abc import Awaitable, Callable, Sequence -from contextlib import suppress from typing import Any from fastapi import HTTPException, Request from fastapi.responses import StreamingResponse +from drowse.server.streaming import ClosingStreamingResponse, finish_worker ProgressCallback = Callable[[str], None] ProgressJob = Callable[[ProgressCallback], Awaitable[Any]] @@ -24,6 +26,7 @@ #: for their read timeout (nginx defaults to 60 s), and a single manifold #: generate / fit progress step can run well past that on MPS. HEARTBEAT_SECONDS = 15.0 +MAX_PROGRESS_MESSAGES = 256 def progress_sse_response( @@ -51,17 +54,42 @@ def progress_sse_response( async def _sse(): loop = asyncio.get_running_loop() - queue: asyncio.Queue[tuple[str, Any]] = asyncio.Queue() + queue: asyncio.Queue[tuple[str, Any]] = asyncio.Queue(maxsize=MAX_PROGRESS_MESSAGES) + pending: deque[str] = deque(maxlen=MAX_PROGRESS_MESSAGES) + pending_lock = threading.Lock() + scheduled = False + + def _flush_progress() -> None: + nonlocal scheduled + with pending_lock: + messages = list(pending) + pending.clear() + scheduled = False + for message in messages: + if queue.full(): + queue.get_nowait() + queue.put_nowait(("progress", message)) def _on_progress(msg: str) -> None: - loop.call_soon_threadsafe(queue.put_nowait, ("progress", msg)) + nonlocal scheduled + with pending_lock: + pending.append(msg) + if scheduled: + return + scheduled = True + loop.call_soon_threadsafe(_flush_progress) + + def _complete(kind: str, payload: Any) -> None: + _flush_progress() + if queue.full(): + queue.get_nowait() + queue.put_nowait((kind, payload)) async with lock: async def _run() -> None: try: payload = await job(_on_progress) - await asyncio.sleep(0) - queue.put_nowait(("done", payload)) + _complete("done", payload) except Exception as e: err = None if error_formatter is not None: @@ -75,7 +103,7 @@ async def _run() -> None: "message": error_message, "code": type(e).__name__, } - queue.put_nowait(("error", err)) + _complete("error", err) task = asyncio.create_task(_run()) try: @@ -102,10 +130,9 @@ async def _run() -> None: # disconnected SSE client cannot release ``session.lock`` # while the underlying job is still mutating session state # or writing artifacts. - with suppress(BaseException): - await task + await finish_worker(task) - return StreamingResponse(_sse(), media_type="text/event-stream") + return ClosingStreamingResponse(_sse(), media_type="text/event-stream") async def sse_or_json( @@ -150,12 +177,12 @@ async def sse_or_json( logger=logger, ) - progress: list[str] = [] + progress: deque[str] = deque(maxlen=MAX_PROGRESS_MESSAGES) async with acquire_session_lock(session) as acquired: if not acquired: raise HTTPException(503, "session locked") try: - payload = await job(progress.append) + payload = await finish_worker(asyncio.ensure_future(job(progress.append))) except HTTPException: # Already carries its own status — a job that mapped its own # failure wins over the generic table. @@ -166,5 +193,5 @@ async def sse_or_json( raise HTTPException(status, str(exc)) from exc raise if json_progress_key is not None and isinstance(payload, dict): - payload[json_progress_key] = progress + payload[json_progress_key] = list(progress) return payload diff --git a/drowse/server/streaming.py b/drowse/server/streaming.py index e799ce93..1fab2225 100644 --- a/drowse/server/streaming.py +++ b/drowse/server/streaming.py @@ -11,7 +11,54 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +import asyncio +from collections.abc import AsyncIterator, Callable, Iterator +from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar, cast + +from anyio import CancelScope +from starlette.responses import StreamingResponse +from starlette.types import Send + +_T = TypeVar("_T") +_P = ParamSpec("_P") + + +async def finish_worker(task: asyncio.Future[_T]) -> _T: + """Join a worker without letting request cancellation abandon its thread.""" + cancelled = False + with CancelScope(shield=True): + while not task.done(): + try: + await asyncio.shield(task) + except asyncio.CancelledError: + cancelled = True + if cancelled: + raise asyncio.CancelledError + return task.result() + + +async def run_in_thread(func: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> _T: + return await finish_worker(asyncio.create_task(asyncio.to_thread(func, *args, **kwargs))) + + +async def stream_events(iterator: Iterator[_T]) -> AsyncIterator[_T]: + sentinel = object() + while True: + event = await run_in_thread(next, iterator, sentinel) + if event is sentinel: + return + yield cast(_T, event) + + +class ClosingStreamingResponse(StreamingResponse): + async def stream_response(self, send: Send) -> None: + try: + await super().stream_response(send) + finally: + close = getattr(self.body_iterator, "aclose", None) + if close is not None: + await close() + if TYPE_CHECKING: from drowse.core.results import GenerationResult diff --git a/drowse/server/template_routes.py b/drowse/server/template_routes.py index 74955fbb..43c389af 100644 --- a/drowse/server/template_routes.py +++ b/drowse/server/template_routes.py @@ -10,7 +10,6 @@ """ from __future__ import annotations -import asyncio from typing import Literal, cast from fastapi import FastAPI, HTTPException @@ -26,6 +25,7 @@ resolve_template, template_dir, ) +from drowse.server.streaming import run_in_thread from drowse.server.app import acquire_session_lock from drowse.server.native_common import NativeRequest from drowse.server.response_models import ( @@ -145,7 +145,7 @@ async def score_template_route( if not acquired: raise HTTPException(503, "session locked") try: - per_ctx = await asyncio.to_thread( + per_ctx = await run_in_thread( session.score_template, tmpl, steering=req.steering, ) except Exception as e: # steering-expr / scoring failure → 400 diff --git a/drowse/server/tree_routes.py b/drowse/server/tree_routes.py index 5f203b9d..4fe6b1be 100644 --- a/drowse/server/tree_routes.py +++ b/drowse/server/tree_routes.py @@ -4,12 +4,12 @@ from __future__ import annotations -import asyncio from typing import Any, cast from fastapi import FastAPI, HTTPException from fastapi.responses import Response +from drowse.server.streaming import run_in_thread from drowse.server.app import acquire_session_lock from drowse.server.native_common import resolve_session_id from drowse.server.response_models import ( @@ -328,7 +328,7 @@ def _on_warning( with warnings.catch_warnings(): warnings.showwarning = _on_warning try: - leaf_id = await asyncio.to_thread( + leaf_id = await run_in_thread( transcript.import_into, session, mode=mode, @@ -540,7 +540,7 @@ async def tree_joint_logprobs( # populated the cache while we waited. hit = _cached_joint_logprobs(cache, key) if hit is None: - hit = await asyncio.to_thread( + hit = await run_in_thread( compute_joint_logprobs, session, req.a_id, req.b_id, ) _remember_joint_logprobs(cache, key, hit) diff --git a/drowse/server/ws_stream.py b/drowse/server/ws_stream.py index d9017727..2d7ddaef 100644 --- a/drowse/server/ws_stream.py +++ b/drowse/server/ws_stream.py @@ -11,15 +11,18 @@ from __future__ import annotations import asyncio +import json import logging +import threading import uuid from collections import deque from contextlib import suppress from dataclasses import dataclass -from typing import Any, Awaitable, Callable, Literal, cast +from typing import Any, Awaitable, Callable, Generic, Literal, TypeVar, cast from fastapi import FastAPI, WebSocket, WebSocketDisconnect from pydantic import ValidationError +from anyio import CancelScope from drowse.core.errors import DrowseError from drowse.core.loom import LoomMutated @@ -31,6 +34,7 @@ from drowse.server.app import acquire_session_lock, ws_auth_ok from drowse.server.native_common import SINGLE_SESSION_ID from drowse.server.request_helpers import merge_steering, parse_request_steering +from drowse.server.streaming import finish_worker from drowse.server.tree_models import cast_json, node_json from drowse.server.ws_events import build_token_event from drowse.server.ws_models import ( @@ -43,6 +47,12 @@ _logger = logging.getLogger(__name__) +MAX_WS_MESSAGE_BYTES = 1024 * 1024 +MAX_WS_PENDING_MESSAGES = 16 +MAX_WS_PENDING_BYTES = 4 * MAX_WS_MESSAGE_BYTES +MAX_WS_OUTBOUND_EVENTS = 256 +WS_SEND_TIMEOUT_SECONDS = 30 + JSONValue = None | bool | int | float | str | list["JSONValue"] | dict[str, "JSONValue"] JSONObject = dict[str, JSONValue] @@ -54,13 +64,8 @@ class _Stop: @dataclass(frozen=True) class _Disconnect: - pass - - -@dataclass(frozen=True) -class _ReaderFailure: - message: str - code: str + code: int = 1000 + reason: str = "" @dataclass(frozen=True) @@ -70,10 +75,88 @@ class _InvalidInbound: _Inbound = ( WSGenerateMessage | WSSubmitMessage | _Stop | _Disconnect - | _ReaderFailure | _InvalidInbound + | _InvalidInbound ) +class _InboundBuffer: + """One bounded FIFO, with coalesced controls that never consume its budget.""" + + def __init__(self) -> None: + self.pending: deque[tuple[_Inbound, int]] = deque() + self.pending_bytes = 0 + self.stop = False + self.terminal: _Disconnect | None = None + self.changed = asyncio.Event() + self.closed = asyncio.Event() + + def put(self, message: _Inbound, size: int = 0) -> bool: + if self.terminal is not None: + return False + if isinstance(message, _Stop): + self.stop = True + else: + if len(self.pending) >= MAX_WS_PENDING_MESSAGES or self.pending_bytes + size > MAX_WS_PENDING_BYTES: + return False + self.pending.append((message, size)) + self.pending_bytes += size + self.changed.set() + return True + + def close(self, code: int = 1000, reason: str = "") -> None: + if self.terminal is None: + self.terminal = _Disconnect(code, reason) + self.pending.clear() + self.pending_bytes = 0 + self.closed.set() + self.changed.set() + + async def get(self, *, control_only: bool = False) -> _Inbound: + while True: + if self.terminal is not None: + return self.terminal + if self.stop and (control_only or not self.pending): + self.stop = False + return _Stop() + if self.pending and not control_only: + message, size = self.pending.popleft() + self.pending_bytes -= size + return message + self.changed.clear() + await self.changed.wait() + + +_T = TypeVar("_T") + + +class _OutboundQueue(Generic[_T]): + """Bound both queued events and callbacks awaiting the event loop.""" + + def __init__(self, overflow: Callable[[], None]) -> None: + self._loop = asyncio.get_running_loop() + self._queue: asyncio.Queue[_T] = asyncio.Queue() + self._slots = threading.BoundedSemaphore(MAX_WS_OUTBOUND_EVENTS) + self._overflow = overflow + self._closed = threading.Event() + + def put(self, item: _T) -> None: + if self._closed.is_set(): + return + if not self._slots.acquire(blocking=False): + self._closed.set() + self._loop.call_soon_threadsafe(self._overflow) + return + self._loop.call_soon_threadsafe(self._queue.put_nowait, item) + + async def get(self) -> _T: + item = await self._queue.get() + self._slots.release() + return item + + def close(self) -> None: + self._closed.set() + + @dataclass(frozen=True) class _TokenFrame: payload: JSONObject @@ -173,11 +256,12 @@ async def session_stream(websocket: WebSocket, session_id: str): if not ws_auth_ok(websocket): await websocket.close(code=1008, reason="unauthorized") return + protocol = "drowse.v1" if "drowse.v1" in websocket.scope.get("subprotocols", []) else None if session_id != SINGLE_SESSION_ID: - await websocket.accept() + await websocket.accept(subprotocol=protocol) await websocket.close(code=1008, reason="session not found") return - await websocket.accept() + await websocket.accept(subprotocol=protocol) # Single perpetual reader. ``websocket.receive_json()`` is bound # to a per-connection ``recv_in_progress`` flag in the underlying @@ -189,36 +273,43 @@ async def session_stream(websocket: WebSocket, session_id: str): # incoming frame through one queue lets both the outer dispatch # loop and the in-flight generation share the read side without # ever overlapping calls into the WS. - incoming: asyncio.Queue[_Inbound] = asyncio.Queue() + incoming = _InboundBuffer() async def _reader(): try: while True: - raw = await websocket.receive_json() - if not isinstance(raw, dict): - await incoming.put(_InvalidInbound("message must be an object")) - elif raw.get("type") in ("generate", "submit"): - try: + frame = await websocket.receive_text() + size = len(frame.encode("utf-8")) + if size > MAX_WS_MESSAGE_BYTES: + incoming.close(1009, "message too large") + return + message: _Inbound + try: + raw = json.loads(frame) + if not isinstance(raw, dict): + message = _InvalidInbound("message must be an object") + elif raw.get("type") in ("generate", "submit"): message = ( WSSubmitMessage(**raw) if raw.get("type") == "submit" else WSGenerateMessage(**raw) ) - await incoming.put(message) - except ValidationError as exc: - await incoming.put( - _InvalidInbound(_validation_message(exc)) - ) - elif raw.get("type") == "stop": - await incoming.put(_Stop()) - else: - await incoming.put(_InvalidInbound(f"unknown message type: {raw.get('type')!r}")) + elif raw.get("type") == "stop": + message = _Stop() + else: + message = _InvalidInbound("unknown message type") + except ValidationError as exc: + message = _InvalidInbound(_validation_message(exc)) + except (ValueError, RecursionError): + message = _InvalidInbound("invalid JSON message") + if not incoming.put(message, size): + incoming.close(1013, "too many pending messages") + return except WebSocketDisconnect: - await incoming.put(_Disconnect()) - except Exception as e: - # Surface any other read-side failure into the queue so - # the dispatcher can close cleanly instead of leaking. - await incoming.put(_ReaderFailure(str(e), type(e).__name__)) + incoming.close() + except Exception: + _logger.exception("native WebSocket reader failed") + incoming.close(1011, "request failed") reader_task = asyncio.create_task(_reader()) @@ -226,8 +317,9 @@ async def _reader(): # lifetime and forward exact ``tree_mutated`` frames. Held # in a queue + forwarder task so the EventBus callback (which # runs on the gen thread) never touches the WS directly. - loop = asyncio.get_running_loop() - tree_event_queue: asyncio.Queue[JSONObject] = asyncio.Queue() + tree_event_queue = _OutboundQueue[JSONObject]( + lambda: incoming.close(1013, "client is not consuming events"), + ) # ``websocket.send_json`` is not safe for concurrent callers — # starlette serializes per-call but two tasks can interleave # bytes on the wire and corrupt the frame sequence. This lock @@ -237,12 +329,12 @@ async def _reader(): ws_send_lock = asyncio.Lock() async def _send_json(payload: JSONObject) -> None: - async with ws_send_lock: - await websocket.send_json(payload) + async with asyncio.timeout(WS_SEND_TIMEOUT_SECONDS): + async with ws_send_lock: + await websocket.send_json(payload) def _queue_tree_event(payload: JSONObject) -> None: - with suppress(Exception): - loop.call_soon_threadsafe(tree_event_queue.put_nowait, payload) + tree_event_queue.put(payload) def _on_loom_event(event: object) -> None: if not isinstance(event, LoomMutated): @@ -283,6 +375,7 @@ async def _tree_forwarder(): try: await _send_json(payload) except Exception: + incoming.close(1013, "client is not consuming events") return if payload.get("op") == "finalize_assistant": updated = payload.get("updated") @@ -292,12 +385,12 @@ async def _tree_forwarder(): continue node_id = node.get("id") if isinstance(node_id, str): - tree_forwarded_finalized.add(node_id) + tree_forwarded_finalized.append(node_id) tree_forwarded_event.set() except asyncio.CancelledError: return - tree_forwarded_finalized: set[str] = set() + tree_forwarded_finalized: deque[str] = deque(maxlen=MAX_WS_PENDING_MESSAGES) tree_forwarded_event = asyncio.Event() forwarder_task = asyncio.create_task(_tree_forwarder()) @@ -332,63 +425,59 @@ async def _wait_for_tree_finalization(node_id: str) -> None: "tree mutation stream ended before generation finalization" ) - deferred_incoming: deque[_Inbound] = deque() - - async def _cancel_and_wait(task: asyncio.Task[Any]) -> None: - task.cancel() - with suppress(asyncio.CancelledError, Exception): - await task - - def _stop_session_safely() -> None: - with suppress(Exception): - session.stop() - + closed_task = asyncio.create_task(incoming.closed.wait()) + request_task: asyncio.Task[None] | None = None try: while True: - msg = ( - deferred_incoming.popleft() - if deferred_incoming - else await incoming.get() - ) + msg = await incoming.get() if isinstance(msg, _Disconnect): - raise WebSocketDisconnect(code=1000) - if isinstance(msg, _ReaderFailure): - raise RuntimeError(msg.message) + with suppress(Exception): + await websocket.close(code=msg.code, reason=msg.reason) + return if isinstance(msg, (WSGenerateMessage, WSSubmitMessage)): - await _ws_handle_generate( + request_task = asyncio.create_task(_ws_handle_generate( session, msg, app.state.default_steering, incoming, - deferred_incoming, _send_json, _wait_for_tree_finalization, + _send_json, _wait_for_tree_finalization, + )) + finished, _ = await asyncio.wait( + {request_task, closed_task}, return_when=asyncio.FIRST_COMPLETED, ) + if closed_task in finished: + request_task.cancel() + with suppress(asyncio.CancelledError): + await finish_worker(request_task) + else: + await request_task + request_task = None elif isinstance(msg, _Stop): - # Idle-state stop: nothing in flight. continue else: await _send_json(_error_frame( msg.message, code="ValidationError", status=400, )) except WebSocketDisconnect: - # Ensure any stray generation is signaled. - _stop_session_safely() return except Exception as e: + _logger.exception("native WebSocket request failed") + status, message = e.user_message() if isinstance(e, DrowseError) else ( + 500, "Request failed. Check the server log for details.", + ) try: - await _send_json(_error_frame( - str(e), code=type(e).__name__, status=500, - )) + await _send_json(_error_frame(message, code=type(e).__name__, status=status)) finally: with suppress(Exception): await websocket.close(code=1011) finally: - # Drop the loom subscription before tearing down the reader - # so the EventBus stops dispatching into a queue nobody - # reads. - with suppress(Exception): - loom_unsub() - await _cancel_and_wait(forwarder_task) - # Reader holds the only ``receive_json()`` call on the WS. - # Cancel + await so the cancellation propagates fully before - # the connection tears down. - await _cancel_and_wait(reader_task) + loom_unsub() + tree_event_queue.close() + with CancelScope(shield=True): + if request_task is not None: + request_task.cancel() + with suppress(asyncio.CancelledError, Exception): + await finish_worker(request_task) + for task in (forwarder_task, reader_task, closed_task): + task.cancel() + await asyncio.gather(forwarder_task, reader_task, closed_task, return_exceptions=True) def _normalize_submit( @@ -500,7 +589,7 @@ async def _ws_handle_commit( )) return try: - new_id = await asyncio.to_thread( + worker_task = asyncio.create_task(asyncio.to_thread( session.append_turn, parent_node_id, authored.text, @@ -508,7 +597,11 @@ async def _ws_handle_commit( raw=msg.raw, role_label=None if msg.raw else commit_label, thinking=None if msg.raw else (authored.thinking or None), - ) + )) + try: + new_id = await asyncio.shield(worker_task) + finally: + await finish_worker(worker_task) except DrowseError as e: status, message = e.user_message() await send_json(_error_frame( @@ -535,8 +628,7 @@ async def _ws_handle_generate( session: DrowseSession, msg: WSGenerateMessage | WSSubmitMessage, default_steering: "Steering | None", - incoming: asyncio.Queue[_Inbound], - deferred_incoming: "deque[_Inbound]", + incoming: _InboundBuffer, send_json: Callable[[JSONObject], Awaitable[None]], wait_for_tree_finalization: Callable[[str], Awaitable[None]], ) -> None: @@ -594,7 +686,7 @@ async def _ws_handle_generate( await _ws_stream_generation( session, msg, steering, sampling, authored, - incoming, deferred_incoming, send_json, wait_for_tree_finalization, + incoming, send_json, wait_for_tree_finalization, ) @@ -604,23 +696,21 @@ async def _ws_stream_generation( steering: "Steering | None", sampling: SamplingConfig | None, authored: _AuthoredTurn | None, - incoming: asyncio.Queue[_Inbound], - deferred_incoming: "deque[_Inbound]", + incoming: _InboundBuffer, send_json: Callable[[JSONObject], Awaitable[None]], wait_for_tree_finalization: Callable[[str], Awaitable[None]], ) -> None: """Run one generate turn and stream token/done/error events. - Concurrency design: the synchronous ``session.generate_stream`` is - driven from a worker thread via ``asyncio.to_thread``. Its - ``on_token`` callback is invoked on the worker thread; it bridges - into the asyncio loop by calling - ``loop.call_soon_threadsafe(queue.put_nowait, event)``. The main + Concurrency design: synchronous generation runs in a worker thread + via ``asyncio.to_thread`` under its own cancellation scope. Its + ``on_token`` callback bridges into asyncio through a bounded queue. + The main coroutine races two tasks: one pulls ``TokenEvent``s from a local queue and forwards them as ``{type: "token", ...}`` frames; the - other pulls client frames from the shared ``incoming`` queue + other pulls controls from the shared ``incoming`` buffer (populated by the connection's single reader task) so an in-flight - ``{type: "stop"}`` can call ``session.stop()`` without blocking on + ``{type: "stop"}`` can signal this worker without blocking on the token loop. ``asyncio.wait(..., FIRST_COMPLETED)`` is used in a loop: whenever @@ -642,7 +732,6 @@ async def _ws_stream_generation( ``submit`` that also generates) is committed once inside the worker, under the same session lock as the whole fan. """ - loop = asyncio.get_running_loop() n = msg.n parent_node_id = msg.parent_node_id submitted_parent_holder: list[str] = [] @@ -655,13 +744,9 @@ async def _ws_stream_generation( seeds: list[int | None] seeds = [base_seed] if n == 1 else list(derive_seed_schedule(base_seed, n)) - def _stop_session_safely() -> None: - with suppress(Exception): - session.stop() - # Acquire the session lock for the full N-way batch lifetime so # concurrent WS clients serialize FIFO instead of overlapping. - # ``session.generate_stream`` itself uses the threading ``_gen_lock`` + # The session engine itself uses the threading ``_gen_lock`` # to gate the actual generation, but the async-level lock is what # queues HTTP/WS endpoints fairly. Bounded to SESSION_LOCK_TIMEOUT_SECONDS # (300 s) so a long-running generation doesn't pin the lock forever; @@ -685,7 +770,10 @@ def _stop_session_safely() -> None: base_sc = sampling if sampling is not None else SamplingConfig() per_sibling_sampling = _dc_replace(base_sc, seed=seed_i) - token_queue: asyncio.Queue[_TokenQueueItem] = asyncio.Queue() + token_queue = _OutboundQueue[_TokenQueueItem]( + lambda: incoming.close(1013, "client is not consuming events"), + ) + cancelled = threading.Event() # The tree assigns the assistant node id at ``begin_assistant`` # time inside ``_generate_core``; we don't know it before the # gen starts. The on_token callback reads the live active @@ -701,7 +789,7 @@ def _on_token( top_alts: list[TokenAlt] | None, perplexity: float | None = None, _node_holder: list[str | None] = current_node_holder, - _token_queue: asyncio.Queue[_TokenQueueItem] = token_queue, + _token_queue: _OutboundQueue[_TokenQueueItem] = token_queue, ) -> None: event = build_token_event( session, @@ -713,9 +801,7 @@ def _on_token( top_alts=top_alts, perplexity=perplexity, ) - loop.call_soon_threadsafe( - _token_queue.put_nowait, _TokenFrame(cast(JSONObject, event)) - ) + _token_queue.put(_TokenFrame(cast(JSONObject, event))) consumer = TokenConsumer( _on_token, TokenConsumerOptions( @@ -748,81 +834,82 @@ def _worker( _on_token: TokenConsumer = consumer, _result_holder: list[GenerationResult] = result_holder, _error_holder: list[BaseException] = error_holder, - _token_queue: asyncio.Queue[_TokenQueueItem] = token_queue, + _token_queue: _OutboundQueue[_TokenQueueItem] = token_queue, _recipe_override: str | None = recipe_override, ) -> None: try: - effective_parent = parent_node_id - if authored is not None: - if not submitted_parent_holder: - commit_label = None - if not msg.raw and msg.sampling is not None: - commit_label = ( - msg.sampling.user_role - if authored.role == "user" - else msg.sampling.assistant_role - ) or None - committed_id = session.append_turn( - parent_node_id, - authored.text, - role=authored.role, - raw=msg.raw, - role_label=commit_label, - thinking=authored.thinking, + with session.generation_state.cancellation_scope(cancelled): + effective_parent = parent_node_id + if authored is not None: + if not submitted_parent_holder: + commit_label = None + if not msg.raw and msg.sampling is not None: + commit_label = ( + msg.sampling.user_role + if authored.role == "user" + else msg.sampling.assistant_role + ) or None + committed_id = session.append_turn( + parent_node_id, + authored.text, + role=authored.role, + raw=msg.raw, + role_label=commit_label, + thinking=authored.thinking, + ) + submitted_parent_holder.append(committed_id) + effective_parent = submitted_parent_holder[0] + if msg.fork_node_id is not None: + # Fork: recipe / sampling / parent all come from + # the source node inside ``fork_from_token``; the + # WS-level steering/sampling/n fields are ignored. + result = session.fork_from_token( + msg.fork_node_id, + int(msg.fork_raw_index), # pyright: ignore[reportArgumentType] # guarded non-None by is_fork check above; int() accepts int|None only at runtime with None already excluded + alt_token_id=msg.fork_alt_token_id, + replacement_text=msg.fork_replacement_text, + **({"seed": msg.fork_seed} if msg.fork_seed is not None else {}), + on_token=_on_token, ) - submitted_parent_holder.append(committed_id) - effective_parent = submitted_parent_holder[0] - if msg.fork_node_id is not None: - # Fork: recipe / sampling / parent all come from - # the source node inside ``fork_from_token``; the - # WS-level steering/sampling/n fields are ignored. - result = session.fork_from_token( - msg.fork_node_id, - int(msg.fork_raw_index), # pyright: ignore[reportArgumentType] # guarded non-None by is_fork check above; int() accepts int|None only at runtime with None already excluded - alt_token_id=msg.fork_alt_token_id, - replacement_text=msg.fork_replacement_text, - **({"seed": msg.fork_seed} if msg.fork_seed is not None else {}), - on_token=_on_token, - ) - elif msg.prefill_node_id is not None: - # Prefill: anchor / parent come from the user node - # inside ``prefill_assistant``; ``input`` is - # ignored. ``steering`` / ``sampling`` ride through - # like a normal generate; ``thinking`` is forced - # off (the prefill is an answer, not a thought). - result = session.prefill_assistant( - msg.prefill_node_id, - str(msg.prefill_text), - steering=steering, - sampling=_sampling, - on_token=_on_token, - ) - else: - gen_kwargs: dict[str, Any] = { - "steering": steering, - "sampling": _sampling, - "stateless": msg.stateless, - "raw": msg.raw, - "thinking": msg.thinking, - "on_token": _on_token, - "parent_node_id": effective_parent, - } - if _recipe_override is not None: - gen_kwargs["recipe_override"] = _recipe_override - if msg.generate_seat is not None: - gen_kwargs["gen_seat"] = msg.generate_seat - # Weave exploration preserves the source even for one - # candidate; ordinary chat keeps its coalescing default. - if n > 1 or not msg.append_same_role: - gen_kwargs["append_same_role"] = False - result = session.generate( - build_input(msg.input), **gen_kwargs, - ).first - _result_holder.append(result) + elif msg.prefill_node_id is not None: + # Prefill: anchor / parent come from the user node + # inside ``prefill_assistant``; ``input`` is + # ignored. ``steering`` / ``sampling`` ride through + # like a normal generate; ``thinking`` is forced + # off (the prefill is an answer, not a thought). + result = session.prefill_assistant( + msg.prefill_node_id, + str(msg.prefill_text), + steering=steering, + sampling=_sampling, + on_token=_on_token, + ) + else: + gen_kwargs: dict[str, Any] = { + "steering": steering, + "sampling": _sampling, + "stateless": msg.stateless, + "raw": msg.raw, + "thinking": msg.thinking, + "on_token": _on_token, + "parent_node_id": effective_parent, + } + if _recipe_override is not None: + gen_kwargs["recipe_override"] = _recipe_override + if msg.generate_seat is not None: + gen_kwargs["gen_seat"] = msg.generate_seat + # Weave exploration preserves the source even for one + # candidate; ordinary chat keeps its coalescing default. + if n > 1 or not msg.append_same_role: + gen_kwargs["append_same_role"] = False + result = session.generate( + build_input(msg.input), **gen_kwargs, + ).first + _result_holder.append(result) except BaseException as e: _error_holder.append(e) finally: - loop.call_soon_threadsafe(_token_queue.put_nowait, _TokenDone()) + _token_queue.put(_TokenDone()) await send_json({ "type": "started", @@ -847,7 +934,7 @@ def _worker( done = False stop_signaled = False token_get = asyncio.create_task(token_queue.get()) - client_get = asyncio.create_task(incoming.get()) + client_get = asyncio.create_task(incoming.get(control_only=True)) try: while not done: finished, _pending = await asyncio.wait( @@ -855,21 +942,11 @@ def _worker( ) if client_get in finished: incoming_msg = client_get.result() - # Disconnect / reader-error lifecycle messages: - # signal the worker to wind down; let the outer - # loop propagate the disconnect on the next - # iteration. - if isinstance(incoming_msg, _Stop): - _stop_session_safely() - stop_signaled = True - elif isinstance(incoming_msg, (_Disconnect, _ReaderFailure)): - _stop_session_safely() - stop_signaled = True - deferred_incoming.append(incoming_msg) - else: - # Out-of-band generate/invalid frame: defer until done. - deferred_incoming.append(incoming_msg) - client_get = asyncio.create_task(incoming.get()) + if isinstance(incoming_msg, _Disconnect): + raise WebSocketDisconnect(code=incoming_msg.code) + cancelled.set() + stop_signaled = True + client_get = asyncio.create_task(incoming.get(control_only=True)) if token_get in finished: item = token_get.result() if isinstance(item, _TokenDone): @@ -878,26 +955,18 @@ def _worker( await send_json(item.payload) token_get = asyncio.create_task(token_queue.get()) finally: - # Keep each queue read alive until it resolves. Cancelling and - # recreating ``incoming.get()`` after every token can race a - # just-delivered stop frame: Queue.get has already removed the - # item, but task cancellation wins before the dispatcher sees - # the result. At turn end, preserve any frame that completed - # just after the final token wait for the outer dispatcher. - if not client_get.done(): + cancelled.set() + token_queue.close() + with CancelScope(shield=True): + # A stop racing the final token must still abort the fan. + if client_get.done() and not client_get.cancelled(): + stop_signaled = True client_get.cancel() - with suppress(asyncio.CancelledError): - await client_get - if not client_get.cancelled(): - deferred_incoming.append(client_get.result()) - if not token_get.done(): token_get.cancel() - with suppress(asyncio.CancelledError): - await token_get - # Drain any residual events the worker pushed between - # sentinel and join — should be none because the - # sentinel is last, but cheap insurance. - await worker_task + try: + await asyncio.gather(client_get, token_get, return_exceptions=True) + finally: + await finish_worker(worker_task) if error_holder and not result_holder: exc = error_holder[0] diff --git a/drowse/web/AGENTS.md b/drowse/web/AGENTS.md index 07b56340..7651f38c 100644 --- a/drowse/web/AGENTS.md +++ b/drowse/web/AGENTS.md @@ -12,7 +12,7 @@ drowse/web/ routes.py # mount logic + SPA fallback dist/ # COMMITTED build artifact, ships in the wheel index.html favicon.ico theme-init.js LICENSE-{Martian-Mono,Wix-Madefor}.txt - assets/{*.css,*.js,*.woff2} + assets/{*.css,*.js,*.woff2,*.json} icons/ social/ # public image assets ``` @@ -24,6 +24,14 @@ fails. `npm run check` is `svelte-check` plus `scripts/check-theme.mjs`, which fails when a referenced CSS custom property has no declaration in the style tokens. +Shared changing labels use `webui/src/lib/ui/MorphText.svelte`; formatted +numeric callers keep `RollingNumber.svelte`. Torph paints an aria-hidden +overlay while Svelte owns the exact selectable source text. Preserve the +offscreen, reduced-motion, selection, wrapping, identity-reset, and finished +animation cleanup policies in `lib/textMotion.ts`. Do not replace interactive +token spans or matrix cells with whole-string morphs. `e2e/torph-motion.spec.ts` +checks the shared controls across desktop browsers and iPhone-sized WebKit. + Package data includes the entire default `dist/` tree. The package-isolation check compares wheel and sdist contents with that tree, so a file omitted from both archives still fails. Hosted WebGPU assets stay in the separate hosted build. @@ -47,6 +55,12 @@ duplicate routes that the first ones shadow — harmless, not rejected. `WebUINotBuilt` raises on mount when the dist directory is empty — only in source installs that haven't run `npm run build`. +The server's HTTP security middleware supplies the default dashboard CSP and +anti-framing headers. API data is `no-store`; static assets retain their normal +revalidation. Browser WS auth uses the `drowse.auth.` +subprotocol alongside `drowse.v1`, never a credential in the URL. Keep the key +in memory. Local-data deletion must report storage failures and allow retry. + ## Wire protocol The dashboard is the sole client of the native `/drowse/v1/*` API; @@ -350,6 +364,16 @@ sortMode)` in `rack/probeRows.ts` is the one merge + sort for both panels (`strength` / `name` / `depth`, with natural-number name collation for SAE feature ids so `sae/9` precedes `sae/10`; rows with no depth CoM sort last). +SAE descriptions appear as wrapping text in both the live cards and token +inspector. `lib/saeDescriptions.ts` checks the exact dictionary before loading +the published Neuronpedia indexes in `lib/data/sae-descriptions/`; these cover +the three verified Gemma Scope 2 browser packs and ship in both builds. Missing +IDs fall back to the feature API with source validation. Each inspector card +links to the original feature and identifies the explanation model. Published +interpretations are distinct from activation measurements; description lookup +never changes a browser pack's activation calibration. Failed batch entries +remain retryable, and one failure cannot discard the other returned labels. + `LayerStrip` is the one per-layer view across every pillar: `HeatmapCell` marks with no outlines, a one-pixel gap between layers, endpoints at least 3:1 from neutral and from the card. A focused strip is an arrow-key layer scrubber with an diff --git a/drowse/web/dist/LICENSE-Torph.txt b/drowse/web/dist/LICENSE-Torph.txt new file mode 100644 index 00000000..0ef179b1 --- /dev/null +++ b/drowse/web/dist/LICENSE-Torph.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Lochie Axon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/drowse/web/dist/assets/App-BHtMtIZ_.js b/drowse/web/dist/assets/App-BHtMtIZ_.js deleted file mode 100644 index e6ee2c26..00000000 --- a/drowse/web/dist/assets/App-BHtMtIZ_.js +++ /dev/null @@ -1,54 +0,0 @@ -import{$ as e,A as t,At as n,B as r,Bt as i,C as a,Ct as o,D as s,Dt as c,E as l,Et as u,F as d,Ft as f,G as p,H as m,I as h,J as g,L as _,Lt as v,M as y,N as b,Nt as x,O as S,Ot as C,P as w,Pt as T,Q as E,R as D,Rt as O,S as k,St as A,T as j,Tt as M,U as N,V as P,W as F,X as I,Y as L,Z as ee,_ as te,_t as R,a as z,at as B,b as ne,bt as V,c as re,ct as ie,d as ae,dt as oe,et as H,ft as U,g as se,gt as ce,h as le,ht as ue,i as de,it as fe,j as pe,k as me,kt as W,l as he,lt as ge,mt as _e,n as ve,nt as ye,o as be,ot as xe,p as Se,pt as Ce,q as G,r as we,rt as Te,s as Ee,st as De,t as Oe,tt as K,u as ke,ut as Ae,v as je,vt as q,w as Me,wt as J,x as Y,xt as Ne,y as Pe,yt as X,z as Fe,zt as Ie}from"./theme-DPLNzLfv.js";typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var Le={appearance:[`M11.5582 13.6469L11.4746 13.7179L4.54692 20.5186C5.04216 20.8239 5.62551 21 6.25 21H17.75C18.3745 21 18.9578 20.8239 19.4531 20.5186L12.5254 13.7179L12.432 13.6399C12.1705 13.4552 11.8174 13.4576 11.5582 13.6469ZM21 6.25C21 4.45507 19.5449 3 17.75 3H6.25C4.45507 3 3 4.45507 3 6.25V17.75C3 18.3771 3.17758 18.9626 3.4852 19.4592L10.4238 12.6475L10.5592 12.5248C11.3941 11.8273 12.615 11.8293 13.4477 12.5306L13.5762 12.6475L20.5148 19.4592C20.8224 18.9626 21 18.3771 21 17.75V6.25ZM15.25 10.75C14.1454 10.75 13.25 9.85457 13.25 8.75C13.25 7.64543 14.1454 6.75 15.25 6.75C16.3546 6.75 17.25 7.64543 17.25 8.75C17.25 9.85457 16.3546 10.75 15.25 10.75Z`],subtract:[`M3.996 13H20c0.552 0 1-0.448 1-1s-0.448-1-1-1H3.996c-0.552 0-1 0.448-1 1s0.448 1 1 1z`],help:[`M12 2c5.523 0 10 4.478 10 10s-4.477 10-10 10S2 17.522 2 12 6.477 2 12 2zm0 13.5c-0.552 0-1 0.448-1 1s0.448 1 1 1 1-0.448 1-1-0.448-1-1-1zm0-8.75c-1.519 0-2.75 1.231-2.75 2.75 0 0.414 0.336 0.75 0.75 0.75 0.38 0 0.694-0.282 0.743-0.648L10.75 9.5c0-0.69 0.56-1.25 1.25-1.25s1.25 0.56 1.25 1.25c0 0.539-0.135 0.805-0.645 1.332L12.47 10.97c-0.878 0.878-1.22 1.447-1.22 2.53 0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75c0-0.539 0.135-0.805 0.645-1.332l0.135-0.138c0.878-0.878 1.22-1.447 1.22-2.53 0-1.519-1.231-2.75-2.75-2.75z`],shuffle:[`M19.207 4.293c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l0.801 0.802c-3.809 0.161-6.169 2.59-8.226 4.706l-0.085 0.088C8.057 13.593 6.147 15.5 3 15.5c-0.552 0-1 0.448-1 1s0.448 1 1 1c4.05 0 6.503-2.525 8.632-4.715l0.085-0.088c2.124-2.184 3.96-4.02 6.857-4.185l-0.781 0.78c-0.39 0.391-0.39 1.025 0 1.415 0.39 0.39 1.024 0.39 1.414 0l2.5-2.5C21.895 8.02 22 7.765 22 7.5c0-0.265-0.105-0.52-0.293-0.707l-2.5-2.5zM3 6.5c3.229 0 5.443 1.605 7.287 3.367-0.197 0.199-0.388 0.396-0.574 0.587l-0.147 0.152c-0.233 0.24-0.459 0.47-0.68 0.693C7.186 9.68 5.476 8.5 3 8.5c-0.552 0-1-0.447-1-1 0-0.552 0.448-1 1-1zm15.594 10.991c-3.01-0.128-5.115-1.671-6.881-3.357 0.197-0.2 0.388-0.397 0.574-0.589l0.147-0.151c0.233-0.24 0.459-0.47 0.68-0.693 1.601 1.524 3.21 2.66 5.46 2.787l-0.781-0.78c-0.39-0.391-0.39-1.025 0-1.415 0.39-0.39 1.024-0.39 1.414 0l2.5 2.5C21.895 15.98 22 16.235 22 16.5c0 0.265-0.105 0.52-0.293 0.707l-2.5 2.5c-0.39 0.39-1.024 0.39-1.414 0-0.39-0.39-0.39-1.024 0-1.414l0.801-0.802z`],add:[`M11.883 3.007L12 3c0.513 0 0.935 0.386 0.993 0.883L13 4v7h7c0.513 0 0.936 0.386 0.993 0.883L21 12c0 0.513-0.386 0.935-0.883 0.993L20 13h-7v7c0 0.513-0.386 0.936-0.883 0.993L12 21c-0.513 0-0.935-0.386-0.993-0.883L11 20v-7H4c-0.513 0-0.936-0.386-0.993-0.883L3 12c0-0.513 0.386-0.935 0.883-0.993L4 11h7V4c0-0.513 0.386-0.936 0.883-0.993L12 3l-0.117 0.007z`],back:[`M15.707 4.293c0.39 0.39 0.39 1.024 0 1.414L9.414 12l6.293 6.293c0.39 0.39 0.39 1.024 0 1.414-0.39 0.39-1.024 0.39-1.414 0l-7-7c-0.39-0.39-0.39-1.024 0-1.414l7-7c0.39-0.39 1.024-0.39 1.414 0z`],chats:[`M9.5 3C5.358 3 2 6.358 2 10.5c0 1.133 0.252 2.21 0.703 3.175-0.302 1.225-0.563 2.534-0.681 3.142-0.134 0.69 0.465 1.293 1.153 1.17 0.623-0.11 1.978-0.36 3.236-0.65C7.354 17.762 8.401 18 9.5 18c4.142 0 7.5-3.358 7.5-7.5C17 6.358 13.642 3 9.5 3zM9.462 19c1.338 1.241 3.13 2 5.1 2 1.1 0 2.145-0.237 3.088-0.663 1.043 0.244 2.186 0.488 2.913 0.64 0.892 0.186 1.672-0.615 1.467-1.5-0.162-0.703-0.418-1.795-0.671-2.803 0.45-0.964 0.703-2.04 0.703-3.174 0-3.283-2.11-6.073-5.047-7.09 0.35 0.638 0.621 1.324 0.8 2.048 1.653 1.068 2.747 2.928 2.747 5.042 0 0.992-0.24 1.925-0.665 2.747l-0.13 0.253 0.07 0.276c0.228 0.895 0.467 1.9 0.642 2.65-0.774-0.163-1.818-0.39-2.74-0.61l-0.264-0.062-0.243 0.121c-0.804 0.4-1.71 0.625-2.67 0.625-1.06 0-2.055-0.274-2.92-0.756C10.978 18.91 10.28 19 9.563 19h-0.1z`],check:[`M8.5 16.586l-3.793-3.793c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l4.5 4.5c0.39 0.39 1.024 0.39 1.414 0l11-11c0.39-0.39 0.39-1.024 0-1.414-0.39-0.39-1.024-0.39-1.414 0L8.5 16.586z`],comparison:[`M21.25 12.5c0.414 0 0.75-0.336 0.75-0.75S21.664 11 21.25 11H2.75C2.336 11 2 11.336 2 11.75s0.336 0.75 0.75 0.75h18.5zM17.75 2C18.993 2 20 3.007 20 4.25V10H4V4.25C4 3.007 5.007 2 6.25 2h11.5zM4 19.25V13.5h16v5.75c0 1.243-1.007 2.25-2.25 2.25H6.25C5.007 21.5 4 20.493 4 19.25z`],controls:[`M8.75 14.5c1.537 0 2.825 1.067 3.163 2.5h9.337c0.414 0 0.75 0.336 0.75 0.75 0 0.38-0.282 0.694-0.648 0.743L21.25 18.5l-9.337 0.001C11.574 19.934 10.286 21 8.75 21c-1.537 0-2.824-1.066-3.163-2.499L2.75 18.5C2.336 18.5 2 18.164 2 17.75c0-0.38 0.282-0.694 0.648-0.743L2.75 17h2.837c0.339-1.433 1.626-2.5 3.163-2.5zM15.25 3c1.537 0 2.825 1.067 3.163 2.5h2.837C21.664 5.5 22 5.836 22 6.25c0 0.38-0.282 0.694-0.648 0.743L21.25 7l-2.837 0.001C18.074 8.434 16.786 9.5 15.25 9.5c-1.537 0-2.824-1.066-3.163-2.499L2.75 7C2.336 7 2 6.664 2 6.25c0-0.38 0.282-0.694 0.648-0.743L2.75 5.5h9.337C12.425 4.067 13.713 3 15.25 3z`],conversation:[`M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10c-1.64 0-3.225-0.396-4.644-1.142l-4.29 1.117c-0.455 0.119-0.92-0.154-1.037-0.608-0.037-0.14-0.037-0.288 0-0.428l1.116-4.289C2.397 15.23 2 13.643 2 12 2 6.477 6.477 2 12 2zm1.252 11H8.75l-0.102 0.007C8.282 13.057 8 13.37 8 13.75s0.282 0.694 0.648 0.743L8.75 14.5h4.502l0.101-0.007c0.367-0.05 0.649-0.363 0.649-0.743s-0.282-0.694-0.649-0.743L13.252 13zm1.998-3.5h-6.5L8.648 9.507C8.282 9.557 8 9.87 8 10.25s0.282 0.694 0.648 0.743L8.75 11h6.5l0.102-0.007C15.718 10.943 16 10.63 16 10.25s-0.282-0.694-0.648-0.743L15.25 9.5z`],copy:[`M8.5 13.75c0 2.347 1.903 4.25 4.25 4.25h1.74c-0.128 1.678-1.53 3-3.24 3h-5C4.455 21 3 19.545 3 17.75v-7.5C3 8.455 4.455 7 6.25 7H8.5v6.75zM17.75 3C19.545 3 21 4.455 21 6.25v7.5c0 1.795-1.455 3.25-3.25 3.25h-5c-1.795 0-3.25-1.455-3.25-3.25v-7.5C9.5 4.455 10.955 3 12.75 3h5z`],credits:[`M8 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm9 0c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM4.25 14C3.007 14 2 15.007 2 16.25v0.25S2 21 8 21s6-4.5 6-4.5v-0.25c0-1.243-1.007-2.25-2.25-2.25h-7.5zM17 19.5c-1.171 0-2.068-0.181-2.755-0.458 0.342-0.575 0.527-1.128 0.627-1.558 0.06-0.26 0.092-0.481 0.11-0.649 0.008-0.084 0.012-0.155 0.015-0.211L15 16.55v-0.3c0-0.872-0.343-1.664-0.902-2.248L14.2 14h5.6c1.215 0 2.2 0.985 2.2 2.2 0 0 0 3.3-5 3.3z`],dismiss:[`M4.21 4.387l0.083-0.094c0.36-0.36 0.928-0.388 1.32-0.083l0.094 0.083L12 10.585l6.293-6.292c0.39-0.39 1.024-0.39 1.414 0 0.39 0.39 0.39 1.024 0 1.414L13.415 12l6.292 6.293c0.36 0.36 0.388 0.928 0.083 1.32l-0.083 0.094c-0.36 0.36-0.928 0.388-1.32 0.083l-0.094-0.083L12 13.415l-6.293 6.292c-0.39 0.39-1.024 0.39-1.414 0-0.39-0.39-0.39-1.024 0-1.414L10.585 12 4.293 5.707c-0.36-0.36-0.388-0.928-0.083-1.32l0.083-0.094L4.21 4.387z`],down:[`M4.293 8.293c0.39-0.39 1.024-0.39 1.414 0L12 14.586l6.293-6.293c0.39-0.39 1.024-0.39 1.414 0 0.39 0.39 0.39 1.024 0 1.414l-7 7c-0.39 0.39-1.024 0.39-1.414 0l-7-7c-0.39-0.39-0.39-1.024 0-1.414z`],download:[`M13 3c0-0.552-0.448-1-1-1s-1 0.448-1 1v12.086l-3.293-3.293c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l5 5c0.39 0.39 1.024 0.39 1.414 0l5-5c0.39-0.39 0.39-1.024 0-1.414-0.39-0.39-1.024-0.39-1.414 0L13 15.086V3zM5 20c-0.552 0-1 0.448-1 1s0.448 1 1 1h14c0.552 0 1-0.448 1-1s-0.448-1-1-1H5z`],error:[`M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2zm-0.001 12.502c-0.552 0-0.999 0.447-0.999 0.999 0 0.551 0.447 0.999 0.999 0.999 0.551 0 0.998-0.448 0.998-0.999 0-0.551-0.447-0.999-0.998-0.999zM11.994 7c-0.414 0-0.75 0.337-0.749 0.751l0.004 4.501 0.007 0.101c0.05 0.367 0.363 0.65 0.743 0.649 0.414 0 0.75-0.337 0.75-0.751l-0.004-4.502-0.007-0.101C12.688 7.282 12.374 7 11.994 7z`],external:[`M11 3c-0.552 0-1 0.448-1 1s0.448 1 1 1h6.586L3.293 19.293c-0.39 0.39-0.39 1.023 0 1.414 0.39 0.39 1.024 0.39 1.414 0L19 6.414V13c0 0.552 0.448 1 1 1s1-0.448 1-1V4c0-0.552-0.448-1-1-1h-9z`],home:[`M13.45 2.533c-0.837-0.707-2.063-0.707-2.9 0L3.8 8.228C3.291 8.655 3 9.284 3 9.948v9.305c0 0.966 0.784 1.75 1.75 1.75h3c0.966 0 1.75-0.784 1.75-1.75V15.25c0-0.68 0.542-1.232 1.217-1.25h2.566c0.675 0.018 1.217 0.57 1.217 1.25v4.003c0 0.966 0.784 1.75 1.75 1.75h3c0.966 0 1.75-0.784 1.75-1.75V9.947c0-0.662-0.292-1.292-0.8-1.72l-6.75-5.694z`],info:[`M12.002 1.999c5.523 0 10.001 4.478 10.001 10.002 0 5.523-4.478 10.001-10.001 10.001C6.478 22.002 2 17.524 2 12.001 2 6.477 6.478 1.999 12.002 1.999zM12 10.5c-0.414 0-0.75 0.336-0.75 0.75v5c0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75v-5c0-0.414-0.336-0.75-0.75-0.75zM12 9c0.552 0 1-0.448 1-1s-0.448-1-1-1-1 0.448-1 1 0.448 1 1 1z`],loom:[`M4 5.5C4 3.567 5.567 2 7.5 2S11 3.567 11 5.5c0 1.59-1.06 2.932-2.511 3.358 0.688 2.253 2.783 3.892 5.261 3.892h0.33C14.425 11.177 15.825 10 17.5 10c1.933 0 3.5 1.567 3.5 3.5S19.433 17 17.5 17c-1.676 0-3.076-1.177-3.42-2.75h-0.33c-2.231 0-4.218-1.044-5.5-2.67v3.5C9.823 15.425 11 16.825 11 18.5c0 1.933-1.567 3.5-3.5 3.5S4 20.433 4 18.5c0-1.676 1.177-3.076 2.75-3.42V8.92C5.177 8.575 4 7.175 4 5.5z`],models:[`M13.409 2.511c-0.904-0.366-1.914-0.366-2.818 0l-7.498 3.04C2.432 5.819 2 6.461 2 7.173v9.653c0 0.712 0.432 1.354 1.092 1.621l7.5 3.04c0.903 0.367 1.913 0.367 2.817 0l7.498-3.04C21.567 18.18 22 17.538 22 16.826V7.173c0-0.713-0.432-1.354-1.093-1.622l-7.498-3.04zm-7.36 5.472c0.147-0.387 0.58-0.582 0.967-0.435L12 9.438l4.984-1.89c0.387-0.147 0.82 0.048 0.967 0.435 0.147 0.387-0.048 0.82-0.435 0.967l-4.766 1.81v5.49c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75v-5.49L6.484 8.95C6.097 8.803 5.902 8.37 6.049 7.983z`],moon:[`M20.026 17.001c-2.762 4.784-8.879 6.423-13.663 3.661-1.302-0.752-2.399-1.77-3.234-2.982-0.28-0.406-0.099-0.966 0.365-1.132 3.767-1.348 5.785-2.91 6.956-5.146C11.682 9.05 12 6.472 11.139 2.94c-0.12-0.489 0.266-0.954 0.769-0.927 1.556 0.083 3.078 0.53 4.457 1.327 4.784 2.762 6.423 8.879 3.66 13.662z`],next:[`M8.293 4.293c-0.39 0.39-0.39 1.024 0 1.414L14.586 12l-6.293 6.293c-0.39 0.39-0.39 1.024 0 1.414 0.39 0.39 1.024 0.39 1.414 0l7-7c0.39-0.39 0.39-1.024 0-1.414l-7-7c-0.39-0.39-1.024-0.39-1.414 0z`],offline:[`M12.858 14.273l7.434 7.434c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414l-17.999-18c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l3.096 3.097C4.747 7.233 4.136 7.73 3.57 8.299 3.08 8.788 2.608 9.365 2.179 9.982c-0.314 0.454-0.201 1.077 0.252 1.392 0.454 0.315 1.077 0.202 1.392-0.252 0.363-0.524 0.761-1.01 1.16-1.41 0.571-0.57 1.195-1.057 1.855-1.46L7.99 9.405c-0.608 0.35-1.18 0.784-1.7 1.303-0.615 0.616-1.117 1.31-1.503 2.074-0.25 0.493-0.052 1.094 0.44 1.344 0.494 0.249 1.095 0.051 1.344-0.441 0.291-0.575 0.668-1.098 1.134-1.563 0.527-0.528 1.128-0.94 1.768-1.234l1.408 1.407c-0.933 0.21-1.82 0.679-2.545 1.405-0.46 0.46-0.826 1.009-1.09 1.612-0.222 0.506 0.01 1.096 0.515 1.317 0.506 0.222 1.096-0.009 1.317-0.515 0.167-0.381 0.394-0.722 0.672-1 0.842-0.842 2.034-1.123 3.108-0.841zm-1.332-5.93l2.228 2.229c0.958 0.278 1.861 0.795 2.616 1.55 0.444 0.444 0.837 0.995 1.137 1.582 0.252 0.491 0.854 0.686 1.346 0.435 0.491-0.252 0.686-0.854 0.435-1.346-0.393-0.767-0.907-1.488-1.504-2.085-1.717-1.717-4.011-2.505-6.258-2.364zM8.51 5.328l1.651 1.651c3.108-0.581 6.44 0.33 8.844 2.735 0.42 0.42 0.822 0.906 1.172 1.413 0.314 0.455 0.936 0.569 1.391 0.255 0.454-0.314 0.569-0.936 0.255-1.39-0.417-0.605-0.896-1.184-1.404-1.692-3.223-3.224-7.833-4.214-11.91-2.972zm4.552 11.114c0.586 0.586 0.586 1.537 0 2.123-0.586 0.586-1.537 0.586-2.123 0-0.586-0.586-0.586-1.537 0-2.123 0.586-0.586 1.537-0.586 2.123 0z`],paused:[`M5.746 3c-0.966 0-1.75 0.784-1.75 1.75v14.5c0 0.966 0.784 1.75 1.75 1.75h3.5c0.967 0 1.75-0.784 1.75-1.75V4.75c0-0.966-0.783-1.75-1.75-1.75h-3.5zm9 0c-0.966 0-1.75 0.784-1.75 1.75v14.5c0 0.966 0.784 1.75 1.75 1.75h3.5c0.967 0 1.75-0.784 1.75-1.75V4.75c0-0.966-0.783-1.75-1.75-1.75h-3.5z`],ready:[`M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2zm3.22 6.97l-4.47 4.47-1.97-1.97c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06l2.5 2.5c0.293 0.293 0.767 0.293 1.06 0l5-5c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.767-0.293-1.06 0z`],refresh:[`M5 12c0-3.866 3.134-7 7-7 1.32 0 2.554 0.365 3.608 1H15c-0.552 0-1 0.448-1 1s0.448 1 1 1h3c0.552 0 1-0.448 1-1V4c0-0.552-0.448-1-1-1s-1 0.448-1 1v0.516C15.57 3.559 13.85 3 12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-0.38-0.024-0.755-0.07-1.124-0.068-0.548-0.568-0.937-1.116-0.868-0.548 0.068-0.936 0.568-0.868 1.116C18.98 11.41 19 11.703 19 12c0 3.866-3.134 7-7 7s-7-3.134-7-7z`],return:[`M7 19c0 0.552 0.448 1 1 1h5c2.242 0 4.01-0.778 5.218-2.023C19.414 16.744 20 15.113 20 13.5c0-1.613-0.586-3.244-1.782-4.477C17.01 7.778 15.242 7 13 7H8.414l2.043-2.043c0.39-0.39 0.39-1.024 0-1.414-0.39-0.39-1.024-0.39-1.414 0l-3.75 3.75c-0.39 0.39-0.39 1.024 0 1.414l3.75 3.75c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414L8.414 9H13c1.758 0 2.99 0.597 3.782 1.415C17.586 11.245 18 12.363 18 13.5s-0.414 2.256-1.218 3.085C15.99 17.403 14.758 18 13 18H8c-0.552 0-1 0.448-1 1z`],search:[`M15.843 17.368C14.5 18.392 12.82 19 11 19c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8c0 1.877-0.646 3.603-1.729 4.967l4.427 4.317c0.396 0.386 0.404 1.019 0.018 1.414-0.386 0.396-1.019 0.404-1.414 0.018l-4.459-4.348zM17 11c0-3.314-2.686-6-6-6s-6 2.686-6 6 2.686 6 6 6 6-2.686 6-6z`],send:[`M12.815 12.197l-7.532 1.255c-0.176 0.03-0.323 0.15-0.386 0.318L2.3 20.728c-0.248 0.64 0.421 1.25 1.035 0.942l18-9c0.553-0.276 0.553-1.065 0-1.341l-18-9C2.72 2.022 2.05 2.632 2.299 3.27l2.598 6.958c0.063 0.167 0.21 0.289 0.386 0.318l7.532 1.255c0.109 0.018 0.182 0.122 0.164 0.23-0.014 0.085-0.08 0.15-0.164 0.165z`],settings:[`M12.012 2.25c0.734 0.009 1.465 0.093 2.182 0.253 0.312 0.07 0.546 0.33 0.582 0.649l0.17 1.527c0.077 0.7 0.669 1.232 1.375 1.233 0.19 0 0.377-0.04 0.552-0.117l1.4-0.615c0.292-0.128 0.633-0.059 0.85 0.174 1.012 1.08 1.766 2.377 2.205 3.792 0.094 0.305-0.015 0.636-0.272 0.825l-1.241 0.916c-0.354 0.26-0.563 0.673-0.563 1.112 0 0.44 0.209 0.853 0.564 1.114l1.242 0.915c0.257 0.19 0.366 0.521 0.272 0.826-0.439 1.415-1.192 2.71-2.204 3.792-0.217 0.232-0.557 0.302-0.849 0.175l-1.406-0.617c-0.402-0.176-0.864-0.15-1.244 0.07s-0.634 0.607-0.682 1.044l-0.17 1.526c-0.034 0.315-0.263 0.574-0.571 0.647-1.448 0.345-2.958 0.345-4.406 0-0.308-0.073-0.537-0.332-0.572-0.647L9.057 19.32c-0.05-0.436-0.303-0.822-0.683-1.041-0.38-0.219-0.84-0.245-1.242-0.07l-1.406 0.617c-0.292 0.127-0.632 0.057-0.85-0.175-1.011-1.082-1.765-2.38-2.203-3.796-0.094-0.305 0.015-0.636 0.272-0.826l1.243-0.916c0.354-0.26 0.564-0.673 0.564-1.112 0-0.44-0.21-0.853-0.564-1.114L2.945 9.973C2.688 9.783 2.58 9.452 2.673 9.147c0.44-1.415 1.193-2.711 2.205-3.792 0.218-0.233 0.558-0.302 0.85-0.174l1.4 0.615c0.403 0.177 0.866 0.15 1.248-0.073 0.38-0.22 0.633-0.609 0.682-1.045l0.17-1.526c0.036-0.319 0.27-0.58 0.583-0.65 0.717-0.159 1.449-0.243 2.201-0.252zM12 9c-1.657 0-3 1.343-3 3s1.343 3 3 3c1.656 0 3-1.343 3-3s-1.344-3-3-3z`],star:[`M10.788 3.102c0.495-1.003 1.926-1.003 2.421 0l2.358 4.778 5.273 0.766c1.107 0.16 1.549 1.522 0.748 2.303l-3.816 3.719 0.901 5.25c0.19 1.104-0.968 1.945-1.959 1.424l-4.716-2.48-4.715 2.48c-0.99 0.52-2.148-0.32-1.96-1.423l0.901-5.251-3.815-3.72c-0.801-0.78-0.359-2.141 0.748-2.302L8.43 7.88l2.358-4.778z`],stop:[`M4.75 3C3.784 3 3 3.784 3 4.75v14.5C3 20.216 3.784 21 4.75 21h14.5c0.966 0 1.75-0.784 1.75-1.75V4.75C21 3.784 20.216 3 19.25 3H4.75z`],sun:[`M12 2c0.414 0 0.75 0.336 0.75 0.75v1.5C12.75 4.664 12.414 5 12 5s-0.75-0.336-0.75-0.75v-1.5C11.25 2.336 11.586 2 12 2zm5 10c0 2.761-2.239 5-5 5s-5-2.239-5-5 2.239-5 5-5 5 2.239 5 5zm4.25 0.75c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-1.5C19.336 11.25 19 11.586 19 12s0.336 0.75 0.75 0.75h1.5zM12 19c0.414 0 0.75 0.336 0.75 0.75v1.5c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75v-1.5c0-0.414 0.336-0.75 0.75-0.75zm-7.75-6.25C4.664 12.75 5 12.414 5 12s-0.336-0.75-0.75-0.75h-1.5C2.336 11.25 2 11.586 2 12s0.336 0.75 0.75 0.75h1.5zM4.22 4.22c0.293-0.293 0.767-0.293 1.06 0l1.5 1.5c0.293 0.293 0.293 0.768 0 1.06-0.293 0.294-0.767 0.294-1.06 0l-1.5-1.5c-0.293-0.292-0.293-0.767 0-1.06zm1.06 15.56c-0.293 0.294-0.767 0.294-1.06 0-0.293-0.292-0.293-0.767 0-1.06l1.5-1.5c0.293-0.293 0.767-0.293 1.06 0 0.293 0.293 0.293 0.768 0 1.06l-1.5 1.5zm14.5-15.56c-0.293-0.293-0.767-0.293-1.06 0l-1.5 1.5c-0.293 0.293-0.293 0.768 0 1.06 0.293 0.294 0.767 0.294 1.06 0l1.5-1.5c0.293-0.292 0.293-0.767 0-1.06zm-1.06 15.56c0.293 0.294 0.767 0.294 1.06 0 0.293-0.292 0.293-0.767 0-1.06l-1.5-1.5c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.768 0 1.06l1.5 1.5z`],swap:[`M15.207 2.29l4 3.996c0.361 0.36 0.39 0.928 0.084 1.32l-0.083 0.095-4 4.005c-0.39 0.39-1.023 0.39-1.414 0-0.36-0.36-0.389-0.927-0.084-1.32l0.083-0.094L16.083 8H5.5C4.987 8 4.564 7.613 4.507 7.116L4.5 6.999c0-0.513 0.386-0.935 0.883-0.993L5.5 5.999h10.59l-2.296-2.293c-0.36-0.36-0.389-0.928-0.084-1.32l0.083-0.095c0.36-0.36 0.928-0.388 1.32-0.084l0.094 0.084 4 3.995-4-3.995zm4.284 14.592L19.497 17c0 0.513-0.386 0.936-0.883 0.993L18.497 18H7.914l2.293 2.293c0.361 0.36 0.39 0.927 0.084 1.32l-0.083 0.094c-0.36 0.36-0.927 0.389-1.32 0.084l-0.094-0.084-4-3.996c-0.36-0.36-0.389-0.927-0.084-1.32l0.083-0.094 4-4.004c0.39-0.39 1.024-0.39 1.415 0 0.36 0.36 0.388 0.927 0.083 1.32l-0.083 0.094L7.918 16h10.58c0.512 0 0.935 0.386 0.993 0.883L19.497 17l-0.006-0.117z`],tokens:[`M2 6.75C2 4.679 3.679 3 5.75 3h12.5C20.321 3 22 4.679 22 6.75v10.5c0 2.071-1.679 3.75-3.75 3.75H5.75C3.679 21 2 19.321 2 17.25V6.75zM12.75 7.5h2.75v0.75C15.5 8.664 15.836 9 16.25 9S17 8.664 17 8.25v-1.5C17 6.336 16.664 6 16.25 6h-8.5C7.336 6 7 6.336 7 6.75v1.5C7 8.664 7.336 9 7.75 9S8.5 8.664 8.5 8.25V7.5h2.75v9h-0.5c-0.414 0-0.75 0.336-0.75 0.75S10.336 18 10.75 18h2.5c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-0.5v-9z`],unsupported:[`M16.906 5.68C13.768 3.237 9.228 3.458 6.343 6.343 3.458 9.228 3.237 13.768 5.68 16.906L16.906 5.68zm1.414 1.414L7.094 18.32c3.138 2.443 7.678 2.222 10.563-0.663 2.885-2.885 3.106-7.425 0.663-10.563zM4.93 4.929c3.905-3.905 10.237-3.905 14.142 0 3.905 3.905 3.905 10.237 0 14.142-3.905 3.905-10.237 3.905-14.142 0-3.905-3.905-3.905-10.237 0-14.142z`],up:[`M4.293 15.707c0.39 0.39 1.024 0.39 1.414 0L12 9.414l6.293 6.293c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414l-7-7c-0.39-0.39-1.024-0.39-1.414 0l-7 7c-0.39 0.39-0.39 1.024 0 1.414z`],upload:[`M5.5 2c-0.552 0-1 0.448-1 1s0.448 1 1 1h13c0.552 0 1-0.448 1-1s-0.448-1-1-1h-13zm7.207 3.793c-0.39-0.39-1.024-0.39-1.414 0l-5 5c-0.39 0.39-0.39 1.024 0 1.414 0.39 0.39 1.024 0.39 1.414 0L11 8.914V21c0 0.552 0.448 1 1 1s1-0.448 1-1V8.914l3.293 3.293c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414l-5-5z`],warning:[`M9.138 3.707c1.228-2.276 4.493-2.276 5.721 0l6.743 12.502c1.168 2.165-0.4 4.793-2.86 4.793H5.255c-2.46 0-4.028-2.628-2.86-4.793L9.137 3.707zM12.001 15c-0.552 0-1 0.448-1 1s0.448 1 1 1 1-0.448 1-1-0.448-1-1-1zm0-7.5c-0.414 0-0.75 0.336-0.75 0.75v4.5c0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75v-4.5c0-0.414-0.336-0.75-0.75-0.75z`]},Re=ee(``),ze=ee(``);function Be(e,t){n(t,!0);let r=Y(t,`class`,3,``),i=Y(t,`size`,3,16),a=Y(t,`spin`,3,!1);var o=ze();let s;m(o,21,()=>Le[t.name],N,(e,t)=>{var n=Re();U(()=>S(n,`d`,B(t))),g(e,n)}),f(o),U(()=>{s=y(o,0,`fluent-icon ${r()}`,`svelte-1xukml3`,s,{spinning:a()}),S(o,`width`,i()),S(o,`height`,i()),S(o,`data-icon`,t.name)}),g(e,o),W()}var Ve=ee(``);function He(e,t){let n=Y(t,`side`,3,`left`);var r=Ve(),i=X(R(r));f(r),U(()=>S(i,`d`,n()===`left`?`M9 4v16`:`M15 4v16`)),g(e,r)}var Ue={subspace:[],manifolds:[],manifold_builder:[`fitting`,`manifold_artifacts`],surface_geometry:[],manifold_merge:[`manifold_artifacts`],manifold_pack:[`manifold_artifacts`],save_conversation:[],download_chat:[],load_conversation:[],compare:[],system_prompt:[],token_drilldown:[],correlation:[],probe_inspector:[],advanced_sampling:[],health:[],appearance:[],session_admin:[`session_admin`],local_runtime:[],help:[],node_compare:[],transcript:[],template_lab:[`manifold_artifacts`,`fitting`],cast:[]};function We(e){return Ge(e,he())}function Ge(e,t){if(!t)return{available:!0,reason:null};let n=t.operations[e];return{available:n.available,reason:n.available?null:n.reasons[0]?je(n.reasons[0],`This action is unavailable in the current browser or model session.`):`This action is unavailable in the current browser or model session.`}}function Ke(e,t=he()){for(let n of Ue[e]){let e=Ge(n,t);if(!e.available)return e}return{available:!0,reason:null}}var qe=V({entries:[]}),Je=0;function Z(e,t={}){let n=++Je,r=t.kind??`info`;return qe.entries=[...qe.entries,{id:n,kind:r,message:e,detail:t.detail??null,ttlMs:t.ttlMs===void 0?r===`error`?null:6e3:t.ttlMs}],n}function Ye(e,t){qe.entries=qe.entries.map(n=>n.id===e?{...n,...t}:n)}function Xe(e){qe.entries=qe.entries.filter(t=>t.id!==e)}var Ze=V({open:null,params:null}),Qe=null,$e=V({docked:!1,visible:!1,params:null});function et(e){Ze.open===`token_drilldown`&&($e.params=e??Ze.params,it()),$e.docked=!0,$e.visible=!0}function tt(){$e.visible=!1,document.getElementById(`workspace-token-sidebar`)?.contains(document.activeElement)&&document.querySelector(`[aria-controls="workspace-token-sidebar"]`)?.focus({preventScroll:!0})}function nt(e){tt(),$e.docked=!1,rt(`token_drilldown`,e)}function rt(e,t=null){let n=Ke(e);if(!n.available){Z(n.reason??`This tool is unavailable.`,{kind:`warning`});return}if(e===`token_drilldown`&&$e.docked){$e.params=t,$e.visible=!0;return}Ze.open===null&&typeof document<`u`&&document.activeElement instanceof HTMLElement&&(Qe=document.activeElement),Ze.open=e,Ze.params=t}function it(){let e=Qe;Qe=null,Ze.open=null,Ze.params=null,queueMicrotask(()=>{e?.isConnected&&e.focus()})}var at=e=>e;function ot(e){let t=e-1;return t*t*t+1}function st(e){let t=typeof e==`string`&&e.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);return t?[parseFloat(t[1]),t[2]||`px`]:[e,`px`]}function ct(e,{delay:t=0,duration:n=400,easing:r=at}={}){let i=+getComputedStyle(e).opacity;return{delay:t,duration:n,easing:r,css:e=>`opacity: ${e*i}`}}function lt(e,{delay:t=0,duration:n=400,easing:r=ot,x:i=0,y:a=0,opacity:o=0}={}){let s=getComputedStyle(e),c=+s.opacity,l=s.transform===`none`?``:s.transform,u=c*(1-o),[d,f]=st(i),[p,m]=st(a);return{delay:t,duration:n,easing:r,css:(e,t)=>` - transform: ${l} translate(${(1-e)*d}${f}, ${(1-e)*p}${m}); - opacity: ${c-u*t}`}}function ut(e,{delay:t=0,duration:n=400,easing:r=ot,axis:i=`y`}={}){let a=getComputedStyle(e),o=+a.opacity,s=i===`y`?`height`:`width`,c=parseFloat(a[s]),l=i===`y`?[`top`,`bottom`]:[`left`,`right`],u=l.map(e=>`${e[0].toUpperCase()}${e.slice(1)}`),d=parseFloat(a[`padding${u[0]}`]),f=parseFloat(a[`padding${u[1]}`]),p=parseFloat(a[`margin${u[0]}`]),m=parseFloat(a[`margin${u[1]}`]),h=parseFloat(a[`border${u[0]}Width`]),g=parseFloat(a[`border${u[1]}Width`]);return{delay:t,duration:n,easing:r,css:e=>`overflow: hidden;opacity: ${Math.min(e*20,1)*o};${s}: ${e*c}px;padding-${l[0]}: ${e*d}px;padding-${l[1]}: ${e*f}px;margin-${l[0]}: ${e*p}px;margin-${l[1]}: ${e*m}px;border-${l[0]}-width: ${e*h}px;border-${l[1]}-width: ${e*g}px;min-${s}: 0`}}var dt=I(``);function ft(e,t){let n=Y(t,`label`,3,`Close drawer`);var r=dt();Be(R(r),{name:`dismiss`}),f(r),U(()=>S(r,`aria-label`,n())),K(`click`,r,function(...e){t.onclick?.apply(this,e)}),g(e,r)}H([`click`]);var pt=[`forEach`,`isDisjointFrom`,`isSubsetOf`,`isSupersetOf`],mt=[`difference`,`intersection`,`symmetricDifference`,`union`],ht=!1,gt=class e extends Set{#e=new Map;#t=J(0);#n=J(0);#r=ie||-1;constructor(e){if(super(),e){for(var t of e)super.add(t);this.#n.v=super.size}ht||this.#a()}#i(e){return ie===this.#r?J(e):o(e)}#a(){ht=!0;var t=e.prototype,n=Set.prototype;for(let e of pt)t[e]=function(...t){return B(this.#t),n[e].apply(this,t)};for(let r of mt)t[r]=function(...t){return B(this.#t),new e(n[r].apply(this,t))}}has(e){var t=super.has(e),n=this.#e,r=n.get(e);if(r===void 0){if(!t)return B(this.#t),!1;r=this.#i(!0),n.set(e,r)}return B(r),t}add(e){return super.has(e)||(super.add(e),A(this.#n,super.size),Ne(this.#t)),this}delete(e){var t=super.delete(e),n=this.#e,r=n.get(e);return r!==void 0&&(n.delete(e),A(r,!1)),t&&(A(this.#n,super.size),Ne(this.#t)),t}clear(){if(super.size!==0){super.clear();var e=this.#e;for(var t of e.values())A(t,!1);e.clear(),A(this.#n,0),Ne(this.#t)}}keys(){return this.values()}values(){return B(this.#t),super.values()}entries(){return B(this.#t),super.entries()}[Symbol.iterator](){return this.keys()}get size(){return B(this.#n)}},_t=class extends Map{#e=new Map;#t=J(0);#n=J(0);#r=ie||-1;constructor(e){if(super(),e){for(var[t,n]of e)super.set(t,n);this.#n.v=super.size}}#i(e){return ie===this.#r?J(e):o(e)}has(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else return B(this.#t),!1;return B(n),!0}forEach(e,t){this.#a(),super.forEach(e,t)}get(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else{B(this.#t);return}return B(n),super.get(e)}set(e,t){var n=this.#e,r=n.get(e),i=super.get(e),a=super.set(e,t),o=this.#t;if(r===void 0)r=this.#i(0),n.set(e,r),A(this.#n,super.size),Ne(o);else if(i!==t){Ne(r);var s=o.reactions===null?null:new Set(o.reactions);(s===null||!r.reactions?.every(e=>s.has(e)))&&Ne(o)}return a}delete(e){var t=this.#e,n=t.get(e),r=super.delete(e);return n!==void 0&&(t.delete(e),A(n,-1)),r&&(A(this.#n,super.size),Ne(this.#t)),r}clear(){if(super.size!==0){super.clear();var e=this.#e;A(this.#n,0);for(var t of e.values())A(t,-1);Ne(this.#t),e.clear()}}#a(){B(this.#t);var e=this.#e;if(this.#n.v!==e.size){for(var t of super.keys())if(!e.has(t)){var n=this.#i(0);e.set(t,n)}}for([,n]of this.#e)B(n)}keys(){return B(this.#t),super.keys()}values(){return this.#a(),super.values()}entries(){return this.#a(),super.entries()}[Symbol.iterator](){return this.entries()}get size(){return B(this.#n),super.size}},vt=class{#e;#t;constructor(e,t){this.#e=e,this.#t=C(t)}get current(){return this.#t(),this.#e()}},yt=/\(.+\)/,bt=new Set([`all`,`print`,`screen`,`and`,`or`,`not`,`only`]),xt=class extends vt{constructor(e,t){let n=yt.test(e)||e.split(/[\s,]+/).some(e=>bt.has(e.trim()))?e:`(${e})`,r=window.matchMedia(n);super(()=>r.matches,e=>Te(r,`change`,e))}},St=ke(),Ct=St.sessions,wt=St.profiles,Tt=St.probes,Et=St.manifolds,Dt=St.templates,Ot=St.tree,kt=St.instruments;function At(e,t,n,r){return St.manifolds.fit(e,t,n,r)}function jt(e,t){return St.manifolds.install(e,t)}function Mt(e,t){return St.manifolds.generate(e,t)}var Nt=96,Pt=96,Ft=new Map,It=[],Lt={geometry:0,lens:0,sae:0},Rt=null;function zt(e,t,n,r,i,a=`interactive`){let o=Jt(e,t,n,r),s=Ft.get(o);if(s)Yt(o,s),s.state===`queued`&&a===`interactive`&&Ut(s);else{if(It.length>=Pt)return Promise.reject(Error(`The token reading queue is full. Wait for a reading to finish, then select this token again.`));let i,c,l=new Promise((e,t)=>{i=e,c=t});s={key:o,family:e,nodeId:t,rawIndex:n,options:{...r},priority:a,promise:l,resolve:i,reject:c,progress:null,listeners:new Set,state:`queued`,invalidated:!1},Ft.set(o,s),Ht(s)}if(i&&(s.listeners.add(i),s.progress&&i(s.progress)),Wt(),Kt(),!i)return s.promise;let c=s;return s.promise.finally(()=>c.listeners.delete(i))}function Bt(e){return Lt[e]}function Vt(e){let t=e?[e]:[`geometry`,`lens`,`sae`];for(let e of t)Lt[e]+=1;for(let[e,n]of Ft)t.includes(n.family)&&(Ft.delete(e),n.invalidated=!0,n.state!==`settled`&&(n.reject(Error(`The conversation or reading source changed. Select the token again to get a current reading.`)),n.listeners.clear()));for(let e=It.length-1;e>=0;--e)It[e].invalidated&&It.splice(e,1);Kt()}function Ht(e){e.priority===`interactive`?It.unshift(e):It.push(e)}function Ut(e){e.priority=`interactive`;let t=It.indexOf(e);t<=0||(It.splice(t,1),It.unshift(e))}function Wt(){if(Rt||It.length===0)return;let e=It.shift();Rt=e,e.state=`active`,Gt(e)}async function Gt(e){try{let t=await kt.tokenReadout(e.family,e.nodeId,e.rawIndex,e.options,void 0,t=>qt(e,t));if(e.invalidated)return;let n=t.measurements.instruments[e.family];if(!n||e.family!==`geometry`&&(!(`readout`in n)||!n.readout))throw Error(`No reading was returned for this token. Check the active reading source and try again.`);e.state=`settled`,Ft.get(e.key)===e&&Yt(e.key,e),e.resolve(t)}catch(t){Ft.get(e.key)===e&&Ft.delete(e.key),e.reject(t)}finally{e.listeners.clear(),Rt===e&&(Rt=null),Xt(),Wt(),Kt()}}function Kt(){let e=Rt===null?0:1;for(let t=0;tsetTimeout(e,r))}}catch(e){o.error=$t(e)}finally{o.polling=!1}}}return{state:o,async start(r={}){if(!(o.running||o.polling)){try{s(await kt.startPreparation(e,{operation:t,...r}))}catch(e){o.running=!1,o.error=$t(e),Z(`${n}: ${o.error}`,{kind:`error`});return}l()}},async cancel(){if(!(!o.running||o.cancelling)){o.cancelling=!0;try{s(await kt.cancelPreparation(e)),Z(`${n} cancelling…`,{kind:`info`})}catch(e){o.cancelling=!1,Z(`${n} cancel: ${$t(e)}`,{kind:`error`})}}},async check(){if(!o.polling)try{let n=await kt.preparationStatus(e);if(n.operation!==t)return;s(n),n.state===`running`&&l()}catch{}}}}var tn=8192,nn=1024;function rn(e){return e===`apple-mobile-webkit`?256:e===`desktop-webkit`||e===`desktop-gecko`?nn:tn}function an(e){return e?.appleMobile===!0?256:rn(e?.runtimeClass)}function on(e,t){return Math.min(e,t)}function sn(e){return e===`http`?256:e===`browser`?5:0}function cn(e){return e===`http`?8:e===`browser`?5:0}function ln(e,t){return Math.max(0,Math.min(sn(t),Math.floor(e)))}var un=.5,dn=`__surprise__`,fn=`__entropy__`;function pn(e){let t=/^(.+)\[(\d+)\]$/.exec(e);return t?{base:t[1],axis:Number(t[2])}:{base:e,axis:0}}function mn(e,t){let{base:n,axis:r}=pn(t),i=e.coordsByProbe?.[n];if(i&&r1e-6?t:un)));if(r===0)return`transparent`;let i=(Math.abs(r)*Sn*100).toFixed(1);return`color-mix(in srgb, ${n===`surprise`?bn:n===`sae`?xn:r>0?vn:yn} ${i}%, transparent)`}function wn(e){return e===`__surprise__`||e===`__probability__`||e===`__entropy__`||e?.startsWith(`jlens/`)?`surprise`:e?.startsWith(`sae/`)?`sae`:`signed`}function Tn(e,t=0){if(!e||e.length===0)return 1;let n=0;for(let r of e){let e=r?.[t];if(typeof e==`number`&&Number.isFinite(e)){let t=Math.abs(e);t>n&&(n=t)}}return n>1e-6?n:1}function En(e,t,n=un,r=un,i=`signed`,a=`signed`){let o=Cn(e,n,i),s=Cn(t,r,a);return{backgroundImage:`linear-gradient(to bottom, ${o} 0%, ${o} 50%, ${s} 50%, ${s} 100%)`}}function Dn(e,t,n=un,r=un,i=`signed`,a=`signed`){return{backgroundImage:`linear-gradient(to bottom, ${Cn(e,n,i)}, ${Cn(t,r,a)})`}}function On(e,t=null,n=!1,r=un,i=un,a=`signed`,o=`signed`){if(t==null){let t=Cn(e,r,a);return t===`transparent`?{}:{backgroundColor:t}}return n?Dn(e,t,r,i,a,o):En(e,t,r,i,a,o)}var kn={BOTH:null,BEFORE:`before`,AFTER:`after`,THINKING:`thinking`,RESPONSE:`response`,PROMPT:`before`,GENERATED:`response`};function An(e,t=1){let n=[];for(let[r,i]of e)i.enabled&&i.mode===`subspace`&&n.push(jn(r,i,t));for(let[t,r]of e)r.enabled&&r.mode===`jlens`&&n.push(Fn(t,r));for(let[t,r]of e)r.enabled&&r.mode===`sae`&&n.push(In(t,r));for(let[t,r]of e)r.enabled&&r.mode===`manifold`&&n.push(Ln(t,r));if(n.length===0)return``;let r=n[0];for(let e=1;eNn(e)).join(`,`),i=`${Mn(e,t.variant)}%${r}`;return`${Nn(n)} ${i}${Pn(t.trigger)}`}function Mn(e,t){return t===`raw`?e:`${e}:${t}`}function Nn(e){return Number.isNaN(e)||!Number.isFinite(e)?`0`:String(e)}function Pn(e){let t=kn[e];return t?`@${t}`:``}function Fn(e,t){return`${Nn(t.alpha)} ${t.ablate?`!`:``}${e}${Pn(t.trigger)}`}function In(e,t){return`${Nn(t.alpha)} ${t.ablate?`!`:``}${e}${Pn(t.trigger)}`}function Ln(e,t){let n=t.label?t.label:t.coords.map(e=>Nn(e)).join(`,`),r=`${Mn(e,t.variant)}%${n}`;return`${(t.onto??0)>0?`${Nn(t.blend)},${Nn(t.onto)}`:Nn(t.blend)} ${r}${Pn(t.trigger)}`}var Rn=V({entries:[],index:null,stash:``,pulledSlot:null}),zn=V({rev:0,text:``});function Bn(e){zn.text=e,zn.rev+=1}function Vn(e){let t=e.trim();if(!t)return;let n=Rn.entries;if((n.length>0?n[n.length-1]:null)!==t){let e=[...n,t];Rn.entries=e.length>200?e.slice(e.length-200):e}Rn.index=null,Rn.stash=``,Rn.pulledSlot=null}function Hn(e,t){let n=Rn.entries,r=qn.queue,i=r.filter(e=>e.rebuild!==null),a=i.length,o=n.length;if(a===0&&o===0)return null;let s=Un(i),c;if(s<0){if(e>0)return null;Rn.stash=t,c=0}else if(c=s+(e<0?1:-1),c>=a+o)c=a+o-1;else if(c<0){Rn.pulledSlot=null,Rn.index=null;let e=Rn.stash;return Rn.stash=``,e}if(c=0?t:null,Rn.index=null,e.text}return Rn.pulledSlot=null,Rn.index=o-1-(c-a),n[Rn.index]}function Un(e){let t=e.length;if(Rn.pulledSlot!==null){let n=qn.queue[Rn.pulledSlot];if(n!==void 0){let r=e.indexOf(n);if(r>=0)return t-1-r}}if(Rn.index!==null){let e=Rn.entries.length;if(Rn.index>=0&&Rn.index=0&&rt.id!==e)}var $n=`rack`;function er(e,t){if(!($.active||qn.queue.length>0)){t();return}let n=qn.queue,r=n[n.length-1];if(r&&r.coalesceKey===$n){let i=r.apply;n[n.length-1]={...r,label:e,apply:async()=>{await i(),await t()}};return}Xn({label:e,text:null,apply:t,awaitsGen:!1,rebuild:null,coalesceKey:$n})}function tr(){return $.active||qn.queue.length>0}var nr=V({entries:new _t,customExpression:null,subspaceAlong:.5,profiles:new _t,correlation:null,catalog:[],loading:!1,error:null}),rr=V({names:[]}),ir=0;function ar(){ir+=1,nr.correlation=null}async function or(){let e=await wt.list();rr.names=e.profiles.map(e=>e.name),nr.profiles.clear();for(let t of e.profiles)nr.profiles.set(t.name,t)}async function sr(e){let t=ir;try{let n=await wt.correlation(e);t===ir&&(nr.correlation=n)}catch{t===ir&&(nr.correlation=null)}}function cr(e=[],t=null,n=`raw`){return{mode:`subspace`,ablate:!1,coords:e,label:t,variant:n,trigger:`BOTH`,enabled:!0}}function lr(e,t){let n=nr.entries.get(e);n&&n.mode===`subspace`&&nr.entries.set(e,t(n))}function ur(e){er(`subspace along ${e.toFixed(3)}`,()=>{nr.subspaceAlong=e})}function dr(e,t){er(`subspace coords ${e}`,()=>{lr(e,e=>({...e,coords:[...t],label:null}))})}function fr(e,t){er(`subspace label ${e} ${t??``}`,()=>{if(t===null){lr(e,e=>({...e,label:null}));return}let n=br(e);lr(e,e=>{if(!n)return{...e,label:t};let r=n.node_labels.indexOf(t),i=r>=0&&n.node_coords[r]?[...n.node_coords[r]]:e.coords;return{...e,label:t,coords:i}})})}function pr(e,t){er(`subspace trigger ${e} ${t}`,()=>{lr(e,e=>({...e,trigger:t}))})}function mr(e,t){er(`${t?`enable`:`disable`} ${e}`,()=>{lr(e,e=>({...e,enabled:t}))})}function hr(e,t){er(`${t?`ablate`:`push`} ${e}`,()=>{lr(e,e=>({...e,ablate:t}))})}function gr(e,t=`raw`){if(nr.entries.has(e))return;nr.customExpression=null;let n=br(e),r=[],i=null;n&&n.node_count===2&&n.node_labels.length>0?(i=n.node_labels[0],r=n.node_coords?.[0]?[...n.node_coords[0]]:[]):n?r=xr(n):i=(e.includes(`/`)?e.slice(e.indexOf(`/`)+1):e).split(`.`)[0],nr.entries.set(e,cr(r,i,t))}function _r(e){nr.entries.delete(e)}function vr(){return nr.customExpression??An(nr.entries,nr.subspaceAlong)}async function yr(){nr.loading=!0;try{nr.catalog=(await Et.list()).manifolds,nr.error=null}catch(e){nr.catalog=[],nr.error=je(e,`Saved directions could not be refreshed.`)}finally{nr.loading=!1}}function br(e){for(let t of nr.catalog)if(`${t.namespace}/${t.name}`===e||t.name===e)return t;return null}function xr(e){return e.domain.type===`box`?e.domain.axes.map(e=>(e.lo+e.hi)/2):Array(e.intrinsic_dim).fill(0)}function Sr(e,t){let n=nr.entries.get(e);n&&n.mode===`manifold`&&nr.entries.set(e,t(n))}function Cr(e,t=`raw`){if(nr.entries.has(e))return;nr.customExpression=null;let n=br(e),r=n?xr(n):[];nr.entries.set(e,{mode:`manifold`,blend:.5,onto:0,coords:r,label:null,variant:t,trigger:`BOTH`,enabled:!0})}function wr(e){nr.entries.delete(e)}var Tr=.3,Er={jlens:`jlens/`,sae:`sae/`};function Dr(e,t){let n=(t,n)=>{let r=nr.entries.get(t);r&&r.mode===e&&nr.entries.set(t,n(r))};return{remove(e){nr.entries.delete(e)},setAlpha(e,r){er(`${t} alpha ${e} ${r.toFixed(3)}`,()=>{n(e,e=>({...e,alpha:r}))})},setAblate(e,t){er(`${t?`ablate`:`push`} ${e}`,()=>{n(e,e=>({...e,ablate:t}))})},setEnabled(e,t){er(`${t?`enable`:`disable`} ${e}`,()=>{n(e,e=>({...e,enabled:t}))})},setTrigger(e,r){er(`${t} trigger ${e} ${r}`,()=>{n(e,e=>({...e,trigger:r}))})}}}var Or={jlens:Dr(`jlens`,`jlens`),sae:Dr(`sae`,`SAE`)};function kr(e){return Or[e]}function Ar(e,t){let n=`${Er[e]}${t}`;nr.entries.has(n)||(nr.customExpression=null,nr.entries.set(n,{mode:e,ablate:!1,alpha:Tr,trigger:`BOTH`,enabled:!0}))}function jr(e){let t=e.trim().replace(/^jlens\//,``);t&&Ar(`jlens`,t)}function Mr(e){Ar(`sae`,String(e))}function Nr(e,t){er(`manifold blend ${e} ${t.toFixed(3)}`,()=>{Sr(e,e=>({...e,blend:t}))})}function Pr(e,t){er(`manifold onto ${e} ${t.toFixed(3)}`,()=>{Sr(e,e=>({...e,onto:t}))})}function Fr(e,t){er(`manifold coords ${e}`,()=>{Sr(e,e=>({...e,coords:[...t],label:null}))})}function Ir(e,t){er(`manifold label ${e} ${t??``}`,()=>{if(t===null){Sr(e,e=>({...e,label:null}));return}let n=br(e);Sr(e,e=>{if(!n)return{...e,label:t};let r=n.node_labels.indexOf(t),i=r>=0&&n.node_coords[r]?[...n.node_coords[r]]:e.coords;return{...e,label:t,coords:i}})})}function Lr(e,t){er(`manifold trigger ${e} ${t}`,()=>{Sr(e,e=>({...e,trigger:t}))})}function Rr(e,t){er(`manifold ${t?`enable`:`disable`} ${e}`,()=>{Sr(e,e=>({...e,enabled:t}))})}function zr(e,t){let n=e=>{let n=t[e];return typeof n==`number`&&Number.isFinite(n)?n:null},r=[],i=e.family===`geometry`?n(`${e.name}:fraction`):null;if(e.family===`geometry`)for(let t=0;t0?t.coords[0]:0}function Wr(e,t){if(Zt(t))return t.per_layer??{};if(e.family===`geometry`&&!e.is_affine)return t.fraction_per_layer??{};let n={};for(let[e,r]of Object.entries(t.coords_per_layer??{}))n[e]=Array.isArray(r)&&r.length>0?r[0]:0;return n}function Gr(e){let t=Hr.entries.get(e);if(!t||!Hi.active)return t;let n=Hi.probeReadings?.[e]??null;if(!n){let r=Hi.probes?.[e],i=null,a=Hi.coordsByProbe?.[e];r===void 0&&a?.[0]!==void 0&&(r=a[0]);let o={};for(let[t,n]of Object.entries(Hi.perLayerScores??{})){let r=n[e];typeof r==`number`&&Number.isFinite(r)&&(o[t]=r)}if(r===void 0&&t.info.family===`lens`){let e=t.info.word,n=Hi.lensAggregate?.find(([t])=>t===e);if(n){r=n[1];for(let[t,n]of Object.entries(Hi.lensReadout??{})){let r=n.find(([t])=>t===e);r&&(o[t]=r[1])}}}if(r===void 0&&t.info.family===`sae`){let e=Hi.saeReadout?.find(e=>e.id===t.info.feature_id);if(e){let n=e.max_act;r=n!=null&&n>0?e.activation/n:e.activation,i=n!=null&&n>0?`activation_over_max`:`raw_activation`;let a=t.info.layers[0];a!==void 0&&(o[String(a)]=r)}}if(r!==void 0){let e=r;if(t.info.family!==`geometry`)return{...t,current:e,sparkline:[e],perLayer:o,reading:{value:e,unit:i??(t.info.family===`lens`?`mean_token_probability`:t.info.max_act==null?`raw_activation`:`activation_over_max`),per_layer:o,depth:null},aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null};let s=t.info.is_affine,c=s?a??[e]:[],l=Object.fromEntries(Object.entries(o).map(([e,t])=>[e,[t]]));n={fraction:s?0:e,nearest:[],coords:c,residual:0,fraction_per_layer:s?{}:o,coords_per_layer:s?l:{},residual_per_layer:{}}}}if(!n)return{...t,current:0,previous:0,sparkline:[],perLayer:{},reading:null,aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:[],trajectory:[]};let r=Ur(t.info,n);return{...t,current:r,previous:r,sparkline:[r],perLayer:Wr(t.info,n),reading:n,aggregate:n,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:Kr(n),trajectory:[]}}function Kr(e){return Zt(e)?[]:e.nearest}function qr(e){return e.family!==`geometry`||e.intrinsic_dim!==2?!1:e.domain?.type===`box`&&!!e.node_coords&&e.node_coords.length>0}function Jr(e,t){let n=e.node_coords;if(!n)return null;let r=e.node_labels.indexOf(t);if(r<0||r>=n.length)return null;let i=n[r];return Array.isArray(i)?[...i]:null}function Yr(e){return e.family===`geometry`?{selector:e.manifold,name:e.name,top_n:e.top_n}:e.family===`lens`?{selector:`jlens/${e.word}`,name:e.name}:{selector:`sae/${e.feature_id}`,name:e.name}}function Xr(e,t=Yr(e)){return{request:t,info:e,sparkline:[],current:0,previous:0,perLayer:{},reading:null,aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:[],trajectory:[],subspaceTrail:[]}}function Zr(e,t=0){let n=Hr.entries.get(e)?.info;return!n||n.family!==`geometry`?1:Tn(n.node_coords,t)}function Qr(){let e=0;for(let t of Hr.active){let n=Gr(t);if(!n||n.info.family!==`sae`)continue;let r=n.aggregate??n.reading;r&&Zt(r)&&r.unit===`activation_over_max`||(e=Math.max(e,n.current??0))}for(let t of ta()){let n=Hi.active?void 0:Vi.meta.get(t.id);t.max_act??n?.max_act??(e=Math.max(e,t.activation))}return Math.max(e,1)}function $r(e){if(!e||e===`__surprise__`||e===`__probability__`||e===`__entropy__`)return un;let{base:t,axis:n}=pn(e),r=Gr(t);if(r?.info.family===`lens`||e.startsWith(`jlens/`))return 1;if(r?.info.family===`sae`){let e=r.aggregate??r.reading;return e&&Zt(e)&&e.unit===`activation_over_max`?1:Qr()}return Zr(t,n)}function ei(){let e=[...Hr.active];return Hr.sortMode===`name`?e.sort():Hr.sortMode===`value`?e.sort((e,t)=>{let n=Hr.entries.get(e)?.current??0;return(Hr.entries.get(t)?.current??0)-n}):Hr.sortMode===`change`&&e.sort((e,t)=>{let n=Hr.entries.get(e),r=Hr.entries.get(t),i=Math.abs((n?.current??0)-(n?.previous??0));return Math.abs((r?.current??0)-(r?.previous??0))-i}),e}var ti=0,ni=0;async function ri(){let e=++ti,t=ni;Hr.loading=!0;try{let n=await Tt.list();if(e!==ti||t!==ni)return;let r=new Set,i=new Set;for(let e of n.probes){r.add(e.name);let t=Hr.entries.get(e.name);JSON.stringify(t?.info)!==JSON.stringify(e)&&(i.add(e.family),t&&i.add(t.info.family)),t?Hr.entries.set(e.name,{...t,info:e}):Hr.entries.set(e.name,Xr(e))}for(let e of[...Hr.entries.keys()])r.has(e)||(i.add(Hr.entries.get(e).info.family),Hr.entries.delete(e));Hr.active=n.probes.map(e=>e.name);for(let e of i)Vt(e);i.size>0&&(ar(),di()),Hr.error=null}catch(n){if(e!==ti||t!==ni)return;Hr.error=je(n,`Live readings could not be refreshed.`)}finally{e===ti&&(Hr.loading=!1)}}async function ii(e,t={}){let n={selector:e,name:t.name,top_n:t.top_n},r=await Tt.attach(n);ni+=1,Hr.error=null;let i={selector:e,name:r.name,...r.family===`geometry`?{top_n:t.top_n??r.top_n}:{}},a=Hr.entries.get(r.name);return a?Hr.entries.set(r.name,{...a,request:i,info:r}):Hr.entries.set(r.name,Xr(r,i)),Hr.active.includes(r.name)||(Hr.active=[...Hr.active,r.name]),Vt(r.family),a&&a.info.family!==r.family&&Vt(a.info.family),ar(),fi.target===null&&(fi.target=r.name),r}async function ai(e){let t=Hr.entries.get(e)?.info.family;await Tt.detach(e),ni+=1,Hr.error=null,Hr.entries.delete(e),Hr.active=Hr.active.filter(t=>t!==e),ar(),fi.target===e&&(fi.target=null),fi.compareTarget===e&&(fi.compareTarget=null),t&&Vt(t)}function oi(e){Hr.sortMode=e}function si(){for(let[e,t]of Hr.entries)Hr.entries.set(e,{...t,nearest:[],aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null,trajectory:[],subspaceTrail:[]})}function ci(e){if(e)for(let[t,n]of Object.entries(e)){let e=Hr.entries.get(t);if(!e)continue;let r=Ur(e.info,n),i=e.sparkline.slice();i.push(r),i.length>60&&i.splice(0,i.length-60);let a=e.trajectory,o=Kr(n);if(qr(e.info)&&o.length>0){let t=Jr(e.info,o[0][0]);t&&(a=e.trajectory.slice(),a.push(t),a.length>Br&&a.splice(0,a.length-Br))}let s=e.subspaceTrail,c=Zt(n)?void 0:n.subspace_coords_per_layer;c&&Object.keys(c).length>0&&(s=e.subspaceTrail.slice(),s.push({perLayer:c}),s.length>Vr&&s.splice(0,s.length-Vr)),Hr.entries.set(t,{...e,sparkline:i,current:r,previous:e.current,perLayer:Wr(e.info,n),reading:n,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:o,trajectory:a,subspaceTrail:s})}}function li(e){if(e)for(let[t,n]of Object.entries(e)){let e=Hr.entries.get(t);e&&Hr.entries.set(t,{...e,aggregate:n,savedAggregate:null,savedCoordinates:[],savedFraction:null,current:Ur(e.info,n),perLayer:Wr(e.info,n),nearest:Kr(n)})}}function ui(){for(let[e,t]of Hr.entries)Hr.entries.set(e,{...t,previous:t.current})}function di(){if(!Q.loaded||$.active)return;let e=(Q.active_node_id?Q.nodes.get(Q.active_node_id):void 0)?.aggregate_readings??{};for(let[t,n]of Hr.entries){let{value:r,coordinates:i,fraction:a}=zr(n.info,e);Hr.entries.set(t,{...n,current:r??0,previous:n.current,perLayer:{},reading:null,aggregate:null,savedAggregate:r,savedCoordinates:i,savedFraction:a,nearest:[],trajectory:[],subspaceTrail:[]})}}var fi=V({target:dn,compareTarget:null,compareTwo:!1,smoothBlend:!1});function pi(e){fi.target=e}function mi(e){fi.compareTarget=e}function hi(){fi.compareTwo=!fi.compareTwo}function gi(e){fi.compareTwo=e}var _i=V({info:null,lastRefresh:null,error:null});function vi(e){return _i.info?.instruments?.find(t=>t.family===e)}function yi(){return vi(`sae`)?.source!=null}async function bi(){try{_i.info=await Ct.get(),_i.lastRefresh=Date.now(),_i.error=null,Ei(),ba()}catch(e){_i.error=je(e,`The model details could not be refreshed.`)}}var xi=V({temperature:null,top_p:null,top_k:null,max_tokens:256,seed:null,system_prompt:``,stop_sequences:``,logit_bias_text:``,presence_penalty:0,frequency_penalty:0,user_role:`user`,assistant_role:`assistant`,thinking:!1,return_top_k:8});function Si(e,t){xi[e]=t}var Ci=null,wi=V({info:null});function Ti(){return an(he()?.signals)}function Ei(){let e=_i.info,t=re()?.snapshot.modelDefaults;e&&t?.model_id===e.model_id?wi.info=structuredClone(x(t)):e&&wi.info?.model_id!==e.model_id&&(wi.info=structuredClone(x(e)));let n=e?`${e.model_id}\0${e.default_user_role??``}\0${e.default_assistant_role??``}`:null;e&&Ci!==n&&(Ci=n,xi.user_role=e.default_user_role??`user`,xi.assistant_role=e.default_assistant_role??`assistant`);let r=e?.config;r&&(typeof r.max_tokens==`number`&&Number.isFinite(r.max_tokens)&&(xi.max_tokens=on(r.max_tokens,Ti())),typeof r.temperature==`number`&&(xi.temperature=r.temperature),typeof r.top_p==`number`&&(xi.top_p=r.top_p),xi.top_k=r.top_k,typeof r.system_prompt==`string`&&(xi.system_prompt=r.system_prompt),typeof r.thinking==`boolean`&&(xi.thinking=r.thinking),xi.return_top_k=ln(xi.return_top_k,ke().mode))}var Di={},Oi=null;function ki(e){let t=e.max_tokens===void 0?e:{...e,max_tokens:on(e.max_tokens,Ti())};return Object.assign(xi,t),Object.assign(Di,t),Oi||=Ai().finally(()=>{Oi=null}),Oi}async function Ai(){for(;Object.keys(Di).length>0;){let e=Di;Di={},_i.info=await Ct.patch(e),_i.lastRefresh=Date.now(),Object.keys(Di).length===0&&Ei()}}function ji(){let e=xi.stop_sequences.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);return e.length>0?e:null}function Mi(){let e=xi.logit_bias_text.trim();if(!e)return null;try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e={};for(let[n,r]of Object.entries(t)){let t=Number(r);Number.isFinite(t)&&(e[String(Number(n))]=t)}return Object.keys(e).length>0?e:null}}catch{}let t={};for(let n of e.split(/\r?\n/)){let e=n.match(/^\s*(-?\d+)\s*[:=,\s]\s*(-?\d+(?:\.\d+)?)\s*$/);e&&(t[String(Number(e[1]))]=Number(e[2]))}return Object.keys(t).length>0?t:null}function Ni(){let e=ji(),t=Mi(),n=ln(xi.return_top_k,ke().mode);return{...e?{stop:e}:{},...t?{logit_bias:t}:{},...xi.presence_penalty===0?{}:{presence_penalty:xi.presence_penalty},...xi.frequency_penalty===0?{}:{frequency_penalty:xi.frequency_penalty},...n>0?{return_top_k:n}:{},...Pi(xi.user_role,_i.info?.default_user_role,`user`,`user_role`),...Pi(xi.assistant_role,_i.info?.default_assistant_role,`assistant`,`assistant_role`)}}function Pi(e,t,n,r){let i=e.trim(),a=t?.trim()||n;return!i||i===a?{}:{[r]:i}}function Fi(){let e={temperature:xi.temperature,top_p:xi.top_p,top_k:xi.top_k,max_tokens:on(xi.max_tokens,Ti()),persist_per_layer_scores:!0,...Hr.active.length>0&&We(`probe_subspace_trails`).available?{persist_subspace_coords:!0}:{},...Ni(),...xi.seed===null?{}:{seed:xi.seed}};return Object.keys(e).length>0?e:null}var Ii=V({layers:null,readout:null,aggregate:null,aggHistory:[],workspaceSortMode:`strength`,busy:!1}),Li=V({sources:[],loading:!1,busy:!1,error:null});async function Ri(){if(!Li.loading){Li.loading=!0;try{Li.sources=(await kt.sources(`lens`)).sources,Li.error=null}catch(e){Li.error=je(e,`Word-likelihood sources could not be refreshed.`)}finally{Li.loading=!1}}}async function zi(e){if(!(Li.busy||!e)){Li.busy=!0,Li.error=null;try{if(vi(`lens`)?.capabilities.source_switch===!0)Ii.layers=(await kt.setLensSource(e)).live_layers;else{let t=await kt.activateInstalledPack(`lens`,{source:e});Ii.layers=t.live.enabled&&`layers`in t.live?t.live.layers??[]:null}Vt(`lens`),await bi(),await Ri(),Z(`J-lens · ${e}`,{kind:`info`})}catch(e){Li.error=je(e,`Word insights could not start. Close and reopen the model after changing its tools.`),Z(`J-lens source: ${Li.error}`,{kind:`error`})}finally{Li.busy=!1}}}function Bi(e){Ii.workspaceSortMode=e}var Vi=V({live:!1,readout:[],history:new _t,meta:new _t,release:null,layer:null,sortMode:`strength`,busy:!1}),Hi=V({active:!1,key:null,tokenText:``,probeReadings:null,probes:null,coordsByProbe:null,perLayerScores:null,lensReadout:null,lensAggregate:null,saeReadout:null,lensLoading:!1,saeLoading:!1,lensError:null,saeError:null}),Ui=140,Wi=null,Gi=null;function Ki(e,t,n){return`${_i.info?.model_id??`unknown-model`}:${e}:${t}:${+!!n}`}function qi(e){return e?{readout:Object.fromEntries(e.layers.map(e=>[String(e.layer),e.tokens.map(e=>[e.token,Math.exp(e.logprob)])])),aggregate:e.aggregate.map(e=>[e.token,e.strength,e.com,e.spread])}:null}function Ji(e){if(!e)return;let t=e.instruments.geometry?.readings,n=e.instruments.lens?.readings,r=e.instruments.sae?.readings;if(!(!t&&!n&&!r))return{...t??{},...n??{},...r??{}}}function Yi(e,t,n){return zt(`lens`,e,t,{topK:Qt(xi.return_top_k),steered:!0,raw:n,layers:`all`},void 0,`background`).then(e=>qi(e.measurements.instruments.lens?.readout))}function Xi(e,t,n){return zt(`sae`,e,t,{topK:Qt(xi.return_top_k),steered:!0,raw:n},void 0,`background`).then(e=>e.measurements.instruments.sae?.readout?.features??[])}function Zi(e,t){Gi!==null&&clearTimeout(Gi),Wi!==null&&clearTimeout(Wi),Gi=null,Wi=null;let n=es(),r=e.rawIndex??null,i=_i.info?.model_id??`unknown-model`,a=t&&r!==null?Ki(t,r,n):`live:${i}:${t??`none`}:${r??`none`}:${e.tokenId??`none`}`,o=e.measurements,s=o?.instruments.lens?.readout,c=o?.instruments.sae?.readout;Hi.active=!0,Hi.key=a,Hi.tokenText=e.text,Hi.probeReadings=Ji(o)??null,Hi.probes=o?.scores??e.probes??null,Hi.coordsByProbe=e.coordsByProbe??null,Hi.perLayerScores=o?.per_layer_scores??e.perLayerScores??null,Hi.lensReadout=null,Hi.lensAggregate=null,Hi.saeReadout=c?.features??null,Hi.lensLoading=!1,Hi.saeLoading=!1,Hi.lensError=null,Hi.saeError=null;let l=qi(s);if(l&&(Hi.lensReadout=l.readout,Hi.lensAggregate=l.aggregate),!t||r===null)return;let u=s===void 0&&_i.info?.jlens_fitted===!0&&vi(`lens`)?.capabilities.token_readout===!0,d=c===void 0&&yi()&&vi(`sae`)?.capabilities.token_readout===!0;Hi.lensLoading=u,Hi.saeLoading=d,!(!u&&!d)&&(Wi=setTimeout(()=>{Wi=null,u&&Yi(t,r,n).then(e=>{!Hi.active||Hi.key!==a||e&&(Hi.lensReadout=e.readout,Hi.lensAggregate=e.aggregate)}).catch(e=>{!Hi.active||Hi.key!==a||(Hi.lensError=je(e,`This token's word-likelihood reading could not be rebuilt. Try again, or close and reopen the model.`))}).finally(()=>{Hi.active&&Hi.key===a&&(Hi.lensLoading=!1)}),d&&Xi(t,r,n).then(e=>{!Hi.active||Hi.key!==a||(Hi.saeReadout=e)}).catch(e=>{!Hi.active||Hi.key!==a||(Hi.saeError=je(e,`This token's feature reading could not be rebuilt. Try again, or close and reopen the model.`))}).finally(()=>{Hi.active&&Hi.key===a&&(Hi.saeLoading=!1)})},Ui))}function Qi(){Wi!==null&&clearTimeout(Wi),Gi!==null&&clearTimeout(Gi),Wi=null,Gi=setTimeout(()=>{Hi.active=!1,Hi.key=null,Hi.tokenText=``,Hi.lensLoading=!1,Hi.saeLoading=!1,Hi.lensError=null,Hi.saeError=null,Gi=null},45)}function $i(){return Hi.active?Hi.lensReadout:Ii.readout}function ea(){return Hi.active?Hi.lensAggregate:Ii.aggregate}function ta(){return Hi.active?Hi.saeReadout??[]:Vi.readout}var na=V({sources:[],loading:!1,busy:!1,error:null});async function ra(){if(!na.loading){na.loading=!0;try{na.sources=(await kt.sources(`sae`)).sources,na.error=null}catch(e){na.error=je(e,`Learned-feature sources could not be refreshed.`)}finally{na.loading=!1}}}function ia(e){Vi.sortMode=e}var aa=new Set,oa=0;function sa(e){Vi.readout=e;for(let t of e){let e=[...Vi.history.get(t.id)??[],t.activation].slice(-60);Vi.history.delete(t.id),Vi.history.set(t.id,e),(t.max_act!=null||t.label!=null)&&Vi.meta.set(t.id,{label:t.label??Vi.meta.get(t.id)?.label??null,max_act:t.max_act??Vi.meta.get(t.id)?.max_act??null})}for(;Vi.history.size>512;){let e=Vi.history.keys().next().value;if(e===void 0)break;Vi.history.delete(e),Vi.meta.delete(e),aa.delete(e)}}async function ca(){if(!yi())return;let e=[];for(let t of Vi.history.keys())if(!(Vi.meta.get(t)?.max_act!=null&&Vi.meta.get(t)?.label?.trim())&&!aa.has(t)&&(e.push(t),e.length>=64))break;if(e.length===0)return;for(let t of e)aa.add(t);let t=oa;try{let n=await kt.saeFeaturesMetadata(e);if(t!==oa)return;for(let[e,t]of Object.entries(n.features))Vi.meta.set(Number(e),{label:t.label??null,max_act:t.max_act??null})}catch{if(t!==oa)return;for(let t of e)aa.delete(t)}}async function la(e){if(!Vi.busy){Vi.busy=!0;try{let t=await kt.setLive(`sae`,{enabled:e});Vi.live=t.enabled,t.enabled||(oa++,Vi.readout=[],Vi.history.clear(),Vi.meta.clear(),aa.clear())}catch(e){Z(`SAE live: `+je(e,`That learned-feature reading is not available.`),{kind:`error`})}finally{Vi.busy=!1}}}var ua=en(`sae`,`fetch`,{label:`SAE fetch`,intervalMs:1e3,successMessage:`SAE loaded`,onSettled:async()=>{await bi(),await ra(),await ri()}});async function da(e,t=null){let n=e.trim();if(n){if(vi(`sae`)?.capabilities.preparations.includes(`fetch`)===!0){await ua.start({release:n,layer:t});return}if(!na.busy){na.busy=!0,na.error=null;try{await kt.activateInstalledPack(`sae`,{source:n,layer:t}),Vt(`sae`),await bi(),await ra(),await ri(),Z(`SAE · ${n}`,{kind:`info`})}catch(e){na.error=je(e,`Model features could not start. Close and reopen the model after changing its tools.`),Z(`SAE source: ${na.error}`,{kind:`error`})}finally{na.busy=!1}}}}var fa=V({enabled:!0,busy:!1});async function pa(e){if(!fa.busy){fa.busy=!0;try{fa.enabled=(await kt.setLive(`geometry`,{enabled:e})).enabled}catch(e){Z(`probe live: `+je(e,`That concept reading is not available.`),{kind:`error`})}finally{fa.busy=!1}}}var ma=V({tab:`subspace`});function ha(e){ma.tab=e}async function ga(e){if(!Ii.busy){Ii.busy=!0;try{let t=await kt.setLive(`lens`,{enabled:e});Ii.layers=t.enabled&&`layers`in t?t.layers??[]:null,t.enabled||(Ii.readout=null,Ii.aggregate=null,Ii.aggHistory=[])}catch(e){Z(`lens live: `+je(e,`Word-likelihood details could not be loaded.`),{kind:`error`})}finally{Ii.busy=!1}}}var _a=en(`lens`,`fetch`,{label:`J-lens fetch`,intervalMs:1e3,successMessage:`J-lens active · live`,onSettled:async()=>{await bi(),await Ri()}}),va=null,ya=null;function ba(){let e=vi(`lens`),t=vi(`sae`),n=vi(`geometry`),r=e?.source??null,i=t===void 0?null:`${t.source??``}:${`layer`in t.live?t.live.layer??``:``}`;r!==va&&Vt(`lens`),i!==ya&&Vt(`sae`),va=r,ya=i,Ii.layers=e?.live.enabled&&`layers`in e.live?e.live.layers:null,Vi.live=t?.live.enabled===!0;let a=t?.source??null,o=t&&`layer`in t.live?t.live.layer:null;(a!==Vi.release||o!==Vi.layer)&&(oa++,Vi.release=a,Vi.layer=o,Vi.readout=[],Vi.history.clear(),Vi.meta.clear(),aa.clear()),fa.enabled=n?.live.enabled!==!1}function xa(e){return e.replace(/\s+/g,` `).trim().toLowerCase()}function Sa(e,t){let n=xa(t);return n.length>0&&xa(e).includes(n)}function Ca(e,t){let n=e.replace(/\s+/g,` `).trim(),r=xa(t),i=r?n.toLowerCase().indexOf(r):-1;if(i<0)return{before:n.slice(0,150),match:``,after:n.length>150?`…`:``};let a=Math.max(0,i-45),o=Math.min(n.length,i+r.length+90);return{before:(a>0?`…`:``)+n.slice(a,i),match:n.slice(i,i+r.length),after:n.slice(i+r.length,o)+(o{Ea.get(n)===r&&Ta.set(n,e.label)}).catch(()=>{}).finally(()=>{Ea.get(n)===r&&Ea.delete(n)})}function ka(e){if(e===void 0){Ta.clear(),Ea.clear();return}for(let t of e)Ta.delete(t),Ea.delete(t)}var Aa=V({mode:`text`,expr:``,matchingIds:null,error:null,loading:!1}),ja=0;function Ma(e){let t=/(?:^|,)\s*sort:(surprise|confidence)\s*(?=,|$)/gi,n=`default`,r=e.replace(t,(e,t)=>(n=t.toLowerCase(),``));return wa.siblingSort=n,r.replace(/,,+/g,`,`).replace(/^\s*,|,\s*$/g,``).trim()}async function Na(e,t=Aa.mode){let n=++ja,r=Q.root_id,i=()=>n===ja&&r===Q.root_id;Aa.expr=e,Aa.mode=t;let a=e.trim();if(!a){Aa.matchingIds=null,Aa.error=null,Aa.loading=!1,wa.siblingSort=`default`;return}let o=[...Q.nodes.values()];if(t===`text`){wa.siblingSort=`default`,Aa.matchingIds=new Set(o.filter(e=>Sa(e.text??``,a)).map(e=>e.id)),Aa.error=null,Aa.loading=!1;return}let s=Ma(a);if(!s){Aa.matchingIds=null,Aa.error=null,Aa.loading=!1;return}let c=s.split(`,`).map(e=>e.trim()).filter(Boolean),l=c.filter(e=>/^text:/i.test(e)).map(e=>e.slice(5).trim()),u=c.some(e=>e.toLowerCase()===`starred`),d=c.filter(e=>!/^text:/i.test(e)&&e.toLowerCase()!==`starred`).join(`,`),f=new Set(o.filter(e=>(!u||e.starred)&&l.every(t=>Sa(e.text??``,t))).map(e=>e.id));Aa.loading=!0,Aa.error=null,Aa.matchingIds=null;try{if(l.some(e=>!e))throw Error(`Enter words after text:.`);let e=d?(await Ot.filter(d)).matching_node_ids:[...f];if(!i())return;Aa.matchingIds=new Set(e.filter(e=>f.has(e)))}catch(e){if(!i())return;e instanceof se?Aa.error=je(e.body&&typeof e.body==`object`&&`detail`in e.body?String(e.body.detail):e.message,`The conversation could not be searched.`):Aa.error=je(e,`The conversation could not be searched.`),Aa.matchingIds=null}finally{i()&&(Aa.loading=!1)}}function Pa(){ja+=1,Aa.expr=``,Aa.matchingIds=null,Aa.error=null,Aa.loading=!1,wa.siblingSort=`default`}var Fa=V({nodeId:null});function Ia(e){Fa.nodeId=e}function La(){Fa.nodeId=null}var Ra=V({ids:[]});function za(e){Ra.ids.indexOf(e)===-1?Ra.ids=[...Ra.ids,e]:Ra.ids=Ra.ids.filter(t=>t!==e)}function Ba(){Ra.ids=[]}function Va(e,t={}){wa.modalRequest={seq:wa.modalRequest.seq+1,kind:e,nodeId:t.nodeId??Q.active_node_id,text:t.text??``,n:t.n??1}}var Ha={channel:null,unsubscribe:null,unsubscribeState:null,listeners:new gt,opening:!1,recoveringGap:!1,treeRecovery:null,ready:null},Ua=null;function Wa(){if(Ha.opening&&Ha.channel&&Ha.ready)return Ha.ready.then(()=>Ha.channel);if(Ha.channel?.isOpen)return Ha.treeRecovery?Ha.treeRecovery.then(()=>Ha.channel):Promise.resolve(Ha.channel);Ha.unsubscribe?.(),Ha.unsubscribeState?.();let e=St.events;Ha.channel=e,Ha.opening=!0;let t=!0,n=null,r=[],i=[],a=!1,o=0,s=0,c=e=>{for(let t of Ha.listeners)try{t(e)}catch{}},l=e=>{if(a){i.push(e),e.type===`tree_mutated`&&(o=Math.max(o,e.rev));return}if(Ja(e)===`tree_resync`&&e.type===`tree_mutated`){d(e.rev);return}c(e)},u=()=>{Ha.channel===e&&(s+=1,a=!1,o=0,i.length=0,Ha.unsubscribe?.(),Ha.unsubscribeState?.(),Ha.unsubscribe=null,Ha.unsubscribeState=null,Ha.channel=null,Ha.opening=!1,Ha.recoveringGap=!1,Ha.treeRecovery=null,Ha.ready=null)},d=t=>{if(o=Math.max(o,t),a||Ha.channel!==e)return;a=!0;let n=++s,r=(async()=>{try{let t=null;for(let r=0;r<3;r+=1){if(t=await Ot.get(),Ha.channel!==e||n!==s)return;if(t.rev>=o)break}if(!t||t.rev{Ha.channel===e&&Ha.treeRecovery===r&&(Ha.treeRecovery=null)})},f=t=>{Ha.channel!==e||Ha.recoveringGap||(Ha.recoveringGap=!0,(async()=>{try{await e.stop();let n=await Ot.get();if(Ha.channel!==e)return;po(n,{preserveLiveTokens:!1}),e.acknowledgeSnapshot(),l({type:`error`,code:t.code,message:`The event stream lost synchronization. Generation was stopped and the authoritative conversation was restored.`})}catch(t){if(Ha.channel!==e)return;let n=je(t,`The conversation could not be restored.`);e.close(),u(),l({type:`error`,code:`TREE_RESYNC_FAILED`,message:`The event stream could not be recovered: ${n}`})}finally{Ha.channel===e&&(Ha.recoveringGap=!1)}})())};Ha.unsubscribe=e.subscribe(e=>{t?r.push(e):e.type===`error`&&e.code===`EVENT_SEQUENCE_GAP`?f(e):l(e)}),Ha.unsubscribeState=e.subscribeState(r=>{if(r.state!==`closed`||r.expected||Ha.channel!==e)return;let i=r.reason??`The Drowse runtime connection closed unexpectedly`,a=je({code:`RUNTIME_CHANNEL_CLOSED`,message:i},`The local model connection closed. Reopen the model and try again.`);if(t){n=i;return}u(),Q.error=a,$.active||Ko.pendingIndex!==null||Q.pendingNodeId!==null||as.processingAb||tr()?l({type:`error`,code:`RUNTIME_CHANNEL_CLOSED`,message:i}):Z(a,{kind:`error`,ttlMs:null})});let p=(async()=>{try{await e.open();let i=await Ot.get();if(n||!e.isOpen)throw Error(n??`The Drowse runtime connection closed during setup`);po(i,{preserveLiveTokens:!1,allowRevisionRegression:!0}),t=!1;for(let e of r)e.type===`tree_mutated`&&e.rev<=i.rev||(e.type===`error`&&e.code===`EVENT_SEQUENCE_GAP`?f(e):l(e));if(r.length=0,Ha.treeRecovery&&await Ha.treeRecovery,Ha.channel!==e||!e.isOpen)throw Error(`The Drowse runtime connection closed during tree recovery`);await Promise.allSettled([bi(),or(),ri(),sr(),yr()])}catch(n){throw t=!1,Q.error=je(n,`The conversation could not reconnect.`),Z(`reconnect: ${Q.error}`,{kind:`error`}),e.close(),Ha.channel===e&&u(),n}finally{Ha.channel===e&&(Ha.opening=!1)}})();return Ha.ready=p,p.then(()=>e)}function Ga(){Ha.unsubscribe?.(),Ha.unsubscribeState?.(),Ha.channel?.close(),Ha.channel=null,Ha.unsubscribe=null,Ha.unsubscribeState=null,Ha.opening=!1,Ha.recoveringGap=!1,Ha.treeRecovery=null,Ha.ready=null}typeof window<`u`&&window.addEventListener(`beforeunload`,Ga);function Ka(){return as.processingAb&&as.pendingTurnIdx!==null?Ko.turns[as.pendingTurnIdx]?.abPair??null:Ko.pendingIndex===null?null:Ko.turns[Ko.pendingIndex]??null}function qa(e){if(!e||as.processingAb||!Q.loaded||Q.pendingNodeId===e&&Q.active_node_id===e&&Ko.pendingIndex!==null&&Ko.turns[Ko.pendingIndex]?.nodeId===e)return;if(Q.pendingNodeId=e,!Q.nodes.has(e)){Q.error=`The conversation lost sync while the reply was arriving. Reload it and try again.`,Z(Q.error,{kind:`error`});return}Q.active_node_id=e,io(),lo();let t=Ko.pendingIndex;if(t!==null){let n=Ko.turns[t];n&&(n.nodeId=e,n.tokens=n.tokens??[],n.thinkingTokens=n.thinkingTokens??[])}}function Ja(e){switch(e.type){case`tree_mutated`:return e.cast&&(ro.roster=e.cast),e.op===`restore`||!ho(e)?`tree_resync`:void 0;case`started`:if($.active=!0,$.replay=null,$.tokensSoFar=0,$.startedAt=performance.now(),Ua=null,$.finishedAt=null,$.tokPerSec=0,$.ppl={logSum:0,count:0,mean:null},$.finishReason=null,Zo.responseTokens=[],Zo.thinkingTokens=[],as.processingAb||si(),e.node_id&&(Q.pendingNodeId=e.node_id,lo()),as.processingAb&&as.pendingTurnIdx!==null){let e=Ko.turns[as.pendingTurnIdx];e&&(e.abPair={role:as.pendingRole??e.role,roleLabel:as.pendingRoleLabel??e.roleLabel,text:``,generated:!0,tokens:[],thinkingTokens:[]}),Ko.pendingIndex=as.pendingTurnIdx}else if(Q.loaded&&e.node_id){lo();let e=Ko.pendingIndex;if(e!==null){let t=Ko.turns[e];t&&(t.tokens=t.tokens??[],t.thinkingTokens=t.thinkingTokens??[])}}else Q.loaded?(Ko.pendingIndex=null,lo()):(Q.error=`The conversation was not ready when generation started. Reload it and try again.`,Z(Q.error,{kind:`error`}));return;case`generation_progress`:qa(e.node_id),$.replay={completed:e.completed,total:e.total};return;case`token`:{qa(e.node_id);let t=Ka(),n=e.thinking?t?.thinkingTokens:t?.tokens;if(e.raw_index!=null&&e.raw_index<=(n?.findLast(e=>e.rawIndex!=null)?.rawIndex??-1))return;let r=e.raw_index==null||e.raw_index>=($.replay?.total??0);if(r&&($.tokensSoFar+=1),typeof e.perplexity==`number`&&Number.isFinite(e.perplexity)&&e.perplexity>0&&($.ppl.logSum+=Math.log(e.perplexity),$.ppl.count+=1,$.ppl.mean=Math.exp($.ppl.logSum/$.ppl.count)),r){let e=performance.now();if(Ua===null)Ua=e;else{let t=(e-Ua)/1e3;t>0&&($.tokPerSec=($.tokensSoFar-1)/t)}}let i=e.measurements,a=Ji(i),o=i?.scores,s=qi(i?.instruments.lens?.readout),c=s?.readout,l=s?.aggregate,u=i?.instruments.sae?.readout?.features,d={text:e.text,thinking:e.thinking,tokenId:e.token_id,perLayerScores:i?.per_layer_scores,probes:o,logprob:e.logprob??null,samplerEntropy:e.sampler_entropy??null,perplexity:e.perplexity??null,topAlts:e.top_alts??null,rawIndex:e.raw_index??null,measurements:i};if(o&&fi.target){let e=o[fi.target];typeof e==`number`&&(d.score=e)}if(a){let e={};for(let[t,n]of Object.entries(a)){let r=n.coords;Array.isArray(r)&&r.length>1&&(e[t]=r)}Object.keys(e).length>0&&(d.coordsByProbe=e)}let f=t;if(f&&(e.thinking?(f.thinking=!0,(f.thinkingTokens??=[]).push(d),as.processingAb||Zo.thinkingTokens.push(d)):(f.text=(f.text??``)+e.text,(f.tokens??=[]).push(d),as.processingAb||Zo.responseTokens.push(d))),!as.processingAb){if(ci(a),c&&(Ii.readout=c),l){Ii.aggregate=l;let e=l.map(([e,t])=>[e,t]);Ii.aggHistory.push(e),Ii.aggHistory.length>60&&Ii.aggHistory.shift()}u&&sa(u)}return}case`done`:{qa(e.node_id),$.active=!1,$.finishedAt=performance.now(),$.finishReason=e.result?.finish_reason??`stop`,as.processingAb||li(Ji(e.result?.measurements));let t=Ka();if(t){t.finishReason=e.result?.finish_reason??`stop`,t.tokensSoFar=e.result?.tokens??$.tokensSoFar,t.meanLogprob=e.result?.mean_logprob??null;let n=Qo($);n!==null&&(t.perplexity=n)}typeof e.result?.tokens==`number`&&Number.isFinite(e.result.tokens)&&($.tokensSoFar=Math.max(0,e.result.tokens-($.replay?.total??0)));let n=as.processingAb,r=Ko.pendingIndex;if(Ko.pendingIndex=null,Q.pendingNodeId&&(Q.pendingNodeId=null,Q.loaded&&lo()),n){as.processingAb=!1,as.pendingTurnIdx=null,as.pendingRole=null,as.pendingRoleLabel=null,Zn();return}ui(),sr(),ca(),us.enabled&&r!==null&&Ko.turns[r]?.generated===!0&&ls(r)||Zn();return}case`error`:{$.active=!1,$.finishedAt=performance.now(),qa(e.node_id);let t=as.processingAb,n=je(e,`Generation stopped before the answer was complete. Try again or reopen the model.`);if(t&&as.pendingTurnIdx!==null){let e=Ko.turns[as.pendingTurnIdx];e&&(e.abPair={role:`system`,text:`Alternative generation stopped: ${n}`})}else Ko.turns=[...Ko.turns,{role:`system`,text:`Drowse stopped: ${n}`}];Ko.pendingIndex=null,Q.pendingNodeId&&(Q.pendingNodeId=null,Q.loaded&&lo()),Z(`Generation: ${n}`,{kind:`error`,ttlMs:null}),as.processingAb=!1,as.pendingTurnIdx=null,as.pendingRole=null,as.pendingRoleLabel=null,Zn();return}}}function Ya(e,t){return t===null?`append`:e===null?`generate`:`send`}function Xa(e,t,n,r){return{id:Yn(),label:Ya(e,n),text:e,apply:()=>Qa(e,t,n,r),awaitsGen:!0,rebuild:e===null?null:e=>Xa(e,t,n,r),createdAt:Date.now(),endsOnUserNode:(n??t)===`user`?!0:(n??t)===`assistant`?!1:null}}async function Za(e,t,n,r={}){if(!(e!==null&&e===``)){if(e!==null&&t===null)throw Error(`A text submission requires an authored role`);if(!(e===null&&n===null)){if(tr()){let{replaceSlot:i,...a}=r,o=Xa(e,t,n,a);Xn({label:o.label,text:o.text,apply:o.apply,awaitsGen:o.awaitsGen,rebuild:o.rebuild,endsOnUserNode:o.endsOnUserNode},{replaceSlot:i??null});return}return Qa(e,t,n,r)}}}async function Qa(e,t,n,r={}){if(!Q.loaded&&(await go(),!Q.loaded))throw Error(`Conversation tree is not ready; retry after it loads`);let i=await Wa(),a=r.steering===void 0?vr():r.steering,o=Fi();$.maxTokens=o?.max_tokens??xi.max_tokens;let s=r.parent_node_id,c=s===`active@drain`?Q.active_node_id:s,l={type:`submit`,text:e,authored_role:t,generated_role:n,steering:a||null,sampling:o,thinking:xi.thinking??!1,raw:r.raw??!1,...r.authored_thinking?{authored_thinking:r.authored_thinking}:{},...c===void 0?{}:{parent_node_id:c},...r.n===void 0?{}:{n:r.n},...r.recipe_override===void 0?{}:{recipe_override:r.recipe_override}};i.send(l)}async function $a(e={}){if(!Q.loaded&&(await go(),!Q.loaded))throw Error(`Conversation tree is not ready; retry after it loads`);let t=await Wa(),n=e.steering===void 0?vr():e.steering,r=e.steering===void 0?n||null:n,i=Fi();$.maxTokens=i?.max_tokens??xi.max_tokens;let a={type:`generate`,...e.append_same_role===void 0?{}:{append_same_role:e.append_same_role},input:null,steering:r,sampling:i,thinking:xi.thinking??!1,stateless:e.stateless??!1,raw:e.raw??!1,...e.parent_node_id===void 0?{}:{parent_node_id:e.parent_node_id},...e.n===void 0?{}:{n:e.n},...e.recipe_override===void 0?{}:{recipe_override:e.recipe_override},...e.generate_seat!==void 0&&e.generate_seat!==`assistant`?{generate_seat:e.generate_seat}:{}};t.send(a)}async function eo(e,t,n,r=!1){let i=await Wa(),a={type:`generate`,fork_node_id:e,fork_raw_index:t,fork_alt_token_id:n,...r?{fork_seed:crypto.getRandomValues(new Uint32Array(1))[0]&2147483647}:{}};i.send(a)}async function to(e,t,n){let r=await Wa(),i={type:`generate`,fork_node_id:e,fork_raw_index:t,fork_replacement_text:n};r.send(i)}function no(){let e=Ha.channel;e&&e.stop().catch(e=>{Ja({type:`error`,code:`RUNTIME_STOP_FAILED`,message:je(e,`The model could not be stopped cleanly.`)})})}var Q=V({loaded:!1,tree_format:null,drowse_version:null,session_id:null,name:null,root_id:null,active_node_id:null,nodes:new _t,children_of:new _t,rev:0,pendingNodeId:null,activePath:[],modelId:null,error:null}),ro=V({roster:{}});function io(){let e=Q.active_node_id;if(!e){Q.activePath=[];return}let t=[],n=e,r=new Set;for(;n&&!r.has(n);)r.add(n),t.push(n),n=Q.nodes.get(n)?.parent_id??null;Q.activePath=t.reverse()}function ao(e){let t=e.measurements,n={text:e.text,thinking:!1};e.token_id!==void 0&&(n.tokenId=e.token_id),e.logprob!==void 0&&(n.logprob=e.logprob),e.sampler_entropy!==void 0&&(n.samplerEntropy=e.sampler_entropy),e.perplexity!==void 0&&(n.perplexity=e.perplexity),e.top_alts&&(n.topAlts=e.top_alts),e.raw_index!==void 0&&(n.rawIndex=e.raw_index);let r=t?.scores??e.probes;r&&(n.probes=r);let i=t?.per_layer_scores??e.per_layer_scores;i&&(n.perLayerScores=i),t&&(n.measurements=t);let a=Ji(t);if(a){let e={};for(let[t,n]of Object.entries(a))!Zt(n)&&n.coords.length>1&&(e[t]=n.coords);Object.keys(e).length>0&&(n.coordsByProbe=e)}return n}function oo(e){let t={role:e.role,text:e.text,roleLabel:e.role_label,nodeId:e.id,generated:e.recipe!==null,appliedSteering:e.applied_steering??null,aggregateReadings:e.aggregate_readings??void 0,finishReason:e.finish_reason??void 0};e.tokens&&e.tokens.length>0&&(t.tokens=e.tokens.map(e=>{let t=ao(e);return t.thinking=!1,t}));let n=[...e.thinking_tokens??[],...e.tokens??[]].map(e=>e.perplexity).filter(e=>typeof e==`number`&&Number.isFinite(e)&&e>0);return n.length>0&&(t.perplexity=Math.exp(n.reduce((e,t)=>e+Math.log(t),0)/n.length)),e.thinking_tokens&&e.thinking_tokens.length>0?(t.thinkingTokens=e.thinking_tokens.map(e=>{let t=ao(e);return t.thinking=!0,t}),t.thinking=!0):e.thinking_text&&(t.thinkingTokens=[{text:e.thinking_text,thinking:!0}],t.thinking=!0),t}function so(e,t){if(e===null)return;let n=Q.children_of.get(e)??[];n.includes(t)||Q.children_of.set(e,[...n,t])}function co(e){let{children:t,...n}=e;return Q.nodes.set(n.id,n),Q.children_of.has(n.id)||Q.children_of.set(n.id,[...t??[]]),n.parent_id===null?Q.root_id=n.id:so(n.parent_id,n.id),n}function lo(e=!0){if(!Q.loaded)return;let t=Q.activePath;if(t.length===0){Ko.turns=[],Ko.pendingIndex=null;return}let n=[],r=new Map(Ko.turns.map(e=>[e.nodeId,e])),i=null;for(let a of t){let t=Q.nodes.get(a);if(!t||t.parent_id===null&&t.role===`system`&&!t.text)continue;let o=r.get(a),s;if(e&&o&&o.role===t.role&&o.nodeId===a){if(o.nodeId=a,(Q.pendingNodeId!==a||!$.active||t.finish_reason!==null)&&(o.text=t.text),o.generated=t.recipe!==null,o.appliedSteering=t.applied_steering??o.appliedSteering??null,o.aggregateReadings=t.aggregate_readings??o.aggregateReadings,o.finishReason=t.finish_reason??o.finishReason,t.finish_reason!==null||(o.tokens?.length??0)===0){let e=oo(t);(e.tokens||e.thinkingTokens)&&(o.tokens=e.tokens,o.thinkingTokens=e.thinkingTokens)}s=o}else s=oo(t);Q.pendingNodeId===a&&(i=n.length),n.push(s)}Ko.turns=n,Ko.pendingIndex=i}function uo(e,t){let n=new Set,r=e=>{e.parent_id&&n.add(`${e.parent_id}|${e.id}`);for(let t of Q.children_of.get(e.id)??[])n.add(`${e.id}|${t}`)};for(let t of e){let e=Q.nodes.get(t.id);(!e||e.parent_id!==t.parent_id||(e.applied_steering??e.recipe?.steering??null)!==(t.applied_steering??t.recipe?.steering??null))&&(e&&r(e),r(t))}for(let e of t){let t=Q.nodes.get(e);t&&r(t)}ka(n)}function fo(e,t){return t.length>0||e.some(e=>{let t=Q.nodes.get(e.id);return t?t.parent_id!==e.parent_id||t.role!==e.role||t.role_label!==e.role_label||t.text!==e.text||t.thinking_text!==e.thinking_text||t.applied_steering!==e.applied_steering||JSON.stringify(t.recipe)!==JSON.stringify(e.recipe)||t.raw_token_ids?.length!==e.raw_token_ids?.length||(t.raw_token_ids??[]).some((t,n)=>t!==e.raw_token_ids?.[n]):!1})}function po(e,t={}){if(Q.loaded&&!t.allowRevisionRegression&&e.model_id===Q.modelId&&e.session_id===Q.session_id&&e.reve.id)),n=[...Q.nodes.keys()].filter(e=>!t.has(e));uo(e.nodes,n),fo(e.nodes,n)&&Vt()}else ka(),Vt();Q.loaded=!0,Q.tree_format=e.tree_format,Q.drowse_version=e.drowse_version,Q.session_id=e.session_id,Q.name=e.name,Q.root_id=e.root_id,Q.active_node_id=e.active_node_id,Q.rev=e.rev,Q.modelId=e.model_id,Q.error=null,Q.nodes.clear();for(let t of e.nodes)Q.nodes.set(t.id,t);Q.children_of.clear();for(let[t,n]of Object.entries(e.children_of))Q.children_of.set(t,[...n]);return ro.roster=e.cast,io(),lo(t.preserveLiveTokens??!0),di(),!0}function mo(){if(!Q.loaded||!Q.root_id||!Q.active_node_id||Q.tree_format===null||Q.drowse_version===null)return null;let e=[];for(let[,t]of Q.nodes)e.push(t);let t={};for(let n of e)t[n.id]=[...Q.children_of.get(n.id)??[]];return{tree_format:Q.tree_format,drowse_version:Q.drowse_version,root_id:Q.root_id,active_node_id:Q.active_node_id,rev:Q.rev,nodes:e,children_of:t,model_id:Q.modelId??_i.info?.model_id??null,session_id:Q.session_id,name:Q.name,cast:{...ro.roster}}}function ho(e){if(Q.loaded&&e.rev>Q.rev+1)return!1;uo([...e.added??[],...e.updated??[]],e.removed??[]),fo(e.updated??[],e.removed??[])&&Vt();for(let t of e.added??[])co(t);for(let t of e.removed??[]){let e=Q.nodes.get(t);if(Q.nodes.delete(t),Q.children_of.delete(t),e?.parent_id){let n=Q.children_of.get(e.parent_id);n&&Q.children_of.set(e.parent_id,n.filter(e=>e!==t))}}for(let t of e.updated??[])co(t);if(e.active_node_id!==void 0&&e.active_node_id!==null&&(Q.active_node_id=e.active_node_id),Q.root_id!==null&&!Q.nodes.has(Q.root_id)){let t=(e.added??[]).find(e=>e.parent_id==null)??[...Q.nodes.values()].find(e=>e.parent_id==null);t&&(Q.root_id=t.id)}return Q.rev=e.rev,io(),lo(),di(),!0}async function go(){if(!($.active&&Q.loaded))try{po(await Ot.get(),{reconcileEdgeLabels:!0})}catch(e){let t=je(e,`The conversation map could not be refreshed.`);Q.loaded||(Q.error=t),Z(`tree: ${t}`,{kind:`error`})}}function _o(e,t){Z(`${e}: ${je(t,`That conversation change could not be saved.`)}`,{kind:`error`})}var vo=`Finish or stop the current reply before deleting this branch.`;function yo(e){if(!$.active)return!1;let t=Q.pendingNodeId;if(!t||!Q.nodes.has(t)||e===t)return!0;let n=(e,t)=>{let n=Q.nodes.get(t)??null;for(;n?.parent_id;){if(n.parent_id===e)return!0;n=Q.nodes.get(n.parent_id)??null}return!1};return n(e,t)||n(t,e)}async function bo(e){try{await Ot.navigate(e),await go()}catch(e){_o(`navigate`,e)}}async function xo(e,t){try{await Ot.edit(e,t),await go()}catch(e){_o(`edit`,e)}}async function So(e,t,n){try{let r=await Ot.branch(e,t,void 0,n);return await go(),r.node_id}catch(e){return _o(`branch`,e),null}}async function Co(e){let t=Q.nodes.get(e);if(!t||t.role!==`user`&&t.role!==`assistant`)return null;let n=t.role===`user`?`assistant`:`user`;return So(e,t.text,n)}async function wo(e){if(yo(e))return Z(vo,{kind:`warning`}),!1;try{let t=Q.nodes.get(e)?.parent_id;return t?(Q.activePath.includes(e)&&await Ot.navigate(t),await Ot.delete(e),await go(),!0):!1}catch(e){return _o(`delete`,e),!1}}async function To(e,t){try{await Ot.star(e,t),await go()}catch(e){_o(`star`,e)}}async function Eo(e,t){try{await Ot.note(e,t),await go()}catch(e){_o(`note`,e)}}async function Do(e,t=1,n={}){if(!Q.loaded)return;let r=Q.nodes.get(e);if(!r||r.role===`system`)return;let i=r.parent_id;if(i)try{await $a({parent_node_id:i,append_same_role:!1,n:t,recipe_override:n.recipe_override??void 0,generate_seat:r.role})}catch(e){_o(`regenerate`,e)}}async function Oo(e=1,t={}){let n=Q.active_node_id;if(n)return Do(n,e,t)}async function ko(e,t={}){if(!Q.loaded)return;let n=Q.nodes.get(e);if(!(!n||n.role===`system`||n.recipe!==null))try{await $a({parent_node_id:n.id,n:t.n??1,recipe_override:t.recipe_override??void 0,generate_seat:n.role===`user`?`assistant`:`user`})}catch(e){_o(`regenerate`,e)}}var Ao=new Set;function jo(e){return Ao.add(e),()=>Ao.delete(e)}var Mo=4,No=`drowse.chat.v4.`,Po=`drowse.chat.v3.`;function Fo(){let e=_i.info?.model_id;return e?No+e:null}function Io(e){if(!e||typeof e!=`object`)return!1;let t=e;if(t.version!==Mo||typeof t.model_id!=`string`||typeof t.saved_at!=`number`||!t.highlight||typeof t.highlight!=`object`)return!1;let n=t.highlight;return!(!(typeof n.target==`string`||n.target===null)||!(typeof n.compareTarget==`string`||n.compareTarget===null)||typeof n.compareTwo!=`boolean`)}function Lo(e){try{return globalThis.localStorage?be(globalThis.localStorage,e):null}catch{return null}}function Ro(e,t){try{globalThis.localStorage?.setItem(e,t)}catch{}}function zo(e){try{globalThis.localStorage&&Ee(globalThis.localStorage,e)}catch{}}function Bo(){let e=Fo();if(!e)return;let t=_i.info?.model_id;t&&zo(Po+t);let n=Lo(e);if(n)try{let t=JSON.parse(n);if(!Io(t)){zo(e);return}if(t.model_id!==_i.info?.model_id)return;Q.pendingNodeId=null;let r=t.highlight.target===`__probability__`?dn:t.highlight.target,i=t.highlight.compareTarget===`__probability__`?dn:t.highlight.compareTarget;fi.target=r,fi.compareTarget=i===r?null:i,fi.compareTwo=t.highlight.compareTwo&&fi.compareTarget!==null}catch{zo(e)}}var Vo=null;function Ho(){Vo||=setTimeout(()=>{Vo=null;let e=Fo();if(!e)return;let t={version:4,model_id:_i.info.model_id,saved_at:Date.now(),highlight:{target:fi.target,compareTarget:fi.compareTarget,compareTwo:fi.compareTwo}};Ro(e,JSON.stringify(t))},250)}function Uo(){Go?.();let e=Ae(()=>{Ce(()=>{if(fi.target,fi.compareTarget,fi.compareTwo,!Wo){Wo=!0;return}Ho()})}),t=()=>{Go===t&&(Go=null,e(),Vo!==null&&clearTimeout(Vo),Vo=null,Wo=!1)};return Go=t,t}var Wo=!1,Go=null;jo(()=>{Vo!==null&&clearTimeout(Vo),Vo=null,Wo=!1});var Ko=V({turns:[],pendingIndex:null});function qo(e,t){return t||(e===`user`?_i.info?.default_user_role??`user`:e===`assistant`?_i.info?.default_assistant_role??`assistant`:e)}function Jo(e,t){return(qo(e,t).charAt(0)||e.charAt(0)||`?`).toUpperCase()}async function Yo(){let e=Q.root_id;if(e!==null){await bo(e);return}throw Error(`Cannot clear chat before the tree root is loaded`)}function Xo(){$.active||qn.queue.length>0?Xn({label:`/clear`,text:null,apply:()=>void Yo(),awaitsGen:!1,rebuild:null,endsOnUserNode:!1}):Yo()}var Zo=V({responseTokens:[],thinkingTokens:[]}),$=V({active:!1,tokensSoFar:0,maxTokens:0,startedAt:null,finishedAt:null,tokPerSec:0,ppl:{logSum:0,count:0,mean:null},finishReason:null});function Qo(e){return e.ppl.count<=0?null:Math.exp(e.ppl.logSum/e.ppl.count)}var $o=V({mode:`chat`});function es(){return _i.info?.is_base_model===!0||$o.mode===`raw`}var ts=`drowse.genui.v1.`;function ns(){let e=_i.info?.model_id;return e?ts+e:null}function rs(){let e=ns(),t=e?Lo(e):null;_i.info?.is_base_model===!0?$o.mode=`raw`:t===`chat`||t===`raw`?$o.mode=t:$o.mode=`chat`}function is(e){$o.mode=_i.info?.is_base_model===!0?`raw`:e;let t=ns();t&&Ro(t,$o.mode)}var as=V({pendingTurnIdx:null,processingAb:!1,pendingRole:null,pendingRoleLabel:null});function os(e){let t=[];for(let n=0;n{cs=null,!(!us.enabled||$.active||as.processingAb)&&ss(e,t)},0),!0)}var us=V({enabled:!1,mode:`unsteered`,custom:``});function ds(){let e=!us.enabled;if(us.enabled=!us.enabled,!e){cs!==null&&(clearTimeout(cs),cs=null);return}if(!$.active)for(let e=Ko.turns.length-1;e>=0;e--){let t=Ko.turns[e];if(t&&!(!t.generated||t.role===`system`)){if(t.abPair)break;ls(e);break}}}function fs(){us.enabled=!1,cs!==null&&(clearTimeout(cs),cs=null)}function ps(e){if(us.mode=e,!(!us.enabled||$.active||as.processingAb))for(let e=Ko.turns.length-1;e>=0;e--){let t=Ko.turns[e];if(t?.generated&&t.role!==`system`){ls(e);return}}}function ms(e){us.custom=e}function hs(){return us.enabled?us.mode===`custom`?us.custom.trim()||null:us.mode:null}async function gs(){await bi(),Bo(),rs(),await Promise.allSettled([or(),ri(),sr(),yr(),go()])}var _s=[`temperature`,`top_p`,`top_k`,`max_tokens`,`seed`,`system_prompt`,`stop_sequences`,`logit_bias_text`,`presence_penalty`,`frequency_penalty`,`thinking`,`return_top_k`,`user_role`,`assistant_role`],vs=new Set([`BOTH`,`BEFORE`,`AFTER`,`THINKING`,`RESPONSE`,`PROMPT`,`GENERATED`]),ys=/^(?:raw|sae(?:-.+)?|role(?:-.+)?|from(?:-.+)?)$/u;function bs(e,t){let n=Cs(e,`conversation snapshot`);As(n,[`customSteeringExpression`,`highlightState`,`model_id`,`probeRack`,`samplingState`,`savedAt`,`session_id`,`steerRack`,`subspaceAlong`,`tree`,`version`],`conversation snapshot`),n.version!==7&&Ps(`snapshot version`),js(n.savedAt,`saved timestamp`),js(n.model_id,`model id`),js(n.session_id,`session id`);let r=Cs(n.tree,`conversation tree`);Ds(r.tree_format,`tree format`),js(r.drowse_version,`tree Drowse version`),js(r.root_id,`tree root id`),js(r.active_node_id,`tree active node id`),Ds(r.rev,`tree revision`),(r.model_id!==n.model_id||r.session_id!==null&&r.session_id!==n.session_id)&&Ps(`tree identity`),Array.isArray(r.nodes)||Ps(`tree nodes`),Cs(r.children_of,`tree children map`),Cs(r.cast,`tree cast`),Es(n.subspaceAlong,`subspace strength`),typeof n.customSteeringExpression!=`string`&&n.customSteeringExpression!==null&&Ps(`custom steering expression`);let i=ws(n.steerRack,`steering rack`),a=new Set;for(let e of i){let t=Cs(e,`steering row`),n=js(t.name,`steering row name`);if(a.has(n)&&Ps(`duplicate steering row ${n}`),a.add(n),(!vs.has(t.trigger)||typeof t.enabled!=`boolean`)&&Ps(`steering row ${n}`),t.mode===`jlens`||t.mode===`sae`){Es(t.alpha,`steering row ${n} alpha`),t.ablate!==void 0&&typeof t.ablate!=`boolean`&&Ps(`steering row ${n} ablation`),t.mode===`jlens`&&!n.startsWith(`jlens/`)&&Ps(`J-lens row ${n}`),t.mode===`sae`&&!/^sae\/(?:0|[1-9]\d*)$/u.test(n)&&Ps(`SAE row ${n}`);continue}t.mode!==`subspace`&&t.mode!==`manifold`&&Ps(`steering row ${n} mode`),t.mode===`subspace`&&t.ablate!==void 0&&typeof t.ablate!=`boolean`&&Ps(`steering row ${n} ablation`),ks(t.coords,`steering row ${n} coordinates`),Ns(t.label,`steering row ${n} label`),(typeof t.variant!=`string`||!ys.test(t.variant))&&Ps(`steering row ${n} variant`),t.mode===`manifold`&&(Es(t.blend,`steering row ${n} blend`),Es(t.onto,`steering row ${n} onto`))}let o=Cs(n.probeRack,`probe rack`);o.sortMode!==`name`&&o.sortMode!==`value`&&o.sortMode!==`change`&&Ps(`probe sort mode`);let s=Ts(o.active,`active probes`);new Set(s).size!==s.length&&Ps(`duplicate active probe`);let c=new Set;for(let e of ws(o.entries,`probe entries`)){let t=Cs(e,`probe row`),n=js(t.name,`probe row name`);c.has(n)&&Ps(`duplicate probe row ${n}`),c.add(n);let r=Cs(t.request,`probe ${n} request`);js(r.selector,`probe ${n} selector`),r.name!==n&&Ps(`probe ${n} alias`),r.top_n!==void 0&&(Ds(r.top_n,`probe ${n} nearest count`),r.top_n<1&&Ps(`probe ${n} nearest count`)),ks(t.sparkline,`probe ${n} sparkline`),Es(t.current,`probe ${n} current value`),Es(t.previous,`probe ${n} previous value`)}(s.some(e=>!c.has(e))||c.size!==s.length)&&Ps(`probe roster`);let l=Cs(n.highlightState,`highlight state`);Ns(l.target,`highlight target`),Ns(l.compareTarget,`highlight compare target`),(typeof l.compareTwo!=`boolean`||typeof l.smoothBlend!=`boolean`)&&Ps(`highlight state`);let u=Cs(n.samplingState,`sampling state`);Object.keys(u).sort().join(`\0`)!==[...t].sort().join(`\0`)&&Ps(`sampling fields`),Os(u.temperature,`sampling temperature`),Os(u.top_p,`sampling top-p`),Os(u.top_k,`sampling top-k`),Es(u.max_tokens,`sampling max tokens`),Os(u.seed,`sampling seed`),Ms(u.system_prompt,`sampling system prompt`),Ms(u.stop_sequences,`sampling stop sequences`),Ms(u.logit_bias_text,`sampling logit bias`),Es(u.presence_penalty,`sampling presence penalty`),Es(u.frequency_penalty,`sampling frequency penalty`),u.thinking!==null&&typeof u.thinking!=`boolean`&&Ps(`sampling thinking`),Es(u.return_top_k,`sampling alternatives`),Ms(u.user_role,`sampling user role`),Ms(u.assistant_role,`sampling assistant role`)}function xs(e){let t=new Map;for(let{name:n,...r}of e.steerRack){let e=structuredClone(r);(e.mode===`subspace`||e.mode===`jlens`||e.mode===`sae`)&&(e.ablate=e.ablate===!0),t.set(n,e)}let n=new Map(e.probeRack.entries.map(e=>[e.name,structuredClone(e)]));return{snapshot:e,steerEntries:t,steeringExpression:e.customSteeringExpression??An(t,e.subspaceAlong),probeRequests:e.probeRack.active.map(e=>structuredClone(n.get(e).request)),probeRows:n}}async function Ss(e){let t=await e.capture();await e.preflight();try{await e.apply()}catch(n){try{await e.rollback(t)}catch(e){throw AggregateError([n,e],`Conversation restore failed and the previous workspace could not be fully restored`)}throw n}}function Cs(e,t){return(!e||typeof e!=`object`||Array.isArray(e))&&Ps(t),e}function ws(e,t){return Array.isArray(e)||Ps(t),e}function Ts(e,t){let n=ws(e,t);return n.every(e=>typeof e==`string`&&e.length>0)||Ps(t),n}function Es(e,t){return(typeof e!=`number`||!Number.isFinite(e))&&Ps(t),e}function Ds(e,t){let n=Es(e,t);return Number.isSafeInteger(n)||Ps(t),n}function Os(e,t){e!==null&&Es(e,t)}function ks(e,t){let n=ws(e,t);return n.every(e=>typeof e==`number`&&Number.isFinite(e))||Ps(t),n}function As(e,t,n){Object.keys(e).sort().join(`\0`)!==[...t].sort().join(`\0`)&&Ps(n)}function js(e,t){return(typeof e!=`string`||e.trim().length===0)&&Ps(t),e}function Ms(e,t){typeof e!=`string`&&Ps(t)}function Ns(e,t){e!==null&&typeof e!=`string`&&Ps(t)}function Ps(e){throw TypeError(`Invalid ${e}`)}var Fs=[{id:`purple`,name:`Lavender`,dark:`#c5b3ff`,light:`#5b3fbf`},{id:`blue`,name:`Sky`,dark:`#a9d5ff`,light:`#245c91`},{id:`mint`,name:`Mint`,dark:`#a4dfc6`,light:`#23664f`},{id:`rose`,name:`Rose`,dark:`#f2b8d4`,light:`#923e68`},{id:`peach`,name:`Peach`,dark:`#f3c6a5`,light:`#88502c`},{id:`periwinkle`,name:`Iris`,dark:`#bfc5ff`,light:`#4b50a1`}],Is=`purple`;function Ls(e){return Fs.some(t=>t.id===e)}function Rs(e=Is){return Fs.find(t=>t.id===e)??Fs[0]}function zs(e){let t=Rs(e);return`--chat-accent-dark: ${t.dark}; --chat-accent-light: ${t.light};`}var Bs=`drowse-saved-conversations`,Vs=1,Hs=`conversations`,Us=`drowse-saved-conversations-v1`,Ws=64*1024*1024,Gs=120,Ks=256,qs=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`ConversationLibraryError`}},Js=Promise.resolve(),Ys=async e=>{let t=Js,n;Js=new Promise(e=>{n=e}),await t;try{return await e()}finally{n()}},Xs=e=>typeof navigator<`u`&&navigator.locks?navigator.locks.request(Us,{mode:`exclusive`},e):Ys(e),Zs=class{samplingKeys;store;now;randomId;runExclusive;initialization=null;constructor(e){this.samplingKeys=[...e.samplingKeys],this.store=e.store??new Qs,this.now=e.now??Date.now,this.randomId=e.randomId??fc,this.runExclusive=e.runExclusive??Xs}initialize(){return this.initialization??=this.store.initialize().catch(e=>{throw this.initialization=null,e}),this.initialization}list(){return this.readList(e=>structuredClone(e))}listSummaries(){return this.readList($s)}async findForTree(e,t){let{conversations:n}=await this.readList(e=>({id:e.id,name:e.name,updatedAt:e.updatedAt,modelId:e.modelId,rootId:e.snapshot.tree.root_id})),r=n.find(n=>n.modelId===e&&n.rootId===t);return r?this.get(r.id):null}async hasAny(){return await this.initialize(),this.store.hasAny?this.store.hasAny():(await this.store.list()).length>0}async readList(e){await this.initialize();let t=t=>{try{if(ec(t.value,this.samplingKeys),t.value.id!==t.key)throw uc(`Saved conversation key does not match its id`);return{conversation:e(t.value)}}catch(e){let n=lc(t.value)?t.value:null;return{issue:{id:t.key,name:typeof n?.name==`string`?n.name:null,reason:dc(e).message}}}},n=this.store.map?await this.store.map(t):(await this.store.list()).map(t),r=[],i=[];for(let e of n)`conversation`in e?r.push(e.conversation):i.push(e.issue);return r.sort((e,t)=>t.updatedAt-e.updatedAt||e.id.localeCompare(t.id)),{conversations:r,issues:i}}async get(e){oc(e,`saved conversation id`),await this.initialize();let t=await this.store.read(e);if(t===void 0)throw new qs(`NOT_FOUND`,`This saved conversation no longer exists`);if(ec(t,this.samplingKeys),t.id!==e)throw uc(`Saved conversation key does not match its id`);return structuredClone(t)}async create(e){let t=ic(e.name);bs(e.snapshot,this.samplingKeys);let n=e.avatarSeed===void 0?null:ac(e.avatarSeed);return await this.initialize(),this.runExclusive(async()=>{let r=this.randomId();for(let e=0;e<4&&await this.store.read(r)!==void 0;e+=1)r=this.randomId();if(await this.store.read(r)!==void 0)throw uc(`Unable to allocate a unique saved conversation id`);let i=this.now(),a={schemaVersion:1,id:r,name:t,avatarSeed:n??ac(this.randomId()),...e.accent===void 0?{}:{accent:e.accent},modelId:e.snapshot.model_id,...e.modelType===void 0?{}:{modelType:e.modelType},createdAt:e.createdAt??i,updatedAt:e.updatedAt??i,snapshot:structuredClone(e.snapshot)};return ec(a,this.samplingKeys),await this.store.write(a),structuredClone(a)})}async update(e,t){return oc(e,`saved conversation id`),await this.initialize(),this.runExclusive(async()=>{let n=await this.store.read(e);if(n===void 0)throw new qs(`NOT_FOUND`,`This saved conversation no longer exists`);ec(n,this.samplingKeys);let r=structuredClone(t.snapshot??n.snapshot),i={...n,...t.accent===void 0?{}:{accent:t.accent},name:t.name===void 0?n.name:ic(t.name),avatarSeed:t.avatarSeed===void 0?n.avatarSeed:ac(t.avatarSeed),modelId:r.model_id,updatedAt:t.snapshot===void 0?n.updatedAt:this.now(),snapshot:r};return ec(i,this.samplingKeys),await this.store.write(i),structuredClone(i)})}async duplicate(e){let t=await this.get(e),n=t.snapshot,r=this.randomId(),i=new Map(n.tree.nodes.map((e,t)=>[e.id,`${r}-${t}`])),a=e=>{let t=i.get(e);if(t===void 0)throw uc(`The conversation has a missing tree node`);return t};return n.tree.root_id=a(n.tree.root_id),n.tree.active_node_id=a(n.tree.active_node_id),n.tree.nodes=n.tree.nodes.map(e=>({...e,id:a(e.id),parent_id:e.parent_id===null?null:a(e.parent_id)})),n.tree.children_of=Object.fromEntries(Object.entries(n.tree.children_of).map(([e,t])=>[a(e),t.map(a)])),this.create({name:`${t.name.slice(0,Gs-7).trimEnd()} (copy)`,avatarSeed:t.avatarSeed,accent:t.accent,modelType:t.modelType,snapshot:n})}async autosave(e,t,n){return bs(e,this.samplingKeys),await this.initialize(),this.runExclusive(async()=>{let r;if(t){let n=await this.store.read(t);if(n===void 0)throw new qs(`NOT_FOUND`,`This chat was deleted. Save as new to keep your current work.`);ec(n,this.samplingKeys),n.modelId===e.model_id&&n.snapshot.tree.root_id===e.tree.root_id&&(r=n)}if(!r){let t=t=>{try{return ec(t.value,this.samplingKeys),t.value.modelId===e.model_id&&t.value.snapshot.tree.root_id===e.tree.root_id?t.value:null}catch{return null}};r=(this.store.map?await this.store.map(t):(await this.store.list()).map(t)).filter(e=>e!==null).sort((e,t)=>t.updatedAt-e.updatedAt)[0]}if(!r&&!e.tree.nodes.some(e=>e.parent_id!==null))return null;if(r&&r.snapshot.tree.rev>e.tree.rev)throw new qs(`INVALID_RECORD`,`A newer version of this chat is already saved. Open it from Your chats, or save this version as new.`);if(r&&(n===void 0||r.modelType===n)&&JSON.stringify({...r.snapshot,savedAt:``})===JSON.stringify({...e,savedAt:``}))return structuredClone(r);let i=this.now(),a=r?.id??this.randomId();if(!r&&await this.store.read(a)!==void 0)throw uc(`Unable to allocate a unique saved conversation id`);let o={schemaVersion:1,id:a,name:r?.name??tc(i),avatarSeed:r?.avatarSeed??ac(this.randomId()),...r?.accent===void 0?{}:{accent:r.accent},modelId:e.model_id,...(n??r?.modelType)===void 0?{}:{modelType:n??r?.modelType},createdAt:r?.createdAt??i,updatedAt:i,snapshot:structuredClone(e)};return ec(o,this.samplingKeys),await this.store.write(o),structuredClone(o)})}async delete(e){return oc(e,`saved conversation id`),await this.initialize(),this.runExclusive(()=>this.store.delete(e))}close(){this.store.close?.(),this.initialization=null}},Qs=class{database=null;initialization=null;initialize(){return this.initialization??=this.initializeOnce().catch(e=>{throw this.initialization=null,e}),this.initialization}async list(){return this.withDatabase(async e=>{let t=e.transaction(Hs,`readonly`),n=hc(t),r=t.objectStore(Hs),[i,a]=await Promise.all([mc(r.getAllKeys()),mc(r.getAll())]);return await n,a.map((e,t)=>({key:String(i[t]),value:e}))})}async map(e){return this.withDatabase(async t=>{let n=t.transaction(Hs,`readonly`),r=hc(n),i=[],a=new Promise((t,r)=>{let a=n.objectStore(Hs).openCursor();a.onerror=()=>r(a.error),a.onsuccess=()=>{let o=a.result;if(o===null){t();return}try{i.push(e({key:String(o.key),value:o.value})),o.continue()}catch(e){n.abort(),r(e)}},n.addEventListener(`abort`,()=>r(n.error),{once:!0})});return await Promise.all([a,r]),i})}async hasAny(){return this.withDatabase(async e=>{let t=e.transaction(Hs,`readonly`),n=hc(t),[r]=await Promise.all([mc(t.objectStore(Hs).count()),n]);return r>0})}async read(e){return this.withDatabase(async t=>{let n=t.transaction(Hs,`readonly`),r=hc(n),i=await mc(n.objectStore(Hs).get(e));return await r,i})}async write(e){await this.withDatabase(async t=>{let n=t.transaction(Hs,`readwrite`),r=hc(n);n.objectStore(Hs).put(e),await r})}async delete(e){return await this.read(e)===void 0?!1:(await this.withDatabase(async t=>{let n=t.transaction(Hs,`readwrite`),r=hc(n);n.objectStore(Hs).delete(e),await r}),!0)}close(){this.invalidate(this.database)}async initializeOnce(){if(typeof indexedDB>`u`)throw new qs(`INDEXEDDB_UNAVAILABLE`,`Browser storage is unavailable`);let e=await pc();this.database=e,e.onversionchange=()=>this.invalidate(e),e.onclose=()=>this.invalidate(e,!1)}async withDatabase(e){for(let t=0;t<2;t+=1){await this.initialize();let n=this.database;if(n===null){this.initialization=null;continue}try{return await e(n)}catch(e){if(t===0&&gc(e)){this.invalidate(n);continue}throw e}}throw new qs(`INDEXEDDB_UNAVAILABLE`,`Browser storage closed while accessing saved conversations`)}invalidate(e,t=!0){e!==null&&(t&&e.close(),this.database===e&&(this.database=null,this.initialization=null))}};function $s(e){let{nodes:t,children_of:n,root_id:r}=e.snapshot.tree;return{schemaVersion:e.schemaVersion,id:e.id,name:e.name,avatarSeed:e.avatarSeed,...e.accent===void 0?{}:{accent:e.accent},modelId:e.modelId,...e.modelType===void 0?{}:{modelType:e.modelType},createdAt:e.createdAt,updatedAt:e.updatedAt,messageCount:t.filter(e=>(e.role===`user`||e.role===`assistant`)&&(e.text.length>0||(e.raw_token_ids?.length??0)>0)).length,threadCount:t.filter(e=>e.id!==r&&(n[e.id]?.length??0)===0).length}}function ec(e,t){if(!lc(e))throw uc(`Saved conversation is not an object`);if(cc(e,[...`modelType`in e?[`modelType`]:[],...`accent`in e?[`accent`]:[],`avatarSeed`,`createdAt`,`id`,`modelId`,`name`,`schemaVersion`,`snapshot`,`updatedAt`]),e.schemaVersion!==1)throw uc(`Saved conversation version is unsupported`);if(oc(e.id,`saved conversation id`),ic(e.name),ac(e.avatarSeed),`accent`in e&&!Ls(e.accent))throw uc(`Chat accent color is invalid`);if(oc(e.modelId,`model id`,512),`modelType`in e&&e.modelType!==`base`&&e.modelType!==`chat`)throw uc(`Model type is invalid`);if(sc(e.createdAt,`creation time`),sc(e.updatedAt,`update time`),e.updatedAtWs)throw new qs(`STORAGE_LIMIT`,`This conversation is larger than the 64 MiB save limit`)}function tc(e=Date.now()){let t=Object.fromEntries(new Intl.DateTimeFormat(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hourCycle:`h23`,timeZoneName:`short`}).formatToParts(e).map(({type:e,value:t})=>[e,t]));return`New Chat - ${t.month} ${t.day} - ${Number(t.hour)}:${t.minute} ${t.timeZoneName}`}function nc(e){return(e.split(`/`).at(-1)??e).replace(/[-_]+/gu,` `).replace(/\b(qwen|gemma|llama|mistral)(\d)/giu,(e,t,n)=>`${t.charAt(0).toUpperCase()}${t.slice(1).toLowerCase()}${n}`).replace(/\b(qwen|gemma|llama|mistral)\b/giu,e=>`${e.charAt(0).toUpperCase()}${e.slice(1).toLowerCase()}`).replace(/\b(\d+(?:\.\d+)?)b\b/giu,`$1B`).replace(/\s+/gu,` `).trim()}function rc(){return fc()}function ic(e){if(typeof e!=`string`)throw uc(`Conversation name is invalid`);let t=e.replace(/\s+/gu,` `).trim();if(!t)throw uc(`Give this conversation a name`);if(t.length>Gs)throw uc(`Conversation names must be ${Gs} characters or fewer`);return t}function ac(e){if(typeof e!=`string`)throw uc(`Avatar seed is invalid`);let t=e.trim();if(!t||t.length>Ks)throw uc(`Avatar seed is invalid`);return t}function oc(e,t,n=256){if(typeof e!=`string`||!e.trim()||e.length>n)throw uc(`${t} is invalid`)}function sc(e,t){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw uc(`${t} is invalid`)}function cc(e,t){let n=Object.keys(e).sort(),r=[...t].sort();if(n.length!==r.length||n.some((e,t)=>e!==r[t]))throw uc(`Saved conversation fields are invalid`)}function lc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function uc(e){return new qs(`INVALID_RECORD`,e)}function dc(e){return e instanceof Error?e:Error(String(e))}function fc(){let e=globalThis.crypto;if(!e?.getRandomValues)throw uc(`Secure random identifiers are unavailable`);if(typeof e.randomUUID==`function`)return e.randomUUID();let t=e.getRandomValues(new Uint8Array(16));t[6]=t[6]&15|64,t[8]=t[8]&63|128;let n=Array.from(t,e=>e.toString(16).padStart(2,`0`));return`${n.slice(0,4).join(``)}-${n.slice(4,6).join(``)}-${n.slice(6,8).join(``)}-${n.slice(8,10).join(``)}-${n.slice(10).join(``)}`}async function pc(){let e=await new Promise((e,t)=>{let n=!1,r=indexedDB.open(Bs,Vs);r.onupgradeneeded=()=>{let e=r.result;e.objectStoreNames.contains(Hs)||e.createObjectStore(Hs,{keyPath:`id`})},r.onsuccess=()=>{if(n){r.result.close();return}n=!0,e(r.result)},r.onerror=()=>{n||(n=!0,t(r.error??new qs(`INDEXEDDB_UNAVAILABLE`,`Saved conversation storage could not be opened`)))},r.onblocked=()=>{n||(n=!0,t(new qs(`INDEXEDDB_BLOCKED`,`Close other Drowse tabs, then try again`)))}});return await de(e,[Hs]),e}function mc(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error??Error(`Browser storage request failed`))})}function hc(e){return new Promise((t,n)=>{e.oncomplete=()=>t(),e.onerror=()=>n(e.error??Error(`Browser storage transaction failed`)),e.onabort=()=>n(e.error??Error(`Browser storage transaction was aborted`))})}function gc(e){return e instanceof DOMException&&e.name===`InvalidStateError`}var _c=5e3;async function vc(e=navigator.storage,t=_c){if(!e)return!1;let n=[];if(e.persist&&n.push(yc(()=>e.persist())),e.persisted&&n.push(yc(()=>e.persisted())),n.length===0)return!1;try{return await xc(bc(n),Sc(t))}catch{return!1}}function yc(e){try{return Promise.resolve(e()).then(e=>e===!0,()=>!1)}catch{return Promise.resolve(!1)}}function bc(e){return new Promise(t=>{let n=e.length,r=!1;for(let i of e)i.then(e=>{if(!r){if(e){r=!0,t(!0);return}--n,n===0&&(r=!0,t(!1))}})})}function xc(e,t){return new Promise((n,r)=>{let i=setTimeout(()=>r(Error(`The persistent-storage request timed out`)),t);e.then(e=>{clearTimeout(i),n(e)},e=>{clearTimeout(i),r(e)})})}function Sc(e){if(!Number.isFinite(e)||e<=0)throw RangeError(`Storage persistence timeouts must be positive numbers`);return e}var Cc=new Zs({samplingKeys:_s}),wc=V({activeId:null,avatarSeed:null,accent:`purple`,status:`idle`,error:null}),Tc=null;function Ec(e){return Tc=e,()=>{Tc===e&&(Tc=null)}}async function Dc(){await Tc?.()}async function Oc(){return navigator.storage?.persist?vc(navigator.storage):null}var kc=0;function Ac(e){let t=e.classList.contains(`theme-toggle`);e.classList.add(`sliding-selection`);let n=document.createElement(`span`);if(n.className=`selection-indicator`,n.setAttribute(`aria-hidden`,`true`),t){let t=++kc;n.style.viewTransitionName=`theme-selection-${t}`,e.querySelectorAll(`button`).forEach((e,n)=>{e.style.viewTransitionName=`theme-option-${t}-${n}`})}e.prepend(n);let r=0,i=0,a=null;function o(){r=0;let n=e.querySelector(`button[aria-pressed="true"], button[aria-selected="true"], button[aria-current="page"]`);if(!n||!n.getClientRects().length){e.removeAttribute(`data-selection-visible`);return}t&&a&&a!==n&&(e.dataset.selectionReady=``),a=n;let o=0,s=0,c=n;for(;c&&c!==e;)o+=c.offsetLeft,s+=c.offsetTop,c=c.offsetParent;e.style.setProperty(`--selection-x`,`${o}px`),e.style.setProperty(`--selection-y`,`${s}px`),e.style.setProperty(`--selection-width`,`${n.offsetWidth}px`),e.style.setProperty(`--selection-height`,`${n.offsetHeight}px`),e.dataset.selectionVisible=``,!t&&!e.hasAttribute(`data-selection-ready`)&&!i&&(i=requestAnimationFrame(()=>{e.dataset.selectionReady=``,i=0}))}function s(){r||=requestAnimationFrame(o)}let c=new ResizeObserver(s);function l(){c.disconnect(),c.observe(e),e.querySelectorAll(`button`).forEach(e=>c.observe(e))}let u=new MutationObserver(e=>{e.some(e=>e.type===`childList`)&&l(),o()});return u.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:[`aria-pressed`,`aria-selected`,`aria-current`,`class`]}),l(),o(),{destroy(){u.disconnect(),c.disconnect(),cancelAnimationFrame(r),cancelAnimationFrame(i),n.remove()}}}var jc=I(``),Mc=I(` `),Nc=I(``),Pc=I(`
`);function Fc(e,t){n(t,!0);let r=Y(t,`value`,15),i=Y(t,`fill`,3,!1),a=Y(t,`ariaLabel`,3,`View`);function o(e){e!==r()&&(r(e),t.onchange?.(e))}var s=Pc();let c;m(s,21,()=>t.items,e=>e.value,(e,t)=>{var n=Nc();let i,a;var s=R(n),c=e=>{g(e,jc())};p(s,e=>{B(t).color&&e(c)});var l=X(s,2),u=R(l,!0);f(l);var d=X(l,2),m=e=>{var n=Mc(),r=R(n,!0);f(n),U(()=>G(r,B(t).meta)),g(e,n)};p(d,e=>{B(t).meta&&e(m)}),f(n),U(()=>{i=y(n,1,`tab svelte-190ojsy`,null,i,{on:B(t).value===r()}),S(n,`aria-label`,B(t).label),S(n,`aria-pressed`,B(t).value===r()),S(n,`title`,B(t).title),n.disabled=B(t).disabled,a=pe(n,``,a,{"--tab-c":B(t).color}),G(u,B(t).label)}),K(`click`,n,()=>o(B(t).value)),g(e,n)}),f(s),w(s,e=>Ac?.(e)),U(()=>{c=y(s,1,`sk-tabs svelte-190ojsy`,null,c,{fill:i()}),S(s,`aria-label`,a())}),g(e,s),W()}H([`click`]);function Ic(e,t){return e?(t===`thinking`?e.thinkingTokens:e.tokens)??[]:[]}function Lc(e){let t=[];return e.forEach((e,n)=>{let r=e.thinkingTokens?.length??0;r>0&&t.push({turnIdx:n,seg:`thinking`,length:r});let i=e.tokens?.length??0;i>0&&t.push({turnIdx:n,seg:`response`,length:i})}),t}function Rc(e,t){return e.findIndex(e=>e.turnIdx===t.turnIdx&&e.seg===t.seg)}function zc(e,t,n){let r=Rc(e,t);if(r<0)return null;let i=t.tokenIdx+n;if(i>=0&&i=e.length)return null;let o=e[a];return{turnIdx:o.turnIdx,seg:o.seg,tokenIdx:n>0?0:o.length-1}}function Bc(e,t,n){let r=n>0?e.find(e=>e.turnIdx>t.turnIdx):[...e].reverse().find(e=>e.turnIdxe.turnIdx===r.turnIdx);return{turnIdx:i.turnIdx,seg:i.seg,tokenIdx:0}}function Vc(e,t){if(e.length===0)return null;let n=Rc(e,t);if(n>=0)return t.tokenIdxe.turnIdx===t.turnIdx);if(r)return{turnIdx:r.turnIdx,seg:r.seg,tokenIdx:Math.min(t.tokenIdx,r.length-1)};let i=e.find(e=>e.turnIdx>t.turnIdx)??e[e.length-1];return{turnIdx:i.turnIdx,seg:i.seg,tokenIdx:0}}var Hc=48,Uc=class{#e=J(null);get data(){return B(this.#e)}set data(e){A(this.#e,e,!0)}#t=J(!1);get loading(){return B(this.#t)}set loading(e){A(this.#t,e,!0)}#n=J(null);get error(){return B(this.#n)}set error(e){A(this.#n,e,!0)}#r=J(null);get origin(){return B(this.#r)}set origin(e){A(this.#r,e,!0)}#i=J(null);get source(){return B(this.#i)}set source(e){A(this.#i,e,!0)}#a=J(null);get progress(){return B(this.#a)}set progress(e){A(this.#a,e,!0)}#o=null;#s=new Map;#c=!1;adopt(e,t){this.#o=null,this.data=e,this.origin=`captured`,this.source=t,this.loading=!1,this.error=null,this.progress=null}clear(){this.#o=null,this.data=null,this.origin=null,this.source=null,this.loading=!1,this.error=null,this.progress=null}dispose(){this.#c=!0,this.clear(),this.#s.clear()}replay(e,t,n,r,i){let a=Wc(e,t,n,r);this.#o=a;let o=this.#s.get(a);if(o&&o.state!==`failed`){this.#s.delete(a),this.#s.set(a,o),this.#l(a,o);return}let s={state:`loading`,data:null,source:null,error:null,progress:{phase:`queued`,completed:0,total:n+1,progress:0,message:`Waiting for the current model task to finish`}};this.#s.set(a,s),this.#l(a,s),zt(e,t,n,r,e=>{let t=Gc(e);t!==null&&(s.progress=t,this.#o===a&&this.#l(a,s))}).then(e=>{let{data:t,source:n}=i(e.measurements);s.state=`ready`,s.data=t,s.source=n,s.error=null,s.progress=null}).catch(e=>{s.state=`failed`,s.error=te(e),s.progress=null}).finally(()=>{this.#u(),this.#o===a&&this.#l(a,s)})}#l(e,t){this.#c||this.#o!==e||(this.loading=t.state===`loading`,this.data=t.data,this.error=t.error,this.origin=t.state===`ready`?`replayed`:null,this.source=t.source,this.progress=t.progress)}#u(){if(!(this.#s.size<=Hc))for(let[e,t]of this.#s){if(this.#s.size<=Hc)break;t.state===`loading`||e===this.#o||this.#s.delete(e)}}};function Wc(e,t,n,r){return JSON.stringify([e,Bt(e),t,n,r.topK??null,r.steered??!0,r.raw??!1,r.layers??null])}function Gc(e){if(e.event!==`progress`||e.data===null||typeof e.data!=`object`)return null;let t=e.data;return t.kind!==`token_readout`||![`queued`,`context`,`readout`,`complete`].includes(String(t.phase))||!Number.isInteger(t.completed)||!Number.isInteger(t.total)||typeof t.progress!=`number`||!Number.isFinite(t.progress)||typeof t.message!=`string`?null:{phase:t.phase,completed:Math.max(0,Number(t.completed)),total:Math.max(0,Number(t.total)),progress:Math.max(0,Math.min(1,t.progress)),message:t.message}}var Kc=V({tab:`lens`});function qc(e,t){return e===`logits`||t[e]?e:t.lens?`lens`:t.sae?`sae`:t.geometry?`geometry`:`logits`}function Jc(e,t){if(t)return t===`__surprise__`?hn(e.logprob):t===`__probability__`?gn(e.logprob):t===`__entropy__`?_n(e.samplerEntropy):mn(e,t)}function Yc(e){let t=fi.target;if(!t)return{};let n=fi.compareTwo&&fi.compareTarget?fi.compareTarget:null;return On(Jc(e,t),n===null?null:Jc(e,n),fi.smoothBlend,$r(t),n===null?void 0:$r(n),Xc(t),n===null?void 0:Xc(n))}function Xc(e){let t=Hr.entries.get(pn(e).base)?.info;return t?.family===`lens`?`surprise`:t?.family===`sae`?`sae`:wn(e)}function Zc(e){let t=Yc(e),n=[];return t.backgroundColor&&n.push(`background-color: ${t.backgroundColor}`),t.backgroundImage&&n.push(`background-image: ${t.backgroundImage}`),n.join(`;`)}var Qc=I(``),$c=I(``),el=I(``),tl=I(`
sequence context
`);function nl(e,t){n(t,!0);let r=c(()=>Math.max(0,t.index-60)),i=c(()=>Math.min(t.tokens.length,t.index+60+1)),o=c(()=>t.tokens.slice(B(r),B(i)).map((e,t)=>({tok:e,i:B(r)+t})));function s(e){return e.replace(/\n/g,`⏎`)}let l=J(null);Ce(()=>{t.index,B(o);let e=B(l)?.querySelector(`.current`);if(B(l)&&e){let t=e.getBoundingClientRect(),n=B(l).getBoundingClientRect();B(l).scrollLeft+=t.left+t.width/2-n.left-B(l).clientWidth/2}});var u=tl(),d=R(u),h=X(R(d),2),_=R(h);f(h),f(d);var v=X(d,2),b=R(v),x=e=>{var t=Qc(),n=R(t);f(t),U(()=>G(n,`…${B(r)??``}`)),g(e,t)};p(b,e=>{B(r)>0&&e(x)});var C=X(b,2);m(C,17,()=>B(o),({tok:e,i:t})=>t,(e,n)=>{let r=()=>B(n).tok,i=()=>B(n).i;var a=$c();let o;var c=R(a,!0);f(a),U((e,n)=>{o=y(a,1,`rtok svelte-cca58d`,null,o,{current:i()===t.index}),pe(a,e),S(a,`aria-current`,i()===t.index),S(a,`title`,`token ${i()+1} / ${t.tokens.length}`),G(c,n)},[()=>Zc(r()),()=>s(r().text)]),K(`click`,a,()=>t.onjump(i())),g(e,a)});var w=X(C,2),T=e=>{var n=el(),r=R(n);f(n),U(()=>G(r,`${t.tokens.length-B(i)}…`)),g(e,n)};p(w,e=>{B(i)A(l,e),()=>B(l)),f(u),U(()=>G(_,`token ${t.index+1} / ${t.tokens.length??``}`)),g(e,u),W()}H([`click`]);var rl=[`0`,`1`,`2`,`3`,`4`,`5`,`6`,`7`,`8`,`9`],il=new Map,al=/[\u0590-\u08ff\u200e\u200f\u202a-\u202e\u2066-\u2069\ufb1d-\ufeff]/u;function ol(e={}){let t=Intl.getCanonicalLocales(e.locales),n=Object.fromEntries(Object.entries(e.format??{}).sort(([e],[t])=>e.localeCompare(t))),r=JSON.stringify([t,n]),i=il.get(r);if(!i){i=new Intl.NumberFormat(t,n);let e=il.keys().next().value;il.size>=64&&e!==void 0&&il.delete(e),il.set(r,i)}return i}function sl(e,t={}){let n=ol(t),r=n.formatToParts(e),i=r.map(e=>e.value).join(``),a=n.resolvedOptions(),o=a.numberingSystem===`latn`&&a.notation===`standard`&&!al.test(i)&&!r.some(e=>e.type===`nan`||e.type===`infinity`),s=JSON.stringify(a);if(!o)return{text:i,tokens:[],rollable:o,signature:s,magnitude:``};let c=r.filter(e=>e.type===`integer`).reduce((e,t)=>e+t.value.length,0),l=-1,u=new Map,d=[],f=``,p=``;for(let e of r)if(e.type===`integer`||e.type===`fraction`){e.type===`integer`?f+=e.value:p+=e.value;for(let t of e.value){let n=e.type===`integer`?--c:l--,r=`digit:${n}`;d.push({key:r,identity:r,text:t,wheel:rl,index:Number(t),place:n})}}else if(e.type===`group`){let t=`group:${c}`;d.push({key:`${t}:${e.value}`,identity:t,text:e.value})}else{let t=u.get(e.type)??0;u.set(e.type,t+1);let n=e.type===`plusSign`||e.type===`minusSign`?`sign`:e.type;d.push({key:`${e.type}:${t}:${e.value}`,identity:`${n}:${t}`,text:e.value})}return{text:i,tokens:d,rollable:o,signature:s,magnitude:`${f.replace(/^0+(?=\d)/u,``)}.${p}`}}function cl(e,t){let[n=``,r=``]=e.magnitude.split(`.`),[i=``,a=``]=t.magnitude.split(`.`);if(n.length!==i.length)return i.length>n.length?1:-1;if(n!==i)return i>n?1:-1;let o=Math.max(r.length,a.length),s=r.padEnd(o,`0`),c=a.padEnd(o,`0`);return c===s?0:c>s?1:-1}function ll(e,t){return{target:0,duration:t,points:Array.from({length:49},(t,n)=>{if(n===48)return 0;let r=Math.max(0,Math.min(1,(n/48-.14)/.86));return e*(1+10*r)*Math.exp(-10*r)})}}function ul(e,t){if(t<=0||e.duration<=0)return e;let n=e.duration+t,r=Math.round((e.points.length-1)*n/e.duration)+1,i=e.points[0]??e.target;return{target:e.target,duration:n,points:Array.from({length:r},(a,o)=>{if(o===r-1)return e.target;let s=o/(r-1)*n-t;return s<=0?i:pl(e,s).position})}}function dl(e,t,n,r){if(r<=0)return{points:[t,t],duration:0,target:t};let i=r/1e3,a=e-t,o=Math.max(Math.abs(a),1)*12/i,s=Math.max(-o,Math.min(o,n))*i;return{points:Array.from({length:49},(e,n)=>{if(n===48)return t;let r=n/48;return t+(a+(s+10*a)*r)*Math.exp(-10*r)}),duration:r,target:t}}function fl(e,t=0,n=24){if(e.duration<=0)return{points:[0,0],duration:0,target:0};let r=e.duration/(e.points.length-1)/1e3;return{duration:e.duration,target:0,points:e.points.map((e,i,a)=>{if(i===0)return Math.max(0,Math.min(1,t));if(i===a.length-1)return 0;let o=Math.abs((a[i+1]-a[i-1])/(2*r)),s=n/6;return Math.max(0,Math.min(1,(o-s)/(n-s)))})}}function pl(e,t){if(t>=e.duration||e.duration===0)return{position:e.target,velocity:0};let n=Math.max(0,t)/e.duration*(e.points.length-1),r=Math.min(Math.floor(n),e.points.length-2),i=e.points[r]??e.target,a=e.points[r+1]??e.target;return{position:i+(a-i)*(n-r),velocity:(a-i)*(e.points.length-1)*1e3/e.duration}}function ml(e,t,n,r=10){let i=Math.floor(e/r)*r+t;return n>0&&ie+.001?i-=r:n===0&&(i+=Math.round((e-i)/r)*r),i}var hl=(e,t)=>e[(t%e.length+e.length)%e.length];function gl(e,t=`outward`){if(t!==`outward`){let n=e.map((e,t)=>e?-1:t).filter(e=>e>=0);t===`end`&&n.reverse();let r=e.map(e=>+!e);return t!==`none`&&n.forEach((e,t)=>{r[e]=t+1}),r}let n=e.map((e,t)=>e?0:t+1);if(!e.includes(!0))return n;let r=-1/0;for(let t=0;t=0;t--)e[t]?r=t:n[t]=Math.min(n[t],r-t);return n}function _l(e,t){let n=new Map,r=[],i=0;for(let a of e){let e=t.get(a);if(!e){r.push(a);continue}for(let t of r)n.set(t,e.x);r.length=0,n.set(a,e.x),i=e.x+e.width}for(let e of r)n.set(e,i);return n}var vl=new WeakMap,yl=class e{view;media;members=new Set;pending=new Set;sizes=new WeakMap;intersections=new WeakMap;resize;intersection;frame=0;static for(t){let n=vl.get(t);return n||(n=new e(t),vl.set(t,n)),n}constructor(e){this.view=e,this.media=e.matchMedia(`(prefers-reduced-motion: reduce)`),this.media.addEventListener(`change`,this.preferences),e.document.addEventListener(`visibilitychange`,this.preferences),e.document.fonts?.addEventListener(`loadingdone`,this.fonts),e.document.fonts?.ready.then(()=>this.fonts()),e.ResizeObserver&&(this.resize=new e.ResizeObserver(e=>{for(let t of e){let e=this.sizes.get(t.target);e?.sizeChanged(t.target,t.contentRect.width,t.contentRect.height)&&e.refresh()}})),e.IntersectionObserver&&(this.intersection=new e.IntersectionObserver(e=>{for(let t of e)this.intersections.get(t.target)?.visibility(t.isIntersecting)},{rootMargin:`64px`}))}preferences=()=>{for(let e of this.members)e.preferenceChanged()};fonts=()=>{for(let e of this.members)e.refresh()};add(e,t){this.members.add(e),this.intersections.set(t,e),this.intersection?.observe(t)}watch(e,t){this.sizes.set(e,t),this.resize?.observe(e)}unwatch(e){this.resize?.unobserve(e),this.sizes.delete(e)}enqueue(e){this.pending.add(e),!this.frame&&(this.frame=this.view.requestAnimationFrame(()=>{this.frame=0;let e=[...this.pending];this.pending.clear();let t=e.map(e=>e.stage());for(let e of t)e?.();let n=e.map(e=>e.measure());for(let e of n)e?.()}))}remove(e,t){this.pending.delete(e),this.members.delete(e),this.intersection?.unobserve(t),this.intersections.delete(t),!this.members.size&&(this.view.cancelAnimationFrame(this.frame),this.resize?.disconnect(),this.intersection?.disconnect(),this.media.removeEventListener(`change`,this.preferences),this.view.document.removeEventListener(`visibilitychange`,this.preferences),this.view.document.fonts?.removeEventListener(`loadingdone`,this.fonts),vl.delete(this.view))}},bl=new WeakMap;function xl(e){let t=e.ownerDocument.defaultView;if(!t)return!1;let n=bl.get(t);return n===void 0&&(n=t.CSS?.supports(`animation-timing-function`,`linear(0, 1)`)??!1,bl.set(t,n)),n}var Sl=class{element;property;animation;motion;value=0;constructor(e,t){this.element=e,this.property=t}read(){let e=this.animation?.currentTime;return this.animation&&this.motion?pl(this.motion,typeof e==`number`?e:0):{position:this.value,velocity:0}}set(e,t){this.cancel(),this.value=e,this.element.style.setProperty(this.property,t(e))}play(e,t,n){if(this.cancel(),this.value=e.target,this.motion=e,this.element.style.setProperty(this.property,t(e.target)),!e.duration||e.points.every(t=>t===e.target)){n?.();return}let r=e.points[0]??e.target,i=e.target-r,a=this.property===`transform`&&Math.abs(i)>1e-5&&xl(this.element),o=a?[{[this.property]:t(r)},{[this.property]:t(e.target)}]:e.points.map(e=>({[this.property]:t(e)})),s=a?`linear(${e.points.map(e=>Number(((e-r)/i).toFixed(6))).join(`,`)})`:`linear`,c=this.element.animate(o,{duration:e.duration,easing:s});this.animation=c,c.onfinish=()=>{this.animation===c&&(this.animation=void 0,this.motion=void 0,c.onfinish=null,c.cancel(),n?.())}}cancel(){this.animation&&=(this.animation.onfinish=null,this.animation.cancel(),void 0),this.motion=void 0}},Cl=`http://www.w3.org/2000/svg`,wl=0,Tl=class{host;layers=new Map;filter;intensity=1;constructor(e){this.host=e}filterUrl(e){if(!this.filter){let e=this.host.ownerDocument,t=e.createElementNS(Cl,`svg`);t.classList.add(`rn-blur-defs`),t.setAttribute(`aria-hidden`,`true`),t.setAttribute(`focusable`,`false`);let n=e.createElementNS(Cl,`filter`),r;do r=`rn-vertical-blur-${++wl}`;while(e.getElementById(r));n.id=r,n.setAttribute(`x`,`-15%`),n.setAttribute(`width`,`130%`),n.setAttribute(`color-interpolation-filters`,`sRGB`);let i=e.createElementNS(Cl,`feGaussianBlur`);n.append(i),t.append(n),this.host.append(t),this.filter={svg:t,blur:i,id:r,height:0}}let t=e*.035*this.intensity;return this.filter.height!==t&&(this.filter.blur.setAttribute(`stdDeviation`,`0 ${t}`),this.filter.height=t),`url("#${this.filter.id}")`}apply(e,t,n,r,i=`roll`){let a=fl(t,r,i===`entry`?6:24);if(a.points.every(e=>e===0))return!1;let o=this.host.ownerDocument.createElement(`span`);o.className=`rn-sharp`,o.append(...e.childNodes);let s=o.cloneNode(!0);s.className=`rn-smear`,s.style.filter=this.filterUrl(n),e.append(o,s);let c=new Sl(o,`opacity`),l=new Sl(s,`opacity`);return this.layers.set(e,{sharp:o,sharpOpacity:c,smearOpacity:l}),c.play(a,e=>String(1-e)),l.play(a,String),!0}remove(e){let t=this.layers.get(e);if(!t)return 0;let n=t.smearOpacity.read().position;return t.sharpOpacity.cancel(),t.smearOpacity.cancel(),e.replaceChildren(...t.sharp.childNodes),this.layers.delete(e),n}destroy(){for(let e of this.layers.keys())this.remove(e);this.filter?.svg.remove(),this.filter=void 0}},El=new WeakSet,Dl=e=>`translateX(${e}px)`,Ol=e=>`scale(${e})`,kl=e=>String(Math.max(0,Math.min(1,e)));function Al(e){if(e.duration!==void 0&&(!Number.isFinite(e.duration)||e.duration<0||e.duration>1e4))throw RangeError(`duration must be between 0 and 10000 milliseconds`)}var jl={validate(e){if(typeof e.value!=`number`&&typeof e.value!=`bigint`)throw TypeError(`value must be a number or bigint`);Al(e)},model:e=>sl(e.value,e),direction:cl},Ml=class{host;source;options;target;displayed;semantic;measurement;visual;measures=new Map;columns=new Map;sizes=new Map;scheduler;enhanced=!1;destroyed=!1;visible=!0;reset=!0;measurementPending=!1;hadClass;previousLeft;blur;blurIntensity=1;constructor(e,t,n){this.host=e,this.source=n,n.validate(t),this.options={...t},this.target=this.displayed=n.model(t);let r=e.ownerDocument,i=e=>{let t=r.createElement(`span`);return t.className=e,t};this.semantic=i(`rn-value`),this.measurement=i(`rn-measure`),this.visual=i(`rn-visual`),this.measurement.setAttribute(`aria-hidden`,`true`),this.visual.setAttribute(`aria-hidden`,`true`),this.semantic.textContent=this.target.text,this.hadClass=e.classList.contains(`rn-root`),e.classList.add(`rn-root`),e.replaceChildren(this.semantic,this.measurement,this.visual);let a=r.defaultView;a&&typeof a.matchMedia==`function`&&typeof a.requestAnimationFrame==`function`&&typeof e.animate==`function`&&(this.scheduler=yl.for(a),this.scheduler.add(this,e),this.scheduler.watch(this.measurement,this)),this.prepare()}canAnimate(){return!!this.scheduler&&this.options.animated!==!1&&(this.options.duration??500)>0&&!this.scheduler.media.matches&&!this.host.ownerDocument.hidden&&(this.visible||this.options.pauseOffscreen===!1)&&this.target.rollable&&this.host.isConnected}update(e){if(this.destroyed)return;let t={...this.options,...e};this.source.validate(t);let n=this.source.model(t),r=n.text===this.target.text&&n.signature===this.target.signature;if(this.options.motionBlur&&!t.motionBlur&&(this.blur?.destroy(),this.blur=void 0),this.options=t,this.target=n,!this.canAnimate()){this.finish();return}r&&this.enhanced||(this.semantic.textContent=n.text,this.prepare())}prepare(){if(!this.canAnimate()){this.finish();return}this.measurementPending=!0,this.scheduler?.enqueue(this)}stage(){if(!this.destroyed)return this.canAnimate()?(this.previousLeft=this.enhanced&&!this.reset?this.measurement.getBoundingClientRect().left:void 0,()=>this.stageMeasurement()):()=>this.finish()}stageMeasurement(){let e=new Set(this.target.tokens.map(e=>e.key));for(let[t,n]of this.measures)e.has(t)||(this.scheduler?.unwatch(n),this.sizes.delete(n),n.remove(),this.measures.delete(t));let t=null;for(let e of this.target.tokens){let n=this.measures.get(e.key);n||(n=this.host.ownerDocument.createElement(`span`),n.className=`rn-token`,this.measures.set(e.key,n),this.scheduler?.watch(n,this)),n.textContent!==e.text&&(n.textContent=e.text);let r=t?t.nextSibling:this.measurement.firstChild;n!==r&&this.measurement.insertBefore(n,r),t=n}this.host.dataset.rnMeasuring=``}measure(){if(this.destroyed)return;if(!this.canAnimate())return()=>this.finish();let e=this.measurement.getBoundingClientRect(),t=this.host.ownerDocument.defaultView;if(!t)return()=>this.finish();let n=t.getComputedStyle(this.measurement);if(n.direction===`rtl`)return()=>this.finish();let r=parseFloat(n.width),i=parseFloat(n.height);if(!r||!i||!e.width||!e.height)return()=>this.finish();let a=e.width/r,o=e.height/i;this.blurIntensity=Math.max(0,parseFloat(n.getPropertyValue(`--rn-blur`))||1),this.sizes.set(this.measurement,{width:r,height:i});let s=new Map;for(let[t,n]of this.measures){let r=n.getBoundingClientRect(),i={width:r.width/a,height:r.height/o};this.sizes.set(n,i),s.set(t,{...i,x:(r.left-e.left)/a,y:(r.top-e.top)/o})}let c=this.previousLeft===void 0?0:(this.previousLeft-e.left)/a;return()=>this.commit(s,c)}makeColumn(e){let t=this.host.ownerDocument.createElement(`span`);t.className=`rn-slot`,t.dataset.rnKey=e.key,e.index!==void 0&&(t.dataset.rnWheel=``);let n=this.host.ownerDocument.createElement(`span`);return n.className=`rn-reel`,t.append(n),this.visual.append(t),{token:e,element:t,reel:n,x:new Sl(t,`transform`),opacity:new Sl(t,`opacity`),roll:new Sl(n,`transform`),exiting:!1,height:0,width:0}}face(e,t){let n=this.host.ownerDocument.createElement(`span`);n.className=`rn-face`,n.textContent=t,n.style.height=`${e.height}px`,e.reel.append(n)}rest(e){this.blur?.remove(e.reel),e.reel.replaceChildren(),this.face(e,e.token.text),e.token.index===void 0?e.roll.set(1,Ol):e.roll.set(e.token.index,()=>`translateY(0px)`)}finishEntry(e){e.entry&&=(e.entry.blurred&&this.blur?.remove(e.reel),e.entry.track.cancel(),e.entry.element.replaceWith(e.reel),void 0)}enter(e,t,n){let r=this.host.ownerDocument.createElement(`span`);r.className=`rn-enter`,e.reel.replaceWith(r),r.append(e.reel);let i=new Sl(r,`transform`);e.entry={element:r,track:i,blurred:!1};let a=ul(ll(e.height,t),n);if(this.options.motionBlur&&e.token.text.trim()){this.blur??=new Tl(this.host),this.blur.intensity=this.blurIntensity;let t={...a,points:a.points.map(t=>t/e.height)};e.entry.blurred=this.blur.apply(e.reel,t,e.height,0,`entry`)}i.play(a,e=>`translateY(${e}px)`,()=>this.finishEntry(e))}commit(e,t){if(this.destroyed)return;this.measurementPending=!1;let n=this.enhanced&&!this.reset,r=n?this.options.duration??500:0,i=this.options.direction===`up`?1:this.options.direction===`down`?-1:this.source.direction(this.displayed,this.target);this.target.text!==this.displayed.text&&(this.host.dataset.rnTrend=i>0?`up`:i<0?`down`:`none`);let a=new Map([...this.columns].map(([e,t])=>{let n=t.x.read();return[e,{...n,x:n.position,width:t.width}]})),o=_l(this.target.tokens.map(e=>e.key),a),s=_l([...a.keys()].sort((e,t)=>a.get(e).x-a.get(t).x),e),c=new Map(this.displayed.tokens.filter(e=>e.index===void 0).map(e=>[e.identity,e.key])),l=new Map(this.target.tokens.filter(e=>e.index===void 0).map(e=>[e.identity,e.key])),u=gl(this.target.tokens.map(e=>e.index!==void 0&&this.columns.has(e.key)&&!this.columns.get(e.key).exiting),this.options.stagger),d=Math.max(0,...this.target.tokens.map((e,t)=>this.columns.has(e.key)?0:u[t]-1)),f=Math.min(r*.045,r*.3/Math.max(1,d));for(let[s,l]of this.target.tokens.entries()){let d=e.get(l.key);if(!d)continue;let p=Math.max(0,u[s]-1)*f,m=c.get(l.identity),h=m!==void 0&&m!==l.key?a.get(m):void 0,g=this.columns.get(l.key),_=!g;g||(g=this.makeColumn(l),this.columns.set(l.key,g),g.x.set(n?(h?.x??o.get(l.key)??d.x)+t:d.x,Dl),g.opacity.set(+!n,kl));let v=g.token.text!==l.text,y=Math.abs(g.height-d.height)>.1,b=g.exiting;g.exiting=!1,g.element.style.width=`${d.width}px`,g.element.style.height=`${d.height}px`,g.element.style.top=`${d.y}px`;let x=a.get(l.key);if(g.x.play(dl(x?x.position+t:g.x.read().position,d.x,x?.velocity??0,r),Dl),_||b||!n){let e=g.opacity.read(),t=dl(e.position,1,e.velocity,l.index===void 0?Math.min(r,180):r);g.opacity.play(_?ul(t,p):t,kl)}if(g.height=d.height,g.width=d.width,(!n||y)&&this.finishEntry(g),!_&&!y&&v&&l.index!==void 0&&l.wheel&&g.token.index!==void 0&&r){let e=g.roll.read(),t=dl(e.position,ml(e.position,l.index,i,l.wheel.length),e.velocity,r),n=Math.floor(Math.min(...t.points)),a=Math.ceil(Math.max(...t.points));g.entry&&(g.entry.blurred=!1);let o=this.blur?.remove(g.reel)??0;g.reel.replaceChildren();for(let e=n;e<=a;e++)this.face(g,hl(l.wheel,e));this.options.motionBlur&&(this.blur??=new Tl(this.host),this.blur.intensity=this.blurIntensity,this.blur.apply(g.reel,t,d.height,o)),g.token=l;let s=g;g.roll.play(t,e=>`translateY(${(n-e)*d.height}px)`,()=>this.rest(s))}else (_||y||v||!n)&&(g.token=l,this.rest(g));if(_&&r&&l.index!==void 0&&this.enter(g,r,p),h&&r&&(_||b)){let e=g.roll.read(),t=g;g.roll.play(dl(_?.96:e.position,1,e.velocity,Math.min(r,180)),Ol,()=>this.rest(t))}}for(let[n,i]of this.columns){if(e.has(n))continue;let o=a.get(n),c=l.get(i.token.identity),u=c?e.get(c):void 0;if(i.x.play(dl(o.position+t,u?.x??s.get(n)??o.position,o.velocity,r),Dl),i.exiting)continue;if(i.exiting=!0,u&&r){let e=i.roll.read();i.roll.play(dl(e.position,1.04,e.velocity,Math.min(r,180)),Ol)}let d=i.opacity.read();i.opacity.play(dl(d.position,0,d.velocity,i.token.index===void 0?Math.min(r,180):r*.65),kl,()=>{i.exiting&&(this.removeColumn(i),this.columns.delete(n))})}this.enhanced=!0,this.reset=!1,this.displayed=this.target,this.host.dataset.rnReady=``}removeColumn(e){this.blur?.remove(e.reel),this.finishEntry(e),e.x.cancel(),e.roll.cancel(),e.opacity.cancel(),e.element.remove()}refresh(){this.destroyed||(this.reset=!0,this.prepare())}sizeChanged(e,t,n){if(this.measurementPending||!this.host.hasAttribute(`data-rn-measuring`))return!1;let r=this.sizes.get(e);return!r||Math.abs(r.width-t)>.2||Math.abs(r.height-n)>.2}visibility(e){this.visible!==e&&(this.visible=e,(e||this.options.pauseOffscreen!==!1)&&this.refresh())}preferenceChanged(){this.refresh()}finish(){if(!this.destroyed){this.measurementPending=!1;for(let e of this.columns.values())this.removeColumn(e);this.columns.clear(),this.blur?.destroy(),this.blur=void 0,this.semantic.textContent=this.target.text,delete this.host.dataset.rnReady,delete this.host.dataset.rnMeasuring,delete this.host.dataset.rnTrend,this.enhanced=!1,this.reset=!0,this.displayed=this.target}}destroy(){if(!this.destroyed){this.finish(),this.destroyed=!0;for(let e of this.measures.values())this.scheduler?.unwatch(e);this.scheduler?.unwatch(this.measurement),this.scheduler?.remove(this,this.host),this.host.replaceChildren(this.host.ownerDocument.createTextNode(this.target.text)),!this.hadClass&&this.host.classList.remove(`rn-root`),El.delete(this.host)}}};function Nl(e,t){if(El.has(e))throw Error(`A rolling number is already mounted on this element`);let n=new Ml(e,t,jl);return El.add(e),n}var Pl=I(` `,1);function Fl(e,t){n(t,!0);let r=Y(t,`digits`,3,0),i=Y(t,`signed`,3,!1),a=c(()=>({value:t.value,locales:`en-US`,format:t.format??{useGrouping:!1,minimumFractionDigits:r(),maximumFractionDigits:r(),signDisplay:i()?`always`:`auto`},duration:280,stagger:`none`,motionBlur:!1,pauseOffscreen:!0})),o=c(()=>new Intl.NumberFormat(`en-US`,B(a).format).format(t.value));function s(e,t){let n=Nl(e,t);return{update:e=>n.update(e),destroy:()=>n.destroy()}}var l=Pl(),u=q(l),d=R(u,!0);f(u);var p=X(u);w(p,(e,t)=>s?.(e,t),()=>B(a)),U(()=>{G(d,B(o)),S(p,`data-value`,t.value)}),g(e,l),W()}function Il(e,t=!1){return Number.isFinite(e)?e!==0&&Math.abs(e)<1e-4?t?e<0?`−<0.01%`:`<0.01%`:e.toExponential(2):t?`${(e*100).toLocaleString(`en-US`,{maximumFractionDigits:2})}%`:e.toLocaleString(`en-US`,{maximumFractionDigits:4}):`Not available`}function Ll(e,t,n=!1){return Number.isFinite(e)?n?Il(e,!0):!Number.isFinite(t)||t<=0?`${Il(e)} · scale unavailable`:`${Il(e)} · ${Il(Math.abs(e)/t,!0)} of scale (${Il(t)})`:`Not available`}function Rl(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&t>0?Math.min(1,Math.abs(e)/t):0}var zl=I(``),Bl=I(` `);function Vl(e,t){n(t,!0);let r=Y(t,`width`,3,144),i=Y(t,`height`,3,8),a=Y(t,`showBaseline`,3,!1),o=Y(t,`bipolar`,3,!1),s=Y(t,`percentage`,3,!1),l=c(()=>Rl(t.value,t.max)*(o()?50:100)),u=c(()=>o()?t.value<0?50-B(l):50:0),d=c(()=>t.color??(t.value>0?`var(--accent-green)`:t.value<0?`var(--accent-red)`:`var(--fg-muted)`)),m=c(()=>t.title??Ll(t.value,t.max,s()));var h=Bl();let _,v;var b=R(h);let x;var C=X(b,2),w=e=>{g(e,zl())};p(C,e=>{o()&&e(w)}),f(h),U(()=>{_=y(h,1,`bar svelte-irr9qk`,null,_,{baseline:a()}),S(h,`title`,B(m)),S(h,`aria-label`,B(m)),v=pe(h,``,v,{"--bar-width":`${r()}px`,height:`${i()}px`}),x=pe(b,``,x,{left:`${B(u)}%`,width:`${B(l)}%`,"--fill":B(d)})}),g(e,h),W()}var Hl=I(` `),Ul=I(`
`);function Wl(e,t){n(t,!0);let r=Y(t,`scale`,3,un),i=Y(t,`size`,3,14),a=Y(t,`positiveColor`,3,`var(--layer-cell-positive)`),o=Y(t,`negativeColor`,3,`var(--layer-cell-negative)`),s=Y(t,`active`,3,!1),l=Y(t,`showValue`,3,!1),u=c(()=>t.value===null||t.value===void 0||!Number.isFinite(t.value)),d=c(()=>{if(B(u))return 0;let e=Number.isFinite(r())&&r()>1e-6?r():un;return Math.max(-1,Math.min(1,t.value/e))}),m=c(()=>{if(B(u))return`var(--layer-cell-empty)`;let e=B(d);if(Math.abs(e)<1e-9)return`var(--layer-cell-neutral)`;let t=e>0?a():o(),n=15+Math.abs(e)*85;return`color-mix(in srgb, var(--layer-cell-neutral) ${100-n}%, ${t} ${n}%)`}),h=c(()=>!B(u)&&Math.abs(B(d))>=.55?`var(--text-on-accent)`:`var(--fg)`),_=c(()=>t.title??(B(u)?`-`:t.value.toFixed(3))),v=c(()=>l()&&!B(u)?t.value.toFixed(2):``);var b=Ul();let x;var C=R(b),w=e=>{var t=Hl(),n=R(t,!0);f(t),U(()=>G(n,B(v))),g(e,t)};p(C,e=>{B(v)&&e(w)}),f(b),U(()=>{x=y(b,1,`cell svelte-w2uko1`,null,x,{active:s()}),pe(b,`width: ${i()??``}px; height: ${i()??``}px; background: ${B(m)??``}; color: ${B(h)??``};`),S(b,`title`,B(_)),S(b,`aria-label`,B(_))}),g(e,b),W()}var Gl=I(`
`),Kl=I(`
`,1),ql=I(`
`),Jl=I(`
`);function Yl(e,t){n(t,!0);let r=Y(t,`emptyMessage`,3,`no data yet, generate a token first`),i=J(0),a=J(!1);Ce(()=>{B(i)>=t.cells.length&&A(i,Math.max(0,t.cells.length-1),!0)});function o(e){if(t.cells.length!==0){if(e.key===`ArrowRight`)A(i,Math.min(t.cells.length-1,B(i)+1),!0);else if(e.key===`ArrowLeft`)A(i,Math.max(0,B(i)-1),!0);else if(e.key===`Home`)A(i,0);else if(e.key===`End`)A(i,t.cells.length-1);else return;e.preventDefault()}}var s=Jl(),l=R(s),u=R(l),d=e=>{var t=Gl(),n=R(t,!0);f(t),U(()=>G(n,r())),g(e,t)},h=e=>{var n=Kl(),r=q(n),o=R(r);f(r);var s=X(r,2);m(s,23,()=>t.cells,e=>e.layer,(e,n,r)=>{{let o=c(()=>B(a)&&B(r)===B(i));Wl(e,{get value(){return B(n).value},get scale(){return t.scale},size:13,get title(){return B(n).title},get positiveColor(){return t.positiveColor},get negativeColor(){return t.negativeColor},get active(){return B(o)}})}}),f(s);var l=X(s,2),u=R(l);f(l),U(()=>{G(o,`L${t.cells[0].layer??``}`),G(u,`L${t.cells[t.cells.length-1].layer??``}`)}),g(e,n)};p(u,e=>{t.cells.length===0?e(d):e(h,-1)}),f(l);var _=X(l,2),v=e=>{var n=ql(),r=R(n,!0);f(n),U(()=>G(r,t.cells[B(i)].title)),g(e,n)};p(_,e=>{B(a)&&t.cells[B(i)]&&e(v)}),f(s),U(e=>{S(l,`aria-label`,t.ariaLabel),S(l,`aria-valuemax`,e),S(l,`aria-valuenow`,B(i)),S(l,`aria-valuetext`,t.cells[B(i)]?.title??r()),S(l,`tabindex`,t.cells.length>0?0:void 0)},[()=>Math.max(0,t.cells.length-1)]),ye(`focus`,l,()=>A(a,!0)),ye(`blur`,l,()=>A(a,!1)),K(`keydown`,l,o),g(e,s),W()}H([`keydown`]);function Xl(e){return e*e*e}function Zl(e){let t=e-1;return t*t*t+1}var Ql=()=>typeof window<`u`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches;function $l(e){return Ql()?0:e}function eu(){return{duration:$l(160),easing:Zl}}function tu(){return{duration:$l(110),easing:Xl}}function nu(e=18,t=0){return{x:e,y:t,duration:$l(220),easing:Zl}}function ru(e=10,t=0){return{x:e,y:t,duration:$l(150),easing:Xl}}function iu(e=-8){return{y:e,duration:$l(200),easing:Zl}}function au(e=-4){return{y:e,duration:$l(130),easing:Xl}}function ou(e=4){return{y:e,duration:$l(170),easing:Zl}}function su(e=-2){return{y:e,duration:$l(100),easing:Xl}}function cu(e){let t=getComputedStyle(e);return{duration:$l(Number.parseFloat(t.getPropertyValue(`--selection-dur`))*1e3),easing:Zl,css:e=>`opacity: ${e}; transform: translateY(${(1-e)*4}px);`}}function lu(){return{duration:$l(200),easing:Zl}}function uu(){return{duration:$l(130),easing:Xl}}function du(){let e=J(!1),t;function n(){clearTimeout(t),t=void 0}return{get mounted(){return B(e)},mount(){n(),A(e,!0)},show(e){n(),e.inert=!1,e.offsetHeight,e.classList.remove(`is-closing`),e.classList.add(`is-open`)},close(r){if(n(),!r){A(e,!1);return}r.inert=!0,r.classList.remove(`is-open`),r.classList.add(`is-closing`);let i=getComputedStyle(r).getPropertyValue(`--dropdown-close-dur`).trim(),a=parseFloat(i)*(i.endsWith(`ms`)?1:1e3),o=()=>{r.classList.remove(`is-closing`),A(e,!1)},s=$l(a);s===0?o():t=setTimeout(o,s)},destroy(){n()}}}var fu=I(`
  • `),pu=I(`
      `),mu=I(`
      `);function hu(e,t){let r=E();n(t,!0);let i=Y(t,`value`,15),o=Y(t,`placeholder`,3,``),s=Y(t,`disabled`,3,!1),l=Y(t,`invalid`,3,!1),u=J(!1),d=du(),h=J(-1),_=J(null),v=J(null),b=J(``),x=J(``),C=null;Ce(()=>{s()&&B(u)&&k(!1)});let w=c(()=>t.options.findIndex(e=>e.value===i())),T=c(()=>B(w)>=0?t.options[B(w)].label:``);async function D(e){let n=t.options[e];!n||n.disabled||(i(n.value),t.onchange?.(n.value),k(!0),await xe())}async function O(){if(!s()&&(A(u,!0),d.mount(),A(h,B(w)>=0?B(w):M(0,1),!0),await xe(),B(u))){try{B(v)?.showPopover()}catch{}te(),await xe(),!(!B(u)||!B(v))&&(d.show(B(v)),B(v)?.focus())}}function k(e){B(u)&&(A(u,!1),d.close(B(v)),A(x,``),e&&queueMicrotask(()=>B(_)?.focus()))}function j(){B(u)?k(!1):O()}function M(e,n){if(t.options.length===0)return-1;let r=e;for(let e=0;e=0&&r=t.options.length&&(r=0)}return-1}function P(e){if(t.options.length===0)return;let n=B(h);for(let r=0;r=t.options.length&&(n=0),!t.options[n].disabled){A(h,n,!0),F();return}}function F(){if(!B(v)||B(h)<0)return;let e=B(v).children[B(h)];if(!e)return;let t=e.offsetTop,n=t+e.offsetHeight;tB(v).scrollTop+B(v).clientHeight&&(B(v).scrollTop=n-B(v).clientHeight)}function I(e){if(e.length!==1)return;let n=e.toLowerCase();if(!/[a-z0-9]/.test(n))return;A(x,B(x)+n),C&&clearTimeout(C),C=setTimeout(()=>{A(x,``),C=null},600);let r=B(x),i=B(h)>=0?(B(h)+1)%t.options.length:0;for(let e=0;e=0&&D(B(h));break;case`Escape`:e.preventDefault(),e.stopPropagation(),k(!0);break;case`Tab`:setTimeout(()=>k(!1),0);break;default:I(e.key)}}function te(){if(!B(_)||!B(v))return;let e=B(_).getBoundingClientRect(),t=window.visualViewport,n=t?.offsetLeft??0,r=t?.offsetTop??0,i=t?.width??window.innerWidth,a=r+(t?.height??window.innerHeight),o=Math.max(0,a-e.bottom-8-2),s=Math.max(0,e.top-r-8-2),c=Math.min(280,Math.max(40,B(v).scrollHeight)),l=oo,u=Math.max(40,Math.min(280,l?s:o)),d=Math.min(c,u),f=Math.min(e.width,i-16);A(b,`left:${Math.max(n+8,Math.min(e.left,n+i-f-8))}px;top:${l?Math.max(r+8,e.top-d-2):Math.min(a-d-8,e.bottom+2)}px;width:${f}px;max-height:${u}px`),B(v).dataset.origin=l?`bottom-left`:`top-left`}function z(e){if(!B(u))return;let t=e.target;B(_)?.contains(t)||B(v)?.contains(t)||k(!1)}function V(){B(u)&&te()}ne(()=>(document.addEventListener(`mousedown`,z,!0),window.addEventListener(`resize`,V),window.addEventListener(`scroll`,V,!0),window.visualViewport?.addEventListener(`resize`,V),window.visualViewport?.addEventListener(`scroll`,V),()=>{document.removeEventListener(`mousedown`,z,!0),window.removeEventListener(`resize`,V),window.removeEventListener(`scroll`,V,!0),window.visualViewport?.removeEventListener(`resize`,V),window.visualViewport?.removeEventListener(`scroll`,V),C&&clearTimeout(C),d.destroy()}));var re=mu();let ie;var ae=R(re),oe=R(ae);let H;var se=R(oe,!0);f(oe);var ce=X(oe,2);Be(R(ce),{name:`down`}),f(ce),f(ae),a(ae,e=>A(_,e),()=>B(_));var le=X(ae,2),ue=e=>{var n=pu();m(n,21,()=>t.options,N,(e,t,n)=>{var i=fu();let a;var o=R(i,!0);f(i),U(()=>{S(i,`id`,`${r}-opt-${n}`),a=y(i,1,`sk-select-opt svelte-1v3k3t3`,null,a,{"is-highlight":n===B(h),"is-active":n===B(w),"is-disabled":!!B(t).disabled}),S(i,`aria-selected`,n===B(w)),S(i,`aria-disabled`,!!B(t).disabled),G(o,B(t).label)}),ye(`mouseenter`,i,()=>B(t).disabled?null:A(h,n,!0)),K(`click`,i,e=>{e.preventDefault(),e.stopPropagation(),D(n)}),K(`keydown`,i,ee),g(e,i)}),f(n),a(n,e=>A(v,e),()=>B(v)),U(()=>{S(n,`id`,`${r}-listbox`),pe(n,B(b)),S(n,`aria-invalid`,l()),S(n,`aria-label`,t.ariaLabel),S(n,`aria-activedescendant`,B(h)>=0?`${r}-opt-${B(h)}`:void 0)}),K(`keydown`,n,ee),g(e,n)};p(le,e=>{d.mounted&&e(ue)}),f(re),U(()=>{ie=y(re,1,`sk-select svelte-1v3k3t3`,null,ie,{"is-open":B(u),"is-disabled":s()}),ae.disabled=s(),S(ae,`title`,t.title),S(ae,`aria-expanded`,B(u)),S(ae,`aria-controls`,B(u)?`${r}-listbox`:void 0),S(ae,`aria-label`,t.ariaLabel),S(ae,`data-invalid`,l()||void 0),S(ae,`aria-describedby`,t.ariaDescribedby),H=y(oe,1,`sk-select-label svelte-1v3k3t3`,null,H,{"is-placeholder":B(w)<0}),G(se,B(T)||o())}),K(`click`,ae,j),K(`keydown`,ae,L),g(e,re),W()}H([`click`,`keydown`]);var gu=I(`
      `),_u=I(`

      Subspace fraction

      `),vu=I(`
      Layer readings
      `);function yu(e,t){n(t,!0);let r=J(``),i=c(()=>Object.keys(t.reading.coords_per_layer??{}).filter(e=>Number.isSafeInteger(Number(e))&&Number(e)>=0&&t.reading.coords_per_layer[e]?.length>0).sort((e,t)=>Number(e)-Number(t))),a=c(()=>B(i).includes(B(r))?B(r):B(i)[0]),o=c(()=>t.reading.coords_per_layer?.[B(a)]??[]),s=c(()=>t.reading.fraction_per_layer?.[B(a)]);var l=L(),u=q(l),d=e=>{var n=vu(),l=R(n),u=X(R(l),2);{let e=c(()=>B(i).map(e=>({value:e,label:`Layer ${e}`}))),n=c(()=>`${t.name} layer`);hu(u,{get value(){return B(a)},get options(){return B(e)},onchange:e=>{A(r,e,!0)},get ariaLabel(){return B(n)}})}f(l);var d=X(l,2),h=R(d);m(h,17,()=>B(o),N,(e,n,r)=>{var i=gu(),o=R(i),s=R(o,!0);f(o);var l=X(o,2);{let e=c(()=>Zr(t.name,r));Vl(l,{get value(){return B(n)},get max(){return B(e)},bipolar:!0})}var u=X(l,2),d=R(u,!0);f(u),f(i),U(e=>{S(i,`aria-label`,`${t.name} layer ${B(a)} axis ${r}`),G(s,t.axisLabels[r]??`c${r}`),G(d,e)},[()=>B(n).toFixed(3)]),g(e,i)});var _=X(h,2),v=e=>{var t=_u(),n=X(R(t)),r=R(n,!0);f(n),f(t),U(e=>G(r,e),[()=>B(s).toFixed(3)]),g(e,t)};p(_,e=>{B(s)!=null&&e(v)}),f(d),f(n),U(()=>S(n,`aria-label`,`${t.name} layer readings`)),g(e,n)};p(u,e=>{B(i).length>0&&e(d)}),g(e,l),W()}var bu=I(`
      `);function xu(e,t){var n=bu(),i=R(n);r(R(i),()=>t.left),f(i);var a=X(i,2);r(R(a),()=>t.bar),f(a);var o=X(a,2);r(R(o),()=>t.middle),f(o);var s=X(o,2);r(R(s),()=>t.right),f(s),f(n),U(()=>S(n,`aria-label`,t.ariaLabel)),g(e,n)}var Su=I(`
      `);function Cu(e,t){let n=Y(t,`accent`,3,`--accent`),i=Y(t,`disabled`,3,!1),a=Y(t,`active`,3,!1);var o=Su();let s,c;var l=R(o);r(R(l),()=>t.statline),f(l);var u=X(l,2);r(R(u),()=>t.body),f(u),f(o),U(()=>{s=y(o,1,`card svelte-17l5p3y`,null,s,{disabled:i(),active:a()}),c=pe(o,``,c,{"--card-accent":`var(${n()??``})`})}),g(e,o)}var wu=I(``);function Tu(e,t){let n=Y(t,`filled`,3,!1),r=c(()=>t.shape===`circle`?n()?`●`:`○`:t.shape===`diamond`?n()?`◆`:`◇`:t.shape===`triangle`?n()?`▲`:`△`:n()?`■`:`□`);var i=wu(),a=R(i,!0);f(i),U(()=>{y(i,1,`marker ${t.shape??``}`,`svelte-1a5iijm`),G(a,B(r))}),g(e,i)}var Eu=I(``);function Du(e,t){let n=Y(t,`variant`,3,`ghost`),i=Y(t,`size`,3,`md`),a=Y(t,`disabled`,3,!1),o=Y(t,`busy`,3,!1),s=Y(t,`static`,3,!1),c=Y(t,`type`,3,`button`);var l=Eu();let u,d;r(R(l),()=>t.children),f(l),U(()=>{u=y(l,1,`sk-btn ${n()??``} ${i()??``}`,`svelte-g9c1iq`,u,{accented:t.accent!==void 0,"loading-pulse":o(),static:s()}),l.disabled=a(),S(l,`title`,t.title),S(l,`aria-label`,t.ariaLabel),S(l,`aria-busy`,o()||void 0),S(l,`type`,c()),d=pe(l,``,d,{"--btn-accent":t.accent,"--btn-solid-fill":t.accent??`var(--action-bg)`,"--btn-solid-ink":t.accent?`var(--text-on-accent)`:`var(--action-ink)`})}),K(`click`,l,function(...e){t.onclick?.apply(this,e)}),g(e,l)}H([`click`]);var Ou=I(`

      `),ku=I(`
      `),Au=I(`

      `);function ju(e,t){let n=Y(t,`detail`,3,null);var i=Au(),a=R(i),o=R(a,!0);f(a);var s=X(a,2),c=e=>{var t=Ou(),r=R(t,!0);f(t),U(()=>G(r,n())),g(e,t)};p(s,e=>{n()&&e(c)});var l=X(s,2),u=e=>{var n=ku();r(R(n),()=>t.children),f(n),g(e,n)};p(l,e=>{t.children&&e(u)}),f(i),U(()=>G(o,t.title)),g(e,i)}var Mu=I(` `),Nu=I(` `),Pu=I(` `),Fu=I(`steered: `),Iu=I(`unsteered`),Lu=I(``),Ru=I(`
      readout
      `);function zu(e,t){n(t,!0);let r=Y(t,`source`,3,null),i=Y(t,`layer`,3,null),a=Y(t,`steered`,15),o=Y(t,`accent`,3,`var(--accent)`);var s=Ru();let c;var l=X(R(s),2),u=e=>{var n=Mu(),r=R(n,!0);f(n),U(()=>{S(n,`title`,t.origin===`captured`?`Recorded when this token was generated. No new model run was needed.`:`Computed by running the recorded context through the model again.`),G(r,t.origin)}),g(e,n)};p(l,e=>{t.origin&&e(u)});var d=X(l,2),m=e=>{var t=Nu(),n=R(t,!0);f(t),U(()=>G(n,r())),g(e,t)};p(d,e=>{r()&&e(m)});var h=X(d,2),_=e=>{var t=Pu(),n=R(t);f(t),U(()=>G(n,`L${i()??``}`)),g(e,t)};p(h,e=>{i()!=null&&i()>=0&&e(_)});var v=X(h,2),b=e=>{var n=Fu(),r=X(R(n)),i=R(r,!0);f(r),f(n),U(()=>G(i,t.steering)),g(e,n)},x=e=>{g(e,Iu())};p(v,e=>{t.steering===null?a()||e(x,1):e(b)});var C=X(v,2),w=e=>{var t=Lu();let n;var r=R(t);f(t),U(()=>{n=y(t,1,`steer-toggle svelte-1drc9te`,null,n,{on:a()}),S(t,`aria-pressed`,a()),S(t,`title`,a()?`Recompute without the original steering to compare its effect.`:`Recompute using the steering saved with this generation.`),G(r,`recipe ${a()?`on`:`off`}`)}),K(`click`,t,()=>{a(!a())}),g(e,t)};p(C,e=>{t.showToggle&&e(w)}),f(s),U(()=>c=pe(s,``,c,{"--inst-accent":o()})),g(e,s),W()}H([`click`]);var Bu=I(` `),Vu=I(`

      `);function Hu(e,t){let n=Y(t,`count`,3,null),i=Y(t,`accent`,3,`var(--accent)`);var a=Vu();let o;var s=R(a),c=R(s),l=R(c),u=R(l,!0);f(l);var d=X(l,2),m=e=>{var t=Bu(),r=R(t,!0);f(t),U(()=>G(r,n())),g(e,t)};p(d,e=>{n()&&e(m)}),f(c),f(s);var h=X(s,2);r(R(h),()=>t.children),f(h),f(a),U(()=>{o=pe(a,``,o,{"--section-accent":i()}),G(u,t.title)}),g(e,a)}var Uu=I(` `),Wu=I(` `),Gu=I(` `),Ku=I(` `),qu=I(`
      `);function Ju(e,t){let n=Y(t,`secondary`,3,null),i=Y(t,`secondaryAccent`,3,!1),a=Y(t,`meta`,3,null),o=Y(t,`badge`,3,null),s=Y(t,`tail`,3,null),c=Y(t,`tailAccent`,3,!1);var l=qu(),u=R(l);r(R(u),()=>t.lead),f(u);var d=X(u,2),m=R(d,!0);f(d);var h=X(d,2),_=e=>{var r=Uu();let a;var o=R(r,!0);f(r),U(()=>{a=y(r,1,`secondary svelte-19muw5c`,null,a,{accent:i()}),S(r,`title`,t.secondaryTitle),G(o,n())}),g(e,r)};p(h,e=>{n()&&e(_)});var v=X(h,2),b=e=>{var n=Wu(),r=R(n,!0);f(n),U(()=>{S(n,`title`,t.metaTitle),G(r,a())}),g(e,n)};p(v,e=>{a()&&e(b)});var x=X(v,2),C=e=>{var n=Gu(),r=R(n,!0);f(n),U(()=>{S(n,`title`,t.badgeTitle),G(r,o())}),g(e,n)};p(x,e=>{o()&&e(C)});var w=X(x,4),T=e=>{var n=Ku();let r;var i=R(n,!0);f(n),U(()=>{r=y(n,1,`tail svelte-19muw5c`,null,r,{accent:c()}),S(n,`title`,t.tailTitle),G(i,s())}),g(e,n)};p(w,e=>{s()&&e(T)}),f(l),U(()=>{S(d,`title`,t.primaryTitle),G(m,t.primary)}),g(e,l)}var Yu=I(` `),Xu=I(` `),Zu=I(`
      `);function Qu(e,t){n(t,!0);let r=Y(t,`ariaLabel`,3,`Supporting evidence`);var i=L(),a=q(i),o=e=>{var n=Zu();m(n,21,()=>t.items,N,(e,t)=>{var n=Xu();let r;var i=R(n),a=X(i),o=e=>{var n=Yu(),r=R(n,!0);f(n),U(()=>G(r,B(t).value)),g(e,n)};p(a,e=>{B(t).value&&e(o)}),f(n),U(()=>{r=y(n,1,`chip svelte-1u6vkiq`,null,r,{soft:B(t).soft}),S(n,`title`,B(t).title),G(i,`${B(t).label??``} `)}),g(e,n)}),f(n),U(()=>S(n,`aria-label`,r())),g(e,n)};p(a,e=>{t.items.length>0&&e(o)}),g(e,i),W()}var $u=I(`%`,1),ed=I(`

      You can inspect another token while this finishes. This result will be kept.

      `),td=I(`subspace`),nd=I(` `),rd=I(` `),id=I(` `),ad=I(` `),od=I(` `),sd=I(`

      Across fitted layers

      `,1),cd=I(`
      `),ld=I(` `,1),ud=I(`

      Concept training isn’t available in this session. You can still add a fitted concept as a probe.

      `),dd=I(`
      `,1);function fd(t,r){n(r,!0);let a=Y(r,`steered`,15),o=c(()=>Object.entries(r.readout.data?.readings??{}).sort(([e],[t])=>e.localeCompare(t,void 0,{sensitivity:`base`}))),s=Ke(`manifold_builder`);function l(e=!1){rt(e?`manifold_builder`:`subspace`,{returnToToken:r.returnToToken,...e?{mode:`discover`}:{}})}let u=c(()=>r.replayAvailable&&((r.readout.data?.steering??null)!==null||!a())),d=c(()=>r.readout.progress!==null&&r.readout.progress.progress>0),h=c(()=>Math.round((r.readout.progress?.progress??0)*100)),_=c(()=>r.readout.progress?.phase===`readout`?`Reading geometry`:r.readout.progress?.phase===`queued`?`Waiting for the model`:`Preparing this token`);function v(e){let t=Hr.entries.get(e)?.info;return t?.family===`geometry`?t.is_affine:null}function b(e,t,n){let r=Hr.entries.get(e)?.info,i=r?.family===`geometry`?r.node_labels:void 0;return n===1&&t===0&&i&&i.length===2?i[0]:`c${t}`}function x(e,t){let n=v(e)===!1,r={};if(n)Object.assign(r,t.fraction_per_layer??{});else for(let[e,n]of Object.entries(t.coords_per_layer??{}))r[e]=Array.isArray(n)&&n.length>0?n[0]:0;return Object.keys(r).sort((e,t)=>Number(e)-Number(t)).map(e=>{let t=r[e],n=t>=0?`+`:``;return{layer:Number(e),value:t,title:`L${e} · ${n}${t.toFixed(3)}`}})}function C(e,t){return v(e)===!1?1:Zr(e,0)}function w(e){return[...(e.nearest??[]).map(([e,t])=>({label:e,value:`d=${t.toFixed(2)}`,title:`whitened distance · ${t.toFixed(3)}`})),...(e.assignment??[]).map(([e,t])=>({label:`~${e}`,value:`${(t*100).toFixed(0)}%`,title:`soft assignment · ${(t*100).toFixed(1)}%`,soft:!0})),...e.residual===0?[]:[{label:`residual`,value:e.residual.toFixed(3),title:`off-surface distance`}],...e.membership==null?[]:[{label:`membership`,value:e.membership.toFixed(3),title:`tube-fit density`}]]}var E=L(),D=q(E),O=t=>{var n=ed(),i=R(n),a=R(i),o=R(a,!0);f(a);var s=X(a,2),c=R(s),l=e=>{var t=$u();Fl(q(t),{get value(){return B(h)}}),T(),g(e,t)},u=t=>{g(t,e(`starting`))};p(c,e=>{B(d)?e(l):e(u,-1)}),f(s),f(i);var m=X(i,2);let v;var b=R(m);f(m);var x=X(m,2),C=R(x,!0);f(x),T(2),f(n),U(()=>{G(o,B(_)),v=y(m,1,`progress-track svelte-1z0f2vr`,null,v,{indeterminate:!B(d)}),S(m,`aria-valuenow`,B(d)?B(h):void 0),S(m,`aria-valuetext`,B(d)?`${B(h)}%`:`Starting`),pe(b,B(d)?`width: ${B(h)}%`:void 0),G(C,r.readout.progress?.message??`Waiting for the model`)}),g(t,n)},k=e=>{{let t=c(()=>`readout: ${r.readout.error}`);ju(e,{get title(){return B(t)}})}},A=e=>{var t=ld(),n=q(t);zu(n,{get origin(){return r.readout.origin},get source(){return r.readout.source},get steering(){return r.readout.data.steering},get showToggle(){return B(u)},accent:`var(--pillar-subspace)`,get steered(){return a()},set steered(e){a(e)}});var s=X(n,2);{let e=c(()=>`${B(o).length} attached`);Hu(s,{title:`PROBE READINGS`,get count(){return B(e)},children:(e,t)=>{var n=cd();m(n,21,()=>B(o),([e,t])=>e,(e,t)=>{var n=c(()=>i(B(t),2));let r=()=>B(n)[0],a=()=>B(n)[1],o=c(()=>a().coords.length),s=c(()=>x(r(),a())),l=c(()=>v(r())),u=c(()=>B(l)===!1?`--pillar-manifold`:`--pillar-subspace`),d=c(()=>w(a()));Cu(e,{get accent(){return B(u)},disabled:!1,statline:e=>{{let t=e=>{{let t=c(()=>B(l)===!1?`diamond`:`circle`);Tu(e,{get shape(){return B(t)},filled:!0})}},n=c(()=>B(l)===null?`geometry`:B(l)?`subspace`:`manifold`),i=c(()=>a().depth_com?.[0]==null?null:`@${a().depth_com[0].toFixed(2)} ±${(a().depth_spread?.[0]??0).toFixed(2)}`);Ju(e,{get primary(){return r()},get primaryTitle(){return r()},get secondary(){return B(n)},secondaryAccent:!0,get meta(){return B(i)},metaTitle:`Where this probe’s signal is concentrated across layers: 0 is the first layer, 1 is the last. The ± value shows how widely it is spread.`,lead:t,$$slots:{lead:!0}})}},body:e=>{var t=sd(),n=X(q(t),2);{let e=e=>{g(e,td())},t=e=>{Vl(e,{percentage:!0,get value(){return a().fraction},max:1,color:`var(--fg)`})},r=e=>{var t=L(),n=q(t),r=e=>{var t=nd(),n=R(t,!0);f(t),U(()=>G(n,a().nearest[0][0])),g(e,t)};p(n,e=>{(a().nearest??[]).length>0&&e(r)}),g(e,t)},i=e=>{var t=rd(),n=R(t,!0);f(t),U(e=>G(n,e),[()=>a().fraction.toFixed(3)]),g(e,t)},o=c(()=>`Subspace fraction ${a().fraction.toFixed(3)}`);xu(n,{get ariaLabel(){return B(o)},left:e,bar:t,middle:r,right:i,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var i=X(n,2);m(i,17,()=>a().coords,N,(e,t,n)=>{{let i=e=>{var t=id();S(t,`title`,`coordinate axis ${n}`);var i=R(t,!0);f(t),U(e=>G(i,e),[()=>b(r(),n,B(o))]),g(e,t)},s=e=>{{let i=c(()=>Zr(r(),n));Vl(e,{get value(){return B(t)},get max(){return B(i)},bipolar:!0})}},l=e=>{var t=L(),r=q(t),i=e=>{var t=ad(),r=R(t);f(t),U((e,n)=>{S(t,`title`,e),G(r,`@${n??``}`)},[()=>`depth center ±${(a().depth_spread?.[n]??0).toFixed(2)} · 0 first, 1 last`,()=>a().depth_com[n].toFixed(2)]),g(e,t)};p(r,e=>{a().depth_com&&a().depth_com[n]!=null&&e(i)}),g(e,t)},u=e=>{var n=od(),r=R(n,!0);f(n),U(e=>G(r,e),[()=>B(t).toFixed(3)]),g(e,n)},d=c(()=>`${r()} axis ${n}`);xu(e,{get ariaLabel(){return B(d)},left:i,bar:s,middle:l,right:u,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}});var u=X(i,2),h=e=>{{let t=c(()=>C(r(),a())),n=c(()=>B(l)===!1?`var(--pillar-manifold)`:void 0),i=c(()=>`${r()} per-layer readings`);Yl(e,{get cells(){return B(s)},get scale(){return B(t)},get positiveColor(){return B(n)},get ariaLabel(){return B(i)}})}};p(u,e=>{B(s).length>0&&e(h)});var _=X(u,2);{let e=c(()=>`Geometry evidence for ${r()}`);Qu(_,{get items(){return B(d)},get ariaLabel(){return B(e)}})}var v=X(_,2),y=e=>{{let t=c(()=>a().coords.map((e,t)=>b(r(),t,B(o))));yu(e,{get name(){return r()},get reading(){return a()},get axisLabels(){return B(t)}})}};p(v,e=>{B(l)&&e(y)}),g(e,t)},$$slots:{statline:!0,body:!0}})}),f(n),g(e,n)},$$slots:{default:!0}})}g(e,t)},j=t=>{ju(t,{title:`Add a probe to see concept readings`,detail:`Choose a fitted concept, or create and train one for this model. Add it as a probe to inspect its readings here.`,children:(t,n)=>{var r=dd(),i=q(r),a=R(i);Du(a,{variant:`solid`,onclick:()=>l(),children:(t,n)=>{T(),g(t,e(`Add a probe`))},$$slots:{default:!0}});var o=X(a,2),c=t=>{Du(t,{onclick:()=>l(!0),children:(t,n)=>{T(),g(t,e(`Create a concept`))},$$slots:{default:!0}})};p(o,e=>{s.available&&e(c)}),f(i);var u=X(i,2),d=e=>{g(e,ud())};p(u,e=>{s.available||e(d)}),g(t,r)},$$slots:{default:!0}})},M=e=>{ju(e,{title:`no raw decode record`,detail:`replay needs a loom node generated with raw-decode capture in this session`})},P=e=>{ju(e,{title:`no readings`})};p(D,e=>{r.readout.loading?e(O):r.readout.error?e(k,1):r.readout.data&&B(o).length>0?e(A,2):r.hasGeometryProbes?r.hasReplayContext?e(P,-1):e(M,4):e(j,3)}),g(t,E),W()}var pd=I(`

      This token has almost all of the probability after sampling settings. - That is not a measure of factual accuracy.

      `),md=I(` `),hd=I(`probability`),gd=I(` `),_d=I(` `),vd=I(`
      Δ top token id
      `,1),yd=I(`

      `),bd=I(`
      `,1),xd=I(` `,1);function Sd(t,r){n(r,!0);let i=ke().mode,a=cn(i),o=sn(i)>0,s=c(()=>i===`http`||i===`browser`&&vi(`geometry`)?.capabilities.token_readout===!0),l=c(()=>{let e=r.token.topAlts;if(!e||e.length===0)return[];let t=e[0]?.logprob??0;return e.map((e,n)=>({rank:n+1,id:e.id,text:e.text,logprob:e.logprob,p:Math.exp(e.logprob),delta:e.logprob-t,chosen:r.token.tokenId!=null&&e.id===r.token.tokenId}))}),u=c(()=>B(l).length===1&&B(l)[0].chosen&&B(l)[0].p>=.9995),d=J(null),h=J(null);function _(e){return e==null||!Number.isFinite(e)?`-`:e.toFixed(3)}function v(e){return Number.isFinite(e)?e>=.001?e.toFixed(4):e.toExponential(2):`-`}function y(e,t){return t===1||!Number.isFinite(e)?`-`:e.toFixed(3)}function b(){o&&(xi.return_top_k??0)===0&&(xi.return_top_k=a)}async function x(e){if(A(h,null),!r.nodeId){A(h,`no generated loom node is available for this token`);return}if(r.token.rawIndex==null){A(h,`this token has no raw-decode index; forking needs a node generated with raw-decode capture in this session`);return}A(d,e.rank,!0);try{await eo(r.nodeId,r.token.rawIndex,e.id),it(),wa.view=`map`,window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`branches`}))}catch(e){A(h,je(e,`Unable to create a branch from this word choice. Try another alternative.`),!0)}finally{A(d,null)}}var S=xd(),C=q(S);zu(C,{origin:`captured`,source:`sampler`,steering:null,steered:!0,showToggle:!1,accent:`var(--pillar-lens)`});var w=X(C,2);{let t=c(()=>B(l).length>0?`${B(l).length} retained`:`capture unavailable`);Hu(w,{title:`RANKED ALTERNATIVES`,get count(){return B(t)},accent:`var(--pillar-lens)`,children:(t,n)=>{var i=L(),a=q(i),S=t=>{var n=bd(),r=q(n),i=e=>{g(e,pd())};p(r,e=>{B(u)&&e(i)});var a=X(r,2);m(a,21,()=>B(l),e=>e.rank,(t,n)=>{Cu(t,{accent:`--pillar-lens`,disabled:!1,get active(){return B(n).chosen},statline:e=>{{let t=e=>{var t=md(),r=R(t);f(t),U(()=>G(r,`#${B(n).rank??``}`)),g(e,t)},r=c(()=>JSON.stringify(B(n).text)),i=c(()=>`id ${B(n).id}`),a=c(()=>B(n).chosen?`generated`:null);Ju(e,{get primary(){return B(r)},get secondary(){return B(i)},get badge(){return B(a)},lead:t,$$slots:{lead:!0}})}},body:t=>{var r=vd(),i=q(r);{let e=e=>{g(e,hd())},t=e=>{Vl(e,{percentage:!0,get value(){return B(n).p},max:1,color:`var(--pillar-lens)`})},r=e=>{var t=gd(),r=R(t);f(t),U(e=>G(r,`logp ${e??``}`),[()=>_(B(n).logprob)]),g(e,t)},a=e=>{var t=_d(),r=R(t,!0);f(t),U(e=>G(r,e),[()=>v(B(n).p)]),g(e,t)},o=c(()=>`Probability ${v(B(n).p)}`);xu(i,{get ariaLabel(){return B(o)},left:e,bar:t,middle:r,right:a,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var a=X(i,2),o=R(a),l=X(R(o)),u=R(l,!0);f(l),f(o);var p=X(o,2),m=X(R(p)),h=R(m,!0);f(m),f(p);var b=X(p,4);{let t=c(()=>!B(s)||B(n).chosen||B(d)!==null),r=c(()=>B(s)?void 0:`Token branching is not available in the browser runtime yet`);Du(b,{size:`sm`,get disabled(){return B(t)},onclick:()=>x(B(n)),get title(){return B(r)},children:(t,r)=>{T();var i=e();U(()=>G(i,B(d)===B(n).rank?`Starting…`:B(n).chosen?`Used`:B(s)?`Start branch`:`View only`)),g(t,i)},$$slots:{default:!0}})}f(a),U(e=>{G(u,e),G(h,B(n).id)},[()=>y(B(n).delta,B(n).rank)]),g(t,r)},$$slots:{statline:!0,body:!0}})}),f(a);var o=X(a,2),b=e=>{var t=yd(),n=R(t,!0);f(t),U(()=>G(n,B(h))),g(e,t)};p(o,e=>{B(h)&&e(b)}),g(t,n)},C=t=>{{let n=c(()=>`logprob ${_(r.token.logprob)} · no alternatives captured`);ju(t,{get title(){return B(n)},children:(t,n)=>{{let n=c(()=>!o||xi.return_top_k>0);Du(t,{onclick:b,get disabled(){return B(n)},children:(t,n)=>{T();var r=e();U(()=>G(r,o?xi.return_top_k>0?`alts on next run`:`enable alts`:`alts unavailable`)),g(t,r)},$$slots:{default:!0}})}},$$slots:{default:!0}})}},w=t=>{ju(t,{title:`no logprob data`,children:(t,n)=>{{let n=c(()=>!o||xi.return_top_k>0);Du(t,{onclick:b,get disabled(){return B(n)},children:(t,n)=>{T();var r=e();U(()=>G(r,o?xi.return_top_k>0?`alts on next run`:`enable alts`:`alts unavailable`)),g(t,r)},$$slots:{default:!0}})}},$$slots:{default:!0}})};p(a,e=>{B(l).length>0?e(S):r.token.logprob==null?e(w,-1):e(C,1)}),g(t,i)},$$slots:{default:!0}})}g(t,S),W()}function Cd(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function wd(e,t,n){let r=e;if(!Cd(r)||r.modelId!==t.model||r.layer!==t.source||String(r.index)!==String(n)||!Cd(r.source)||r.source.hfRepoId!==t.repository||r.source.hfFolderId!==t.folder||!Array.isArray(r.explanations))throw Error(`The description belongs to a different SAE dictionary.`);let i=r.explanations.find(e=>Cd(e)&&typeof e.description==`string`&&!!e.description.trim());return{label:i?.description.trim()??null,explanationModel:typeof i?.explanationModelName==`string`?i.explanationModelName:null,url:`https://www.neuronpedia.org/${encodeURIComponent(t.model)}/${encodeURIComponent(t.source)}/${n}`}}var Td=new Map;async function Ed(e,t,n){if(!Number.isSafeInteger(t)||t<0)throw Error(`Invalid SAE feature ID.`);let r=JSON.stringify([e,t]),i=Td.get(r);if(i)return i;let a=await fetch(`https://www.neuronpedia.org/api/feature/${encodeURIComponent(e.model)}/${encodeURIComponent(e.source)}/${t}`,{signal:n,credentials:`omit`,referrerPolicy:`no-referrer`});if(!a.ok)throw Error(`Descriptions could not be loaded. Try again when you are online.`);let o=wd(await a.json(),e,t);return Td.set(r,o),Td.size>512&&Td.delete(Td.keys().next().value),o}var Dd=I(` `),Od=I(``),kd=I(` `),Ad=I(` `,1),jd=I(`
      `);function Md(e,t){n(t,!0);let r=c(()=>`var(${t.accent})`),a=c(()=>Math.max(1,...Object.values(t.readings).filter(e=>e.unit===`raw_activation`).map(e=>e.value))),o=c(()=>Object.entries(t.readings).sort(([e],[t])=>e.localeCompare(t,void 0,{sensitivity:`base`})));function s(e){let t=e.per_layer??{};return Object.keys(t).sort((e,t)=>Number(e)-Number(t)).map(n=>({layer:Number(n),value:t[n],title:`L${n} · ${Il(t[n],e.unit===`mean_token_probability`)} · ${l[e.unit]}`}))}let l={mean_token_probability:`mean fitted-layer probability`,activation_over_max:`activation / corpus max`,raw_activation:`raw activation (no corpus max cached)`};function u(e){return Math.max(...e.map(e=>e.value??0),1e-12)}var d=L(),h=q(d),_=e=>{{let n=c(()=>`${B(o).length} captured`);Hu(e,{title:`PINNED PROBES`,get count(){return B(n)},get accent(){return B(r)},children:(e,n)=>{var d=jd();m(d,21,()=>B(o),([e,t])=>e,(e,n)=>{var o=c(()=>i(B(n),2));let d=()=>B(o)[0],m=()=>B(o)[1],h=c(()=>s(m()));Cu(e,{get accent(){return t.accent},disabled:!1,statline:e=>{{let n=e=>{Tu(e,{get shape(){return t.shape},filled:!0})},r=c(()=>`probe ${d()}`),i=c(()=>m().depth?.center?.[0]==null?null:`@${m().depth.center[0].toFixed(2)} ±${(m().depth.spread?.[0]??0).toFixed(2)}`);Ju(e,{get primary(){return d()},get primaryTitle(){return B(r)},get meta(){return B(i)},metaTitle:`Where this probe’s signal is concentrated across layers: 0 is the first layer, 1 is the last. The ± value shows how widely it is spread.`,lead:n,$$slots:{lead:!0}})}},body:e=>{var t=Ad(),n=q(t);{let e=e=>{var t=Dd(),n=R(t,!0);f(t),U(()=>{S(t,`title`,l[m().unit]),G(n,m().unit===`raw_activation`?`activation`:`strength`)}),g(e,t)},t=e=>{{let t=c(()=>m().unit===`mean_token_probability`),n=c(()=>Math.max(m().value,0)),i=c(()=>m().unit===`raw_activation`?B(a):1);Vl(e,{get percentage(){return B(t)},get value(){return B(n)},get max(){return B(i)},get color(){return B(r)}})}},i=e=>{g(e,Od())},o=e=>{var t=kd(),n=R(t,!0);f(t),U(e=>G(n,e),[()=>m().value.toFixed(3)]),g(e,t)},s=c(()=>`Pinned probe ${d()}`);xu(n,{get ariaLabel(){return B(s)},left:e,bar:t,middle:i,right:o,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var i=X(n,2),o=e=>{{let t=c(()=>u(B(h))),n=c(()=>`${d()} per-layer strength`);Yl(e,{get cells(){return B(h)},get scale(){return B(t)},get positiveColor(){return B(r)},get ariaLabel(){return B(n)}})}};p(i,e=>{B(h).length>1&&e(o)}),g(e,t)},$$slots:{statline:!0,body:!0}})}),f(d),g(e,d)},$$slots:{default:!0}})}};p(h,e=>{B(o).length>0&&e(_)}),g(e,d),W()}var Nd=I(`%`,1),Pd=I(`

      You can inspect another token while this finishes. This result will be kept.

      `),Fd=I(` `,1),Id=I(``),Ld=I(`

      Checking the published feature records…

      `),Rd=I(``),zd=I(` `),Bd=I(` `),Vd=I(`

      `,1),Hd=I(`
      `),Ud=I(`

      `),Wd=I(`
      `,1),Gd=I(`
      `,1),Kd=I(`

      Feature descriptions are published interpretations, not definitive meanings. Activations are not probabilities.

      `,1);function qd(t,r){n(r,!0);let i=Y(r,`steered`,15);ne(()=>{ra()});let a=c(()=>na.sources.find(e=>e.source===r.readout.source&&e.layer===r.readout.data?.layer)),o=c(()=>B(a)?.description_source),l=c(()=>JSON.stringify(B(o)??null)),u=J(``),d=J(`activation`),h=J(V({})),_=J(!1),v=J(``),b=null,x=c(()=>(r.readout.data?.features??[]).some(e=>!e.label?.trim()&&!B(h)[e.id])),C=c(()=>new Map([...r.readout.data?.features??[]].sort((e,t)=>t.activation-e.activation).map((e,t)=>[e.id,t+1])));Ce(()=>(`${r.readout.data?.node_id}${r.readout.data?.raw_index}${r.readout.source}${r.readout.data?.layer}`,B(l),r.readout.data?.features.map(e=>e.id).join(`,`),A(h,{},!0),A(v,``),A(_,!1),A(u,``),De(()=>{E()}),()=>{b?.abort(),b=null}));let w=c(()=>{let e=B(u).trim().toLowerCase();return[...r.readout.data?.features??[]].filter(t=>!e||`sae/${t.id} ${t.label??B(h)[t.id]?.label??``}`.toLowerCase().includes(e)).sort((e,t)=>B(d)===`id`?e.id-t.id:t.activation-e.activation)});async function E(){let e=B(o);if(!e||!r.readout.data||B(_))return;let t=new AbortController;b=t,A(_,!0),A(v,``);let n=setTimeout(()=>t.abort(),2e4),i=r.readout.data.features.filter(e=>!e.label?.trim()&&!B(h)[e.id]);try{for(let n=0;n[n.id,await Ed(e,n.id,t.signal)]));if(b!==t)return;for(let e of r)e.status===`fulfilled`?A(h,{...B(h),[e.value[0]]:e.value[1]},!0):A(v,`Some descriptions could not be loaded. Check your connection and try again.`);if(t.signal.aborted)break}}catch{b===t&&A(v,`Some descriptions could not be loaded. Check your connection and try again.`)}finally{clearTimeout(n),b===t&&A(_,!1)}}let D=c(()=>r.replayAvailable&&((r.readout.data?.steering??null)!==null||!i())),O=c(()=>r.readout.progress!==null&&r.readout.progress.progress>0),k=c(()=>Math.round((r.readout.progress?.progress??0)*100)),M=c(()=>r.readout.progress?.phase===`readout`?`Reading model features`:r.readout.progress?.phase===`queued`?`Waiting for the model`:`Preparing this token`),N=c(()=>Math.max(...(r.readout.data?.features??[]).filter(e=>!(e.max_act!=null&&e.max_act>0)).map(e=>e.activation),1));function P(e){return e.max_act!=null&&e.max_act>0?e.activation/e.max_act:null}function F(e){return e.max_act!=null&&e.max_act>0?[{label:`activation`,value:e.activation.toFixed(3),title:`raw activation · ${e.activation.toFixed(3)}`},{label:`reference maximum`,value:e.max_act.toFixed(3),title:`Reference maximum supplied with this feature: ${e.max_act.toFixed(3)}`}]:[]}var I=L(),ee=q(I),te=t=>{var n=Pd(),i=R(n),a=R(i),o=R(a,!0);f(a);var s=X(a,2),c=R(s),l=e=>{var t=Nd();Fl(q(t),{get value(){return B(k)}}),T(),g(e,t)},u=t=>{g(t,e(`starting`))};p(c,e=>{B(O)?e(l):e(u,-1)}),f(s),f(i);var d=X(i,2);let m;var h=R(d);f(d);var _=X(d,2),v=R(_,!0);f(_),T(2),f(n),U(()=>{G(o,B(M)),m=y(d,1,`progress-track svelte-w3bzpw`,null,m,{indeterminate:!B(O)}),S(d,`aria-valuenow`,B(O)?B(k):void 0),S(d,`aria-valuetext`,B(O)?`${B(k)}%`:`Starting`),pe(h,B(O)?`width: ${B(k)}%`:void 0),G(v,r.readout.progress?.message??`Waiting for the model`)}),g(t,n)},z=e=>{{let t=c(()=>`readout: ${r.readout.error}`);ju(e,{get title(){return B(t)}})}},re=e=>{var t=Kd(),n=q(t);zu(n,{get origin(){return r.readout.origin},get source(){return r.readout.source},get layer(){return r.readout.data.layer},get steering(){return r.readout.data.steering},get showToggle(){return B(D)},accent:`var(--pillar-sae)`,get steered(){return i()},set steered(e){i(e)}});var a=X(n,2),l=X(R(a),2),b=e=>{var t=Fd(),n=q(t),r=R(n,!0);f(n),T(2),U(()=>{n.disabled=B(_)||!B(x),S(n,`aria-busy`,B(_)),G(r,B(_)?`Loading descriptions…`:B(v)?`Retry descriptions`:B(x)?`Load published descriptions`:`Descriptions checked`)}),K(`click`,n,E),g(e,t)},O=e=>{g(e,Id())};p(l,e=>{B(o)?e(b):e(O,-1)});var k=X(l,2),M=e=>{g(e,Ld())};p(k,e=>{B(_)&&e(M)});var I=X(k,2),L=e=>{var t=Rd(),n=R(t,!0);f(t),U(()=>G(n,B(v))),g(e,t)};p(I,e=>{B(v)&&e(L)}),f(a);var ee=X(a,2),te=e=>{Md(e,{get readings(){return r.pinned},accent:`--pillar-sae`,shape:`triangle`})},z=c(()=>r.readout.origin===`captured`&&r.pinned&&Object.keys(r.pinned).length>0);p(ee,e=>{B(z)&&e(te)});var ne=X(ee,2),V=e=>{ju(e,{title:`no features fired at this position`})},re=e=>{var t=Gd(),n=q(t),i=R(n),a=X(R(i));s(a),f(i);var l=X(i,2);hu(X(R(l)),{ariaLabel:`Sort by`,options:[{value:`activation`,label:`Activation`},{value:`id`,label:`Feature ID`}],get value(){return B(d)},set value(e){A(d,e,!0)}}),f(l),f(n);var v=X(n,2);{let e=c(()=>`${B(w).length} of ${r.readout.data.features.length} recorded`);Hu(v,{title:`SAE activations`,get count(){return B(e)},accent:`var(--pillar-sae)`,children:(e,t)=>{var n=Wd(),i=q(n);m(i,21,()=>B(w),e=>e.id,(e,t)=>{let n=c(()=>P(B(t))),i=c(()=>F(B(t))),a=c(()=>B(h)[B(t).id]),s=c(()=>B(t).label?.trim()||B(a)?.label);var l=Hd();Cu(R(l),{accent:`--pillar-sae`,disabled:!1,statline:e=>{{let n=e=>{var n=zd(),r=R(n);f(n),U(e=>G(r,`#${e??``}`),[()=>B(C).get(B(t).id)]),g(e,n)},i=c(()=>`sae/${B(t).id}`),a=c(()=>`Layer ${r.readout.data?.layer??`-`}`);Ju(e,{get primary(){return B(i)},get tail(){return B(a)},tailTitle:`SAE layer`,lead:n,$$slots:{lead:!0}})}},body:e=>{var r=Vd(),l=q(r);let u;var d=R(l,!0);f(l);var m=X(l,2),h=e=>{var t=Bd(),n=R(t);f(t),U(()=>{S(t,`href`,B(a).url),G(n,`Neuronpedia${B(a).explanationModel?` · ${B(a).explanationModel}`:` · feature record`}`)}),g(e,t)};p(m,e=>{B(a)&&e(h)});var v=X(m,2),b=R(v),x=R(b,!0);f(b);var C=X(b,2),w=R(C,!0);f(C);var T=X(C,2),E=R(T),D=e=>{{let t=c(()=>Math.max(B(n),0));Vl(e,{get value(){return B(t)},max:1,color:`var(--pillar-sae)`})}},O=e=>{{let n=c(()=>Math.max(B(t).activation,0));Vl(e,{get value(){return B(n)},get max(){return B(N)},color:`color-mix(in srgb, var(--pillar-sae) 55%, transparent)`})}};p(E,e=>{B(n)==null?e(O,-1):e(D)}),f(T),f(v);var k=X(v,2);{let e=c(()=>`Metadata for feature sae/${B(t).id}`);Qu(k,{get items(){return B(i)},get ariaLabel(){return B(e)}})}U(e=>{u=y(l,1,`feature-description svelte-w3bzpw`,null,u,{missing:!B(s)}),G(d,B(s)||(B(a)?`No description published for this feature`:B(o)?B(_)?`Loading description…`:`Description could not be loaded`:`No description included in this pack`)),S(v,`aria-label`,`Activation for sae/${B(t).id}`),G(x,B(n)==null?`Raw activation`:`Relative activation`),G(w,e)},[()=>B(n)==null?B(t).activation.toFixed(2):B(n).toFixed(3)]),g(e,r)},$$slots:{statline:!0,body:!0}}),f(l),U(()=>S(l,`aria-label`,`SAE feature ${B(t).id}, layer ${r.readout.data.layer}`)),g(e,l)}),f(i);var a=X(i,2),s=e=>{var t=Ud(),n=R(t),r=X(n);f(t),U(()=>G(n,`No recorded features match “${B(u)??``}”. `)),K(`click`,r,()=>{A(u,``)}),g(e,t)};p(a,e=>{B(w).length===0&&e(s)}),g(e,n)},$$slots:{default:!0}})}j(a,()=>B(u),e=>A(u,e)),g(e,t)};p(ne,e=>{r.readout.data.features.length===0?e(V):e(re,-1)}),g(e,t)},ie=e=>{var t=L(),n=q(t),i=e=>{ju(e,{title:`No SAE is available for this model`})},a=e=>{ju(e,{title:`No SAE is available for this conversation length`})},o=e=>{ju(e,{title:`No SAE is installed`,detail:`Add the available SAE in Model settings, then reopen the model.`})},s=e=>{ju(e,{title:`No SAE is loaded`,detail:`Check Model settings for a compatible SAE.`})};p(n,e=>{r.availability===`unavailable`?e(i):r.availability===`context-unavailable`?e(a,1):r.availability===`available`?e(o,2):e(s,-1)}),g(e,t)},ae=e=>{ju(e,{title:`no raw decode record`,detail:`replay needs a loom node generated with raw-decode capture in this session`})},oe=e=>{ju(e,{title:`no readout`})};p(ee,e=>{r.readout.loading?e(te):r.readout.error?e(z,1):r.readout.data?e(re,2):r.saeLoaded?r.hasReplayContext?e(oe,-1):e(ae,4):e(ie,3)}),g(t,I),W()}H([`click`]);var Jd=I(` `);function Yd(e,t){ju(e,{title:`no J-LENS fit`,children:(e,n)=>{var r=Jd(),i=R(r);f(r),U(()=>G(i,`drowse lens fit ${t.modelId??``??``}`)),g(e,r)},$$slots:{default:!0}})}var Xd=I(`%`,1),Zd=I(`

      You can inspect another token while this finishes. This result will be kept.

      `),Qd=I(``),$d=I(`strength`),ef=I(` `),tf=I(` `),nf=I(` `,1),rf=I(`
      `),af=I(`
      `),of=I(``),sf=I(` `),cf=I(` `),lf=I(`
      L \\ rank
      `),uf=I(` `,1);function df(t,r){n(r,!0);let i=Y(r,`steered`,15),a=c(()=>r.replayAvailable&&((r.readout.data?.steering??null)!==null||!i())),o=c(()=>Math.max(0,...r.readout.data?.layers.map(e=>e.tokens.length)??[])),s=c(()=>r.readout.data?.layers.length??0),l=c(()=>r.readout.progress!==null&&r.readout.progress.progress>0),u=c(()=>Math.round((r.readout.progress?.progress??0)*100)),d=c(()=>r.readout.progress?.phase===`readout`?`Reading the J-lens`:r.readout.progress?.phase===`queued`?`Waiting for the model`:`Preparing this token`);function h(e){return`background: color-mix(in srgb, var(--pillar-lens) ${Math.round(Math.min(1,Math.exp(e))*60)}%, transparent);`}function _(e,t){let n=Math.exp(t.logprob),r=n>=.001?n.toFixed(4):n.toExponential(2);return`L${e} · ${JSON.stringify(t.token)} · ${Il(n,!0)} · p=${r} · logprob=${t.logprob.toFixed(3)}`}function v(e){let t=e.token.trim();return t.length>0?t:JSON.stringify(e.token)}function b(e){return e.trim()||JSON.stringify(e)}function x(e){return(r.readout.data?.layers??[]).map(t=>{let n=t.tokens.find(t=>t.token===e.token),r=n?Math.exp(n.logprob):null;return{layer:t.layer,value:r,title:r==null?`L${t.layer} · below top-${B(o)}`:`L${t.layer} · ${Il(r,!0)} · p ${r.toPrecision(3)}`}})}function C(e){return Math.max(...e.map(e=>e.value??0),1e-12)}function w(e){let t=Math.exp(e);return t>=.001?t.toFixed(3):t.toExponential(1)}function E(e){if(e.ctrlKey||Math.abs(e.deltaY)<=Math.abs(e.deltaX))return;let t=e.currentTarget.closest(`[data-token-details-scroll]`);if(!t)return;let n=e.deltaMode===WheelEvent.DOM_DELTA_LINE?16:e.deltaMode===WheelEvent.DOM_DELTA_PAGE?t.clientHeight:1,r=t.scrollTop;t.scrollTop+=e.deltaY*n,t.scrollTop!==r&&e.preventDefault()}var D=L(),O=q(D),k=t=>{var n=Zd(),i=R(n),a=R(i),o=R(a,!0);f(a);var s=X(a,2),c=R(s),m=e=>{var t=Xd();Fl(q(t),{get value(){return B(u)}}),T(),g(e,t)},h=t=>{g(t,e(`starting`))};p(c,e=>{B(l)?e(m):e(h,-1)}),f(s),f(i);var _=X(i,2);let v;var b=R(_);f(_);var x=X(_,2),C=R(x,!0);f(x),T(2),f(n),U(()=>{G(o,B(d)),v=y(_,1,`progress-track svelte-9hulvj`,null,v,{indeterminate:!B(l)}),S(_,`aria-valuenow`,B(l)?B(u):void 0),S(_,`aria-valuetext`,B(l)?`${B(u)}%`:`Starting`),pe(b,B(l)?`width: ${B(u)}%`:void 0),G(C,r.readout.progress?.message??`Waiting for the model`)}),g(t,n)},A=e=>{{let t=c(()=>`readout: ${r.readout.error}`);ju(e,{get title(){return B(t)}})}},j=e=>{var t=uf(),n=q(t);zu(n,{get origin(){return r.readout.origin},get source(){return r.readout.source},get steering(){return r.readout.data.steering},get showToggle(){return B(a)},accent:`var(--pillar-lens)`,get steered(){return i()},set steered(e){i(e)}});var l=X(n,2),u=e=>{Md(e,{get readings(){return r.pinned},accent:`--pillar-lens`,shape:`square`})},d=c(()=>r.readout.origin===`captured`&&r.pinned&&Object.keys(r.pinned).length>0);p(l,e=>{B(d)&&e(u)});var T=X(l,2),D=e=>{{let t=c(()=>`${r.readout.data.aggregate?.length??0} tokens`);Hu(e,{title:`AGGREGATE WORKSPACE`,get count(){return B(t)},accent:`var(--pillar-lens)`,children:(e,t)=>{var n=af();m(n,21,()=>r.readout.data.aggregate??[],N,(e,t,n)=>{let i=c(()=>x(B(t))),a=c(()=>B(i).filter(e=>e.value!=null).length);var o=rf(),l=R(o);{let e=e=>{{let i=e=>{var t=Qd();t.textContent=`#${n+1}`,g(e,t)},a=c(()=>b(B(t).token)),o=c(()=>`@${B(t).com.toFixed(2)} ±${B(t).spread.toFixed(2)}`),s=c(()=>B(t).token===r.readout.data?.token_text?`generated`:null);Ju(e,{get primary(){return B(a)},get meta(){return B(o)},metaTitle:`Where this word’s probability is concentrated across layers: 0 is the first layer, 1 is the last. The ± value shows how widely it is spread.`,get badge(){return B(s)},lead:i,$$slots:{lead:!0}})}},o=e=>{var n=nf(),r=q(n);{let e=e=>{g(e,$d())},n=e=>{Vl(e,{percentage:!0,get value(){return B(t).strength},max:1,color:`var(--pillar-lens)`})},i=e=>{var t=ef(),n=R(t);f(t),U(()=>G(n,`${B(a)??``}/${B(s)??``} layers`)),g(e,t)},o=e=>{var n=tf(),r=R(n,!0);f(n),U(e=>G(r,e),[()=>B(t).strength.toFixed(3)]),g(e,n)},l=c(()=>`Strength ${B(t).strength.toFixed(3)}`);xu(r,{get ariaLabel(){return B(l)},left:e,bar:n,middle:i,right:o,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var o=X(r,2);{let e=c(()=>C(B(i))),n=c(()=>`Per-layer strength for ${b(B(t).token)}`);Yl(o,{get cells(){return B(i)},get scale(){return B(e)},positiveColor:`var(--layer-cell-lens)`,get ariaLabel(){return B(n)}})}g(e,n)},u=c(()=>B(t).token===r.readout.data.token_text);Cu(l,{accent:`--pillar-lens`,disabled:!1,get active(){return B(u)},statline:e,body:o,$$slots:{statline:!0,body:!0}})}f(o),g(e,o)}),f(n),g(e,n)},$$slots:{default:!0}})}};p(T,e=>{(r.readout.data.aggregate??[]).length>0&&e(D)});var O=X(T,2);{let e=c(()=>`${r.readout.data.layers.length} layers × ${B(o)} ranks`);Hu(O,{title:`LAYER × VOCABULARY`,get count(){return B(e)},accent:`var(--pillar-lens)`,children:(e,t)=>{var n=lf(),i=R(n),a=R(i),s=R(a);m(X(R(s)),17,()=>({length:B(o)}),N,(e,t,n)=>{var r=of();r.textContent=n+1,g(e,r)}),f(s),f(a);var c=X(a);m(c,21,()=>r.readout.data.layers,e=>e.layer,(e,t)=>{var n=cf(),i=R(n),a=R(i);f(i),m(X(i),17,()=>B(t).tokens,e=>e.id,(e,n)=>{var i=sf();let a;var o=R(i),s=R(o,!0);f(o);var c=X(o,2),l=R(c);f(c),f(i),U((e,t,o,c)=>{a=y(i,1,`lens-cell svelte-9hulvj`,null,a,{hit:B(n).id===r.readout.data.token_id}),pe(i,e),S(i,`title`,t),G(s,o),G(l,`p ${c??``}`)},[()=>h(B(n).logprob),()=>_(B(t).layer,B(n)),()=>v(B(n)),()=>w(B(n).logprob)]),g(e,i)}),f(n),U(()=>G(a,`L${B(t).layer??``}`)),g(e,n)}),f(c),f(i),f(n),ye(`wheel`,n,E),g(e,n)},$$slots:{default:!0}})}g(e,t)},M=e=>{Yd(e,{get modelId(){return r.modelId}})},P=e=>{ju(e,{title:`no raw decode record`,detail:`replay needs a loom node generated with raw-decode capture in this session`})},F=e=>{ju(e,{title:`no readout`})};p(O,e=>{r.readout.loading?e(k):r.readout.error?e(A,1):r.readout.data?e(j,2):r.jlensFitted?r.hasReplayContext?e(F,-1):e(P,4):e(M,3)}),g(t,D),W()}function ff(e,t,n,r){let i=e.models.flatMap(e=>e.variants).find(e=>e.id===t);if(!i)return`unknown`;let a=i.packs.filter(e=>e.kind===r);if(a.length===0)return`unavailable`;if(n===null)return`available`;let o=i.contextProfiles.find(e=>e.contextTokens===n);return o&&a.some(e=>e.compatibleContextBindingSha256.includes(o.bindingSha256))?`available`:`context-unavailable`}async function pf(e){let t=re();if(!t)return`unknown`;let{modelVariantId:n,contextTokens:r}=t.snapshot;if(!n)return`unknown`;try{return ff((await t.catalog({preferCached:!0,offline:typeof navigator<`u`&&navigator.onLine===!1})).document,n,r,e)}catch{return`unknown`}}var mf=I(` `),hf=I(` `),gf=I(`no replay`),_f=I(` `),vf=I(``),yf=I(` `),bf=I(`
      generation recipe
      `,1),xf=I(`
      `),Sf=I(`
      Edit this token or replace it with a longer phrase. Spacing is preserved.
      `),Cf=I(``),wf=I(`
      Branch from this token
      `,1),Tf=I(`

      `),Ef=I(`

      `),Df=I(`

      `),Of=I(`
      `),kf=I(`
      `),Af=I(``);function jf(t,r){n(r,!0);let i=Y(r,`docked`,3,!1),o=Y(r,`active`,3,!0),l=J(null),u=c(()=>r.params);function d(){i()?tt():it()}function _(){let e=B(D)?{turnIdx:B(D).turnIdx,tokenIdx:B(D).tokenIdx,isThinking:B(D).seg===`thinking`}:B(u);i()?nt(e):et(e)}let v=c(()=>B(u)?{turnIdx:B(u).turnIdx,seg:B(u).isThinking?`thinking`:`response`,tokenIdx:B(u).tokenIdx}:null),b=J(null),x=J(`primary`),C=[{value:`primary`,label:`steered`,title:`primary turn`},{value:`shadow`,label:`unsteered`,title:`A/B shadow turn`}];Ce(()=>{let e=B(v);A(b,e?{...e}:null,!0),A(x,`primary`)});let w=c(()=>Ko.turns.map((e,t)=>t===(B(b)?.turnIdx??-1)&&B(x)===`shadow`&&e.abPair?e.abPair:e)),E=c(()=>Lc(B(w))),D=c(()=>B(b)?Vc(B(E),B(b)):null),O=-1;Ce(()=>{let e=B(D)?.turnIdx??-1;e!==O&&(O=e,B(x)!==`primary`&&A(x,`primary`))});let k=c(()=>B(D)!=null&&B(D).turnIdx>=0&&B(D).turnIdxB(D)?B(w)[B(D).turnIdx]??null:null),N=c(()=>B(D)?Ic(B(M),B(D).seg):[]),P=c(()=>B(D)!=null&&B(D).tokenIdx>=0&&B(D).tokenIdxB(D)?B(x)===`shadow`?B(M)?.nodeId??null:B(k)?.nodeId?B(k).nodeId:B(D).turnIdx<0||Q.activePath.length===0?null:Q.activePath.map(e=>Q.nodes.get(e)).filter(Boolean).filter(e=>!(e.parent_id===null&&e.role===`system`&&!e.text))[B(D).turnIdx]?.id??null:null),L=c(()=>B(I)!=null&&B(P)?.rawIndex!=null),ee=c(()=>B(x)===`primary`&&B(I)!=null&&B(P)?.rawIndex!=null&&B(P)?.tokenId!=null&&!$.active),te=c(()=>B(x)===`primary`&&B(I)!=null&&B(P)?.rawIndex!=null&&!$.active),z=J(!1),V=J(null),re=J(!1),ie=J(``),ae=J(!1),oe=J(null);Ce(()=>{B(I),B(P)?.rawIndex,A(V,null),A(re,!1),A(ie,``)});async function H(){if(!B(te)||!B(P))return;A(ie,B(P).text,!0),A(re,!0),A(V,null),await xe(),B(oe)?.focus();let e=B(ie).search(/\S/),t=B(ie).trimEnd().length;B(oe)?.setSelectionRange(e>=0?e:0,t>0?t:B(ie).length)}async function se(){if(!(!B(te)||!B(I)||B(P)?.rawIndex==null)){if(B(ie).length===0){A(V,`Enter replacement text.`),B(oe)?.focus();return}A(V,null),A(ae,!0);try{await to(B(I),B(P).rawIndex,B(ie)),i()||it(),wa.view=`map`,window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`branches`}))}catch(e){A(V,je(e,`Unable to replace this token and start a new branch.`),!0)}finally{A(ae,!1)}}}async function le(){if(!(!B(ee)||!B(I)||B(P)?.rawIndex==null||B(P).tokenId==null)){A(V,null),A(z,!0);try{await eo(B(I),B(P).rawIndex,B(P).tokenId,!0),i()||it(),wa.view=`map`,window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`branches`}))}catch(e){A(V,je(e,`Unable to continue this branch from the selected token.`),!0)}finally{A(z,!1)}}}let ue=c(()=>B(I)?Q.nodes.get(B(I))??null:null),de=c(()=>B(ue)?.recipe?.sampling??null),fe=c(()=>B(ue)?.recipe?.steering??B(M)?.appliedSteering??null);function pe(e){return e==null||!Number.isFinite(e)?`-`:Number.isInteger(e)?String(e):e.toFixed(2)}let me=c(()=>{let e=B(de),t=B(ue)?.recipe;if(!e&&!t)return[];let n=[`Temperature ${pe(e?.temperature)}`,`Top P ${pe(e?.top_p)}`,`Top K ${pe(e?.top_k)}`,`Max tokens ${pe(e?.max_tokens)}`],r=t?.seed??e?.seed;return r!=null&&n.push(`Seed ${r}`),e?.presence_penalty&&n.push(`Presence penalty ${pe(e.presence_penalty)}`),e?.frequency_penalty&&n.push(`Frequency penalty ${pe(e.frequency_penalty)}`),e?.return_top_k!=null&&n.push(`Return top K ${e.return_top_k}`),t?.thinking!=null&&n.push(t.thinking?`Thinking on`:`Thinking off`),(t?.probes.length??0)>0&&n.push(`${t.probes.length} recipe probes`),n});function he(e){e&&A(b,e,!0)}let ge=c(()=>B(D)!=null&&zc(B(E),B(D),-1)!==null),_e=c(()=>B(D)!=null&&zc(B(E),B(D),1)!==null),ve=c(()=>B(D)!=null&&Bc(B(E),B(D),-1)!==null),be=c(()=>B(D)!=null&&Bc(B(E),B(D),1)!==null);function Se(e){B(D)&&he(zc(B(E),B(D),e))}function we(e){B(D)&&he(Bc(B(E),B(D),e))}function Te(e){B(D)&&A(b,{...B(D),tokenIdx:e===`home`?0:Math.max(0,B(N).length-1)},!0)}let Ee=c(()=>B(D)!=null&&B(v)!=null&&B(D).turnIdx===B(v).turnIdx&&B(D).seg===B(v).seg&&B(D).tokenIdx===B(v).tokenIdx);function Oe(){B(v)&&A(b,{...B(v)},!0)}let ke=c(()=>{if(!B(D))return null;let e=B(D).seg===`thinking`?`response`:`thinking`;return B(E).some(t=>t.turnIdx===B(D).turnIdx&&t.seg===e)?e:null});function Ae(){!B(D)||!B(ke)||A(b,{turnIdx:B(D).turnIdx,seg:B(ke),tokenIdx:0},!0)}function Me(e){if(e.defaultPrevented||!o()||i()&&!B(l)?.contains(e.target))return;if(e.key===`Escape`){e.preventDefault(),i()||it();return}let t=e.target;if(!(t&&(t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`||t.isContentEditable||t.closest(`[role="slider"], [role="listbox"]`)))){switch(e.key){case`ArrowLeft`:Se(-1);break;case`ArrowRight`:Se(1);break;case`ArrowUp`:we(-1);break;case`ArrowDown`:we(1);break;case`Home`:Te(`home`);break;case`End`:Te(`end`);break;default:return}e.preventDefault()}}let Ne=c(()=>B(M)?B(M).roleLabel??B(M).role:``),Fe=c(()=>{let e=B(P)?.topAlts;if(!e||e.length===0||B(P)?.tokenId==null)return null;let t=e.findIndex(e=>e.id===B(P).tokenId);return t>=0?t+1:null});function Ie(e){return Number.isFinite(e)?e>=.001?e.toFixed(3):e.toExponential(1):`-`}let Le=c(()=>[{value:`geometry`,label:`geometry`,meta:String(Object.keys(B(P)?.measurements?.instruments.geometry?.readings??{}).length),color:`var(--fg-dim)`,title:`activation geometry`},{value:`logits`,label:`logits`,meta:String(B(P)?.topAlts?.length??0),title:`sampling alternatives`},{value:`sae`,label:`sae`,meta:String(B(P)?.measurements?.instruments.sae?.readout?.features.length??0),color:`var(--pillar-sae)`,title:`sparse features`},{value:`lens`,label:`j-lens`,meta:String(B(P)?.measurements?.instruments.lens?.readout?.layers.length??0),color:`var(--pillar-lens)`,title:`workspace readout`}]),Re=c(()=>B(k)?.abPair!=null),ze=c(()=>_i.info?.jlens_fitted===!0),Ve=c(yi),Ue=J(`unknown`);ne(()=>{let e=!0;return pf(`sae`).then(t=>{e&&A(Ue,t,!0)}),()=>{e=!1}});let We=c(()=>vi(`lens`)?.capabilities.token_readout===!0),Ge=c(()=>vi(`sae`)?.capabilities.token_readout===!0),Ke=c(()=>vi(`geometry`)?.capabilities.token_readout===!0),qe=c(()=>Qt(xi.return_top_k)),Je=new Uc,Z=new Uc,Ye=new Uc,Xe=c(()=>{let e=Kc.tab;if(!B(P)||!B(D))return`${e}:missing`;if(e===`logits`)return`${e}:ready`;let t=e===`geometry`?Ye:e===`sae`?Z:Je;return`${e}:${t.loading?`loading`:t.error?`error`:t.data?`ready`:`empty`}`});Pe(()=>{Je.dispose(),Z.dispose(),Ye.dispose()});let Ze=J(!0),Qe=J(!0),$e=J(!0),rt=c(()=>Hr.active.some(e=>Hr.entries.get(e)?.info.family===`geometry`)),at=c(()=>B(P)?.measurements?.instruments.lens?.readings??null),ot=c(()=>B(P)?.measurements?.instruments.sae?.readings??null),st=c(()=>{let e=B(P)?.measurements?.instruments.lens;return!e?.readout||!B(P)?null:{node_id:B(I)??``,raw_index:B(P).rawIndex??-1,token_id:B(P).tokenId??-1,token_text:B(P).text,steering:e.binding.steering,aggregate:e.readout.aggregate,layers:e.readout.layers}}),ct=c(()=>{let e=B(P)?.measurements?.instruments.sae;return!e?.readout||!B(P)?null:{node_id:B(I)??``,raw_index:B(P).rawIndex??-1,token_id:B(P).tokenId??-1,token_text:B(P).text,steering:e.binding.steering,layer:e.binding.layer??-1,features:e.readout.features}}),lt=c(()=>{let e=B(P)?.measurements?.instruments.geometry;return!e||Object.keys(e.readings??{}).length===0?null:{steering:e.binding?.steering??null,readings:e.readings}}),ut=J(null);Ce(()=>{!o()||!B(u)||!B(P)||!_i.info||B(ut)===B(u)||(Kc.tab=qc(B(u).initialTab??De(()=>Kc.tab),{lens:B(st)!==null||B(L)&&B(ze)&&B(We),sae:B(ct)!==null||B(L)&&B(Ve)&&B(Ge),geometry:B(lt)!==null||B(L)&&B(rt)&&B(Ke)}),A(ut,B(u),!0))}),Ce(()=>{if(!o()||Kc.tab!==`lens`)return;let e=B(st);if(!B(We)&&!B(Ze)&&A(Ze,!0),(B(Ze)||!B(We))&&e){Je.adopt(e,B(P)?.measurements?.instruments.lens?.binding.source??null);return}if(Je.clear(),!B(We)||!B(ze))return;let t=B(I),n=B(P)?.rawIndex;if(!t||n==null)return;let r=B(P)?.tokenId??-1,i=B(P)?.text??``,a=Li.sources.find(e=>e.active)?.source??null;Je.replay(`lens`,t,n,{topK:B(qe),steered:B(Ze),raw:es(),layers:`all`},e=>{let o=e.instruments.lens;if(!o?.readout)throw Error(`No J-lens reading was returned. Check the active lens source and try again.`);return{data:{node_id:t,raw_index:n,token_id:r,token_text:i,steering:o?.binding.steering??null,aggregate:o.readout.aggregate,layers:o.readout.layers},source:o?.binding.source??a??null}})}),Ce(()=>{if(!o()||Kc.tab!==`sae`)return;let e=B(ct);if(!B(Ge)&&!B(Qe)&&A(Qe,!0),(B(Qe)||!B(Ge))&&e){Z.adopt(e,B(P)?.measurements?.instruments.sae?.binding.source??null);return}if(Z.clear(),!B(Ge)||!B(Ve))return;let t=B(I),n=B(P)?.rawIndex;if(!t||n==null)return;let r=B(P)?.tokenId??-1,i=B(P)?.text??``,a=na.sources.find(e=>e.active)?.source??vi(`sae`)?.source??null;Z.replay(`sae`,t,n,{topK:B(qe),steered:B(Qe),raw:es()},e=>{let o=e.instruments.sae;if(!o?.readout)throw Error(`No SAE reading was returned. Check the active feature source and try again.`);return{data:{node_id:t,raw_index:n,token_id:r,token_text:i,steering:o?.binding.steering??null,layer:o?.binding.layer??-1,features:o.readout.features},source:o?.binding.source??a??null}})}),Ce(()=>{if(!o()||Kc.tab!==`geometry`)return;let e=B(lt);if(!B(Ke)&&!B($e)&&A($e,!0),(B($e)||!B(Ke))&&e){Ye.adopt(e,null);return}if(Ye.clear(),!B(Ke)||!B(rt))return;let t=B(I),n=B(P)?.rawIndex;!t||n==null||Ye.replay(`geometry`,t,n,{steered:B($e),raw:es()},e=>{let t=e.instruments.geometry;if(!t)throw Error(`No probe readings were returned. Check that the probes are attached and try again.`);return{data:{steering:t?.binding?.steering??null,readings:t?.readings??{}},source:null}})});var dt=Af();ye(`keydown`,ce,Me);let pt;var mt=R(dt),ht=R(mt),gt=R(ht);He(R(gt),{side:`right`}),f(gt),ft(X(gt,4),{onclick:d}),f(ht);var _t=X(ht,2),vt=R(_t),yt=t=>{var n=bf(),r=q(n),i=R(r),a=R(i,!0);f(i);var o=X(i,2),s=R(o),c=t=>{var n=e();U(()=>G(n,`Completion ${B(D).turnIdx??``}`)),g(t,n)},l=t=>{var n=e();U(()=>G(n,`turn ${B(D).turnIdx??``} · ${B(Ne)??``} · ${B(D).seg??``}`)),g(t,n)};p(s,e=>{_i.info?.is_base_model?e(c):e(l,-1)}),f(o);var u=X(o,2),d=e=>{var t=mf(),n=R(t);f(t),U(()=>G(n,`id ${B(P).tokenId??``}`)),g(e,t)};p(u,e=>{B(P).tokenId!=null&&e(d)});var h=X(u,2),_=e=>{var t=hf(),n=R(t);f(t),U(()=>G(n,`raw ${B(P).rawIndex??``}`)),g(e,t)},v=e=>{g(e,gf())};p(h,e=>{B(P).rawIndex==null?e(v,-1):e(_)});var y=X(h,2),b=e=>{var t=_f(),n=R(t);f(t),U((e,t)=>G(n,`p ${e??``} · logp ${t??``}${B(Fe)===null?``:` · rank ${B(Fe)}/${B(P).topAlts?.length??0}`}`),[()=>Ie(Math.exp(B(P).logprob)),()=>B(P).logprob.toFixed(3)]),g(e,t)};p(y,e=>{B(P).logprob!=null&&e(b)}),f(r);var x=X(r,2),C=R(x),w=R(C);Be(R(w),{name:`back`}),f(w);var T=X(w,2),E=R(T);f(T);var O=X(T,2);Be(R(O),{name:`next`}),f(O),f(C);var k=X(C,2),A=R(k);Be(R(A),{name:`up`}),f(A);var j=X(A,2),M=R(j);f(j);var F=X(j,2);Be(R(F),{name:`down`}),f(F),f(k);var I=X(k,2),L=e=>{var t=vf();Be(R(t),{name:`return`}),f(t),K(`click`,t,Oe),g(e,t)};p(I,e=>{B(Ee)||e(L)}),f(x);var ee=X(x,2),te=R(ee),z=X(R(te),2),ne=R(z,!0);f(z),m(X(z,2),16,()=>B(me),e=>e,(e,t)=>{var n=yf(),r=R(n,!0);f(n),U(()=>G(r,t)),g(e,n)}),f(te),f(ee),U(e=>{G(a,e),o.disabled=!B(ke),S(o,`title`,B(ke)?`Show the ${B(ke)} tokens from this same turn.`:void 0),w.disabled=!B(ge),G(E,`${B(D).tokenIdx+1} / ${B(N).length??``}`),O.disabled=!B(_e),A.disabled=!B(ve),G(M,`turn ${B(D).turnIdx??``}`),F.disabled=!B(be),S(z,`title`,B(fe)??`no steering`),G(ne,B(fe)??`unsteered`)},[()=>JSON.stringify(B(P).text)]),K(`click`,o,Ae),K(`click`,w,()=>Se(-1)),K(`click`,O,()=>Se(1)),K(`click`,A,()=>we(-1)),K(`click`,F,()=>we(1)),g(t,n)},bt=e=>{var t=xf(),n=R(t),r=R(n,!0);f(n),f(t),U(()=>G(r,B(u)?`Selected token unavailable`:`No token selected`)),g(e,t)};p(vt,e=>{B(P)&&B(D)?e(yt):e(bt,-1)}),f(_t),f(mt);var xt=X(mt,2),St=e=>{var t=wf(),n=q(t);nl(n,{get tokens(){return B(N)},get index(){return B(D).tokenIdx},onjump:e=>{B(D)&&A(b,{...B(D),tokenIdx:e},!0)}});var r=X(n,2),i=R(r),o=X(R(i),2),c=R(o);f(o),f(i);var l=X(i,2),u=R(l),d=R(u,!0);f(u);var m=X(u,2),h=R(m,!0);f(m),f(l);var _=X(l,2),v=e=>{var t=Sf(),n=X(R(t),2),r=R(n);s(r),a(r,e=>A(oe,e),()=>B(oe));var i=X(r,2),o=R(i,!0);f(i),f(n),T(2),f(t),U(()=>{i.disabled=!B(te)||B(ae)||B(ie).length===0,G(o,B(ae)?`Starting…`:`Start branch`)}),ye(`submit`,t,e=>{e.preventDefault(),se()}),j(r,()=>B(ie),e=>A(ie,e)),g(e,t)};p(_,e=>{B(re)&&e(v)});var y=X(_,2),x=e=>{var t=Cf(),n=R(t,!0);f(t),U(()=>G(n,B(V))),g(e,t)};p(y,e=>{B(V)&&e(x)}),f(r),U(()=>{G(c,`Keep the text up to here and write a new ending. Your original ${_i.info?.is_base_model?`completion`:`response`} stays saved.`),u.disabled=!B(te)||B(ae),S(u,`title`,B(te)?void 0:$.active?`Finish or stop the current generation first`:`This saved token does not have an exact replay boundary`),G(d,B(re)?`Cancel replacement`:`Replace token…`),m.disabled=!B(ee)||B(z),S(m,`title`,B(ee)?void 0:$.active?`Finish or stop the current generation first`:`This saved token does not have an exact replay boundary`),G(h,B(z)?`Starting…`:`Continue from here`)}),K(`click`,u,()=>{B(re)?(A(re,!1),A(V,null)):H()}),K(`click`,m,()=>void le()),g(e,t)};p(xt,e=>{B(P)&&B(D)&&e(St)});var Ct=X(xt,2),wt=R(Ct);Fc(wt,{get items(){return B(Le)},ariaLabel:`Token detail view`,get value(){return Kc.tab},set value(e){Kc.tab=e}});var Tt=X(wt,2),Et=e=>{Fc(e,{get items(){return C},ariaLabel:`Token branch`,get value(){return B(x)},set value(e){A(x,e,!0)}})};p(Tt,e=>{B(Re)&&e(Et)}),f(Ct);var Dt=X(Ct,2);F(R(Dt),()=>B(Xe),e=>{var t=kf(),n=R(t),r=e=>{var t=Tf();t.textContent=`Geometry token replay is unavailable in this runtime. Geometry captured during generation can still be inspected.`,g(e,t)},i=e=>{var t=Ef();t.textContent=`J-lens token replay is unavailable in this runtime. J-lens data captured during generation can still be inspected.`,g(e,t)},a=e=>{var t=Df();t.textContent=`SAE token replay is unavailable in this runtime. Sparse-feature data captured during generation can still be inspected.`,g(e,t)};p(n,e=>{B(P)&&B(D)&&Kc.tab===`geometry`&&!B(Ke)&&(B(rt)||B(lt))?e(r):B(P)&&B(D)&&Kc.tab===`lens`&&!B(We)&&(B(ze)||B(st))?e(i,1):B(P)&&B(D)&&Kc.tab===`sae`&&!B(Ge)&&(B(Ve)||B(ct))&&e(a,2)});var o=X(n,2),s=e=>{var t=Of(),n=R(t,!0);f(t),U(()=>G(n,B(u)?`This token is no longer available. Select another token to inspect it.`:`Select a token in your conversation or Loom to see its full details here.`)),g(e,t)},l=e=>{{let t=c(()=>({turnIdx:B(D).turnIdx,tokenIdx:B(D).tokenIdx,isThinking:B(D).seg===`thinking`}));fd(e,{get readout(){return Ye},get returnToToken(){return B(t)},get hasGeometryProbes(){return B(rt)},get hasReplayContext(){return B(L)},get replayAvailable(){return B(Ke)},get steered(){return B($e)},set steered(e){A($e,e,!0)}})}},d=e=>{Sd(e,{get token(){return B(P)},get nodeId(){return B(I)}})},m=e=>{qd(e,{get readout(){return Z},get saeLoaded(){return B(Ve)},get availability(){return B(Ue)},get hasReplayContext(){return B(L)},get pinned(){return B(ot)},get replayAvailable(){return B(Ge)},get steered(){return B(Qe)},set steered(e){A(Qe,e,!0)}})},_=e=>{{let t=c(()=>_i.info?.model_id??null);df(e,{get readout(){return Je},get jlensFitted(){return B(ze)},get hasReplayContext(){return B(L)},get pinned(){return B(at)},get modelId(){return B(t)},get replayAvailable(){return B(We)},get steered(){return B(Ze)},set steered(e){A(Ze,e,!0)}})}};p(o,e=>{!B(P)||!B(D)?e(s):Kc.tab===`geometry`?e(l,1):Kc.tab===`logits`?e(d,2):Kc.tab===`sae`?e(m,3):e(_,-1)}),f(t),h(1,t,()=>cu),g(e,t)}),f(Dt),f(dt),a(dt,e=>A(l,e),()=>B(l)),U(()=>{pt=y(dt,1,`drawer svelte-b6e72b`,null,pt,{docked:i()}),S(gt,`aria-pressed`,i()),S(gt,`aria-label`,i()?`Undock token details`:`Dock token details`),S(gt,`title`,i()?`Show token details in a window`:`Keep token details in a sidebar`)}),K(`click`,gt,_),g(t,dt),W()}H([`click`]);var Mf={effect:`dither`,pixelSize:3,visibility:.1};function Nf(e){return{effect:e.effect===`original`||e.effect===`pixel`?e.effect:`dither`,pixelSize:Number.isFinite(e.pixelSize)?Math.min(12,Math.max(1,Math.round(e.pixelSize))):3,visibility:Number.isFinite(e.visibility)?Math.min(.14,Math.max(.04,e.visibility)):.1}}function Pf(e){if(![`image/jpeg`,`image/png`,`image/webp`].includes(e.type))throw Error(`Choose a PNG, JPEG, or WebP image.`);if(!e.size||e.size>10485760)throw Error(`Choose an image smaller than 10 MB.`)}function Ff(e,t){let n=Math.min(1,2048/Math.max(e,t));return{width:Math.max(1,Math.round(e*n)),height:Math.max(1,Math.round(t*n))}}var If=V({...Mf,url:``,name:``,ready:!1,busy:!1,error:``}),Lf={...Mf,image:null,name:``},Rf=null;async function zf(){return new Promise((e,t)=>{let n=indexedDB.open(`drowse-appearance`,1);n.onupgradeneeded=()=>n.result.createObjectStore(`settings`),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}function Bf(e){(Lf.image!==e.image||!If.url)&&(If.url&&URL.revokeObjectURL(If.url),If.url=e.image?URL.createObjectURL(e.image):``),Lf=e,Object.assign(If,Nf(e),{name:e.name})}function Vf(){return Rf??=(async()=>{try{let e=await zf(),t=await new Promise((t,n)=>{let r=e.transaction(`settings`,`readonly`),i=r.objectStore(`settings`).get(`background`);i.onsuccess=()=>t(i.result),i.onerror=()=>n(i.error),r.oncomplete=()=>e.close(),r.onabort=()=>e.close()});t&&Bf({...Nf(t),image:t.image instanceof Blob?t.image:null,name:typeof t.name==`string`?t.name:``})}catch{If.error=`Background storage is unavailable in this browser. Your workspace still works without an image.`}finally{If.ready=!0}})()}async function Hf(e){let t=await zf();await new Promise((n,r)=>{let i=t.transaction(`settings`,`readwrite`);i.objectStore(`settings`).put(e,`background`),i.oncomplete=()=>{t.close(),n()},i.onabort=()=>{t.close(),r(i.error)}}),Bf(e)}async function Uf(e){if(!If.busy){If.busy=!0,If.error=``;try{await Vf(),await Hf({...Lf,...Nf({...Lf,...e})})}catch{If.error=`The background setting could not be saved. Try again or free some browser storage.`}finally{If.busy=!1}}}async function Wf(e){if(!If.busy){If.busy=!0,If.error=``;try{Pf(e),await Vf();let t=await createImageBitmap(e),n;try{let e=Ff(t.width,t.height),r=document.createElement(`canvas`);r.width=e.width,r.height=e.height;let i=r.getContext(`2d`);if(!i)throw Error(`Image processing is unavailable in this browser.`);i.drawImage(t,0,0,e.width,e.height),n=await new Promise((e,t)=>r.toBlob(n=>n?e(n):t(Error(`This image could not be processed.`)),`image/webp`,.85))}finally{t.close()}await Hf({...Lf,image:n,name:e.name.slice(0,160)})}catch(e){If.error=e instanceof Error&&(e.message.startsWith(`Choose `)||e.message.startsWith(`Image processing`)||e.message.startsWith(`This image`))?e.message:`The image could not be saved. Try another image or free some browser storage.`}finally{If.busy=!1}}}async function Gf(){if(!If.busy){If.busy=!0,If.error=``;try{await Vf(),await Hf({...Lf,image:null,name:``})}catch{If.error=`The background could not be removed. Try again.`}finally{If.busy=!1}}}var Kf=` -attribute vec2 position; -varying vec2 uv; -void main() { uv = position * 0.5 + 0.5; gl_Position = vec4(position, 0.0, 1.0); } -`,qf=` -precision mediump float; -uniform sampler2D image; -uniform vec2 resolution; -uniform vec2 imageSize; -uniform float pixelSize; -uniform float effect; -varying vec2 uv; -float bayer(vec2 point) { - vec2 p = mod(floor(point), 4.0); - vec2 a = mod(p, 2.0); - vec2 b = floor(p / 2.0); - return (4.0 * (2.0 * a.x + 3.0 * a.y - 4.0 * a.x * a.y) - + (2.0 * b.x + 3.0 * b.y - 4.0 * b.x * b.y) + 0.5) / 16.0; -} -void main() { - vec2 cell = floor(uv * resolution / pixelSize); - vec2 coord = effect < 0.5 ? uv : (cell + 0.5) * pixelSize / resolution; - float scale = max(resolution.x / imageSize.x, resolution.y / imageSize.y); - coord = (coord - 0.5) * resolution / (imageSize * scale) + 0.5; - vec4 color = texture2D(image, vec2(coord.x, 1.0 - coord.y)); - if (effect > 1.5) color.rgb = floor(color.rgb * 5.0 + bayer(cell)) / 5.0; - gl_FragColor = color; -} -`;function Jf(e){let t=e.getContext(`webgl`,{alpha:!0,antialias:!1,depth:!1,preserveDrawingBuffer:!1});if(!t)return null;let n=[];function r(e,r){let i=t.createShader(e);return n.push(i),t.shaderSource(i,r),t.compileShader(i),t.getShaderParameter(i,t.COMPILE_STATUS)?i:null}let i=r(t.VERTEX_SHADER,Kf),a=r(t.FRAGMENT_SHADER,qf),o=t.createProgram(),s=t.createBuffer(),c=t.createTexture();function l(){t.deleteTexture(c),t.deleteBuffer(s),t.deleteProgram(o),n.forEach(e=>t.deleteShader(e))}if(!i||!a||(t.attachShader(o,i),t.attachShader(o,a),t.linkProgram(o),!t.getProgramParameter(o,t.LINK_STATUS)))return l(),null;t.useProgram(o),t.bindBuffer(t.ARRAY_BUFFER,s),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),t.STATIC_DRAW);let u=t.getAttribLocation(o,`position`);t.enableVertexAttribArray(u),t.vertexAttribPointer(u,2,t.FLOAT,!1,0,0),t.bindTexture(t.TEXTURE_2D,c),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE);let d=Object.fromEntries([`resolution`,`imageSize`,`pixelSize`,`effect`].map(e=>[e,t.getUniformLocation(o,e)]));return{image(e){t.bindTexture(t.TEXTURE_2D,c),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),t.uniform2f(d.imageSize,e.naturalWidth,e.naturalHeight)},draw(n){let r=e.getBoundingClientRect();!r.width||!r.height||(e.width=Math.round(r.width),e.height=Math.round(r.height),t.viewport(0,0,e.width,e.height),t.uniform2f(d.resolution,e.width,e.height),t.uniform1f(d.pixelSize,n.pixelSize),t.uniform1f(d.effect,n.effect===`original`?0:n.effect===`pixel`?1:2),t.drawArrays(t.TRIANGLE_STRIP,0,4))},dispose:l}}var Yf=I(``);function Xf(e,t){n(t,!0);let r=J(void 0),i=J(!1),o=J(0),s=()=>{};ne(()=>{Vf()}),Ce(()=>{let e=B(r),t=If.url;if(B(o),A(i,!1),!e||!t)return;let n=Jf(e);if(!n)return;let a=!1,c=!1,l=e=>{e.preventDefault(),c=!1,A(i,!1)},u=()=>M(o);e.addEventListener(`webglcontextlost`,l),e.addEventListener(`webglcontextrestored`,u);let d=new Image,f=()=>{c&&!a&&n.draw(If)};s=f,d.onload=()=>{a||(n.image(d),c=!0,f(),A(i,!0))},d.src=t;let p=new ResizeObserver(f);return p.observe(e),()=>{a=!0,d.onload=null,p.disconnect(),e.removeEventListener(`webglcontextlost`,l),e.removeEventListener(`webglcontextrestored`,u),n.dispose(),s=()=>{}}}),Ce(()=>{If.effect,If.pixelSize,s()});var c=L(),l=q(c),u=e=>{var t=Yf();let n;var o=R(t);let s;a(o,e=>A(r,e),()=>B(r)),f(t),U(()=>{n=pe(t,``,n,{opacity:`calc(${If.visibility} * var(--workspace-background-strength, 1))`,"background-image":B(i)?`none`:`url("${If.url}")`}),s=y(o,1,`svelte-hzgefb`,null,s,{rendered:B(i)})}),g(e,t)};p(l,e=>{If.url&&e(u)}),g(e,c),W()}var Zf=I(``),Qf=I(` `);function $f(e,r){n(r,!0);let i=Y(r,`value`,15),o=Y(r,`step`,3,1),c=Y(r,`disabled`,3,!1),l=Y(r,`invalid`,3,!1),u=Y(r,`allowEmpty`,3,!1),d=J(null);function m(){B(d)?.focus()}function h(){B(d)?.select()}function _(e){if(e===null)return null;let t=e;return r.min!==void 0&&tr.max&&(t=r.max),t}function v(e){let t=_(e);i(t),r.oninput?.(t)}function b(e){let t=_(e);i(t),r.onchange?.(t)}function x(e){let t=e.currentTarget.value;if(t===``){v(u()?null:0);return}let n=Number(t);Number.isFinite(n)&&v(n)}function C(e){let t=e.currentTarget.value;if(t===``){b(u()?null:0);return}let n=Number(t);Number.isFinite(n)&&b(n)}function w(e){if(r.onkeydown?.(e),e.defaultPrevented||e.key!==`Enter`)return;e.preventDefault(),e.stopPropagation();let t=B(d)?.value??``;if(t===``){b(u()?null:0);return}let n=Number(t);Number.isFinite(n)&&b(n)}function T(e){if(c())return;let t=(i()??0)+e*o(),n=(o().toString().split(`.`)[1]??``).length;t=Number(t.toFixed(n)),v(t),r.onchange?.(_(t)),B(d)?.focus()}var E={focus:m,select:h},D=Qf();let O;var k=R(D);s(k),a(k,e=>A(d,e),()=>B(d));var j=X(k,2),M=e=>{var t=Zf(),n=R(t);Be(R(n),{name:`up`,size:12}),f(n);var r=X(n,2);Be(R(r),{name:`down`,size:12}),f(r),f(t),K(`click`,n,()=>T(1)),K(`click`,r,()=>T(-1)),g(e,t)};return p(j,e=>{c()||e(M)}),f(D),U(()=>{O=y(D,1,`sk-number svelte-j94t9a`,null,O,{"is-disabled":c(),"is-invalid":l()}),t(k,i()===null?``:i()),S(k,`min`,r.min),S(k,`max`,r.max),S(k,`step`,o()),S(k,`placeholder`,r.placeholder),k.disabled=c(),S(k,`title`,r.title),S(k,`aria-label`,r.ariaLabel),S(k,`aria-invalid`,l()),S(k,`aria-describedby`,r.ariaDescribedby)}),K(`input`,k,x),K(`change`,k,C),K(`keydown`,k,w),g(e,D),W(E)}H([`input`,`change`,`keydown`,`click`]);var ep=I(` `);function tp(e,t){let r=E();n(t,!0);let i=Y(t,`label`,3,`About this setting`),o=J(!1),s,c,l=J(``),u=!1,d=!1,p=!1,m,h=du();function _(e){e.pointerType!==`touch`&&(clearTimeout(m),d=!0,A(o,!0))}function v(e){e.pointerType!==`touch`&&(d=!1,clearTimeout(m),m=setTimeout(()=>{(document.activeElement!==s||!s.matches(`:focus-visible`))&&A(o,!1)},150))}function b(){if(!B(o)||!s||!c)return;let e=window.visualViewport,t=e?.offsetLeft??0,n=e?.offsetTop??0,r=e?.width??window.innerWidth,i=e?.height??window.innerHeight;c.style.maxWidth=`min(18rem, ${r-16}px)`,c.style.maxHeight=`${i-16}px`;let a=s.getBoundingClientRect(),u=c.getBoundingClientRect(),d=Math.max(t+8,Math.min(a.left,t+r-u.width-8)),f=a.bottom+6;A(l,`left:${d}px;top:${f+u.height<=n+i-8?f:Math.max(n+8,a.top-u.height-6)}px;max-width:min(18rem, ${r-16}px);max-height:${i-16}px`)}Ce(()=>{B(o)?(h.mount(),xe().then(()=>{!B(o)||u||(c.showPopover(),b(),h.show(c))})):c?.matches(`:popover-open`)&&h.close(c)}),Ce(()=>{h.mounted||c?.hidePopover()}),ne(()=>{let e=e=>{e.target instanceof Node&&!s.contains(e.target)&&!c.contains(e.target)&&A(o,!1)};return document.addEventListener(`pointerdown`,e,!0),document.addEventListener(`keydown`,x,!0),window.addEventListener(`resize`,b),window.addEventListener(`scroll`,b,!0),window.visualViewport?.addEventListener(`resize`,b),window.visualViewport?.addEventListener(`scroll`,b),()=>{u=!0,clearTimeout(m),h.destroy(),document.removeEventListener(`pointerdown`,e,!0),document.removeEventListener(`keydown`,x,!0),window.removeEventListener(`resize`,b),window.removeEventListener(`scroll`,b,!0),window.visualViewport?.removeEventListener(`resize`,b),window.visualViewport?.removeEventListener(`scroll`,b)}});function x(e){e.key===`Escape`&&B(o)&&(A(o,!1),e.preventDefault(),e.stopPropagation())}var C=ep();let w;var T=R(C);Be(R(T),{name:`help`,size:20}),f(T),a(T,e=>s=e,()=>s);var D=X(T,2),O=R(D,!0);f(D),a(D,e=>c=e,()=>c),f(C),U(()=>{w=y(C,1,`info-tip svelte-46n1f7`,null,w,{open:B(o)}),S(T,`aria-label`,i()),S(T,`aria-describedby`,r),S(T,`aria-expanded`,B(o)),S(D,`id`,r),pe(D,B(l)),G(O,t.text)}),ye(`pointerenter`,C,_),ye(`pointerleave`,C,v),K(`focusout`,C,e=>{!d&&!e.currentTarget.contains(e.relatedTarget)&&A(o,!1)}),ye(`focus`,T,()=>{s.matches(`:focus-visible`)&&A(o,!0)}),K(`pointerdown`,T,e=>{p=e.pointerType===`touch`}),K(`click`,T,e=>{A(o,e.detail>0&&p?!B(o):!0,!0)}),g(e,C),W()}H([`focusout`,`pointerdown`,`click`]);var np=I(`
      `),rp=I(`
      `);function ip(e,t){n(t,!0);let i=Y(t,`expanded`,15),a=Y(t,`flush`,3,!1);function o(){i(!i())}var s=rp();let c;var l=R(s),u=R(l);Be(R(u),{name:`next`}),f(u);var d=X(u,2),m=R(d,!0);f(d),f(l);var _=X(l,2),v=e=>{var n=np();r(R(n),()=>t.children),f(n),h(1,n,()=>ut,lu),h(2,n,()=>ut,uu),g(e,n)};p(_,e=>{i()&&e(v)}),f(s),U(()=>{c=y(s,1,`sk-disclosure svelte-13s59ym`,null,c,{"is-open":i(),"is-flush":a()}),S(l,`aria-expanded`,i()),G(m,t.summary)}),K(`click`,l,o),g(e,s),W()}H([`click`]);var ap=I(``),op=I(`

      Conversation format

      `),sp=I(`

      Sampling settings

      Sampling filters and penalties

      Top K
      Frequency penalty
      Presence penalty

      Captured output and reproducibility

      Return top K
      Seed
      `);function cp(e,r){n(r,!0),k(r,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{r.params});let i=[{value:`chat`,label:`chat`},{value:`raw`,label:`raw`}],a=c(()=>_i.info?.is_base_model===!0),o=ke().mode,s=sn(o),l=s>0,u=4096,d=J(!1),p={topK:`Top K limits sampling to the K most likely next tokens. Leave it blank to use the model's default.`,frequencyPenalty:`Frequency penalty reduces the probability of tokens in proportion to how often they have already appeared.`,presencePenalty:`Presence penalty reduces the probability of any token that has already appeared, regardless of frequency.`,returnTopK:o===`browser`?`Return top K retains up to five alternative tokens so you can inspect or branch from them later.`:`Return top K retains alternative tokens so you can inspect or branch from them later.`,seed:`Seed fixes the random-number sequence so repeated runs are easier to compare.`};function h(e){if(e===null){Si(`top_k`,null),ki({top_k:null});return}let t=Math.max(1,Math.min(u,Math.floor(e)));Si(`top_k`,t),ki({top_k:t})}function _(e,t){t!==null&&Si(e,Math.max(-2,Math.min(2,t)))}function v(e){e!==null&&Si(`return_top_k`,ln(e,o))}function b(e){Si(`seed`,e===null?null:Math.floor(e))}let x=c(()=>{let e=xi.logit_bias_text.trim();if(!e)return!0;try{let t=JSON.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)}catch{return e.split(/\r?\n/).filter(Boolean).every(e=>/^\s*-?\d+\s*[:=,\s]\s*-?\d+(?:\.\d+)?\s*$/.test(e))}});var C=sp(),T=R(C);ft(X(R(T),2),{get onclick(){return it}}),f(T);var E=X(T,2),D=R(E),O=X(R(D),2),j=R(O),M=R(j);tp(X(R(M)),{get text(){return p.topK},label:`About Top K`}),f(M),$f(X(M,2),{get value(){return xi.top_k},min:1,max:u,step:1,placeholder:`Model default`,allowEmpty:!0,onchange:h,ariaLabel:`Top K`}),f(j);var N=X(j,2),P=R(N);tp(X(R(P)),{get text(){return p.frequencyPenalty},label:`About Frequency penalty`}),f(P),$f(X(P,2),{get value(){return xi.frequency_penalty},min:-2,max:2,step:.05,onchange:e=>_(`frequency_penalty`,e),ariaLabel:`Frequency penalty`}),f(N);var F=X(N,2),I=R(F);tp(X(R(I)),{get text(){return p.presencePenalty},label:`About Presence penalty`}),f(I),$f(X(I,2),{get value(){return xi.presence_penalty},min:-2,max:2,step:.05,onchange:e=>_(`presence_penalty`,e),ariaLabel:`Presence penalty`}),f(F),f(O),f(D);var L=X(D,2),ee=X(R(L),2),te=R(ee),z=R(te);tp(X(R(z)),{get text(){return p.returnTopK},label:`About Return top K`}),f(z);var ne=X(z,2);{let e=c(()=>!l);$f(ne,{get value(){return xi.return_top_k},min:0,get max(){return s},step:1,get disabled(){return B(e)},onchange:v,ariaLabel:`Return top K`})}f(te);var V=X(te,2),re=R(V);tp(X(R(re)),{get text(){return p.seed},label:`About Seed`}),f(re),$f(X(re,2),{get value(){return xi.seed},min:0,step:1,placeholder:`Not fixed`,allowEmpty:!0,onchange:b,ariaLabel:`Seed`}),f(V),f(ee),f(L),ip(X(L,2),{summary:`Additional parameters`,get expanded(){return B(d)},set expanded(e){A(d,e,!0)},children:(e,n)=>{var r=op(),o=R(r),s=X(R(o),2);m(s,21,()=>i,e=>e.label,(e,t)=>{var n=ap();let r;var i=R(n,!0);f(n),U(()=>{r=y(n,1,`mode-opt svelte-s9wnam`,null,r,{active:$o.mode===B(t).value}),S(n,`aria-pressed`,$o.mode===B(t).value),n.disabled=B(a)&&B(t).value===`chat`,G(i,B(t).value===`chat`?`Chat template`:`Raw completion`)}),K(`click`,n,()=>is(B(t).value)),g(e,n)}),f(s),w(s,e=>Ac?.(e));var c=X(s,2),l=R(c,!0);f(c),f(o);var u=X(o,2),d=X(R(u),2);_e(d),S(d,`placeholder`,`One sequence per line -### -<|eot_id|>`),f(u);var p=X(u,2),h=X(R(p),2);_e(h),S(h,`placeholder`,`{"198": -4, "220": 1.5}`);let _;var v=X(h,2);let b;var C=R(v,!0);f(v),f(p),f(r),U(()=>{G(l,B(a)?`Base models continue the exact text in the buffer, without chat roles or a system prompt.`:`This model normally opens in chat template mode.`),t(d,xi.stop_sequences),t(h,xi.logit_bias_text),S(h,`aria-invalid`,!B(x)),_=y(h,1,`svelte-s9wnam`,null,_,{invalid:!B(x)}),b=y(v,1,`hint svelte-s9wnam`,null,b,{error:!B(x)}),G(C,B(x)?`Use a JSON object or one token ID and value per line.`:`Use JSON or write one token ID and value per line.`)}),K(`input`,d,e=>Si(`stop_sequences`,e.currentTarget.value)),K(`input`,h,e=>Si(`logit_bias_text`,e.currentTarget.value)),g(e,r)},$$slots:{default:!0}}),f(E),f(C),g(e,C),W()}H([`click`,`input`]);var lp=ee(``);function up(e,t){n(t,!0);let r=[`M12 2c0.414 0 0.75 0.336 0.75 0.75v1.5C12.75 4.664 12.414 5 12 5s-0.75-0.336-0.75-0.75v-1.5C11.25 2.336 11.586 2 12 2z`,`m5 10c0 2.761-2.239 5-5 5s-5-2.239-5-5 2.239-5 5-5 5 2.239 5 5z`,`m4.25 0.75c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-1.5C19.336 11.25 19 11.586 19 12s0.336 0.75 0.75 0.75h1.5z`,`M12 19c0.414 0 0.75 0.336 0.75 0.75v1.5c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75v-1.5c0-0.414 0.336-0.75 0.75-0.75z`,`m-7.75-6.25C4.664 12.75 5 12.414 5 12s-0.336-0.75-0.75-0.75h-1.5C2.336 11.25 2 11.586 2 12s0.336 0.75 0.75 0.75h1.5z`,`M4.22 4.22c0.293-0.293 0.767-0.293 1.06 0l1.5 1.5c0.293 0.293 0.293 0.768 0 1.06-0.293 0.294-0.767 0.294-1.06 0l-1.5-1.5c-0.293-0.292-0.293-0.767 0-1.06z`,`m1.06 15.56c-0.293 0.294-0.767 0.294-1.06 0-0.293-0.292-0.293-0.767 0-1.06l1.5-1.5c0.293-0.293 0.767-0.293 1.06 0 0.293 0.293 0.293 0.768 0 1.06l-1.5 1.5z`,`m14.5-15.56c-0.293-0.293-0.767-0.293-1.06 0l-1.5 1.5c-0.293 0.293-0.293 0.768 0 1.06 0.293 0.294 0.767 0.294 1.06 0l1.5-1.5c0.293-0.292 0.293-0.767 0-1.06z`,`m-1.06 15.56c0.293 0.294 0.767 0.294 1.06 0 0.293-0.292 0.293-0.767 0-1.06l-1.5-1.5c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.768 0 1.06l1.5 1.5z`].join(``),i=Y(t,`class`,3,``);var a=lp(),o=R(a);f(a),U(()=>{y(a,0,b(i()),`svelte-6z6lim`),S(o,`d`,t.name===`sunny`?r:`M20.026 17.001c-2.762 4.784-8.879 6.423-13.663 3.661-1.302-0.752-2.399-1.77-3.234-2.982-0.28-0.406-0.099-0.966 0.365-1.132 3.767-1.348 5.785-2.91 6.956-5.146C11.682 9.05 12 6.472 11.139 2.94c-0.12-0.489 0.266-0.954 0.769-0.927 1.556 0.083 3.078 0.53 4.457 1.327 4.784 2.762 6.423 8.879 3.66 13.662z`)}),g(e,a),W()}var dp=I(`
      `);function fp(e,t){n(t,!0);let r=J(V(Oe()));ne(()=>we(e=>{A(r,e,!0)}));var i=dp(),a=R(i);let o;up(R(a),{name:`sunny`,class:`theme-icon`}),f(a);var s=X(a,2);let c;up(R(s),{name:`moon`,class:`theme-icon`}),f(s),f(i),w(i,e=>Ac?.(e)),U(()=>{S(a,`aria-pressed`,B(r)===`light`),o=y(a,1,`svelte-1ihlba3`,null,o,{active:B(r)===`light`}),S(s,`aria-pressed`,B(r)===`dark`),c=y(s,1,`svelte-1ihlba3`,null,c,{active:B(r)===`dark`})}),K(`click`,a,()=>ve(`light`)),K(`click`,s,()=>ve(`dark`)),g(e,i),W()}H([`click`]);var pp=I(`
      Pixel size
      `),mp=I(`
      Treatment
      Visibility

      The image stays dim so text and token colors remain readable. The effect is static and does not animate during generation.

      `,1),hp=I(``),gp=I(`

      Appearance

      Theme

      Choose a light or dark workspace.

      Workspace background

      Optional. Images stay on this device and are never uploaded to a server.

      PNG, JPEG, or WebP. Up to 10 MB; resized to use less memory.

      `);function _p(t,r){n(r,!0);let i=[{value:`original`,label:`Original`},{value:`pixel`,label:`Pixels`},{value:`dither`,label:`Dither`}],a=[1,2,3,4,6,8,12].map(e=>({value:String(e),label:`${e} px`})),o=[{value:`0.04`,label:`Subtle`},{value:`0.1`,label:`Balanced`},{value:`0.14`,label:`Visible`}];var s=gp(),l=R(s);ft(X(R(l)),{get onclick(){return it}}),f(l);var u=X(l,2),d=R(u);fp(X(R(d)),{}),f(d);var m=X(d,2),h=X(R(m),2),_=X(R(h),2);T(2),f(h);var v=X(h,2),y=t=>{var n=mp(),r=q(n),s=R(r),l=R(s,!0);f(s),Du(X(s),{get disabled(){return If.busy},onclick:()=>void Gf(),children:(t,n)=>{T(),g(t,e(`Remove image`))},$$slots:{default:!0}}),f(r);var u=X(r,2);hu(X(R(u)),{ariaLabel:`Background treatment`,get value(){return If.effect},get options(){return i},get disabled(){return If.busy},onchange:e=>void Uf({effect:e})}),f(u);var d=X(u,2),m=e=>{var t=pp(),n=X(R(t));{let e=c(()=>String(If.pixelSize));hu(n,{ariaLabel:`Background pixel size`,get value(){return B(e)},get options(){return a},get disabled(){return If.busy},onchange:e=>void Uf({pixelSize:Number(e)})})}f(t),g(e,t)};p(d,e=>{If.effect!==`original`&&e(m)});var h=X(d,2),_=X(R(h));{let e=c(()=>String(If.visibility));hu(_,{ariaLabel:`Background visibility`,get value(){return B(e)},get options(){return o},get disabled(){return If.busy},onchange:e=>void Uf({visibility:Number(e)})})}f(h),T(2),U(()=>G(l,If.name)),g(t,n)};p(v,e=>{If.url&&e(y)});var b=X(v,2),x=e=>{var t=hp(),n=R(t,!0);f(t),U(()=>G(n,If.error)),g(e,t)};p(b,e=>{If.error&&e(x)});var S=X(b,2),C=R(S,!0);f(S),f(m),f(u),f(s),U(()=>{_.disabled=!If.ready||If.busy,G(C,If.busy?`Saving on this device…`:If.url?`Background saved on this device.`:`Using the plain workspace background.`)}),K(`change`,_,e=>{let t=e.currentTarget.files?.[0];t&&Wf(t),e.currentTarget.value=``}),g(t,s),W()}H([`change`]);var vp=I(`Custom guidance`),yp=I(`Uses the current reply settings`),bp=I(` `),xp=I(`
    • `),Sp=I(``),Cp=I(``),wp=I(`

      Response guidance

      `),Tp=I(`

      Role settings

      Conversation roles

        `);function Ep(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let r=J(``),i=J(``),a=J(null),o=J(null),l=J(!1),u=J(null),d=J(null),h=null,_=null,v=c(()=>_i.info?.default_user_role??`user`),b=c(()=>_i.info?.default_assistant_role??`assistant`),x=c(()=>[...new Set([B(v),B(b),xi.user_role.trim(),xi.assistant_role.trim()].filter(Boolean))]),C=c(()=>{let e=new Map;for(let[t,n]of Object.entries(ro.roster)){let r=t===`user`?B(v):t===`assistant`?B(b):t;(!e.get(r)||t===`user`||t===`assistant`)&&e.set(r,{key:t,label:r,member:n})}for(let t of B(x)){if(e.has(t))continue;let n=t===B(v)?`user`:t===B(b)?`assistant`:t;e.set(t,{key:n,label:t,member:ro.roster[n]??null})}let t=B(x).map(t=>e.get(t)).filter(e=>e!==void 0),n=[...e.values()].filter(e=>!B(x).includes(e.label)).sort((e,t)=>e.label.localeCompare(t.label));return[...t,...n]}),w=c(()=>B(o)?ro.roster[B(o)]??null:null),T=c(()=>B(o)!==null&&(B(r).trim()!==(B(w)?.recipe?.steering??``)||B(i).trim()!==(B(w)?.notes??``))),E=c(()=>B(l)?`Saving…`:B(T)?`Changes save automatically`:B(d)===B(o)?`Saved`:`Changes save automatically`);function D(e){A(a,e.label,!0),A(o,e.key,!0),A(r,e.member?.recipe?.steering??``,!0),A(i,e.member?.notes??``,!0),A(u,null)}function O(){h!==null&&(clearTimeout(h),h=null)}function M(){A(u,null),A(d,null),O(),h=setTimeout(()=>{h=null,N()},450)}Ce(()=>{let e=B(C);B(o)!==null&&e.some(e=>e.key===B(o))||e[0]&&D(e[0])});async function N(){if(O(),_&&!await _)return!1;let e=B(o);if(!e||!B(T))return!0;let t=B(a),n=B(r).trim(),s=B(i).trim();A(l,!0),A(u,null);let c=(async()=>{try{let t=await Ot.castPut(e,{steering:n===``?null:n,notes:s});return ro.roster={...ro.roster,[e]:t.member},B(o)===e&&A(d,e,!0),!0}catch(e){return A(u,je(e,`Unable to save ${t??`this role`}. Check the fields and try again.`),!0),!1}finally{A(l,!1)}})();_=c;let f=await c;return _===c&&(_=null),f&&B(o)===e&&B(T)?N():f}async function P(e){e.key!==B(o)&&await N()&&D(e)}async function F(){await N()&&it()}async function I(e){try{await Ot.castDelete(e);let t={...ro.roster};delete t[e],ro.roster=t,B(o)===e&&(A(r,``),A(i,``),A(d,null))}catch(e){Z(je(e,`Unable to remove this speaker. Try again.`),{kind:`error`})}}async function L(){O(),!(_&&!await _)&&B(o)&&await I(B(o))}Pe(()=>{O(),B(T)&&N()});var ee=Tp(),te=R(ee);ft(X(R(te),2),{onclick:()=>void F()}),f(te);var z=X(te,2),ne=R(z),V=X(R(ne),2);m(V,21,()=>B(C),e=>e.label,(e,t)=>{var n=xp();let r;var i=R(n),a=R(i),s=R(a,!0);f(a);var c=X(a,2),l=R(c),u=R(l,!0);f(l);var d=X(l,2),m=e=>{g(e,vp())},h=e=>{g(e,yp())};p(d,e=>{B(t).member?.recipe?.steering?e(m):e(h,-1)});var _=X(d,2),v=e=>{var n=bp(),r=R(n,!0);f(n),U(()=>G(r,B(t).member.notes)),g(e,n)};p(_,e=>{B(t).member?.notes&&e(v)}),f(c),f(i),f(n),U(e=>{r=y(n,1,`member svelte-2ivmxu`,null,r,{editing:B(o)===B(t).key}),S(i,`aria-pressed`,B(o)===B(t).key),G(s,e),G(u,B(t).label)},[()=>B(t).label.slice(0,1).toUpperCase()]),K(`click`,i,()=>void P(B(t))),g(e,n)}),f(V),f(ne);var re=X(ne,2),ie=e=>{var t=wp(),n=R(t),o=R(n),c=R(o),d=R(c,!0);f(c),f(o),f(n);var m=X(n,2),h=R(m);tp(X(R(h),2),{label:`About role guidance`,text:`Guidance used whenever this role writes. Settings for one reply take priority.`}),f(h);var _=X(h,2);s(_),f(m);var v=X(m,2),y=X(R(v),2);s(y),f(v);var b=X(v,2),x=e=>{var t=Sp(),n=R(t,!0);f(t),U(()=>G(n,B(u))),g(e,t)};p(b,e=>{B(u)&&e(x)});var C=X(b,2),T=R(C),D=R(T,!0);f(T);var O=X(T,2),k=e=>{var t=Cp();U(()=>t.disabled=B(l)),K(`click`,t,()=>void L()),g(e,t)};p(O,e=>{B(w)?.origin===`configured`&&e(k)}),f(C),f(t),U(()=>{G(d,B(a)),S(_,`aria-label`,`Response guidance for ${B(a)}`),G(D,B(E))}),K(`input`,_,M),j(_,()=>B(r),e=>A(r,e)),K(`input`,y,M),j(y,()=>B(i),e=>A(i,e)),g(e,t)};p(re,e=>{B(o)&&B(a)&&e(ie)}),f(z),f(ee),g(e,ee),W()}H([`click`,`input`]);function Dp(e){return e.family===`geometry`&&e.is_affine&&e.intrinsic_dim===1}function Op(e,t,n,r){let i=new Set(e);if(r)for(let e of t){let t=n.get(e)?.info;t&&Dp(t)&&i.add(e)}return[...i].sort((e,t)=>e.localeCompare(t,void 0,{sensitivity:`base`}))}function kp(e,t,n){let r=new Set(n);return e.filter(e=>{let n=t.get(e)?.info;return!n||!Dp(n)||!r.has(e)}).map(e=>({name:e,reason:Ap(t.get(e)?.info)})).sort((e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`}))}function Ap(e){return e?e.family===`lens`?`J-lens readout, not a residual direction`:e.family===`sae`?`SAE readout, not a residual direction`:e.is_affine?e.intrinsic_dim===1?`not exposed as a direction by this runtime`:`multidimensional subspace, not one direction`:`curved manifold, not one direction`:`not exposed as a direction by this runtime`}var jp=I(` `,1),Mp=I(`Choose at least two controls`),Np=I(`Choose two controls`),Pp=I(``),Fp=I(`
        Loading layer comparison…
        `),Ip=I(`
        Choose two available profiles or probes to compare their layers.
        `),Lp=I(` `),Rp=I(``),zp=I(` `),Bp=I(`
        /
        `),Vp=I(``);function Hp(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let r=ke().mode===`http`,i=c(()=>Op(rr.names,Hr.active,Hr.entries,r)),a=J(``),o=J(``),s=c(()=>B(i).length===0?[{value:``,label:`(empty)`}]:B(i).map(e=>({value:e,label:e}))),l=J(null),u=J(!1),d=J(null);Ce(()=>{or().catch(()=>{})}),Ce(()=>{if(B(i).length===0){A(a,``),A(o,``);return}(!B(a)||!B(i).includes(B(a)))&&A(a,B(i)[0],!0),(!B(o)||!B(i).includes(B(o)))&&A(o,B(i).find(e=>e!==B(a))??B(a),!0)});async function h(e,t){if(!e||!t){A(l,null);return}A(u,!0),A(d,null);try{A(l,await wt.pairwise(e,t),!0)}catch(e){e instanceof se?A(d,je(e,`Unable to compare these directions. ${e.body&&typeof e.body==`object`&&`detail`in e.body?String(e.body.detail):e.message}`),!0):A(d,je(e,`Unable to compare these directions. Try again.`),!0),A(l,null)}finally{A(u,!1)}}Ce(()=>{h(B(a),B(o))});function _(e,t,n){return`${B(a)} L${e} × ${B(o)} L${t}: ${n==null?`-`:n.toFixed(3)}`}function v(){it()}function y(e){e.key===`Escape`&&(e.preventDefault(),v())}let b=c(()=>B(l)?.matrix??null),x=c(()=>B(l)?.layers_a??[]),C=c(()=>B(l)?.layers_b??[]);var w=Vp();ye(`keydown`,ce,y);var T=R(w),E=R(T),D=X(R(E),2),O=R(D),j=e=>{var t=jp(),n=q(t),r=R(n);f(n);var i=X(n,2),s=R(i);f(i),U(()=>{G(r,`${B(a)??``} × ${B(o)??``}`),G(s,`${B(x).length??``} × ${B(C).length??``} layers · model ${B(l).model??`-`??``}`)}),g(e,t)},M=e=>{g(e,Mp())},N=e=>{g(e,Np())};p(O,e=>{B(l)?e(j):B(i).length<2?e(M,1):e(N,-1)}),f(D),f(E),ft(X(E,2),{onclick:v}),f(T);var P=X(T,2),F=R(P),I=X(R(F),2);{let e=c(()=>B(i).length===0);hu(I,{get options(){return B(s)},get disabled(){return B(e)},ariaLabel:`Concept A`,get value(){return B(a)},set value(e){A(a,e,!0)}})}f(F);var L=X(F,2),ee=X(R(L),2);{let e=c(()=>B(i).length===0);hu(ee,{get options(){return B(s)},get disabled(){return B(e)},ariaLabel:`Concept B`,get value(){return B(o)},set value(e){A(o,e,!0)}})}f(L),f(P);var te=X(P,2),z=R(te),ne=e=>{var t=Pp(),n=R(t);f(t),U(()=>G(n,`Comparison failed: ${B(d)??``}`)),g(e,t)},V=e=>{g(e,Fp())},re=e=>{g(e,Ip())},ie=e=>{var t=Bp(),n=R(t);pe(n,`--cell: 26px;`);var r=R(n),i=R(r),s=R(i),l=R(s),u=R(l,!0);f(l);var d=X(l,4),p=R(d,!0);f(d),f(s),m(X(s),16,()=>B(C),e=>e,(e,t)=>{var n=Lp(),r=R(n),i=R(r);f(r),f(n),U(()=>{S(n,`title`,`${B(o)??``} L${t??``}`),G(i,`L${t??``}`)}),g(e,n)}),f(i),f(r);var h=X(r);m(h,22,()=>B(x),e=>e,(e,t,n)=>{var r=zp(),i=R(r),o=R(i);f(i),m(X(i),18,()=>B(C),e=>e,(e,r,i)=>{let a=c(()=>B(b)[B(n)]?.[B(i)]??null);var o=Rp(),s=R(o);{let e=c(()=>_(t,r,B(a)));Wl(s,{get value(){return B(a)},size:26,get title(){return B(e)}})}f(o),g(e,o)}),f(r),U(()=>{S(i,`title`,`${B(a)??``} L${t??``}`),G(o,`L${t??``}`)}),g(e,r)}),f(h),f(n),f(t),U(()=>{G(u,B(a)),G(p,B(o))}),g(e,t)};p(z,e=>{B(d)?e(ne):B(u)&&!B(b)?e(V,1):!B(b)||B(x).length===0||B(C).length===0?e(re,2):e(ie,-1)}),f(te),f(w),U(()=>S(te,`aria-busy`,B(u))),g(e,w),W()}var Up=I(``),Wp=I(` `,1),Gp=I(`
        Omitted unsupported probes:
        `),Kp=I(``),qp=I(`
        Loading correlations…
        `),Jp=I(`
        No single-direction profiles are available for correlation.
        `),Yp=I(` `),Xp=I(``),Zp=I(` `),Qp=I(`
        name
        `),$p=I(``);function em(t,r){n(r,!0),k(r,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{r.params});let i=J(!1),a=J(null);async function o(){A(i,!0),A(a,null);try{await sr(null)}catch(e){A(a,je(e,`Unable to compare the active directions. Try again.`),!0)}finally{A(i,!1)}}Ce(()=>{nr.correlation||o()});let s=c(()=>nr.correlation),l=c(()=>B(s)?.names??[]),u=c(()=>B(s)?kp(Hr.active,Hr.entries,B(s).names):[]);function d(e,t,n){return`${e} vs ${t}: ${n==null?`-`:n.toFixed(3)}`}function h(){it()}function _(e){e.key===`Escape`&&(e.preventDefault(),h())}var v=$p();ye(`keydown`,ce,_);var y=R(v),b=R(y),x=X(R(b),2),C=R(x),w=R(C),E=X(w),D=t=>{var n=e();U(()=>G(n,`· ${B(u).length??``} unsupported ${B(u).length===1?`probe`:`probes`} omitted`)),g(t,n)};p(E,e=>{B(u).length>0&&e(D)}),f(C),f(x),f(b);var O=X(b,2),j=R(O);Du(j,{size:`sm`,onclick:()=>void o(),get disabled(){return B(i)},title:`refresh`,children:(t,n)=>{T();var r=e();U(()=>G(r,B(i)?`…`:`refresh`)),g(t,r)},$$slots:{default:!0}}),ft(X(j,2),{onclick:h}),f(O),f(y);var M=X(y,2),N=e=>{var t=Gp();m(X(R(t),2),19,()=>B(u),e=>e.name,(e,t,n)=>{var r=Wp(),i=q(r),a=e=>{g(e,Up())};p(i,e=>{B(n)>0&&e(a)});var o=X(i,2),s=R(o,!0);f(o);var c=X(o,2),l=R(c);f(c),U(()=>{S(o,`title`,B(t).reason),G(s,B(t).name),G(l,`(${B(t).reason??``})`)}),g(e,r)}),f(t),g(e,t)};p(M,e=>{B(s)&&B(u).length>0&&e(N)});var P=X(M,2),F=R(P),I=e=>{var t=Kp(),n=R(t);f(t),U(()=>G(n,`Correlation failed: ${B(a)??``}`)),g(e,t)},L=e=>{g(e,qp())},ee=e=>{g(e,Jp())},te=e=>{var t=Qp(),n=R(t);pe(n,`--cell: 26px;`);var r=R(n),i=R(r);m(X(R(i)),16,()=>B(l),e=>e,(e,t)=>{var n=Yp(),r=R(n),i=R(r,!0);f(r),f(n),U(()=>{S(n,`title`,t),G(i,t)}),g(e,n)}),f(i),f(r);var a=X(r);m(a,20,()=>B(l),e=>e,(e,t)=>{var n=Zp(),r=R(n),i=R(r,!0);f(r),m(X(r),16,()=>B(l),e=>e,(e,n)=>{let r=c(()=>B(s).matrix[t]?.[n]??null);var i=Xp(),a=R(i);{let e=c(()=>d(t,n,B(r)));Wl(a,{get value(){return B(r)},size:26,get title(){return B(e)}})}f(i),g(e,i)}),f(n),U(()=>{S(r,`title`,t),G(i,t)}),g(e,n)}),f(a),f(n),f(t),g(e,t)};p(F,e=>{B(a)?e(I):B(i)&&!B(s)?e(L,1):!B(s)||B(l).length===0?e(ee,2):e(te,-1)}),f(P),f(v),U(()=>{G(w,`${B(l).length??``} comparable ${B(l).length===1?`direction`:`directions`} `),S(P,`aria-busy`,B(i))}),g(t,v),W()}var tm=V({busy:!1});async function nm(e=!1){let t=wi.info;if(!(tm.busy||$.active)){if(!t||t.model_id!==_i.info?.model_id)throw Error(`Open a model before resetting its settings.`);tm.busy=!0;try{let n=t.config;if(await ki({temperature:n.temperature??1,top_p:n.top_p??1,top_k:n.top_k,max_tokens:n.max_tokens??1024,system_prompt:n.system_prompt??``,...t.thinking_is_optional?{thinking:n.thinking??!1}:{}}),Object.assign(xi,{seed:null,stop_sequences:``,logit_bias_text:``,presence_penalty:0,frequency_penalty:0,return_top_k:ln(8,ke().mode)}),!e)return;nr.entries.clear(),nr.customExpression=t.default_steering,nr.subspaceAlong=.5,xi.user_role=t.default_user_role??`user`,xi.assistant_role=t.default_assistant_role??`assistant`,Object.assign(us,{enabled:!1,mode:`unsteered`,custom:``}),is(t.is_base_model?`raw`:`chat`);for(let e of[...Hr.active])await ai(e);for(let e of t.instruments){if(e.family!==`geometry`&&e.family!==`lens`&&e.family!==`sae`)continue;let t=_i.info?.instruments.find(t=>t.family===e.family);t&&(e.source&&e.source!==t.source&&e.family!==`geometry`&&(e.family===`lens`&&t.capabilities.source_switch?await kt.setLensSource(e.source):ke().mode===`browser`&&await kt.activateInstalledPack(e.family,{source:e.source,...`layer`in e.live?{layer:e.live.layer}:{}})),JSON.stringify(t.live)!==JSON.stringify(e.live)&&await kt.setLive(e.family,{enabled:e.live.enabled,...`layers`in e.live?{layers:e.live.layers}:{}}))}if(await bi(),_i.error)throw Error(_i.error)}finally{tm.busy=!1}}}var rm=I(`

        Reset settings

        Restore generation settings, system prompt, roles, steering, and readings. Chats and downloaded files stay saved.

        `,1),im=I(`

        Reset the current model’s settings to their starting values?

        `,1),am=I(`

        Available when the current reply finishes.

        `),om=I(``),sm=I(`
        `);function cm(t,r){n(r,!0);let i=Y(r,`full`,3,!1),a=J(!1),o=J(null);async function s(){A(o,null);try{await nm(i()),A(a,!1),Z(i()?`Model settings reset.`:`Generation settings reset.`,{kind:`info`})}catch(e){A(o,je(e,`Settings could not be fully reset. Try again.`),!0)}}var l=sm(),u=R(l),d=e=>{var t=rm();T(2),g(e,t)};p(u,e=>{i()&&e(d)});var m=X(u,2),h=t=>{var n=im(),r=X(q(n),2),i=R(r);Du(i,{get disabled(){return tm.busy},onclick:()=>A(a,!1),children:(t,n)=>{T(),g(t,e(`Cancel`))},$$slots:{default:!0}});var o=X(i,2);{let t=c(()=>tm.busy||$.active);Du(o,{variant:`solid`,get disabled(){return B(t)},onclick:()=>void s(),children:(t,n)=>{T(),g(t,e(`Reset Settings`))},$$slots:{default:!0}})}f(r),g(t,n)},_=t=>{{let n=c(()=>!wi.info||tm.busy||$.active);Du(t,{get disabled(){return B(n)},onclick:()=>i()?A(a,!0):void s(),children:(t,n)=>{T();var r=e();U(()=>G(r,tm.busy?`Resetting…`:i()?`Reset Settings`:`Reset to original`)),g(t,r)},$$slots:{default:!0}})}};p(m,e=>{B(a)?e(h):e(_,-1)});var v=X(m,2),y=e=>{g(e,am())};p(v,e=>{$.active&&e(y)});var b=X(v,2),x=e=>{var t=om(),n=R(t,!0);f(t),U(()=>G(n,B(o))),g(e,t)};p(b,e=>{B(o)&&e(x)}),f(l),g(t,l),W()}var lm=I(`

        Model health

        `),um=I(``),dm=I(`

        clear

        `),fm=I(`
      • `),pm=I(`
          `),mm=I(`

          `),hm=I(`

          generation

          Perplexity

          loom tree

          artifacts

          probes

          checks

          warnings

          `);function gm(t,r){n(r,!0);let i=Y(r,`params`,3,null),a=c(()=>i()?.embedded===!0),o=J(!1),s=J(null),l=J(null),u=c(()=>Qo($)),d=c(()=>{let e=[];return _i.info||e.push(`session info is not loaded`),_i.error&&e.push(_i.error),Q.error&&e.push(`loom API error: ${Q.error}`),nr.catalog.length===0&&e.push(`no manifold artifacts are available`),Hr.active.length===0&&e.push(`no active probes; internal-state views will be sparse`),e});async function h(){A(o,!0),A(l,null);try{await Promise.all([bi(),or(),ri(),go(),yr(),sr()]),A(s,new Date().toLocaleTimeString(),!0)}catch(e){A(l,je(e,`Unable to refresh every diagnostic. Reopen the model and try again.`),!0)}finally{A(o,!1)}}var _=hm();let v;var b=R(_),x=e=>{var t=lm();ft(X(R(t),2),{get onclick(){return it}}),f(t),g(e,t)};p(b,e=>{B(a)||e(x)});var C=X(b,2),w=R(C),E=R(w),D=R(E),O=R(D,!0);f(D);var k=X(D,2),j=R(k,!0);f(k),f(E),Du(X(E,2),{variant:`solid`,get busy(){return B(o)},get disabled(){return B(o)},onclick:h,children:(t,n)=>{T();var r=e();U(()=>G(r,B(o)?`checking…`:`refresh`)),g(t,r)},$$slots:{default:!0}}),f(w);var M=X(w,2),N=e=>{var t=um(),n=R(t);f(t),U(()=>G(n,`Health check failed: ${B(l)??``}`)),g(e,t)};p(M,e=>{B(l)&&e(N)});var P=X(M,2);cm(R(P),{full:!0}),f(P);var F=X(P,2),I=R(F),L=X(R(I),2),ee=R(L,!0);f(L);var te=X(L,2),z=R(te);f(te),f(I);var ne=X(I,2),V=X(R(ne),2),re=R(V,!0);f(V);var ie=X(V,2),ae=R(ie);f(ie),f(ne);var oe=X(ne,2),H=X(R(oe),2),se=R(H,!0);f(H);var ce=X(H,2),le=R(ce);f(ce),f(oe);var ue=X(oe,2),de=X(R(ue),2),fe=R(de,!0);f(de);var pe=X(de,2),me=R(pe);f(pe),f(ue);var he=X(ue,2),ge=X(R(he),2),_e=R(ge,!0);f(ge);var ve=X(ge,2),ye=R(ve);f(ve),f(he),f(F);var be=X(F,2),xe=X(R(be),2),Se=R(xe);let Ce;var we=R(Se);f(Se);var Te=X(Se,2);let Ee;var De=R(Te);f(Te);var Oe=X(Te,2);let K;var ke=R(Oe);f(Oe);var Ae=X(Oe,2);let q;var Me=R(Ae);f(Ae);var Ne=X(Ae,2);let Pe;var Fe=R(Ne);f(Ne),f(xe),f(be);var Ie=X(be,2),Le=X(R(Ie),2),Re=e=>{g(e,dm())},ze=e=>{var t=pm();m(t,20,()=>B(d),e=>e,(e,t)=>{var n=fm(),r=R(n,!0);f(n),U(()=>G(r,t)),g(e,n)}),f(t),g(e,t)};p(Le,e=>{B(d).length===0?e(Re):e(ze,-1)});var Be=X(Le,2),Ve=e=>{var t=mm(),n=R(t);f(t),U(()=>G(n,`updated ${B(s)??``}`)),g(e,t)};p(Be,e=>{B(s)&&e(Ve)}),f(Ie),f(C),f(_),U((e,t)=>{v=y(_,1,`drawer-shell svelte-1p8xu43`,null,v,{embedded:B(a)}),S(_,`role`,B(a)?`region`:void 0),S(_,`aria-label`,B(a)?`Model controls`:`Health drawer`),S(C,`aria-busy`,B(o)),G(O,_i.info?.model_id??`no model`),G(j,_i.info?`${_i.info.device}/${_i.info.dtype}`:`session offline`),G(ee,$.active?`active`:$.finishReason??`idle`),G(z,`${$.tokensSoFar??``}/${($.maxTokens||`-`)??``} tokens · ${e??``} tok/s`),G(re,t),G(ae,`${$.ppl.count??``} steps`),G(se,Q.nodes.size||`-`),G(le,`rev ${(Q.loaded?Q.rev:`-`)??``} · depth ${(Q.activePath.length||`-`)??``}`),G(fe,nr.catalog.length),G(me,`${nr.entries.size??``} racked · ${rr.names.length??``} resident`),G(_e,Hr.active.length),G(ye,`${Hr.entries.size??``} rows · ${nr.correlation?`matrix cached`:`no matrix`}`),Ce=y(Se,1,`svelte-1p8xu43`,null,Ce,{ok:!!_i.info}),G(we,`Session details: ${_i.info?`loaded`:`unavailable`}`),Ee=y(Te,1,`svelte-1p8xu43`,null,Ee,{ok:Q.loaded&&!Q.error}),G(De,`Loom: ${Q.loaded&&!Q.error?`loaded`:`unavailable`}`),K=y(Oe,1,`svelte-1p8xu43`,null,K,{ok:nr.catalog.length>0}),G(ke,`Response controls: ${nr.catalog.length>0?`available`:`none installed`}`),q=y(Ae,1,`svelte-1p8xu43`,null,q,{ok:Hr.active.length>0}),G(Me,`Probes: ${Hr.active.length>0?`active`:`none active`}`),Pe=y(Ne,1,`svelte-1p8xu43`,null,Pe,{ok:nr.correlation!==null}),G(Fe,`Correlation: ${nr.correlation===null?`not measured`:`available`}`)},[()=>$.tokPerSec.toFixed(1),()=>B(u)===null?`-`:B(u).toFixed(2)]),g(t,_),W()}var _m=I(`

          Browser fitting

          `),vm=I(`

          Conversation

          EscStops generation or closes a panel
          EnterSends a message
          Shift + EnterStarts a new line
          + EnterAdds text without generating
          Select a tokenOpens its details

          Loom

          These keys apply while the Loom has keyboard focus.

          j / kMoves between alternatives
          h / lMoves to an earlier turn or its first continuation
          EnterOpens the selected branch
          sStars the selected turn
          nAdds a note
          /Searches the conversation
          + RGenerates another answer
          + EEdits the selected turn
          + BCreates an alternate branch
          + NOpens the map navigator
          + DDeletes the branch and its continuations
          `),ym=I(`

          Steering expressions are the text form of response controls. They describe directions and when those directions apply. The controls create them automatically; this section is only a technical reference.

          Examples

          0.3 honestA light push toward honesty 0.4 warm@responseWarmth only during the reply 0.5 personas%pirateThe pirate point on a persona manifold !sycophanticThe sycophantic direction removed 0.3 a + 0.5 bTwo directions applied together

          Basic grammar

          `),bm=I(`

          Help

          What each area does

          Conversation

          The chat appears here. Color on a model reply can show token surprisal, sampler entropy, or a saved reading.

          Controls

          Response controls shape and measure the next reply. Model controls manage the active model, its tools, and local storage. Chat controls let you name your chat, change its avatar, and save or download a copy.

          Loom

          Weave shows your current text beside its alternative continuations. Map shows where the paths divide; drag to move around or pinch to zoom.

          Common terms

          Token
          One unit of text for the model. It may be a whole word, part of one, or punctuation.
          Token surprisal
          How unlikely the chosen token was after sampling settings were applied. It measures a word choice, not whether the reply is true.
          Sampler entropy
          How spread out the next-token probabilities were after sampling settings. Low entropy can come from restrictive settings, even when the reply is wrong.
          Direction
          An internal pattern used to steer a reply toward or away from a trait.
          Reading
          A measurement of an internal pattern. It observes the reply without changing it.
          J-lens
          A fitted projection of a layer's activations into token probabilities. Aggregate strength is the mean across fitted layers, not the final sampler probability or a record of the model's thoughts.
          SAE feature
          A learned activation pattern. Its label is an interpretation, not proof of a concept or cause. Normalized strength compares activation with a reference maximum and can exceed 1.
          Captured or replayed
          Captured readings were recorded during the original run. Replayed readings are computed later; their source and steering are shown beside them. An unsteered replay is a separate measurement, not the original capture.
          Loom
          The conversation map, including its alternate continuations.
          `);function xm(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let r=typeof navigator<`u`&&/Mac|iPhone|iPad|iPod/.test(navigator.platform)?`Cmd`:`Ctrl`,i=J(!1),a=J(!1),o=ae();var s=bm(),c=R(s);ft(X(R(c),2),{get onclick(){return it}}),f(c);var l=X(c,2),u=R(l),d=X(R(u),2),m=X(R(d),6),h=e=>{var t=_m(),n=X(R(t),2),r=R(n);f(n),f(t),U(()=>G(r,`Browser fitting supports up to ${o??``} dimensions. Larger fits need the Python/server runtime.`)),g(e,t)};p(m,e=>{o!==null&&e(h)}),f(d),f(u);var _=X(u,4);ip(_,{summary:`Keyboard shortcuts`,get expanded(){return B(i)},set expanded(e){A(i,e,!0)},children:(e,t)=>{var n=vm(),i=R(n),a=X(R(i),2),o=R(a),s=X(R(o),3),c=R(s),l=R(c),u=R(l,!0);f(l),T(2),f(c),T(),f(s),T(),f(o),f(a),f(i);var d=X(i,2),p=X(R(d),4),m=R(p),h=X(R(m),6),_=R(h),v=R(_),y=R(v,!0);f(v),T(2),f(_),T(),f(h);var b=X(h),x=R(b),S=R(x),C=R(S,!0);f(S),T(2),f(x),T(),f(b);var w=X(b),E=R(w),D=R(E),O=R(D,!0);f(D),T(2),f(E),T(),f(w);var k=X(w),A=R(k),j=R(A),M=R(j,!0);f(j),T(2),f(A),T(),f(k);var N=X(k),P=R(N),F=R(P),I=R(F,!0);f(F),T(2),f(P),T(),f(N),f(m),f(p),f(d),f(n),U(()=>{G(u,r),G(y,r),G(C,r),G(O,r),G(M,r),G(I,r)}),g(e,n)},$$slots:{default:!0}}),ip(X(_,2),{summary:`Steering expression reference`,get expanded(){return B(a)},set expanded(e){A(a,e,!0)},children:(e,t)=>{var n=ym(),r=X(R(n),8);r.textContent=`expr := term (("+" | "-") term)* -term := [coeff "*"?] ["!"] selector ["@" trigger] -selector := atom (("~" | "|") atom | "%" position)? -position := signed_num ("," signed_num)* | label -atom := [ns "/"] NAME ["." NAME] [":" variant] | "sae/" INT -trigger := before | after | both | thinking | response - | prompt | generated | when: -variant := raw | sae | sae- - | role- | from- -`,f(n),g(e,n)},$$slots:{default:!0}}),f(l),f(s),g(e,s),W()}var Sm=I(`[BASE]`);function Cm(e,t){let n=Y(t,`plain`,3,!1);var r=Sm();let i;U(()=>i=y(r,1,`base-tag svelte-1ove6n8`,null,i,{plain:n()})),g(e,r)}var wm=(e,t)=>`mo-root${e===`always`?` mo-always`:``}${t?` mo-expr`:``}`;function Tm(e){let t=Math.round(e.num(`motion.blink`,3500,6500)),n=Math.round(e.num(`motion.saccade`,4200,7600)),r=e.num(`motion.lookX`,1,2.2),i=e.num(`motion.lookY`,.8,1.7),a=e=>Math.round(e*100)/100;return{phase:Math.round(e.num(`motion.phase`,0,2800)),bob:Math.round(e.num(`motion.bob`,0,3400)),blink:t,blinkPhase:Math.round(e.num(`motion.blinkPhase`,0,t)),saccade:n,saccadePhase:Math.round(e.num(`motion.saccadePhase`,0,n)),lookX:a(r)*(e.bool(`motion.lookXFlip`)?-1:1),lookY:a(i)*(e.bool(`motion.lookYFlip`)?-1:1),lookMX:a(r),lookMY:a(i)}}function Em(e){let t=e=>`${-e}ms`,n=Tm(e);return{"--mo-phase":t(n.phase),"--mo-bob-phase":t(n.bob),"--mo-blink":`${n.blink}ms`,"--mo-blink-phase":t(n.blinkPhase),"--mo-look-x":String(n.lookX),"--mo-look-mx":String(n.lookMX),"--mo-look-y":String(n.lookY),"--mo-look-my":String(n.lookMY),"--mo-saccade":`${n.saccade}ms`,"--mo-saccade-phase":t(n.saccadePhase)}}function Dm({l:e,c:t,h:n}){let r=n*Math.PI/180,i=t*Math.cos(r),a=t*Math.sin(r),o=e+.3963377774*i+.2158037573*a,s=e-.1055613458*i-.0638541728*a,c=e-.0894841775*i-1.291485548*a,l=o*o*o,u=s*s*s,d=c*c*c;return[4.0767416621*l-3.3077115913*u+.2309699292*d,-1.2684380046*l+2.6097574011*u-.3413193965*d,-.0041960863*l-.7034186147*u+1.707614701*d]}var Om=e=>e.every(e=>e>=-1e-4&&e<=1.0001);function km(e){let t=Dm(e);if(!Om(t)){let n=0,r=e.c;for(let t=0;t<12;t++){let t=(n+r)/2;Om(Dm({...e,c:t}))?n=t:r=t}t=Dm({...e,c:n})}return t.map(e=>Math.min(1,Math.max(0,e)))}function Am(e){let[t,n,r]=km(e);return .2126*t+.7152*n+.0722*r}function jm(e,t){let n=Am(e),r=Am(t);return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}function Mm(e,t,n){if(jm(e,t)>=n)return e;let r=e.l>=t.l?1:-1;for(let i of[r,-r]){let r={...e};for(let e=0;e<60;e++){if(r.l=Math.min(1,Math.max(0,r.l+i*.02)),jm(r,t)>=n)return r;if(r.l===0||r.l===1)break}}let i={...e,l:0,c:0},a={...e,l:1,c:0};return jm(i,t)>=jm(a,t)?i:a}function Nm(e){return`#`+km(e).map(e=>{let t=e<=.0031308?12.92*e:1.055*e**.4166666666666667-.055;return Math.round(t*255).toString(16).padStart(2,`0`)}).join(``)}var Pm=[[.2,{l:.86,c:.085}],[.36,{l:.9,c:.028}],[.62,{l:.73,c:.135}],[.8,{l:.62,c:.165}],[.93,{l:.87,c:.16}],[1,{l:.34,c:.035}]],Fm=e=>Pm.find(([t])=>e{let n=Fm(t),r=Mm({l:n.l,c:n.c,h:e},Im,Lm);return{bg:{l:.965,c:.01,h:e},head:r,eye:r.l>=.5?{l:.17,c:.02,h:e}:{l:.97,c:.012,h:e}}},zm=[[`head`,`bg`,1.25],[`eye`,`head`,4.5]];function Bm(e,t=!0,n=0){let r=Rm(e,n);if(t)for(let[e,t,n]of zm)r[e]=Mm(r[e],r[t],n);return r}function Vm(e,t=!0,n=0){let r=Bm(e,t,n),i={};for(let e in r)i[e]=Nm(r[e]);return i}var Hm=e=>{let t=Math.round(e*100)/100;return Object.is(t,-0)?`0`:String(t)};function Um({cx:e,cy:t,rx:n,ry:r,n:i=4,rot:a=0}){let o=Math.min(1,(8*2**(-1/i)-4)/3),s=n,c=r,l=s*o,u=c*o,d=[[s,0],[s,u],[l,c],[0,c],[-l,c],[-s,u],[-s,0],[-s,-u],[-l,-c],[0,-c],[l,-c],[s,-u],[s,0]],f=a*Math.PI/180,p=Math.cos(f),m=Math.sin(f),h=n=>{let[r,i]=d[n];return`${Hm(e+r*p-i*m)} ${Hm(t+r*m+i*p)}`},g=`M${h(0)}`;for(let e=1;e<13;e+=3)g+=`C${h(e)} ${h(e+1)} ${h(e+2)}`;return g+`Z`}function Wm(e,t,n,r,i,a=0){let o=i.length,s=a*Math.PI/180,c=i.map((i,a)=>{let c=s+2*Math.PI*a/o;return[e+n*i*Math.cos(c),t+r*i*Math.sin(c)]}),l=e=>c[(e%o+o)%o],u=`M${Hm(l(0)[0])} ${Hm(l(0)[1])}`;for(let e=0;e0?a<1?a/2:.5:0,c=o*Math.PI/180-Math.PI/2,l=Array.from({length:i},(a,o)=>{let s=c+2*Math.PI*o/i;return[e+n*Math.cos(s),t+r*Math.sin(s)]}),u=e=>l[(e%i+i)%i],d=(e,t)=>{let[n,r]=u(e),[i,a]=u(t);return`${Hm(n+(i-n)*s)} ${Hm(r+(a-r)*s)}`},f=`M${d(0,-1)}`;for(let e=0;e>>19;return e}function Ym(e){return e=Math.imul(e^e>>>16,2246822507),e=Math.imul(e^e>>>13,3266489909),(e^e>>>16)>>>0}var Xm=new TextEncoder;function Zm(e){return e.normalize(`NFC`).trim().toLowerCase()}function Qm(e,t=!0){let n=t?Zm(e):e;return Jm(1779033703^n.length,Xm.encode(n))}function $m(e,t){return Ym(Jm(Jm(e,Uint8Array.of(255)),Xm.encode(t)))/4294967296}function eh(e,t=!0,n){let r=Qm(e,t),i=e=>{let t=n?.[e],i=Array.isArray(t)?t[Math.floor($m(r,e)*t.length)]:t;return i===void 0?$m(r,e):i>0?i<1?i:.999999:0};return i.num=(e,t,n)=>t+i(e)*(n-t),i.int=(e,t,n)=>t+Math.floor(i(e)*(n-t+1)),i.pick=(e,t)=>t[Math.floor(i(e)*t.length)],i.bool=(e,t=.5)=>i(e)(i(e)*2-1)*t,i}function th(e,t,n){let r=t.expression;return n||!r?{l:e,wrap:``}:r.bake(e,r.p)}var nh=(e,t)=>t?`${e}`:e;function rh(e,t){let n=eh(e,t.normalize??!0,t.traits);return{t:n,palette:{...Vm(t.hue??n.num(`hue`,0,360),t.contrast??!0,t.tone??n(`tone`)),...t.palette}}}function ih(e,t,n){let r=t.background??e.background;if(r!==!1)return{d:r===`square`?`M0 0H100V100H0Z`:Um({cx:50,cy:50,rx:50,ry:50,n:r===`circle`?2:6}),fill:n.bg}}function ah(e){return(t,n={},r)=>{let{t:i,palette:a}=rh(t,n),o=r?.(i,a),s=th(e.layout(i),n,o);return{cls:o?.cls,bg:ih(e,n,a),inner:nh(e.render(s.l,a,!!o),s.wrap),vars:o?.vars}}}var oh=(e,t,n)=>{let r=t.rx,i=e.num(`eye.rx`,.075,.105)*r,a=e.num(`eye.ratio`,1.9,3.2),o=e.num(`eye.scale`,.78,1.24),s=e.num(`eye.stretch`,.85,1.18),c=e.num(`eye.gap`,.1,.24)*r,l=i*Math.max(1,o),u=i*a*Math.max(1,o*s),d=l+r*.03+c,f=e.jitter(`gaze.x`,.09)*n.rx,p=e.num(`gaze.y`,-.2,.08)*n.ry,m=e.jitter(`eye.dy`,.04)*n.ry,h=Math.hypot(l,u),g=Math.hypot((Math.abs(f)+d+h)/n.rx,(Math.abs(p)+Math.abs(m)+h)/n.ry),_=g>.9?.9/g:1,v=i*_,y=v*a,b=d*_,x=Math.max(0,Math.min(1,c/u)),S=Math.min(12,Math.asin(x)*180/Math.PI),C=e.num(`eye.lean`,-1,1)*S,w=Math.max(-12,Math.min(12,C+e.jitter(`eye.lean2`,3.5))),T=n.cx+f*_,E=n.cy+p*_;return[{cx:T-b,cy:E,rx:v,ry:y,n:e.num(`eye.n`,3.5,6),rot:C},{cx:T+b,cy:E+m*_,rx:v*o,ry:y*o*s,n:e.num(`eye.n`,3.5,6),rot:w}]};function sh(e,t){let n=t=>(e.find(([,e])=>t1+e.jitter(`body.r${n}`,.16))};r.body?.(e,a);let o=r.face?.(a)??a,s={petals:[],extra:[]};return r.decorate?.(e,a,s),{shape:r.name,draw:r.path,body:a,face:o,petals:s.petals,extra:s.extra,eyes:t(e,a,o)}}function i(e,t,n){let r=e=>Math.round(e*100)/100,i=``+e.petals.map(e=>``).join(``)+e.extra.map(e=>``).join(``)+``+e.eyes.map((e,t)=>{let i=``;return n?`${i}`:i}).join(``)+``;return n?`${i}`:i}return{layout:r,render:i,background:!1}}var ch=e=>Gm(e),lh=e=>Wm(e.cx,e.cy,e.rx,e.ry,e.radii,e.rot),uh=e=>t=>({cx:t.cx,cy:t.cy,rx:t.rx*e,ry:t.ry*e}),dh=e=>uh(Math.min(...e.radii)*.95)(e),fh=e=>uh(.84)(e),ph={name:`round`,core:1},mh={name:`organic`,core:.98,path:lh,face:dh},hh={name:`boxy`,core:.86,body:(e,t)=>{t.n=e.num(`body.n`,3.4,6),t.rot=e.num(`body.rot`,-20,20)}},gh={name:`capsule`,core:1.02,body:(e,t)=>{t.ry*=e.num(`capsule.squat`,.55,.68)},face:uh(.94),decorate:(e,t,n)=>{for(let e of[-1,1])n.petals.push({cx:t.cx+e*(t.rx-t.ry),cy:t.cy,r:t.ry})},path:e=>Km(e.cx,e.cy,e.rx-e.ry,e.ry)},_h=sh([[ph,.22],[mh,.48],[hh,.6],[gh,.7],[{name:`nub`,core:.88,decorate:(e,t,n)=>{let r=e.int(`nub.n`,1,2);for(let i=0;i{let r=e.int(`cloud.n`,4,6);for(let i=0;i{t.cy+=.22*t.ry,t.n=2},face:e=>({cx:e.cx,cy:e.cy+e.ry*.05,rx:e.rx*.88,ry:e.ry*.88}),decorate:(e,t,n)=>{n.extra.push(qm(t.cx,t.cy,t.rx,t.ry,e.num(`droplet.tip`,1.4,1.65)))}},.915],[{name:`hexagon`,core:1.05,path:ch,face:fh,body:(e,t)=>{t.sides=6,t.rot=e.num(`body.rot`,-12,12),t.round=e.num(`poly.round`,.24,.5)}},.95],[{name:`sun`,core:.7,decorate:(e,t,n)=>{let r=e.int(`sun.n`,6,9),i=t.rx*e.num(`sun.dist`,1,1.08),a=t.rx*e.num(`sun.r`,.2,.26),o=e.num(`sun.rot`,0,2*Math.PI);for(let e=0;e{t.sides=3,t.rot=e.num(`body.rot`,-5,5),t.round=e.num(`poly.round`,.24,.5)},face:e=>({cx:e.cx,cy:e.cy+e.ry*.1,rx:e.rx*.54,ry:e.ry*.36})},1]],oh),vh=(e,t)=>(n,r)=>{let i=t?t.vars(t.p):{},a=t?.tint?t.tint(r,t.p):r;return{cls:wm(e,!!Object.keys(i).length||!!t?.tint),vars:{...Em(n),"--mo-head":a.head,"--mo-eye":a.eye,...i}}};function yh(e,t={}){return ah(_h)(e,t,t.animate&&vh(t.animate,t.expression))}function bh({l:e,c:t,h:n}){let r=n*Math.PI/180,i=t*Math.cos(r),a=t*Math.sin(r),o=e+.3963377774*i+.2158037573*a,s=e-.1055613458*i-.0638541728*a,c=e-.0894841775*i-1.291485548*a,l=o*o*o,u=s*s*s,d=c*c*c;return[4.0767416621*l-3.3077115913*u+.2309699292*d,-1.2684380046*l+2.6097574011*u-.3413193965*d,-.0041960863*l-.7034186147*u+1.707614701*d]}var xh=e=>e.every(e=>e>=-1e-4&&e<=1.0001);function Sh(e){let t=bh(e);if(!xh(t)){let n=0,r=e.c;for(let t=0;t<12;t++){let t=(n+r)/2;xh(bh({...e,c:t}))?n=t:r=t}t=bh({...e,c:n})}return t.map(e=>Math.min(1,Math.max(0,e)))}function Ch(e){let[t,n,r]=Sh(e);return .2126*t+.7152*n+.0722*r}function wh(e,t){let n=Ch(e),r=Ch(t);return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}function Th(e,t,n){if(wh(e,t)>=n)return e;let r=e.l>=t.l?1:-1;for(let i of[r,-r]){let r={...e};for(let e=0;e<60;e++){if(r.l=Math.min(1,Math.max(0,r.l+i*.02)),wh(r,t)>=n)return r;if(r.l===0||r.l===1)break}}let i={...e,l:0,c:0},a={...e,l:1,c:0};return wh(i,t)>=wh(a,t)?i:a}function Eh(e){return`#`+Sh(e).map(e=>{let t=e<=.0031308?12.92*e:1.055*e**.4166666666666667-.055;return Math.round(t*255).toString(16).padStart(2,`0`)}).join(``)}var Dh=[[.2,{l:.86,c:.085}],[.36,{l:.9,c:.028}],[.62,{l:.73,c:.135}],[.8,{l:.62,c:.165}],[.93,{l:.87,c:.16}],[1,{l:.34,c:.035}]],Oh=e=>Dh.find(([t])=>e{let n=Oh(t),r=Th({l:n.l,c:n.c,h:e},kh,Ah);return{bg:{l:.965,c:.01,h:e},head:r,eye:r.l>=.5?{l:.17,c:.02,h:e}:{l:.97,c:.012,h:e}}},Mh=[[`head`,`bg`,1.25],[`eye`,`head`,4.5]];function Nh(e,t=!0,n=0){let r=jh(e,n);if(t)for(let[e,t,n]of Mh)r[e]=Th(r[e],r[t],n);return r}function Ph(e,t=!0,n=0){let r=Nh(e,t,n),i={};for(let e in r)i[e]=Eh(r[e]);return i}var Fh=e=>{let t=Math.round(e*100)/100;return Object.is(t,-0)?`0`:String(t)};function Ih({cx:e,cy:t,rx:n,ry:r,n:i=4,rot:a=0}){let o=Math.min(1,(8*2**(-1/i)-4)/3),s=n,c=r,l=s*o,u=c*o,d=[[s,0],[s,u],[l,c],[0,c],[-l,c],[-s,u],[-s,0],[-s,-u],[-l,-c],[0,-c],[l,-c],[s,-u],[s,0]],f=a*Math.PI/180,p=Math.cos(f),m=Math.sin(f),h=n=>{let[r,i]=d[n];return`${Fh(e+r*p-i*m)} ${Fh(t+r*m+i*p)}`},g=`M${h(0)}`;for(let e=1;e<13;e+=3)g+=`C${h(e)} ${h(e+1)} ${h(e+2)}`;return g+`Z`}function Lh(e,t,n,r,i,a=0){let o=i.length,s=a*Math.PI/180,c=i.map((i,a)=>{let c=s+2*Math.PI*a/o;return[e+n*i*Math.cos(c),t+r*i*Math.sin(c)]}),l=e=>c[(e%o+o)%o],u=`M${Fh(l(0)[0])} ${Fh(l(0)[1])}`;for(let e=0;e0?a<1?a/2:.5:0,c=o*Math.PI/180-Math.PI/2,l=Array.from({length:i},(a,o)=>{let s=c+2*Math.PI*o/i;return[e+n*Math.cos(s),t+r*Math.sin(s)]}),u=e=>l[(e%i+i)%i],d=(e,t)=>{let[n,r]=u(e),[i,a]=u(t);return`${Fh(n+(i-n)*s)} ${Fh(r+(a-r)*s)}`},f=`M${d(0,-1)}`;for(let e=0;e>>19;return e}function Hh(e){return e=Math.imul(e^e>>>16,2246822507),e=Math.imul(e^e>>>13,3266489909),(e^e>>>16)>>>0}var Uh=new TextEncoder;function Wh(e){return e.normalize(`NFC`).trim().toLowerCase()}function Gh(e,t=!0){let n=t?Wh(e):e;return Vh(1779033703^n.length,Uh.encode(n))}function Kh(e,t){return Hh(Vh(Vh(e,Uint8Array.of(255)),Uh.encode(t)))/4294967296}function qh(e,t=!0,n){let r=Gh(e,t),i=e=>{let t=n?.[e],i=Array.isArray(t)?t[Math.floor(Kh(r,e)*t.length)]:t;return i===void 0?Kh(r,e):i>0?i<1?i:.999999:0};return i.num=(e,t,n)=>t+i(e)*(n-t),i.int=(e,t,n)=>t+Math.floor(i(e)*(n-t+1)),i.pick=(e,t)=>t[Math.floor(i(e)*t.length)],i.bool=(e,t=.5)=>i(e)(i(e)*2-1)*t,i}function Jh(e,t,n){let r=t.expression;return n||!r?{l:e,wrap:``}:r.bake(e,r.p)}var Yh=(e,t)=>t?.tint?t.tint(e,t.p):e,Xh=(e,t)=>t?`${e}`:e,Zh=e=>e.replace(/[&<>]/g,e=>e===`&`?`&`:e===`<`?`<`:`>`);function Qh(e,t){let n=qh(e,t.normalize??!0,t.traits);return{t:n,palette:{...Ph(t.hue??n.num(`hue`,0,360),t.contrast??!0,t.tone??n(`tone`)),...t.palette}}}var $h=e=>e.title?`${Zh(e.title)}`:``;function eg(e,t,n){let r=t.background??e.background;if(r!==!1)return{d:r===`square`?`M0 0H100V100H0Z`:Ih({cx:50,cy:50,rx:50,ry:50,n:r===`circle`?2:6}),fill:n.bg}}var tg=e=>e?``:``;function ng(e){return(t,n={})=>{let{t:r,palette:i}=Qh(t,n),a=Yh(i,n.expression),o=n.size?` width="${n.size}" height="${n.size}"`:``,s=Jh(e.layout(r),n);return`${$h(n)+tg(eg(e,n,a))+Xh(e.render(s.l,a),s.wrap)}`}}var rg=(e,t,n)=>{let r=t.rx,i=e.num(`eye.rx`,.075,.105)*r,a=e.num(`eye.ratio`,1.9,3.2),o=e.num(`eye.scale`,.78,1.24),s=e.num(`eye.stretch`,.85,1.18),c=e.num(`eye.gap`,.1,.24)*r,l=i*Math.max(1,o),u=i*a*Math.max(1,o*s),d=l+r*.03+c,f=e.jitter(`gaze.x`,.09)*n.rx,p=e.num(`gaze.y`,-.2,.08)*n.ry,m=e.jitter(`eye.dy`,.04)*n.ry,h=Math.hypot(l,u),g=Math.hypot((Math.abs(f)+d+h)/n.rx,(Math.abs(p)+Math.abs(m)+h)/n.ry),_=g>.9?.9/g:1,v=i*_,y=v*a,b=d*_,x=Math.max(0,Math.min(1,c/u)),S=Math.min(12,Math.asin(x)*180/Math.PI),C=e.num(`eye.lean`,-1,1)*S,w=Math.max(-12,Math.min(12,C+e.jitter(`eye.lean2`,3.5))),T=n.cx+f*_,E=n.cy+p*_;return[{cx:T-b,cy:E,rx:v,ry:y,n:e.num(`eye.n`,3.5,6),rot:C},{cx:T+b,cy:E+m*_,rx:v*o,ry:y*o*s,n:e.num(`eye.n`,3.5,6),rot:w}]};function ig(e,t){let n=t=>(e.find(([,e])=>t1+e.jitter(`body.r${n}`,.16))};r.body?.(e,a);let o=r.face?.(a)??a,s={petals:[],extra:[]};return r.decorate?.(e,a,s),{shape:r.name,draw:r.path,body:a,face:o,petals:s.petals,extra:s.extra,eyes:t(e,a,o)}}function i(e,t,n){let r=e=>Math.round(e*100)/100,i=``+e.petals.map(e=>``).join(``)+e.extra.map(e=>``).join(``)+``+e.eyes.map((e,t)=>{let i=``;return n?`${i}`:i}).join(``)+``;return n?`${i}`:i}return{layout:r,render:i,background:!1}}var ag=e=>Rh(e),og=e=>Lh(e.cx,e.cy,e.rx,e.ry,e.radii,e.rot),sg=e=>t=>({cx:t.cx,cy:t.cy,rx:t.rx*e,ry:t.ry*e}),cg=e=>sg(Math.min(...e.radii)*.95)(e),lg=e=>sg(.84)(e),ug={name:`round`,core:1},dg={name:`organic`,core:.98,path:og,face:cg},fg={name:`boxy`,core:.86,body:(e,t)=>{t.n=e.num(`body.n`,3.4,6),t.rot=e.num(`body.rot`,-20,20)}},pg={name:`capsule`,core:1.02,body:(e,t)=>{t.ry*=e.num(`capsule.squat`,.55,.68)},face:sg(.94),decorate:(e,t,n)=>{for(let e of[-1,1])n.petals.push({cx:t.cx+e*(t.rx-t.ry),cy:t.cy,r:t.ry})},path:e=>zh(e.cx,e.cy,e.rx-e.ry,e.ry)},mg=ng(ig([[ug,.22],[dg,.48],[fg,.6],[pg,.7],[{name:`nub`,core:.88,decorate:(e,t,n)=>{let r=e.int(`nub.n`,1,2);for(let i=0;i{let r=e.int(`cloud.n`,4,6);for(let i=0;i{t.cy+=.22*t.ry,t.n=2},face:e=>({cx:e.cx,cy:e.cy+e.ry*.05,rx:e.rx*.88,ry:e.ry*.88}),decorate:(e,t,n)=>{n.extra.push(Bh(t.cx,t.cy,t.rx,t.ry,e.num(`droplet.tip`,1.4,1.65)))}},.915],[{name:`hexagon`,core:1.05,path:ag,face:lg,body:(e,t)=>{t.sides=6,t.rot=e.num(`body.rot`,-12,12),t.round=e.num(`poly.round`,.24,.5)}},.95],[{name:`sun`,core:.7,decorate:(e,t,n)=>{let r=e.int(`sun.n`,6,9),i=t.rx*e.num(`sun.dist`,1,1.08),a=t.rx*e.num(`sun.r`,.2,.26),o=e.num(`sun.rot`,0,2*Math.PI);for(let e=0;e{t.sides=3,t.rot=e.num(`body.rot`,-5,5),t.round=e.num(`poly.round`,.24,.5)},face:e=>({cx:e.cx,cy:e.cy+e.ry*.1,rx:e.rx*.54,ry:e.ry*.36})},1]],rg));function hg(e,t){return`data:image/svg+xml,`+mg(e,t).replace(/"/g,`'`).replace(/[%#<>{}|\\^[\]`]/g,e=>`%`+e.charCodeAt(0).toString(16).toUpperCase()).replace(/\s+/g,` `)}var gg=ee(` `),_g=ee(``),vg=ee(``),yg=I(``);function bg(e,t){n(t,!0);let r=k(t,[`$$slots`,`$$events`,`$$legacy`,`name`,`size`,`background`,`palette`,`hue`,`tone`,`normalize`,`contrast`,`title`,`animate`,`expression`,`traits`,`class`,`style`]),i=c(()=>({size:t.size,background:t.background,palette:t.palette,hue:t.hue,tone:t.tone,normalize:t.normalize,contrast:t.contrast,title:t.title,expression:t.expression,traits:t.traits})),a=c(()=>t.animate?``:hg(t.name,B(i))),o=c(()=>t.animate?yh(t.name,{...B(i),animate:t.animate}):null),s=c(()=>r),u=c(()=>r),d=c(()=>{let{alt:e,...t}=B(u);return t}),m=c(()=>[...Object.entries(B(o)?.vars??{}).map(([e,t])=>`${e}:${t}`),...t.style?[t.style]:[]].join(`;`));var h=L(),_=q(h),v=e=>{var n=vg();l(n,()=>({xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 100 100`,width:t.size,height:t.size,role:t.title?`img`:void 0,"aria-hidden":t.title?void 0:!0,class:t.class,style:B(m),...B(s)}));var r=R(n),i=e=>{var n=gg(),r=R(n,!0);f(n),U(()=>G(r,t.title)),g(e,n)};p(r,e=>{t.title&&e(i)});var a=X(r),c=e=>{var t=_g();U(()=>{S(t,`d`,B(o).bg.d),S(t,`fill`,B(o).bg.fill)}),g(e,t)};p(a,e=>{B(o).bg&&e(c)});var u=X(a);P(u,()=>B(o).inner,!0),f(u),f(n),U(()=>y(u,0,b(B(o).cls))),g(e,n)},x=e=>{var n=yg();l(n,()=>({src:B(a),width:t.size,height:t.size,alt:B(u).alt??t.title??``,class:t.class,style:t.style,...B(d)})),fe(n),g(e,n)};p(_,e=>{B(o)?e(v):e(x,-1)}),g(e,h),W()}var xg=/^[a-z0-9._-]+$/;function Sg(e){return typeof e==`string`&&xg.test(e)}var Cg=8192,wg=262144,Tg=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`SessionPersistenceError`}};Promise.resolve();function Eg(e){Dg(e)}function Dg(e){if(Fg(e,`Loom tree`),Ig(e,[`active_node_id`,`cast`,`children_of`,`model_id`,`name`,`nodes`,`rev`,`root_id`,`drowse_version`,`session_id`,`tree_format`],`Loom tree`),e.tree_format!==2)throw Jg(`Loom tree format is unsupported`);if(zg(e.drowse_version,`Drowse version`,128,!1),Bg(e.model_id,`Loom model id`,512),Bg(e.session_id,`Loom session id`,256),Bg(e.name,`Loom name`,256),qg(e.rev,`Loom revision`),Rg(e.root_id,`root node id`,256),Rg(e.active_node_id,`active node id`,256),!Array.isArray(e.nodes)||e.nodes.length<1||e.nodes.length>Cg)throw Jg(`Loom tree must contain between 1 and ${Cg} nodes`);if(Fg(e.children_of,`Loom children map`),Fg(e.cast,`Loom cast`),Object.keys(e.cast).length>128)throw Jg(`Loom cast is too large`);for(let[t,n]of Object.entries(e.cast)){if(!Sg(t))throw Jg(`Loom cast label must be a lowercase role slug`);kg(n)}let t=new Map,n=0;for(let r of e.nodes){if(Og(r),t.has(r.id))throw Jg(`Duplicate loom node id: ${r.id}`);if(t.set(r.id,r),n+=(r.tokens?.length??0)+(r.thinking_tokens?.length??0),n>wg)throw Jg(`Loom tree contains too many token rows`)}let r=t.get(e.root_id);if(r===void 0)throw Jg(`Loom root node does not exist`);if(r.parent_id!==null)throw Jg(`Loom root node must not have a parent`);if(r.role!==`system`)throw Jg(`Loom root node must have the system role`);if(!t.has(e.active_node_id))throw Jg(`Loom active node does not exist`);let i=Object.keys(e.children_of);if(i.length!==t.size||i.some(e=>!t.has(e)))throw Jg(`Loom children map must contain exactly one row per node`);let a=new Set,o=new Map;for(let[n,r]of Object.entries(e.children_of)){if(!Array.isArray(r)||r.length>Cg)throw Jg(`Loom children row is invalid: ${n}`);let e=new Set;for(let i of r){Rg(i,`child node id`,256);let r=t.get(i);if(r===void 0||r.parent_id!==n)throw Jg(`Loom parent relationship is inconsistent: ${i}`);if(e.has(i)||a.has(i))throw Jg(`Duplicate loom child relationship: ${i}`);e.add(i),a.add(i)}o.set(n,r)}for(let n of t.values())if(n.id!==e.root_id){if(n.parent_id===null||!t.has(n.parent_id))throw Jg(`Loom node has an invalid parent: ${n.id}`);if(!a.has(n.id))throw Jg(`Loom node is absent from its parent's children row: ${n.id}`)}if(a.size!==t.size-1)throw Jg(`Loom tree is disconnected or cyclic`);let s=new Set,c=[e.root_id];for(;c.length>0;){let e=c.pop();if(s.has(e))throw Jg(`Loom tree contains a cycle`);s.add(e),c.push(...o.get(e)??[])}if(s.size!==t.size)throw Jg(`Loom tree is disconnected`)}function Og(e){if(Fg(e,`Loom node`),Ig(e,[`aggregate_readings`,`applied_steering`,`created_at`,`edit_count`,`edited_at`,`finish_reason`,`id`,`mean_logprob`,`mean_surprise`,`notes`,`parent_id`,`raw_token_ids`,`recipe`,`role`,`role_label`,`starred`,`text`,`thinking_text`,`thinking_tokens`,`tokens`],`Loom node`),Rg(e.id,`node id`,256),Bg(e.parent_id,`parent node id`,256),![`user`,`assistant`,`system`].includes(String(e.role)))throw Jg(`Loom node role is invalid`);if(zg(e.text,`node text`,4*1024*1024,!0),Vg(e.role_label,`node role label`),Bg(e.thinking_text,`node thinking text`,4*1024*1024),Pg(e.aggregate_readings,`node aggregate readings`,4096),Bg(e.applied_steering,`node steering expression`,64*1024),Bg(e.finish_reason,`node finish reason`,1024),typeof e.starred!=`boolean`)throw Jg(`Node starred flag is invalid`);if(zg(e.notes,`node notes`,256*1024,!0),Hg(e.created_at,`node creation timestamp`),Ug(e.edited_at,`node edit timestamp`),qg(e.edit_count,`node edit count`),Gg(e.mean_logprob,`node mean log probability`),Gg(e.mean_surprise,`node mean surprise`),e.recipe!==null&&Ag(e.recipe),Mg(e.tokens,`node tokens`),Mg(e.thinking_tokens,`node thinking tokens`),e.raw_token_ids!==null){if(!Array.isArray(e.raw_token_ids)||e.raw_token_ids.length>wg)throw Jg(`Node raw token ids are invalid`);for(let t of e.raw_token_ids)qg(t,`raw token id`)}}function kg(e){if(Fg(e,`Cast member`),Lg(e,[`notes`,`recipe`],[`origin`],`Cast member`),zg(e.notes,`cast member notes`,256*1024,!0),e.recipe!==null&&Ag(e.recipe),e.origin!==void 0&&![`configured`,`observed`,`structural`].includes(String(e.origin)))throw Jg(`Cast member origin is invalid`)}function Ag(e){if(Fg(e,`Recipe`),Ig(e,[`probe_hashes`,`probes`,`sampling`,`seed`,`steering`,`thinking`],`Recipe`),Bg(e.steering,`recipe steering`,64*1024),e.sampling!==null&&jg(e.sampling),e.thinking!==null&&typeof e.thinking!=`boolean`)throw Jg(`Recipe thinking value is invalid`);if(Kg(e.seed,`recipe seed`),!Array.isArray(e.probes)||e.probes.length>4096)throw Jg(`Recipe probes are invalid`);for(let t of e.probes)Rg(t,`recipe probe`,1024);if(Fg(e.probe_hashes,`Recipe probe hashes`),Object.keys(e.probe_hashes).length>4096)throw Jg(`Recipe probe hashes are too large`);for(let[t,n]of Object.entries(e.probe_hashes))Rg(t,`recipe probe hash key`,1024),zg(n,`recipe probe hash`,512,!1)}function jg(e){if(Fg(e,`Recipe sampling`),Ig(e,[`assistant_role`,`frequency_penalty`,`logit_bias`,`logprobs`,`max_tokens`,`persist_per_layer_scores`,`persist_subspace_coords`,`presence_penalty`,`return_hidden`,`return_probe_readings`,`return_top_k`,`seed`,`stop`,`temperature`,`top_k`,`top_p`,`user_role`],`Recipe sampling`),Gg(e.temperature,`sampling temperature`),Gg(e.top_p,`sampling top-p`),Kg(e.top_k,`sampling top-k`),Kg(e.max_tokens,`sampling max tokens`),Kg(e.seed,`sampling seed`),Kg(e.logprobs,`sampling logprobs`),Wg(e.presence_penalty,`sampling presence penalty`),Wg(e.frequency_penalty,`sampling frequency penalty`),qg(e.return_top_k,`sampling return top-k`),e.return_top_k>256)throw Jg(`Sampling return top-k is too large`);for(let t of[`persist_per_layer_scores`,`persist_subspace_coords`,`return_hidden`,`return_probe_readings`])if(typeof e[t]!=`boolean`)throw Jg(`Sampling ${t} is invalid`);if(Vg(e.user_role,`sampling user role`),Vg(e.assistant_role,`sampling assistant role`),e.stop!==null){if(!Array.isArray(e.stop)||e.stop.length>1024)throw Jg(`Sampling stop list is invalid`);for(let t of e.stop)zg(t,`sampling stop`,64*1024,!0)}if(e.logit_bias!==null){if(Fg(e.logit_bias,`Sampling logit bias`),Object.keys(e.logit_bias).length>65536)throw Jg(`Sampling logit bias is too large`);for(let[t,n]of Object.entries(e.logit_bias)){if(!/^-?\d+$/.test(t))throw Jg(`Sampling logit bias token id is invalid`);Wg(n,`sampling logit bias`)}}}function Mg(e,t){if(e!==null){if(!Array.isArray(e)||e.length>wg)throw Jg(`${t} are invalid`);for(let t of e){if(Fg(t,`Loom token row`),t.token_id!==void 0&&qg(t.token_id,`token id`),t.text!==void 0&&zg(t.text,`token text`,64*1024,!0),t.logprob!==void 0&&Gg(t.logprob,`token log probability`),t.sampler_entropy!==void 0&&(Gg(t.sampler_entropy,`token sampler entropy`),typeof t.sampler_entropy==`number`&&t.sampler_entropy<0))throw Jg(`Token sampler entropy is invalid`);if(t.perplexity!==void 0&&Gg(t.perplexity,`token perplexity`),t.raw_index!==void 0&&t.raw_index!==null&&qg(t.raw_index,`raw token index`),t.probes!==void 0&&Pg(t.probes,`token probes`,4096),t.per_layer_scores!==void 0){if(Fg(t.per_layer_scores,`token per-layer scores`),Object.keys(t.per_layer_scores).length>1024)throw Jg(`Token per-layer score map is too large`);for(let e of Object.values(t.per_layer_scores))Pg(e,`token layer scores`,4096)}if(t.top_alts!==void 0){if(!Array.isArray(t.top_alts)||t.top_alts.length>256)throw Jg(`Token alternatives are invalid`);for(let e of t.top_alts)Fg(e,`Token alternative`),Ig(e,[`id`,`logprob`,`text`],`Token alternative`),qg(e.id,`alternative token id`),zg(e.text,`alternative token text`,64*1024,!0),Wg(e.logprob,`alternative log probability`)}t.measurements!==void 0&&Fg(t.measurements,`token measurement envelope`),Ng(t,{maxDepth:24,maxValues:131072,maxStringLength:4*1024*1024,maxArrayLength:wg})}}}function Ng(e,t){let n=new WeakSet,r=0,i=(e,a)=>{if(r+=1,r>t.maxValues)throw Jg(`Session state contains too many values`);if(a>t.maxDepth)throw Jg(`Session state is nested too deeply`);if(!(e===null||typeof e==`boolean`)){if(typeof e==`number`){if(!Number.isFinite(e))throw Jg(`Session state contains a non-finite number`);return}if(typeof e==`string`){if(e.length>t.maxStringLength)throw Jg(`Session state string is too long`);return}if(typeof e!=`object`)throw Jg(`Session state must contain JSON values only`);if(n.has(e))throw Jg(`Session state must not contain repeated object references`);if(n.add(e),Array.isArray(e)){if(e.length>t.maxArrayLength)throw Jg(`Session state array is too long`);for(let t of e)i(t,a+1);return}if(Fg(e,`Session state value`),Object.keys(e).length>16384)throw Jg(`Session state object has too many fields`);for(let[t,n]of Object.entries(e)){if(t.length>1024||t.includes(`\0`))throw Jg(`Session state key is invalid`);i(n,a+1)}}};i(e,0)}function Pg(e,t,n){Fg(e,t);let r=Object.entries(e);if(r.length>n)throw Jg(`${t} is too large`);for(let[e,n]of r){if(e.length>1024||e.includes(`\0`))throw Jg(`${t} key is invalid`);Wg(n,t)}}function Fg(e,t){if(typeof e!=`object`||!e||Array.isArray(e)||Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null)throw Jg(`${t} is invalid`)}function Ig(e,t,n){Lg(e,t,[],n)}function Lg(e,t,n,r){let i=Object.keys(e).sort(),a=new Set([...t,...n]);if(t.some(e=>!i.includes(e))||i.some(e=>!a.has(e)))throw Jg(`${r} fields are invalid`)}function Rg(e,t,n){if(zg(e,t,n,!1),/\p{Cc}/u.test(e))throw Jg(`${t} contains a control character`)}function zg(e,t,n,r){if(typeof e!=`string`||!r&&e.length===0||e.length>n)throw Jg(`${t} is invalid`)}function Bg(e,t,n){e!==null&&zg(e,t,n,!0)}function Vg(e,t){if(e!==null&&!Sg(e))throw Jg(`${t} is not a lowercase role slug`)}function Hg(e,t){if(typeof e!=`number`||!Number.isFinite(e)||e<0)throw Jg(`${t} is invalid`)}function Ug(e,t){e!==null&&Hg(e,t)}function Wg(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw Jg(`${t} is invalid`)}function Gg(e,t){e!==null&&Wg(e,t)}function Kg(e,t){if(e!==null&&!Number.isSafeInteger(e))throw Jg(`${t} is invalid`)}function qg(e,t){if(!Number.isSafeInteger(e)||Number(e)<0)throw Jg(`${t} is invalid`)}function Jg(e){return new Tg(`INVALID_SESSION_STATE`,e)}var Yg=`drowse-chat-backup`;async function Xg(e){let t=new TextEncoder().encode(JSON.stringify(e)),n=await crypto.subtle.digest(`SHA-256`,t);return[...new Uint8Array(n)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function Zg(e){ec(e,_s),Eg(e.snapshot.tree);let t={format:Yg,version:1,exportedAt:new Date().toISOString(),sha256:await Xg(e),conversation:e};return JSON.stringify(t)}async function Qg(e,t){if(e.size>68157440)throw Error(`This backup exceeds the 65 MiB import limit.`);let n;try{n=JSON.parse(await e.text())}catch{throw Error(`This file is not valid chat backup JSON.`)}if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Choose a Drowse chat backup or a version 7 conversation file.`);if(`format`in n){if(![`drowse-chat-backup`,`polythetic-chat-backup`,`saklas-chat-backup`].includes(String(n.format))||!(`version`in n)||n.version!==1)throw Error(`This chat backup format or version is not supported.`);if(!(`conversation`in n)||!(`sha256`in n))throw Error(`This chat backup is incomplete.`);if(n.sha256!==await Xg(n.conversation))throw Error(`This backup failed its integrity check. The file may be damaged or edited; choose the original download.`);let e=z(n.conversation);return ec(e,_s),Eg(e.snapshot.tree),t.create({name:e.name,avatarSeed:e.avatarSeed,accent:e.accent,modelType:e.modelType,snapshot:e.snapshot,createdAt:e.createdAt,updatedAt:e.updatedAt})}let r=z(n);return bs(r,_s),Eg(r.tree),t.create({name:tc(),snapshot:r})}async function $g(e,t){let n=await e.get(t);t_(new Blob([await Zg(n)],{type:`application/json`}),n.name)}function e_(e){return`${e.trim().replace(/(?:\.(?:drowse|polythetic|saklas)chat|\.(?:drowse|polythetic|saklas)-chat\.json|\.json)$/iu,``).replace(/[^a-z0-9._-]+/giu,`-`).replace(/^-+|-+$/gu,``).slice(0,80)||`chat`}.drowsechat`}function t_(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=e_(t),document.body.append(r),r.click(),r.remove(),setTimeout(()=>URL.revokeObjectURL(n),3e4)}function n_(e=new Date){let t=_i.info,n=mo();if(!t||!n)throw Error(`The conversation is still loading`);let r={version:7,savedAt:e.toISOString(),model_id:t.model_id,session_id:t.id,tree:i_(n),steerRack:[...nr.entries.entries()].map(([e,t])=>({name:e,...i_(t)})),subspaceAlong:nr.subspaceAlong,customSteeringExpression:nr.customExpression,probeRack:{sortMode:Hr.sortMode,active:[...Hr.active],entries:[...Hr.entries.entries()].map(([e,t])=>({name:e,request:i_(t.request),sparkline:[...t.sparkline],current:t.current,previous:t.previous}))},highlightState:i_({...fi}),samplingState:i_({...xi})};return bs(r,_s),r}async function r_(e){let t=i_(e);bs(t,_s);let n=xs(t);return await Ss({capture:a_,async preflight(){let e=_i.info;if(!e||t.model_id!==e.model_id)throw Error(`This conversation belongs to a different model`);let r=await Ct.validateSteering(n.steeringExpression,void 0,St.mode===`browser`?{probeRequests:n.probeRequests,tree:n.snapshot.tree}:void 0);if(!r.valid)throw Error(r.error??`Steering preflight failed`)},async apply(){await Ot.restore(n.snapshot.tree),await o_(n.probeRequests),l_(n),await go()},rollback:u_}),{turns:t.tree.nodes.filter(e=>e.parent_id!==null).length,terms:t.steerRack.length,probes:t.probeRack.active.length}}function i_(e){return JSON.parse(JSON.stringify(e))}async function a_(){let e=[...Hr.entries].map(([e,t])=>[e,i_(t)]),t=new Map(e);return{tree:await Ot.get(),steerEntries:[...nr.entries].map(([e,t])=>[e,i_(t)]),subspaceAlong:nr.subspaceAlong,customSteeringExpression:nr.customExpression,probeRequests:Hr.active.map(e=>i_(t.get(e).request)),probeEntries:e,probeSortMode:Hr.sortMode,highlight:i_({...fi}),sampling:i_({...xi})}}async function o_(e){for(let e of[...Hr.active])await ai(e);for(let t of e)await ii(t.selector,{name:t.name,top_n:t.top_n})}function s_(e){nr.entries.clear();for(let[t,n]of e)nr.entries.set(t,i_(n))}function c_(e){for(let[t,n]of e){let e=Hr.entries.get(t);if(!e)throw Error(`Probe ${t} was not restored`);`info`in n?Hr.entries.set(t,{...i_(n),info:e.info}):Hr.entries.set(t,{...e,request:i_(n.request),sparkline:[...n.sparkline],current:n.current,previous:n.previous})}}function l_(e){s_(e.steerEntries),nr.subspaceAlong=e.snapshot.subspaceAlong,nr.customExpression=e.snapshot.customSteeringExpression,Object.assign(xi,i_(e.snapshot.samplingState)),Object.assign(fi,i_(e.snapshot.highlightState)),Hr.sortMode=e.snapshot.probeRack.sortMode,c_(e.probeRows)}async function u_(e){let t=[];try{await Ot.restore(e.tree)}catch(e){t.push(e)}try{await o_(e.probeRequests)}catch(e){t.push(e)}s_(e.steerEntries),nr.subspaceAlong=e.subspaceAlong,nr.customExpression=e.customSteeringExpression,Object.assign(xi,e.sampling),Object.assign(fi,e.highlight),Hr.sortMode=e.probeSortMode;try{c_(e.probeEntries)}catch(e){t.push(e)}try{await go()}catch(e){t.push(e)}if(t.length>0)throw AggregateError(t,`Workspace rollback failed`)}var d_=I(`
          Protect saved chats

          `),f_=I(``),p_=I(`

          Wait for the current reply to finish before opening another chat.

          `),m_=I(`

          Loading saved chats…

          `),h_=I(`

          `),g_=I(``),__=I(` `),v_=I(`Open now`),y_=I(`
          `),b_=I(`

          `),x_=I(`
          `),S_=I(`
          `),C_=I(`

          Delete this saved data? This cannot be undone.

          `),w_=I(`
          Could not read this chat
          `),T_=I(`
          The saved data is still in storage.
          `),E_=I(`
          `),D_=I(`

          Saved chats

          Named conversations stay on this device until you delete them. Click an avatar for a new one.

          `);function O_(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>void t.params);let r=J(null),i=J(V([])),o=J(V([])),l=J(``),u=J(!0),d=J(null),h=J(null),_=J(null),v=J(null),b=J(null),x=J(null),C=J(``),w=J(!1),E=J(null),D=J(`checking`),O=J(!1),M=J(!1),N=c(()=>_i.info?.model_id??null),P=c(()=>{let e=B(l).trim().toLocaleLowerCase();return e?B(i).filter(t=>t.name.toLocaleLowerCase().includes(e)||nc(t.modelId).toLocaleLowerCase().includes(e)):B(i)});ne(()=>{L(),F()});async function F(){if(!navigator.storage?.persisted){A(D,`unavailable`);return}try{A(D,await navigator.storage.persisted()?`protected`:`unprotected`,!0)}catch{A(D,`unavailable`)}}async function I(){A(O,!0);try{let e=await Oc();A(D,e===!0?`protected`:e===!1?`unprotected`:`unavailable`,!0),A(M,e!==!0),e&&Z(`Saved chats are protected from automatic browser cleanup.`,{kind:`info`})}finally{A(O,!1)}}async function L(){A(u,!0),A(d,null);try{let e=await Cc.listSummaries();A(i,e.conversations,!0),A(o,e.issues,!0)}catch(e){A(d,je(e,`Saved conversations could not be opened.`),!0)}finally{A(u,!1)}}async function ee(e){if(!(e.modelId!==B(N)||$.active)){A(h,e.id,!0),A(d,null);try{await Dc();let t=await Cc.get(e.id);await r_(t.snapshot),wc.activeId=e.id,wc.avatarSeed=t.avatarSeed,wc.accent=t.accent??`purple`,Z(`Opened “${e.name}”.`,{kind:`info`}),it()}catch(e){A(d,je(e,`This conversation could not be opened. Your current work was left unchanged.`),!0)}finally{A(h,null)}}}async function te(e){A(_,e.id,!0),A(d,null);try{let t=await Cc.update(e.id,{avatarSeed:rc()});wc.activeId===e.id&&(wc.avatarSeed=t.avatarSeed),le(t)}catch(e){A(d,je(e,`The avatar could not be changed.`),!0)}finally{A(_,null)}}function z(e){A(b,null),A(x,e.id,!0),A(C,e.name,!0),xe().then(()=>{B(E)?.focus(),B(E)?.select()})}async function re(e){A(_,e.id,!0),A(d,null);try{le(await Cc.update(e.id,{name:B(C)})),A(x,null)}catch(e){A(d,je(e,`The conversation could not be renamed.`),!0)}finally{A(_,null)}}function ie(e,t){e.key===`Enter`?(e.preventDefault(),B(C).trim()&&B(_)!==t.id&&re(t)):e.key===`Escape`&&(e.preventDefault(),A(x,null))}function ae(e){A(x,null),A(b,e,!0)}async function oe(e){A(_,e,!0),A(d,null);try{await Cc.delete(e),A(i,B(i).filter(t=>t.id!==e),!0),A(o,B(o).filter(t=>t.id!==e),!0),A(b,null),Z(`Saved conversation deleted.`,{kind:`info`})}catch(e){A(d,je(e,`The saved conversation could not be deleted.`),!0)}finally{A(_,null)}}async function H(e){A(_,e.id,!0),A(d,null);try{await Dc(),await $g(Cc,e.id)}catch(e){A(d,je(e,`This conversation could not be exported. Your saved chat was not changed.`),!0)}finally{A(_,null)}}async function se(e){let t=e.currentTarget,n=t.files?.[0]??null;if(t.value=``,!(!n||B(w))){A(w,!0),A(d,null);try{let e=await Qg(n,Cc);A(i,[$s(e),...B(i)],!0),Z(`Imported “${e.name}” as a separate chat.`,{kind:`info`}),Oc()}catch(e){A(d,je(e,`This conversation file could not be imported.`),!0)}finally{A(w,!1)}}}async function ce(e){if(!(B(_)!==null||B(w)||B(h)!==null)){A(_,e.id,!0),A(v,e.id,!0),A(d,null);try{await Dc();let t=await Cc.duplicate(e.id);A(i,[$s(t),...B(i)],!0),Z(`Created “${t.name}”. The original chat is unchanged.`,{kind:`info`})}catch(e){A(d,je(e,`The chat could not be duplicated. The original chat was not changed.`),!0)}finally{A(_,null),A(v,null)}}}function le(e){A(i,B(i).map(t=>t.id===e.id?$s(e):t),!0)}function ue(e){let t=e-Date.now();for(let[e,n]of[[`year`,365*24*60*60*1e3],[`month`,720*60*60*1e3],[`day`,1440*60*1e3],[`hour`,3600*1e3],[`minute`,60*1e3]])if(Math.abs(t)>=n||e===`minute`){let r=Math.round(t/n);return new Intl.RelativeTimeFormat(void 0,{numeric:`auto`}).format(r,e)}return`just now`}function de(e){return new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`short`}).format(new Date(e))}var fe=D_(),me=R(fe);ft(X(R(me),2),{get onclick(){return it}}),f(me);var he=X(me,2),ge=R(he),_e=X(R(ge),2);s(_e),f(ge);var ve=X(ge,2);a(ve,e=>A(r,e),()=>B(r));var ye=X(ve,2),be=R(ye),Se=X(be,2),we=R(Se,!0);f(Se),f(ye),f(he);var Te=X(he,2),Ee=e=>{var t=d_(),n=R(t),r=X(R(n),2),i=R(r,!0);f(r),f(n);var a=X(n,2),o=R(a,!0);f(a),f(t),U(()=>{G(i,B(M)?`Your browser did not grant protection. Your chats are still saved locally.`:`Automatic browser cleanup protection is off.`),a.disabled=B(O),G(o,B(O)?`Checking…`:B(M)?`Try again`:`Protect storage`)}),K(`click`,a,()=>void I()),g(e,t)};p(Te,e=>{!B(u)&&B(i).length>0&&B(D)===`unprotected`&&e(Ee)});var De=X(Te,2),Oe=R(De),ke=e=>{var t=f_(),n=R(t,!0);f(t),U(()=>G(n,B(d))),g(e,t)};p(Oe,e=>{B(d)&&e(ke)});var Ae=X(Oe,2),q=e=>{g(e,p_())};p(Ae,e=>{$.active&&e(q)});var Me=X(Ae,2),Y=e=>{g(e,m_())},Ne=e=>{var t=h_(),n=R(t),r=R(n,!0);f(n);var i=X(n,2),a=R(i,!0);f(i),f(t),U((e,t)=>{G(r,e),G(a,t)},[()=>B(l).trim()?`No matches`:`No saved chats yet`,()=>B(l).trim()?`Try a different name or model.`:`Save the current chat to name it and keep its full loom.`]),g(e,t)},Pe=e=>{var t=E_(),n=R(t);m(n,17,()=>B(P),e=>e.id,(e,t)=>{let n=c(()=>B(t).modelId===B(N));var r=S_();let i;var o=R(r),l=R(o);bg(R(l),{get name(){return B(t).avatarSeed},size:62,background:`circle`,alt:``}),f(l);var u=X(l,2),d=R(u),m=e=>{var n=g_(),r=X(R(n),2);s(r),a(r,e=>A(E,e),()=>B(E)),f(n),U(()=>r.disabled=B(_)===B(t).id),K(`keydown`,r,e=>ie(e,B(t))),j(r,()=>B(C),e=>A(C,e)),g(e,n)},T=e=>{var n=__(),r=R(n,!0);f(n),U(()=>{S(n,`title`,B(t).name),G(r,B(t).name),n.dir=n.dir}),g(e,n)};p(d,e=>{B(x)===B(t).id?e(m):e(T,-1)});var D=X(d,2),O=R(D),k=R(O,!0),M=X(k),P=e=>{Cm(e,{})};p(M,e=>{(B(t).modelType===`base`||B(n)&&_i.info?.is_base_model)&&e(P)}),f(O);var F=X(O,2),I=e=>{g(e,v_())};p(F,e=>{wc.activeId===B(t).id&&e(I)}),f(D),f(u);var L=X(u,2),ne=R(L,!0);f(L),f(o);var V=X(o,2),se=e=>{var n=y_(),r=R(n),i=X(r,2);f(n),U(e=>i.disabled=e,[()=>!B(C).trim()||B(_)===B(t).id]),K(`click`,r,()=>A(x,null)),K(`click`,i,()=>void re(B(t))),g(e,n)},le=e=>{var n=b_(),r=R(n),i=R(r);f(r);var a=X(r,2),o=X(a,2);f(n),U(()=>{S(n,`aria-label`,`Confirm deletion of ${B(t).name}`),G(i,`Delete “${B(t).name??``}”? This cannot be undone.`),o.disabled=B(_)===B(t).id}),K(`click`,a,()=>A(b,null)),K(`click`,o,()=>void oe(B(t).id)),g(e,n)},fe=e=>{var r=x_(),i=R(r),a=R(i,!0);f(i);var o=X(i,2),s=X(o,2),c=X(s,2),l=X(c,2);f(r),U(e=>{i.disabled=!B(n)||$.active||B(h)!==null,S(i,`title`,e),G(a,B(h)===B(t).id?`Opening…`:B(n)?`Open`:`Different model`),s.disabled=B(_)!==null,c.disabled=B(_)!==null||B(w)||B(h)!==null,S(c,`aria-label`,`Duplicate ${B(t).name}`),S(c,`aria-busy`,B(v)===B(t).id)},[()=>B(n)?void 0:`Load ${nc(B(t).modelId)} to open this chat`]),K(`click`,i,()=>void ee(B(t))),K(`click`,o,()=>z(B(t))),K(`click`,s,()=>void H(B(t))),K(`click`,c,()=>void ce(B(t))),K(`click`,l,()=>ae(B(t).id)),g(e,r)};p(V,e=>{B(x)===B(t).id?e(se):B(b)===B(t).id?e(le,1):e(fe,-1)}),f(r),U((e,n,a,o,s)=>{i=y(r,1,`conversation-card svelte-1qiwp0e`,null,i,{current:wc.activeId===B(t).id}),S(r,`data-saved-conversation`,B(t).id),S(r,`data-chat-accent`,B(t).accent??`purple`),pe(r,e),S(l,`aria-busy`,B(_)===B(t).id),l.disabled=B(_)===B(t).id,S(l,`aria-label`,`Generate another avatar for ${B(t).name}`),G(k,n),S(L,`datetime`,a),S(L,`title`,o),G(ne,s)},[()=>zs(B(t).accent),()=>nc(B(t).modelId),()=>new Date(B(t).updatedAt).toISOString(),()=>de(B(t).updatedAt),()=>ue(B(t).updatedAt)]),K(`click`,l,()=>void te(B(t))),g(e,r)}),m(X(n,2),17,()=>B(o),e=>e.id,(e,t)=>{var n=T_(),r=R(n),i=X(R(r),2),a=R(i),o=R(a,!0);f(a),T(2),f(i),f(r);var s=X(r,2),c=e=>{var n=C_(),r=X(R(n),2),i=X(r,2);f(n),K(`click`,r,()=>A(b,null)),K(`click`,i,()=>void oe(B(t).id)),g(e,n)},l=e=>{var n=w_(),r=R(n),i=X(r,2);f(n),U(e=>S(r,`title`,e),[()=>je(B(t).reason,`This saved chat could not be read. The data is still in storage.`)]),K(`click`,i,()=>ae(B(t).id)),g(e,n)};p(s,e=>{B(b)===B(t).id?e(c):e(l,-1)}),f(n),U(()=>G(o,B(t).name||`Unavailable saved chat`)),g(e,n)}),f(t),g(e,t)};p(Me,e=>{B(u)?e(Y):B(P).length===0&&B(o).length===0?e(Ne,1):e(Pe,-1)}),f(De),f(fe),U(()=>{be.disabled=$.active,Se.disabled=B(w),S(Se,`aria-busy`,B(w)),G(we,B(w)?`Importing…`:`Import file`)}),j(_e,()=>B(l),e=>A(l,e)),K(`change`,ve,se),K(`click`,be,()=>rt(`save_conversation`)),K(`click`,Se,()=>B(r)?.click()),g(e,fe),W()}H([`change`,`click`,`keydown`]);var k_=I(`

          This tool is not available here

          Close this panel and choose an available action from All tools.

          `);function A_(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>void t.params);var r=k_(),i=R(r);ft(X(R(i),2),{get onclick(){return it}}),f(i),f(r),g(e,r),W()}var j_=I(``),M_=I(`
          `);function N_(e,t){n(t,!0);let r=Y(t,`value`,15),i=Y(t,`ariaLabel`,3,`Mode`);function a(e){e!==r()&&(r(e),t.onchange?.(e))}function o(e){let t=e.currentTarget,n=t.closest(`[role="tablist"]`);if(!n)return;let r=[...n.querySelectorAll(`[role="tab"]`)],i=r.indexOf(t);if(i<0||r.length===0)return;let a=i;if(e.key===`ArrowRight`)a=(i+1)%r.length;else if(e.key===`ArrowLeft`)a=(i-1+r.length)%r.length;else if(e.key===`Home`)a=0;else if(e.key===`End`)a=r.length-1;else return;e.preventDefault(),r[a].focus(),r[a].click()}var s=M_();m(s,21,()=>t.tabs,e=>e.value,(e,t)=>{var n=j_();let i;var s=R(n,!0);f(n),U(()=>{i=y(n,1,`sk-mode-tab svelte-bsf8gw`,null,i,{active:B(t).value===r()}),S(n,`aria-selected`,B(t).value===r()),S(n,`tabindex`,B(t).value===r()?0:-1),G(s,B(t).label)}),K(`click`,n,()=>a(B(t).value)),K(`keydown`,n,o),g(e,n)}),f(s),w(s,e=>Ac?.(e)),U(()=>S(s,`aria-label`,i())),g(e,s),W()}H([`click`,`keydown`]);var P_=`Optional: give each node its own assistant voice. During steering, Drowse uses the role of the nearest node.`,F_=/^(?:raw|sae(?:-[a-z0-9._-]+)?|role(?:-[a-z0-9._-]+)?|from(?:-[a-z0-9._-]+)?)$/u;function I_(e,t,n){let r=`${e.namespace}/${e.name}`,i=H_(e,t),a=e.node_roles??[],o=a.filter(e=>e!==null),s=o.length===a.length&&a.length>0&&a.every(e=>e===a[0])?a[0]:null,c=o.length>0&&s===null,l=[];for(let e of i)if(G_(e)){if(e===`raw`&&s!==null){let e=`role-${s}`;l.push({selector:`${r}:${e}`,variant:e,label:`shared role · ${s}`,available:!0,unavailableReason:null});continue}if(e===`raw`&&c){l.push({selector:r,variant:`raw`,label:`nearest node role`,available:!0,unavailableReason:null});continue}l.push({selector:e===`raw`?r:`${r}:${e}`,variant:e,label:K_(e),available:!0,unavailableReason:null})}if(l.length===0&&e.fitted_for_session)if(s!==null){let e=`role-${s}`;l.push({selector:`${r}:${e}`,variant:e,label:`shared role · ${s}`,available:!0,unavailableReason:null})}else l.push({selector:r,variant:`raw`,label:c?`nearest node role`:`residual`,available:!0,unavailableReason:null});return J_(l).sort((e,t)=>q_(e.variant)-q_(t.variant)||e.label.localeCompare(t.label))}function L_(e,t){return e.find(e=>e.selector===t)??e.find(e=>e.available)??e[0]??null}function R_(e,t){let n=W_(e);return n===null?!1:n===`${t.namespace}/${t.name}`||n===t.name}function z_(e,t,n){return e.family===`geometry`?R_(e.manifold,t)||n!==void 0&&R_(n,t):!1}function B_(e,t,n){let r=[...t.keys()].filter(t=>R_(t,e)),i=[...n.values()].filter(t=>z_(t.info,e,t.request.selector)).map(e=>e.info.name);return{rack:[...new Set(r)].sort(),probes:[...new Set(i)].sort()}}function V_(e,t){let n=[];return t.rack.length>0&&n.push(`steering: ${t.rack.join(`, `)}`),t.probes.length>0&&n.push(`readings: ${t.probes.join(`, `)}`),n.length===0?null:`Remove ${e.namespace}/${e.name} from active tools before deleting it (${n.join(`; `)}).`}function H_(e,t){let n=e.tensor_variants??{};if(t!==null){let e=n[t];if(e)return[...e];let r=n[U_(t)];if(r)return[...r]}let r=Object.values(n);return r.length===1?[...r[0]]:e.fitted_for_session?[`raw`]:[]}function U_(e){let t=new TextEncoder().encode(e),n=``;for(let e of t)n+=String.fromCharCode(e);return`_z${btoa(n).replaceAll(`+`,`-`).replaceAll(`/`,`_`).replace(/=+$/u,``)}`}function W_(e){let t=e.trim();if(!t||t.startsWith(`sae/`)||t.startsWith(`jlens/`))return null;let n=t.indexOf(`%`);n>=0&&(t=t.slice(0,n));let r=t.lastIndexOf(`:`);return r>=0&&F_.test(t.slice(r+1))&&(t=t.slice(0,r)),t||null}function G_(e){return F_.test(e)}function K_(e){return e===`raw`?`residual`:e===`sae`?`SAE`:e.startsWith(`sae-`)?`SAE · ${e.slice(4)}`:e===`from`?`transferred`:e.startsWith(`from-`)?`transferred · ${e.slice(5)}`:e===`role`?`shared role`:`shared role · ${e.slice(5)}`}function q_(e){return e===`raw`||e===`role`||e.startsWith(`role-`)?0:e===`sae`||e.startsWith(`sae-`)?1:2}function J_(e){let t=new Set;return e.filter(e=>t.has(e.selector)?!1:(t.add(e.selector),!0))}function Y_(e){return e?{sphere:`Sphere`,torus:`Torus`,"klein-bottle":`Klein bottle`,"projective-plane":`Real projective plane (RP²)`}[e]??e.replaceAll(`-`,` `):`Unresolved surface`}function X_(e){return e.type===`klein`?`Klein bottle · two angles in radians. Crossing the u seam reverses v; these are coordinates, not a flat surface.`:e.type===`projective`?`Real projective plane (RP²) · polar and azimuth angles in radians. Opposite points on the sphere represent the same position.`:null}function Z_(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Enter a JSON array of points, such as [[0, 1, 2], …].`)}if(!Array.isArray(t)||t.length<32||t.length>384)throw Error(`Use 32–384 points. Larger clouds must be sampled before inspection.`);let n=Array.isArray(t[0])?t[0].length:0;if(n<2||n>1024||!t.every(e=>Array.isArray(e)&&e.length===n&&e.every(e=>typeof e==`number`&&Number.isFinite(e))))throw Error(`Each point needs the same 2–1,024 finite numeric coordinates.`);if(new Set(t.map(e=>JSON.stringify(e))).size!==t.length)throw Error(`Remove duplicate points before inspecting the surface.`);return t}function Q_(){return Array.from({length:96},(e,t)=>{let n=1-2*(t+.5)/96,r=t*Math.PI*(3-Math.sqrt(5)),i=Math.sqrt(1-n*n);return[i*Math.cos(r),i*Math.sin(r),n]})}var $_=I(` `),ev=I(``);function tv(e,t){n(t,!0);let r=Y(t,`checked`,15),i=Y(t,`disabled`,3,!1);function a(e){r(e.currentTarget.checked),t.onchange?.(r())}var o=ev();let c;var l=R(o);s(l);var u=X(l,2),d=R(u),m=R(d);let h;f(d),f(u);var _=X(u,2),v=e=>{var n=$_();let r;var a=R(n,!0);f(n),U(()=>{r=y(n,1,`sk-checkbox-label svelte-vw6mhy`,null,r,{"is-disabled":i()}),G(a,t.label)}),g(e,n)};p(_,e=>{t.label&&e(v)}),f(o),U(()=>{c=y(o,1,`sk-checkbox-row svelte-vw6mhy`,null,c,{"is-disabled":i()}),S(l,`aria-label`,t.ariaLabel??void 0),l.disabled=i(),S(l,`title`,t.title),h=y(m,1,`sk-checkbox-glyph svelte-vw6mhy`,null,h,{"is-visible":r()})}),K(`change`,l,a),Me(l,r),g(e,o),W()}H([`change`]);var nv=I(`
          `),rv=I(`
          `);function iv(e,t){n(t,!0);let i=Y(t,`expanded`,15,!1),a=Y(t,`summary`,3,`Advanced options`);var o=rv();ip(R(o),{get summary(){return a()},flush:!0,get expanded(){return i()},set expanded(e){i(e)},children:(e,n)=>{var i=nv();r(R(i),()=>t.children),f(i),g(e,i)},$$slots:{default:!0}}),f(o),g(e,o),W()}var av=I(`
        • `),ov=I(`

            `);function sv(e,t){let r=E();n(t,!0);var i=L(),a=q(i),o=e=>{var n=ov(),i=R(n),a=R(i);f(i);var o=X(i,2);m(o,20,()=>t.messages,e=>e,(e,t)=>{var n=av(),r=R(n,!0);f(n),U(()=>G(r,t)),g(e,n)}),f(o),f(n),U(()=>{S(n,`aria-labelledby`,`${r}-heading`),S(i,`id`,`${r}-heading`),G(a,`Check these details before you ${t.verb??``}`)}),g(e,n)};p(a,e=>{t.messages.length>0&&e(o)}),g(e,i),W()}var cv=I(`hosted browser limit · dimensions`),lv=I(``),uv=I(``),dv=I(``),fv=I(`
            `,1);function pv(e,t){n(t,!0);let r=Y(t,`tuning`,7),i=Y(t,`maxDimLimit`,3,null);var a=fv(),o=q(a),s=R(o),l=X(R(s),2);{let e=c(()=>i()??void 0);$f(l,{get value(){return r().maxDim},min:1,get max(){return B(e)},step:1,oninput:e=>{e!==null&&(r().maxDim=e)}})}var u=X(l,2),d=e=>{var t=cv(),n=X(R(t)),r=R(n,!0);f(n),T(),f(t),U(()=>G(r,i())),g(e,t)};p(u,e=>{i()!==null&&e(d)}),f(s);var m=X(s,2),h=e=>{var t=lv();$f(X(R(t),2),{get value(){return r().varThreshold},min:0,max:1,step:.05,oninput:e=>{e!==null&&(r().varThreshold=e)}}),f(t),g(e,t)},_=e=>{var t=uv();$f(X(R(t),2),{get value(){return r().kNN},min:1,step:1,allowEmpty:!0,placeholder:`max(5, ⌈log K⌉)`,oninput:e=>{r().kNN=e}}),f(t),g(e,t)};p(m,e=>{r().fitMode===`pca`||r().fitMode===`auto`?e(h):e(_,-1)}),f(o);var v=X(o,2),y=e=>{var t=dv();$f(X(R(t),2),{get value(){return r().bandwidth},min:0,step:.01,allowEmpty:!0,placeholder:`median(k-NN edges)`,oninput:e=>{r().bandwidth=e}}),f(t),g(e,t)};p(v,e=>{r().fitMode===`spectral`&&e(y)}),g(e,a),W()}var mv=I(` `),hv=I(``);function gv(e,t){n(t,!0);let r=Y(t,`group`,15),i=Y(t,`disabled`,3,!1),a=c(()=>r()===t.value);function o(){i()||B(a)||(r(t.value),t.onchange?.(t.value))}function s(e){if(i())return;if(e.key===` `||e.key===`Enter`){e.preventDefault(),o();return}let t=e.currentTarget.closest(`[role="radiogroup"]`);if(!t)return;let n=[...t.querySelectorAll(`[role="radio"]`)].filter(e=>!e.disabled),r=n.indexOf(e.currentTarget);if(r<0||n.length===0)return;let a=r,s=getComputedStyle(t).direction===`rtl`;if(e.key===`ArrowDown`||e.key===`ArrowRight`)a=(r+(e.key===`ArrowRight`&&s?-1:1)+n.length)%n.length;else if(e.key===`ArrowUp`||e.key===`ArrowLeft`)a=(r+(e.key===`ArrowLeft`&&s?1:-1)+n.length)%n.length;else if(e.key===`Home`)a=0;else if(e.key===`End`)a=n.length-1;else return;e.preventDefault(),n[a].focus(),n[a].click()}var l=hv();let u;var d=R(l),m=R(d),h=R(m);let _;f(m),f(d);var v=X(d,2),b=e=>{var n=mv(),r=R(n,!0);f(n),U(()=>G(r,t.label)),g(e,n)};p(v,e=>{t.label&&e(b)}),f(l),U(()=>{u=y(l,1,`sk-radio svelte-k8e4dq`,null,u,{"is-selected":B(a),"is-disabled":i()}),S(l,`aria-checked`,B(a)),S(l,`aria-label`,t.ariaLabel),S(l,`tabindex`,B(a)&&!i()?0:-1),S(l,`data-name`,t.name),l.disabled=i(),S(l,`title`,t.title),_=y(h,1,`sk-radio-dot svelte-k8e4dq`,null,_,{"is-visible":B(a)})}),K(`click`,l,o),K(`keydown`,l,s),g(e,l),W()}H([`click`,`keydown`]);var _v=I(`

            linear PCA · automatic curved-shape detection is not included in the hosted release

            `),vv=I(`
            `),yv=I(`

            fit method

            `);function bv(t,r){n(r,!0);let i=Y(r,`spectralNote`,3,`curved`),a=Y(r,`linearOnly`,3,!1);Ce(()=>{a()&&r.tuning.fitMode!==`pca`&&r.onchange(`pca`)});var o=yv(),s=X(R(o),2),c=e=>{g(e,_v())},l=e=>{var t=vv(),n=R(t);gv(n,{get group(){return r.tuning.fitMode},value:`auto`,label:`auto`,get onchange(){return r.onchange}});var i=X(n,2);gv(i,{get group(){return r.tuning.fitMode},value:`pca`,label:`pca`,get onchange(){return r.onchange}}),gv(X(i,2),{get group(){return r.tuning.fitMode},value:`spectral`,label:`spectral`,get onchange(){return r.onchange}}),f(t),g(e,t)};p(s,e=>{a()?e(c):e(l,-1)});var u=X(s,2),d=R(u),m=t=>{g(t,e(`Suggest a flat or periodic layout per model. This does not recover Klein-bottle or RP² coordinates.`))},h=t=>{g(t,e(`flat`))},_=t=>{var n=e();U(()=>G(n,i())),g(t,n)};p(d,e=>{r.tuning.fitMode===`auto`?e(m):r.tuning.fitMode===`pca`?e(h,1):e(_,-1)}),f(u),f(o),g(t,o),W()}function xv(e){return e.trim().toLowerCase().replace(/[^a-z0-9._-]+/g,`_`).replace(/^[_.-]+|[_.-]+$/g,``)}function Sv(e){return{namespace:xv(e.namespace)||`local`,name:xv(e.name),description:e.description.trim()}}function Cv(e){return e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean)}function wv(e=ae()){return{fitMode:`auto`,maxDim:e===null?8:Math.min(8,e),varThreshold:.7,kNN:null,bandwidth:null}}function Tv(e){let t={max_dim:e.maxDim};return(e.fitMode===`pca`||e.fitMode===`auto`)&&(t.var_threshold=e.varThreshold),(e.fitMode===`spectral`||e.fitMode===`auto`)&&(e.kNN!==null&&e.kNN>0&&(t.k_nn=e.kNN),e.bandwidth!==null&&e.bandwidth>0&&(t.bandwidth=e.bandwidth)),t}function Ev(e,t=ae()){return e!==null&&e<1?`Use a maximum dimension of at least 1.`:e!==null&&t!==null&&e>t?`Hosted browser fitting supports at most ${t} dimensions.`:null}function Dv(e,t=ae()){let n=[],r=Ev(e.maxDim,t);return r&&n.push(r),(e.fitMode===`pca`||e.fitMode===`auto`)&&(e.varThreshold<=0||e.varThreshold>1)&&n.push(`variance ∈ (0, 1]`),n}function Ov(e){return!e.data||typeof e.data!=`object`?null:e.data.message??null}var kv=I(` `,1),Av=I(`

            `),jv=I(`
            `),Mv=I(`
            `),Nv=I(``),Pv=I(`

            `),Fv=I(`

            domain

            dim · min nodes

            `),Iv=I(`

            `),Lv=I(``),Rv=I(`
            `),zv=I(`

            `),Bv=I(`

            `),Vv=I(`

            `),Hv=I(`

            `),Uv=I(`
            `),Wv=I(`
            `),Gv=I(`

            `),Kv=I(`

            nodes

            Roles are optional. When nodes use different roles, Drowse follows the role of the nearest node.

            `);function qv(e,r){n(r,!0);let i=J(!1),o=ae(),l=St.mode!==`http`,u=V(wv(o)),d=J(!1),_=J(!1),v=J(!1),b=J(null),x=J(null),C=J(`box`),w=J(2),E=J(2),D=V([{name:`x`,lo:0,hi:1,periodic:!1},{name:`y`,lo:0,hi:1,periodic:!1},{name:`z`,lo:0,hi:1,periodic:!1}]),O=c(()=>B(C)===`box`?B(w):B(C)===`sphere`?B(E):2),k=c(()=>B(C)===`projective`?6:2*B(O)+1);function j(){return!l&&B(C)===`klein`?{type:`klein`}:!l&&B(C)===`projective`?{type:`projective`,dim:2}:B(C)===`sphere`?{type:`sphere`,dim:B(E)}:{type:`box`,axes:D.slice(0,B(w)).map(e=>({name:e.name,periodic:e.periodic,period:e.hi-e.lo,lo:e.lo,hi:e.hi}))}}function M(e){A(w,e,!0),A(C,`box`),te()}function P(){A(C,`sphere`),te()}function F(e){A(E,e,!0),te()}let I=J(V([])),ee=/^[a-z0-9._-]+$/;function te(){let e=B(O);A(I,B(I).map(t=>{let n=t.coords.slice(0,e);for(;n.lengthn!==e),!0)}function re(e,t,n){A(I,B(I).map((r,i)=>i===e?{...r,[t]:n}:r),!0)}function ie(e,t,n){A(I,B(I).map((r,i)=>{if(i!==e)return r;let a=r.coords.slice();return a[t]=n,{...r,coords:a}}),!0)}function oe(e){return e.statements.split(/\r?\n/).map(e=>e.trim()).filter(Boolean)}function H(e){if(!e.every(Number.isFinite))return!1;if(B(C)!==`box`)return!0;for(let t=0;tn.hi)return!1}return!0}let se=c(()=>{let e=[];if(xv(r.identity.name)||e.push(`name required`),!B(i)&&B(C)===`box`)for(let t=0;t lo`)}B(i)?B(I).length<2&&e.push(`nodes: ${B(I).length} / 2`):B(I).lengthxv(e.label)===t).length>1?`Each node label must be unique.`:null:`Enter a label for this node.`}function ue(e){return!B(v)||B(i)||H(B(I)[e].coords)?null:`Keep every coordinate inside the selected domain.`}function de(e){return!B(v)||oe(B(I)[e]).length>0?null:`Add at least one example statement.`}function fe(e){if(!B(v))return null;let t=B(I)[e].role.trim();return t&&!ee.test(t)?`Use lowercase letters, numbers, dots, underscores, or hyphens.`:null}function pe(){if(!B(v))return null;let e=B(i)?2:B(k);return B(I).length .grid2 > .field:nth-child(2) input`)??null}function he(e){let t=B(b)?.querySelectorAll(`.field`)??[];for(let n of t)if(n.querySelector(`.label`)?.textContent?.trim()===e)return n.querySelector(`input`);return null}async function ge(){if(await xe(),!xv(r.identity.name)){me()?.focus();return}if(!B(i)&&B(C)===`box`){let e=D.slice(0,B(w)).findIndex(e=>e.hi<=e.lo);if(e>=0){B(b)?.querySelector(`#authored-axis-${e}-hi input`)?.focus();return}}if(pe()){B(x)?.focus();return}for(let e=0;eo?`max dim`:`variance`)?.focus())}async function ve(){if(B(_))return;if(A(v,!0),!B(se).ok){await ge();return}A(_,!0);let{namespace:e,name:t,description:n}=Sv(r.identity);if(B(i)){let i={namespace:e,name:t,description:n,fit_mode:u.fitMode,hyperparams:Tv(u),nodes:B(I).map(e=>{let t=e.role.trim();return{label:xv(e.label),statements:oe(e),...t?{role:t}:{}}})};try{await Et.createDiscover(i),await yr(),Z(`Created ${e}/${t} (auto-domain, ${u.fitMode} fit). Open Manifolds to fit it.`,{kind:`info`}),r.oncomplete?r.oncomplete():(it(),rt(`manifolds`))}catch(e){Z(`Couldn't create the manifold: ${ye(e)}`,{kind:`error`,ttlMs:null})}finally{A(_,!1)}return}let a={namespace:e,name:t,description:n,domain:j(),nodes:B(I).map(e=>{let t=e.role.trim();return{label:xv(e.label),coords:e.coords.slice(0,B(O)),statements:oe(e),...t?{role:t}:{}}})};try{let n=await Et.create(a);await yr();let i=n.advisories??[];i.length>0?Z(`Created ${e}/${t}. Check ${i.length} coordinate ${i.length===1?`warning`:`warnings`}.`,{kind:`warning`,detail:i.join(`; `),ttlMs:1e4}):Z(`built manifold ${e}/${t}`,{kind:`info`}),r.oncomplete?r.oncomplete():(it(),rt(`manifolds`))}catch(e){Z(`Couldn't create the manifold: ${ye(e)}`,{kind:`error`,ttlMs:null})}finally{A(_,!1)}}function ye(e){return je(e,`Unable to build this direction. Check the highlighted fields and try again.`)}var be=Kv(),Se=R(be);tv(R(Se),{label:`auto-domain`,get checked(){return B(i)},set checked(e){A(i,e,!0)}}),f(Se);var Ce=X(Se,2),we=e=>{bv(e,{get tuning(){return u},get linearOnly(){return l},spectralNote:`curved · best with ≥50 nodes`,onchange:e=>u.fitMode=e})},Te=e=>{var n=Fv(),r=X(R(n),2),i=R(r);let a;var o=X(i,2);let u;var d=X(o,2);let h;var _=X(d,2);let v;var b=X(_,2),x=e=>{var t=kv(),n=q(t);let r;var i=X(n,2);let a;U(()=>{r=y(n,1,`kind-btn`,null,r,{active:B(C)===`klein`}),S(n,`aria-pressed`,B(C)===`klein`),a=y(i,1,`kind-btn`,null,a,{active:B(C)===`projective`}),S(i,`aria-pressed`,B(C)===`projective`)}),K(`click`,n,()=>{A(C,`klein`),te()}),K(`click`,i,()=>{A(C,`projective`),te()}),g(e,t)};p(b,e=>{l||e(x)}),f(r);var I=X(r,2),ee=e=>{var n=Mv();m(n,21,()=>D.slice(0,B(w)),N,(e,n,r)=>{var i=jv(),a=R(i),o=X(R(a),2);s(o),f(a);var l=X(a,2);$f(X(R(l),2),{get value(){return B(n).lo},step:.1,oninput:e=>{e!==null&&(D[r].lo=e)}}),f(l);var u=X(l,2),d=X(R(u),2);S(d,`id`,`authored-axis-${r}-hi`);var m=R(d);{let e=c(()=>ce(r)!==null),t=c(()=>`${B(n).name||`Axis ${r+1}`} high value`),i=c(()=>ce(r)?`authored-axis-${r}-error`:void 0);$f(m,{get value(){return B(n).hi},step:.1,get invalid(){return B(e)},get ariaLabel(){return B(t)},get ariaDescribedby(){return B(i)},oninput:e=>{e!==null&&(D[r].hi=e)}})}f(d),f(u);var h=X(u,2);tv(R(h),{get checked(){return B(n).periodic},label:`periodic`,onchange:e=>{D[r].periodic=e}}),f(h);var _=X(h,2),v=e=>{var t=Av();S(t,`id`,`authored-axis-${r}-error`);var n=R(t,!0);f(t),U(e=>G(n,e),[()=>ce(r)]),g(e,t)},y=c(()=>ce(r));p(_,e=>{B(y)&&e(v)}),f(i),U(()=>t(o,B(n).name)),K(`input`,o,e=>{D[r].name=e.currentTarget.value}),g(e,i)}),f(n),g(e,n)},z=e=>{var t=L(),n=q(t),r=e=>{var t=Nv();hu(X(R(t),2),{get value(){return B(E)},options:[{value:1,label:`S¹ (circle)`},{value:2,label:`S² (sphere)`},{value:3,label:`S³`}],ariaLabel:`Sphere dimension`,onchange:F}),f(t),g(e,t)},i=e=>{var t=Pv(),n=R(t);f(t),U(e=>G(n,`${e??``} Spread nodes across the whole surface; the minimum count alone does not guarantee a stable fit.`),[()=>X_(j())]),g(e,t)};p(n,e=>{B(C)===`sphere`?e(r):e(i,-1)}),g(e,t)};p(I,e=>{B(C)===`box`?e(ee):e(z,-1)});var ne=X(I,2),V=X(R(ne)),re=R(V,!0);f(V);var ie=X(V,2),ae=R(ie,!0);f(ie),T(),f(ne),f(n),U(()=>{a=y(i,1,`kind-btn`,null,a,{active:B(C)===`box`&&B(w)===1}),S(i,`aria-pressed`,B(C)===`box`&&B(w)===1),u=y(o,1,`kind-btn`,null,u,{active:B(C)===`box`&&B(w)===2}),S(o,`aria-pressed`,B(C)===`box`&&B(w)===2),h=y(d,1,`kind-btn`,null,h,{active:B(C)===`box`&&B(w)===3}),S(d,`aria-pressed`,B(C)===`box`&&B(w)===3),v=y(_,1,`kind-btn`,null,v,{active:B(C)===`sphere`}),S(_,`aria-pressed`,B(C)===`sphere`),G(re,B(O)),G(ae,B(k))}),K(`click`,i,()=>M(1)),K(`click`,o,()=>M(2)),K(`click`,d,()=>M(3)),K(`click`,_,P),g(e,n)};p(Ce,e=>{B(i)?e(we):e(Te,-1)});var Ee=X(Ce,2),De=X(R(Ee),2),Oe=e=>{var t=Iv(),n=R(t);f(t),U(()=>G(n,`add ≥${(B(i)?2:B(k))??``} nodes`)),g(e,t)};p(De,e=>{B(I).length===0&&e(Oe)});var ke=X(De,2);m(ke,21,()=>B(I),N,(e,n,r)=>{var a=Wv();S(a,`data-node-index`,r);var o=R(a),l=R(o);S(l,`aria-controls`,`authored-node-${r}-details`);var u=R(l),d=R(u,!0);f(u),f(l);var _=X(l,2);s(_),S(_,`aria-label`,`Node ${r+1} label`);var v=X(_,2),y=e=>{var t=Rv();m(t,21,()=>B(n).coords,N,(e,t,i)=>{var a=Lv(),o=R(a);{let e=c(()=>`Node ${B(n).label||r+1}, coordinate ${i+1}`),a=c(()=>ue(r)!==null),s=c(()=>ue(r)?`authored-node-${r}-coords-error`:void 0);$f(o,{get value(){return B(t)},step:.1,get ariaLabel(){return B(e)},get invalid(){return B(a)},get ariaDescribedby(){return B(s)},oninput:e=>ie(r,i,e??0)})}f(a),g(e,a)}),f(t),g(e,t)};p(v,e=>{B(i)||e(y)});var b=X(v,2);Be(R(b),{name:`dismiss`}),f(b),f(o);var x=X(o,2),C=e=>{var t=zv();S(t,`id`,`authored-node-${r}-label-error`);var n=R(t,!0);f(t),U(e=>G(n,e),[()=>le(r)]),g(e,t)},w=c(()=>le(r));p(x,e=>{B(w)&&e(C)});var T=X(x,2),E=e=>{var t=Bv();S(t,`id`,`authored-node-${r}-coords-error`);var n=R(t,!0);f(t),U(e=>G(n,e),[()=>ue(r)]),g(e,t)},D=c(()=>ue(r));p(T,e=>{B(D)&&e(E)});var O=X(T,2),k=e=>{var t=Vv();S(t,`id`,`authored-node-${r}-role-error`);var n=R(t,!0);f(t),U(e=>G(n,e),[()=>fe(r)]),g(e,t)},A=c(()=>fe(r));p(O,e=>{B(A)&&e(k)});var j=X(O,2),M=e=>{var t=Hv();S(t,`id`,`authored-node-${r}-statements-error`);var n=R(t,!0);f(t),U(e=>G(n,e),[()=>de(r)]),g(e,t)},P=c(()=>de(r));p(j,e=>{B(P)&&e(M)});var F=X(j,2),I=e=>{var i=Uv();S(i,`id`,`authored-node-${r}-details`);var a=R(i),o=X(R(a),2);s(o),f(a);var c=X(a,2);_e(c),f(i),U((e,i,a,s)=>{t(o,B(n).role),S(o,`aria-invalid`,e),S(o,`aria-describedby`,i),t(c,B(n).statements),S(c,`aria-label`,`Statements for node ${B(n).label||r+1}`),S(c,`aria-invalid`,a),S(c,`aria-describedby`,s)},[()=>fe(r)!==null,()=>fe(r)?`authored-node-${r}-role-error`:void 0,()=>de(r)!==null,()=>de(r)?`authored-node-${r}-statements-error`:void 0]),K(`input`,o,e=>re(r,`role`,e.currentTarget.value)),K(`input`,c,e=>re(r,`statements`,e.currentTarget.value)),h(1,i,()=>ut,lu),h(2,i,()=>ut,uu),g(e,i)};p(F,e=>{B(n).expanded&&e(I)}),f(a),U((e,i)=>{S(l,`aria-expanded`,B(n).expanded),S(l,`aria-label`,`${B(n).expanded?`Collapse`:`Expand`} node ${B(n).label||r+1}`),G(d,B(n).expanded?`▾`:`▸`),t(_,B(n).label),S(_,`aria-invalid`,e),S(_,`aria-describedby`,i),S(b,`aria-label`,`remove node ${B(n).label??``}`)},[()=>le(r)!==null,()=>le(r)?`authored-node-${r}-label-error`:void 0]),K(`click`,l,()=>re(r,`expanded`,!B(n).expanded)),K(`input`,_,e=>re(r,`label`,e.currentTarget.value)),K(`click`,b,()=>ne(r)),g(e,a)}),f(ke);var Ae=X(ke,2);a(Ae,e=>A(x,e),()=>B(x));var Me=X(Ae,2),Y=e=>{var t=Gv(),n=R(t,!0);f(t),U(e=>G(n,e),[()=>pe()]),g(e,t)},Ne=c(()=>pe());p(Me,e=>{B(Ne)&&e(Y)});var Pe=X(Me,2);f(Ee);var Fe=X(Ee,2),Ie=e=>{iv(e,{get expanded(){return B(d)},set expanded(e){A(d,e,!0)},children:(e,t)=>{pv(e,{get tuning(){return u},get maxDimLimit(){return o}})},$$slots:{default:!0}})};p(Fe,e=>{B(i)&&e(Ie)});var Le=X(Fe,2);{let e=c(()=>B(v)?B(se).messages:[]);sv(Le,{verb:`build`,get messages(){return B(e)}})}var Re=X(Le,2),ze=R(Re,!0);f(Re),f(be),a(be,e=>A(b,e),()=>B(b)),U(()=>{S(Pe,`title`,P_),Re.disabled=B(_),G(ze,B(_)?`building…`:B(i)?`build · ${u.fitMode}`:`build`)}),K(`click`,Ae,z),K(`click`,Re,ve),g(e,be),W()}H([`click`,`input`]);var Jv=I(` `),Yv=I(` `),Xv=I(` `),Zv=I(``),Qv=I(` `),$v=I(`No compatible learned-feature pack is installed.`),ey=I(`
            feature space for fit
            `),ty=I(``),ny=I(`

            each concept becomes its assistant voice; unsupported chat templates fail before fitting

            `),ry=I(`
            `,1),iy=I(`

            concepts

            kind

            `);function ay(e,t){n(t,!0);let r=ae(),i=St.mode!==`http`,o=V(wv(r)),l=J(``),u=J(`abstract`),d=J(`You are {c}.`),m=J(1),h=J(!1),_=J(!1),v=J(``),y=J(!0),b=J(!1),x=J(``),C=J(!1),w=J(!1),E=J(null),D=J(null),O=J(null),k=J(null),M=c(()=>Cv(B(l))),N=c(()=>[{value:``,label:`Standard fit (no feature pack)`},...na.sources.map(e=>({value:e.source,label:e.name?.trim()||e.source}))]);ne(()=>{i&&ra()});let P=c(()=>{let e=[];xv(t.identity.name)||e.push(`name required`),B(M).length<2&&e.push(`concepts: ${B(M).length} / 2`);let n=new Set;for(let t of B(M)){let r=xv(t);r?n.has(r)?e.push(`duplicate concept "${r}"`):n.add(r):e.push(`invalid concept "${t}"`)}if(B(m)<=0&&e.push(`samples / prompt > 0`),B(u)===`custom`){let t=B(d).trim();t?t.includes(`{c}`)||e.push(`system template needs "{c}"`):e.push(`system template required`)}return e.push(...Dv(o,r)),{ok:e.length===0,messages:e}}),F=c(()=>{if(!B(w))return null;if(B(M).length<2)return`Enter at least two concepts.`;let e=new Set;for(let t of B(M)){let n=xv(t);if(!n)return`Concept “${t}” needs a letter or number.`;if(e.has(n))return`Each concept must be unique after formatting.`;e.add(n)}return null}),I=c(()=>B(w)&&B(m)<=0?`Use at least one sample per prompt.`:null),L=c(()=>!B(w)||B(u)!==`custom`?null:B(d).trim()?B(d).includes(`{c}`)?null:`Include the "{c}" placeholder.`:`Enter a system template.`);Ce(()=>{let e=B(O)?.querySelector(`input`);e&&(B(I)?(e.setAttribute(`aria-invalid`,`true`),e.setAttribute(`aria-describedby`,`discover-samples-error`)):(e.removeAttribute(`aria-invalid`),e.removeAttribute(`aria-describedby`)))});function ee(){return(B(E)?.closest(`.mb-form`))?.querySelector(`:scope > .grid2 > .field:nth-child(2) input`)??null}function z(e){let t=B(E)?.querySelectorAll(`.field`)??[];for(let n of t)if(n.querySelector(`.label`)?.textContent?.trim()===e)return n.querySelector(`input`);return null}async function re(){if(await xe(),!xv(t.identity.name)){ee()?.focus();return}if(B(F)){B(D)?.focus();return}if(B(I)){B(O)?.querySelector(`input`)?.focus();return}if(B(L)){B(k)?.focus();return}Dv(o,r).length!==0&&(A(b,!0),await xe(),z(o.maxDim<1||r!==null&&o.maxDim>r?`max dim`:`variance`)?.focus())}async function ie(){if(B(C))return;if(A(w,!0),!B(P).ok){await re();return}A(C,!0),A(x,`Starting generation…`);let{namespace:e,name:n,description:r}=Sv(t.identity),i=Tv(o),a={namespace:e,name:n,description:r,concepts:B(M).map(e=>xv(e)),kind:B(u),custom_system:B(u)===`custom`?B(d).trim():void 0,samples_per_prompt:B(m),fit_mode:o.fitMode,hyperparams:i,force:B(_),role_per_node:B(h)},s=Z(`generating ${e}/${n} corpora…`,{kind:`info`,ttlMs:null});try{if(await Mt(a,e=>{if(e.event!==`progress`)return;let t=Ov(e);t&&(A(x,t,!0),Ye(s,{detail:t}))}),Xe(s),B(y)){let t=Z(`fitting ${e}/${n}…`,{kind:`info`,ttlMs:null});A(x,`Starting fit…`);try{await At(e,n,{sae:B(v).trim()||null,fit_mode:o.fitMode,hyperparams:i},e=>{if(e.event!==`progress`)return;let n=Ov(e);n&&(A(x,n,!0),Ye(t,{detail:n}))}),Xe(t),Z(`fit ${e}/${n} (${o.fitMode})`,{kind:`info`})}catch(e){Xe(t),Z(`Couldn't fit the manifold: ${te(e)}`,{kind:`error`,ttlMs:null})}}else Z(`Generated ${e}/${n}. Open Manifolds to fit it.`,{kind:`info`});await yr(),t.oncomplete?t.oncomplete():(it(),rt(`manifolds`))}catch(e){Xe(s),Z(`Couldn't generate the manifold: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{A(C,!1),A(x,``)}}var oe=iy(),H=R(oe),se=X(R(H),2),ce=X(R(se),2);_e(ce),a(ce,e=>A(D,e),()=>B(D));var le=X(ce,2),ue=e=>{var t=Jv(),n=R(t,!0);f(t),U(()=>G(n,B(F))),g(e,t)};p(le,e=>{B(F)&&e(ue)});var de=X(le,2),fe=R(de),pe=R(fe,!0);f(fe),T(),f(de),f(se);var me=X(se,2),he=R(me),ge=X(R(he),2),ve=R(ge);gv(ve,{value:`abstract`,label:`abstract`,get group(){return B(u)},set group(e){A(u,e,!0)}});var ye=X(ve,2);gv(ye,{value:`concrete`,label:`concrete`,get group(){return B(u)},set group(e){A(u,e,!0)}}),gv(X(ye,2),{value:`custom`,label:`custom`,get group(){return B(u)},set group(e){A(u,e,!0)}}),f(ge),f(he);var be=X(he,2),Se=X(R(be),2);$f(Se,{get value(){return B(m)},min:1,step:1,oninput:e=>{e!==null&&A(m,e,!0)}});var we=X(Se,2),Te=e=>{var t=Yv(),n=R(t,!0);f(t),U(()=>G(n,B(I))),g(e,t)};p(we,e=>{B(I)&&e(Te)}),f(be),a(be,e=>A(O,e),()=>B(O)),f(me);var Ee=X(me,2),De=e=>{var t=Zv(),n=X(R(t),2);_e(n),a(n,e=>A(k,e),()=>B(k));var r=X(n,2),i=e=>{var t=Xv(),n=R(t,!0);f(t),U(()=>G(n,B(L))),g(e,t)};p(r,e=>{B(L)&&e(i)}),f(t),U(()=>{S(n,`aria-invalid`,!!B(L)),S(n,`aria-describedby`,B(L)?`discover-system-error`:void 0)}),j(n,()=>B(d),e=>A(d,e)),g(e,t)};p(Ee,e=>{B(u)===`custom`&&e(De)}),f(H);var Oe=X(H,2);bv(Oe,{get tuning(){return o},get linearOnly(){return i},spectralNote:`curved · best with ≥50 nodes`,onchange:e=>o.fitMode=e});var ke=X(Oe,2);iv(ke,{get expanded(){return B(b)},set expanded(e){A(b,e,!0)},children:(e,t)=>{var n=ry(),a=q(n),l=e=>{var t=ey(),n=X(R(t),2);{let e=c(()=>na.loading||na.busy);hu(n,{get options(){return B(N)},get disabled(){return B(e)},ariaLabel:`Feature space used for manifold fitting`,get value(){return B(v)},set value(e){A(v,e,!0)}})}var r=X(n,2),i=e=>{var t=Qv(),n=R(t,!0);f(t),U(()=>G(n,na.error)),g(e,t)},a=e=>{g(e,$v())};p(r,e=>{na.error?e(i):!na.loading&&na.sources.length===0&&e(a,1)}),f(t),g(e,t)},u=e=>{var t=ty(),n=X(R(t),2);s(n),f(t),j(n,()=>B(v),e=>A(v,e)),g(e,t)};p(a,e=>{i?e(l):e(u,-1)});var d=X(a,2);pv(d,{get tuning(){return o},get maxDimLimit(){return r}});var m=X(d,2),b=R(m);tv(b,{label:`fit now`,get checked(){return B(y)},set checked(e){A(y,e,!0)}});var x=X(b,2);tv(x,{label:`node roles`,get title(){return P_},get checked(){return B(h)},set checked(e){A(h,e,!0)}});var S=X(x,2),C=e=>{g(e,ny())};p(S,e=>{B(h)&&e(C)}),tv(X(S,2),{label:`overwrite`,get checked(){return B(_)},set checked(e){A(_,e,!0)}}),f(m),g(e,n)},$$slots:{default:!0}});var Ae=X(ke,2),je=R(Ae,!0);f(Ae);var Me=X(Ae,2);{let e=c(()=>B(w)?B(P).messages:[]);sv(Me,{verb:`generating`,get messages(){return B(e)}})}var Y=X(Me,2),Ne=R(Y,!0);f(Y),f(oe),a(oe,e=>A(E,e),()=>B(E)),U(()=>{S(oe,`aria-busy`,B(C)),S(ce,`aria-invalid`,!!B(F)),S(ce,`aria-describedby`,B(F)?`discover-concepts-error`:void 0),G(pe,B(M).length),G(je,B(x)),Y.disabled=B(C),G(Ne,B(C)?`generating…`:B(y)?`generate + fit`:`generate`)}),j(ce,()=>B(l),e=>A(l,e)),K(`click`,Y,ie),g(e,oe),W()}H([`click`]);function oy(e){return e instanceof se?sy(sy(e.body)?.error)?.code===`FITTING_CANCELLED`:sy(e)?.code===`FITTING_CANCELLED`}function sy(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}var cy=I(`

            loading…

            `),ly=I(`

            no templates yet

            `),uy=I(` `),dy=I(`

            slot · values × contexts

            `),fy=I(` `,1),py=I(` `),my=I(`hosted browser limit · dimensions`),hy=I(`
            `,1),gy=I(`

            template

            `);function _y(t,r){n(r,!0);let i=ae(),o=V(wv(i)),s=J(V([])),l=J(!0),u=J(``),d=J(null),m=J(!0),h=J(!1),_=J(!1),v=J(!1),y=J(``),b=J(null),x=J(null),C=J(null),w=J(null),E=J(!1),D=J(!1),O=re(),k=St.mode!==`http`;ne(async()=>{try{A(s,(await Dt.list()).templates,!0)}catch(e){Z(`couldn't load templates: ${te(e)}`,{kind:`error`})}finally{A(l,!1)}});let j=c(()=>B(s).map(e=>({value:`${e.namespace}/${e.name}`,label:`${e.namespace}/${e.name} · ${e.slot} · ${e.n_values}×${e.n_contexts}`}))),M=c(()=>B(s).find(e=>`${e.namespace}/${e.name}`===B(u))??null),N=c(()=>{let e=[];xv(r.identity.name)||e.push(`name required`),B(M)||e.push(`template required`);let t=Ev(B(d),i);return t&&e.push(t),{ok:e.length===0,messages:e}}),P=c(()=>B(v)&&!B(M)?`Choose a template.`:null),F=c(()=>B(v)?Ev(B(d),i):null);Ce(()=>{let e=B(x)?.querySelector(`button`);e&&(B(P)?(e.setAttribute(`aria-invalid`,`true`),e.setAttribute(`aria-describedby`,`templated-source-error`)):(e.removeAttribute(`aria-invalid`),e.removeAttribute(`aria-describedby`)))}),Ce(()=>{let e=B(C)?.querySelector(`input`);e&&(B(F)?(e.setAttribute(`aria-invalid`,`true`),e.setAttribute(`aria-describedby`,`templated-max-dim-error`)):(e.removeAttribute(`aria-invalid`),e.removeAttribute(`aria-describedby`)))});function I(){return(B(b)?.closest(`.mb-form`))?.querySelector(`:scope > .grid2 > .field:nth-child(2) input`)??null}async function L(){if(await xe(),!xv(r.identity.name)){I()?.focus();return}if(B(P)){(B(x)?.querySelector(`button`)??B(w))?.focus();return}B(F)&&(A(h,!0),await xe(),B(C)?.querySelector(`input`)?.focus())}function ee(){it(),rt(`template_lab`,{tab:`build`})}async function z(){if(!(!O||!B(E)||B(D))){A(D,!0),A(y,`Cancelling fit…`);try{await O.cancelFitting()}catch(e){Z(`Couldn't cancel the fit: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{A(D,!1)}}}async function ie(){if(B(_))return;if(A(v,!0),!B(N).ok||!B(M)){await L();return}A(_,!0),A(y,`Starting authoring…`);let{namespace:e,name:t,description:n}=Sv(r.identity),i={};B(d)!==null&&B(d)>=1&&(i.max_dim=B(d));let a={namespace:e,name:t,description:n,fit_mode:o.fitMode,template_ref:`${B(M).namespace}/${B(M).name}`,hyperparams:i},s=Z(`authoring ${e}/${t}…`,{kind:`info`,ttlMs:null});try{if(await Et.createFromTemplate(a),Xe(s),B(m)){let n=Z(`fitting ${e}/${t}…`,{kind:`info`,ttlMs:null});A(y,`Starting fit…`),A(E,!0);try{await At(e,t,{fit_mode:o.fitMode,hyperparams:i},e=>{if(e.event!==`progress`)return;let t=e.data&&typeof e.data==`object`?e.data.message:null;t&&(A(y,t,!0),Ye(n,{detail:t}))}),Xe(n),Z(`fit ${e}/${t} (${o.fitMode})`,{kind:`info`})}catch(r){Xe(n),oy(r)?Z(`Fit cancelled. ${e}/${t} was kept and can be fitted later.`,{kind:`info`}):Z(`Couldn't fit the manifold: ${te(r)}`,{kind:`error`,ttlMs:null})}finally{A(E,!1),A(D,!1)}}else Z(`Created ${e}/${t}. Open Manifolds to fit it.`,{kind:`info`});await yr(),r.oncomplete?r.oncomplete():(it(),rt(`manifolds`))}catch(e){Xe(s),Z(`Couldn't create the manifold: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{A(_,!1),A(y,``)}}var oe=gy(),H=R(oe),se=X(R(H),2),ce=e=>{g(e,cy())},le=e=>{g(e,ly())},ue=e=>{var t=fy(),n=q(t),r=X(R(n),2);{let e=c(()=>[{value:``,label:`Choose a template`},...B(j)]);hu(r,{get value(){return B(u)},get options(){return B(e)},ariaLabel:`Template`,onchange:e=>{A(u,String(e),!0)}})}var i=X(r,2),o=e=>{var t=uy(),n=R(t,!0);f(t),U(()=>G(n,B(P))),g(e,t)};p(i,e=>{B(P)&&e(o)}),f(n),a(n,e=>A(x,e),()=>B(x));var s=X(n,2),l=e=>{var t=dy(),n=X(R(t)),r=R(n,!0);f(n);var i=X(n,2),a=R(i,!0);f(i);var o=X(i,2),s=R(o,!0);f(o),T(),f(t),U(()=>{G(r,B(M).slot),G(a,B(M).n_values),G(s,B(M).n_contexts)}),g(e,t)};p(s,e=>{B(M)&&e(l)}),g(e,t)};p(se,e=>{B(l)?e(ce):B(s).length===0?e(le,1):e(ue,-1)});var de=X(se,2);a(de,e=>A(w,e),()=>B(w)),f(H);var fe=X(H,2);bv(fe,{get tuning(){return o},get linearOnly(){return k},onchange:e=>o.fitMode=e});var pe=X(fe,2);iv(pe,{get expanded(){return B(h)},set expanded(e){A(h,e,!0)},children:(e,t)=>{var n=hy(),r=q(n),o=X(R(r),2);{let e=c(()=>i??void 0),t=c(()=>i===null?`auto`:`auto · max ${i}`);$f(o,{get value(){return B(d)},min:1,get max(){return B(e)},step:1,allowEmpty:!0,get placeholder(){return B(t)},oninput:e=>{A(d,e,!0)}})}var s=X(o,2),l=e=>{var t=py(),n=R(t,!0);f(t),U(()=>G(n,B(F))),g(e,t)},u=e=>{var t=my(),n=X(R(t)),r=R(n,!0);f(n),T(),f(t),U(()=>G(r,i)),g(e,t)};p(s,e=>{B(F)?e(l):i!==null&&e(u,1)}),f(r),a(r,e=>A(C,e),()=>B(C));var h=X(r,2);tv(R(h),{label:`fit now`,get checked(){return B(m)},set checked(e){A(m,e,!0)}}),f(h),g(e,n)},$$slots:{default:!0}});var me=X(pe,2),he=R(me,!0);f(me);var ge=X(me,2);{let e=c(()=>B(v)?B(N).messages:[]);sv(ge,{verb:`building`,get messages(){return B(e)}})}var _e=X(ge,2),ve=R(_e),ye=t=>{Du(t,{variant:`ghost`,get disabled(){return B(D)},onclick:z,children:(t,n)=>{T();var r=e();U(()=>G(r,B(D)?`cancelling…`:`cancel`)),g(t,r)},$$slots:{default:!0}})};p(ve,e=>{O&&B(E)&&e(ye)});var be=X(ve,2),Se=R(be,!0);f(be),f(_e),f(oe),a(oe,e=>A(b,e),()=>B(b)),U(()=>{S(oe,`aria-busy`,B(_)),G(he,B(y)),be.disabled=B(_),G(Se,B(_)?`building…`:B(m)?`build + fit`:`build`)}),K(`click`,de,ee),K(`click`,be,ie),g(t,oe),W()}H([`click`]);var vy=I(`

            Create a concept or scale

            `);function yy(e,t){n(t,!0);let r=c(()=>t.params?.returnToToken),i=J(V(De(()=>t.params?.mode===`discover`?`discover`:`authored`))),a=St.mode!==`http`,o=V({namespace:`local`,name:``,description:``});function l(){if(B(r)){rt(`token_drilldown`,B(r));return}it(),rt(`manifolds`)}function u(){let{namespace:e,name:t}=Sv(o),n=nr.catalog.find(n=>n.namespace===e&&n.name===t),i=n?.resolved_fit_mode??n?.fit_mode;rt(i===`spectral`||i===`authored`?`manifolds`:`subspace`,{returnToToken:B(r)})}var d=vy(),m=R(d);ft(X(R(m),2),{onclick:l}),f(m);var h=X(m,2),_=R(h);{let e=c(()=>[{value:`discover`,label:a?`linear`:`auto`},{value:`templated`,label:`template`},{value:`authored`,label:`custom`}]);N_(_,{get tabs(){return B(e)},ariaLabel:`Authoring mode`,get value(){return B(i)},set value(e){A(i,e,!0)}})}var v=X(_,2),y=R(v),b=X(R(y),2);s(b),f(y);var x=X(y,2),S=X(R(x),2);s(S),f(x),f(v);var C=X(v,2),w=X(R(C),2);s(w),f(C);var T=X(C,2),E=e=>{{let t=c(()=>B(r)?u:void 0);qv(e,{get identity(){return o},get oncomplete(){return B(t)}})}},D=e=>{{let t=c(()=>B(r)?u:void 0);ay(e,{get identity(){return o},get oncomplete(){return B(t)}})}},O=e=>{{let t=c(()=>B(r)?u:void 0);_y(e,{get identity(){return o},get oncomplete(){return B(t)}})}};p(T,e=>{B(i)===`authored`?e(E):B(i)===`discover`?e(D,1):e(O,-1)}),f(h),f(d),j(b,()=>o.namespace,e=>o.namespace=e),j(S,()=>o.name,e=>o.name=e),j(w,()=>o.description,e=>o.description=e),g(e,d),W()}var by=I(``),xy=I(`

            Evidence details

            Homology over two coefficient fields helps distinguish orientable surfaces from non-orientable ones.

            Betti numbers (mod 2)
            Betti numbers (mod 3)
            Relative persistence
            `),Sy=I(`

            Paste a JSON array with 32–384 distinct points in 2–1,024 dimensions. Use synthetic Euclidean coordinates; model activations require whitening first.

            `,1),Cy=I(`

            Available in the native Python app

            This browser release cannot inspect topology or steer on Klein bottles and RP² yet. Open Drowse’s native dashboard to use these tools.

            Surface inspection also needs the drowse[topology] Python extra. No language model is needed for the inspection itself.

            `),wy=I(`

            Surface geometry

            Inspect a sampled surface, then author coordinates separately to steer on it.

            What can be identified?

            Spheres, tori, Klein bottles, and real projective planes. Sparse, noisy, or very thin surfaces may remain unresolved.

            A match is evidence of topology, not proof that the samples form a closed surface. It does not recover a steering chart.

            `);function Ty(t,r){n(r,!0);let i=St.mode===`http`&&!!Et.inspectSurface,o=J(``),s=J(!1),c=J(``),l=J(null),u=J(void 0),d=J(void 0),m=0;Pe(()=>{m++});function h(){m++,A(l,null),A(c,``)}async function _(e){if(e.preventDefault(),B(s)||!i||!Et.inspectSurface)return;A(l,null),A(c,``);let t;try{t=Z_(B(o))}catch(e){A(c,e.message,!0),await xe(),B(u)?.focus();return}let n=m;A(s,!0);try{let e=await Et.inspectSurface(t);if(m!==n)return;A(l,e,!0),await xe(),B(d)?.focus(),B(d)?.scrollIntoView({block:`start`})}catch(e){m===n&&A(c,te(e),!0)}finally{A(s,!1)}}var v=wy(),y=R(v);ft(X(R(y),2),{get onclick(){return it}}),f(y);var b=X(y,2),x=X(R(b),4),C=t=>{var n=Sy(),r=q(n),i=X(R(r),4);_e(i),a(i,e=>A(u,e),()=>B(u));var m=X(i,2),v=R(m);Du(v,{get disabled(){return B(s)},onclick:()=>{A(o,JSON.stringify(Q_()),!0),h()},children:(t,n)=>{T(),g(t,e(`Use sphere example`))},$$slots:{default:!0}}),Du(X(v,2),{variant:`solid`,type:`submit`,get disabled(){return B(s)},children:(t,n)=>{T();var r=e();U(()=>G(r,B(s)?`Inspecting…`:`Inspect surface`)),g(t,r)},$$slots:{default:!0}}),f(m);var y=X(m,2),b=R(y,!0);f(y);var x=X(y,2),C=e=>{var t=by(),n=R(t,!0);f(t),U(()=>G(n,B(c))),g(e,t)};p(x,e=>{B(c)&&e(C)}),f(r);var w=X(r,2),E=e=>{var t=xy(),n=R(t),r=R(n,!0);f(n);var i=X(n,2),o=R(i,!0);f(i),a(i,e=>A(d,e),()=>B(d));var s=X(i,2),c=R(s,!0);f(s);var u=X(s,2),p=R(u);f(u);var m=X(u,2),h=X(R(m),4),_=X(R(h)),v=R(_,!0);f(_);var y=X(_,3),b=R(y,!0);f(y);var x=X(y,3),S=R(x);f(x),f(h),f(m),f(t),U((e,t,n,i)=>{G(r,B(l).candidate?`Topology suggestion`:`No reliable match`),G(o,e),G(c,B(l).reason),G(p,`${B(l).sample_count??``} points inspected · No steering coordinates recovered`),G(v,t),G(b,n),G(S,`${i??``} · not a confidence probability`)},[()=>Y_(B(l).candidate),()=>B(l).betti_mod2?.join(`, `)??`Not resolved`,()=>B(l).betti_mod3?.join(`, `)??`Not resolved`,()=>B(l).relative_persistence?.toFixed(3)??`Not available`]),g(e,t)};p(w,e=>{B(l)&&e(E)}),Du(X(w,2),{onclick:()=>rt(`manifold_builder`),children:(t,n)=>{T(),g(t,e(`Create a manifold with coordinates`))},$$slots:{default:!0}}),U(e=>{i.readOnly=B(s),S(i,`aria-invalid`,e),S(i,`aria-describedby`,`surface-input-help${B(c)?` surface-error`:``}`),G(b,B(s)?`Computing surface evidence locally. This can take a minute; generation is unchanged.`:``)},[()=>!!B(c)]),ye(`submit`,r,_),K(`input`,i,h),j(i,()=>B(o),e=>A(o,e)),g(t,n)},w=e=>{g(e,Cy())};p(x,e=>{i?e(C):e(w,-1)}),f(b),f(v),g(t,v),W()}H([`input`]);var Ey=I(`

            Create or download at least two learned response controls first.

            `),Dy=I(`
          • `),Oy=I(`

            `),ky=I(` Combining…`,1),Ay=I(`
            Response controls (choose at least two)
              `),jy=I(`

              Combine response controls

              `);function My(t,r){n(r,!0),k(r,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{r.params});function i(e){return`${e.namespace}/${e.name}`}function a(e){return e.fit_mode===`pca`||e.fit_mode===`spectral`||e.fit_mode===`auto`}let o=new gt,l=J(``),u=J(``),d=J(!1),h=c(()=>nr.catalog.filter(e=>a(e)));function _(e){o.has(e)?o.delete(e):o.add(e)}let v=c(()=>{let e=new Set;for(let t of o){let n=nr.catalog.find(e=>i(e)===t);n&&n.fit_mode&&e.add(n.fit_mode)}return[...e].sort()}),y=c(()=>!B(d)&&o.size>=2&&B(l).trim().length>0&&(B(v).length<=1||B(u)!==``));async function b(e){e.preventDefault();let t=B(l).trim();if(o.size<2){Z(`pick >= 2 discover manifolds to merge`,{kind:`error`});return}if(!t){Z(`target name required`,{kind:`error`});return}let n=[...o].map(e=>{let[t,n]=e.split(`/`);return{namespace:t,name:n}});A(d,!0);let r=Z(`merging ${n.length} manifolds into '${t}'…`,{kind:`info`,ttlMs:null});try{await Et.merge({name:t,sources:n,fit_mode:B(u)||void 0}),await yr(),Xe(r),Z(`Merged into local/${t}. Fit the merged manifold next.`,{kind:`info`}),it()}catch(e){Xe(r),Z(`Couldn't merge the manifolds: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{A(d,!1)}}ne(()=>{yr()});var x=jy(),C=R(x);ft(X(R(C),2),{get onclick(){return it}}),f(C);var w=X(C,2),E=R(w),D=e=>{g(e,Ey())},O=t=>{var n=Ay(),r=R(n),a=X(R(r),2);m(a,21,()=>B(h),e=>i(e),(e,t)=>{let n=c(()=>i(B(t)));var r=Dy(),a=R(r),l=R(a);s(l);var u=X(l,2),p=R(u,!0);f(u);var m=X(u,2),h=R(m);f(m),f(a),f(r),U(e=>{me(l,e),l.disabled=B(d),G(p,B(n)),G(h,`${B(t).domain_label??``} · ${B(t).node_count??``} nodes · - ${B(t).fit_mode??``}`)},[()=>o.has(B(n))]),K(`change`,l,()=>_(B(n))),g(e,r)}),f(a),f(r);var x=X(r,2),C=X(R(x),2);s(C),f(x);var w=X(x,2),E=X(R(w),2);{let e=c(()=>B(d)||o.size===0),t=c(()=>[...B(v).length<=1?[{value:``,label:`Match the source (${B(v)[0]??`automatic`})`}]:[],{value:`pca`,label:`pca`},{value:`spectral`,label:`spectral`}]);hu(E,{ariaLabel:`Combined response control layout method`,get disabled(){return B(e)},get options(){return B(t)},get value(){return B(u)},set value(e){A(u,e,!0)}})}f(w);var D=X(w,2),O=e=>{var t=Oy(),n=R(t);f(t),U(e=>G(n,`The selected controls use different layout methods: ${e??``}.`),[()=>B(v).join(`, `)]),g(e,t)};p(D,e=>{B(v).length>1&&e(O)});var k=X(D,2),M=R(k),N=X(M,2),P=R(N),F=e=>{var t=ky();Be(q(t),{name:`refresh`,spin:!0}),T(),g(e,t)},I=t=>{var n=e();U(()=>G(n,`Combine ${o.size??``} controls`)),g(t,n)};p(P,e=>{B(d)?e(F):e(I,-1)}),f(N),f(k),f(n),U(e=>{C.disabled=B(d),N.disabled=!B(y),S(N,`title`,e)},[()=>o.size<2?`Choose at least two response controls`:B(l).trim()?`Combine controls`:`Enter a name for the combined control`]),ye(`submit`,n,b),j(C,()=>B(l),e=>A(l,e)),K(`click`,M,function(...e){it?.apply(this,e)}),g(t,n)};p(E,e=>{B(h).length<2?e(D):e(O,-1)}),f(w),f(x),g(t,x),W()}H([`change`,`click`]);var Ny=I(``),Py=I(``),Fy=I(`

              `),Iy=I(`

              `),Ly=I(``),Ry=I(``),zy=I(`

              loading portable packs…

              `),By=I(` `,1),Vy=I(``),Hy=I(`
            • Publisher unverified
            • `),Uy=I(`
                `),Wy=I(`

                Portable control files

                Checksums verify archive integrity, not the publisher’s identity.

                `),Gy=I(`

                loading manifolds…

                `),Ky=I(`

                `),qy=I(` `),Jy=I(`fitted`),Yy=I(`stale`),Xy=I(`
              • `),Zy=I(`
                  `),Qy=I(` `,1),$y=I(`

                  Only public, browser-compatible Drowse packs appear here.

                  `),eb=I(`

                  searching…

                  `),tb=I(``),nb=I(`

                  `),rb=I(` `),ib=I(` `),ab=I(` `),ob=I(`
                • `),sb=I(`
                    `),cb=I(``),lb=I(`

                    Downloaded response controls

                    `);function ub(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let r=J(`installed`),i=J(``),o=J(V([])),l=J(!1),u=J(null),d=J(null),h=J(null),_=St.mode!==`http`,v=We(`manifold_artifacts`),b=!_||v.available,x=J(null),C=J(null),E=J(V([])),D=J(!1),O=J(null),M=J(null),N=J(null),P=J(null),F=J(null),I=null;function L(){I&&clearTimeout(I);let e=B(i).trim();if(!e){A(o,[],!0),A(u,null),A(l,!1);return}A(l,!0),I=setTimeout(()=>{ee(e)},300)}async function ee(e){try{A(o,(await Et.search(e,20)).results??[],!0),A(u,null)}catch(e){A(o,[],!0),e instanceof se?e.status===503?A(u,_?`Hugging Face search is unavailable. Check your connection and try again.`:'huggingface_hub isn\'t installed on the server. Run `pip install -e ".[serve]"` and restart.',!0):e.status===502?A(u,je(e,`Hugging Face search was interrupted. Check your connection and try again.`),!0):A(u,je(e,`Unable to search Hugging Face. Try again.`),!0):A(u,je(e,`Unable to search Hugging Face. Try again.`),!0)}finally{A(l,!1)}}async function te(e){let t=typeof e.repository==`string`?e.repository:`${e.namespace}/${e.name}`,n=le(e),i=typeof e.revision==`string`?`${t}@${e.revision}`:t;A(d,n,!0),A(h,null);try{let e=await jt({target:i},e=>{if(e.event===`progress`){let t=e.data;t?.message?A(h,t.message,!0):t?.phase===`downloading`&&t.downloadedBytes!==void 0?A(h,`Downloading ${`${(t.downloadedBytes/1e6).toFixed(1)} MB`}${t.totalBytes?` of ${(t.totalBytes/1e6).toFixed(1)} MB`:``}`):t?.phase&&A(h,`${t.phase[0].toUpperCase()}${t.phase.slice(1)} archive`)}});await yr(),A(r,`installed`),Z(`installed ${e.namespace}/${e.name}`,{kind:`info`})}catch(e){e instanceof se?e.status===503?Z(_?`Hugging Face install is unavailable. Check your connection and try again.`:`huggingface_hub isn't installed on the server`,{kind:`error`,ttlMs:null}):e.status===502?Z(je(e,`The Hugging Face download was interrupted. Check your connection and try again.`),{kind:`error`,ttlMs:null}):e.status===409?Z(`${n} is already installed`,{kind:`error`,ttlMs:null}):Z(je(e,`Unable to install ${n}. Check the pack and try again.`),{kind:`error`,ttlMs:null}):Z(je(e,`Unable to install ${n}. Check the pack and try again.`),{kind:`error`,ttlMs:null})}finally{A(d,null),A(h,null)}}async function z(){if(!(!_||!v.available)){A(D,!0);try{A(E,(await Et.drowseArchiveList()).packs,!0),A(M,null)}catch(e){A(M,oe(e),!0)}finally{A(D,!1)}}}async function re(e,t=!1){if(!e.name.toLowerCase().endsWith(`.drowse`)){A(M,`Choose a .drowse file.`);return}A(O,`import`),A(M,null),A(N,`Inspecting archive`);try{let n=await Et.drowseArchiveInstall(e,{force:t},e=>{if(!e.data||typeof e.data!=`object`)return;let t=e.data;A(N,t.path?`${t.phase??`Verifying`}: ${t.path}`:t.phase??`Verifying archive`,!0)});A(P,null),await z(),await yr(),Z(`installed ${n.namespace}/${n.name}`,{kind:`info`})}catch(n){let r=oe(n);A(M,r,!0),A(P,/already installed/i.test(r)&&!t?e:null,!0)}finally{A(O,null),A(N,null)}}async function ie(e){A(O,`export:${e.id}`),A(M,null);try{let t=await Et.drowseArchiveExport(e.id),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`${e.name}.drowse`,r.click(),setTimeout(()=>URL.revokeObjectURL(n),0)}catch(e){A(M,oe(e),!0)}finally{A(O,null)}}async function ae(e){let t=V_(e,B_(e,nr.entries,Hr.entries));if(t){A(M,t,!0);return}A(O,`delete:${e.id}`),A(M,null);try{await Et.drowseArchiveDelete(e.id),A(F,null),await z(),await yr()}catch(e){A(M,oe(e),!0)}finally{A(O,null)}}function oe(e){return je(e,`Unable to update local direction packs. Check the file and try again.`)}function H(e,t=!1){A(r,e,!0),t&&queueMicrotask(()=>{B(e===`installed`?x:C)?.focus()})}function ce(e){if(!b)return;let t=null;e.key===`ArrowLeft`||e.key===`ArrowRight`?t=B(r)===`installed`?`search`:`installed`:e.key===`Home`?t=`installed`:e.key===`End`&&(t=`search`),t!==null&&(e.preventDefault(),H(t,!0))}function le(e){return`repository`in e&&typeof e.repository==`string`?e.repository:`${e.namespace}/${e.name}`}function ue(e){return e.fit_mode&&e.fit_mode!==`authored`?e.fit_mode:null}ne(()=>{yr(),z()});var de=lb(),fe=R(de);ft(X(R(fe),2),{get onclick(){return it}}),f(fe);var pe=X(fe,2),me=R(pe);let he;a(me,e=>A(x,e),()=>B(x));var ge=X(me,2),_e=e=>{var t=Ny();let n;a(t,e=>A(C,e),()=>B(C)),U(()=>{S(t,`aria-selected`,B(r)===`search`),S(t,`tabindex`,B(r)===`search`?0:-1),n=y(t,1,`svelte-lozhsl`,null,n,{active:B(r)===`search`})}),K(`click`,t,()=>H(`search`)),K(`keydown`,t,ce),g(e,t)};p(ge,e=>{b&&e(_e)}),f(pe),w(pe,e=>Ac?.(e));var ve=X(pe,2),ye=R(ve),be=e=>{var t=Qy(),n=q(t),r=e=>{var t=Wy(),n=R(t),r=X(R(n),2),i=e=>{var t=Py();let n;var r=R(t),i=R(r,!0);f(r);var a=X(r,2);f(t),U(()=>{n=y(t,1,`file-action svelte-lozhsl`,null,n,{disabled:B(O)!==null}),G(i,B(O)===`import`?`verifying…`:`import pack`),a.disabled=B(O)!==null}),K(`change`,a,e=>{let t=e.currentTarget,n=t.files?.[0];n&&re(n),t.value=``}),g(e,t)};p(r,e=>{v.available&&e(i)}),f(n);var a=X(n,2),o=e=>{var t=Fy(),n=R(t,!0);f(t),U(()=>G(n,v.reason)),g(e,t)},s=e=>{var t=Iy(),n=R(t,!0);f(t),U(()=>G(n,B(N))),g(e,t)};p(a,e=>{v.available?B(N)&&e(s,1):e(o)});var c=X(a,2),l=e=>{var t=Ly(),n=R(t,!0);f(t),U(()=>G(n,B(M))),g(e,t)};p(c,e=>{v.available&&B(M)&&e(l)});var u=X(c,2),d=e=>{var t=Ry(),n=X(R(t),2),r=X(n,2);f(t),U(()=>{n.disabled=B(O)!==null,r.disabled=B(O)!==null}),K(`click`,n,()=>void re(B(P),!0)),K(`click`,r,()=>A(P,null)),g(e,t)};p(u,e=>{v.available&&B(P)&&e(d)});var h=X(u,2),_=e=>{g(e,zy())},b=e=>{var t=Uy();m(t,21,()=>B(E),e=>e.id,(e,t)=>{var n=Hy(),r=R(n),i=R(r),a=R(i);f(i);var o=X(i,2),s=R(o,!0);f(o),T(2),f(r);var c=X(r,2),l=R(c),u=X(l,2),d=e=>{var n=By(),r=q(n),i=R(r);f(r);var a=X(r,2),o=X(a,2);U(()=>{G(i,`Delete ${B(t).namespace??``}/${B(t).name??``} from this device? Export a backup first if you want to keep it.`),a.disabled=B(O)!==null,o.disabled=B(O)!==null}),K(`click`,a,()=>void ae(B(t))),K(`click`,o,()=>A(F,null)),g(e,n)},m=e=>{var n=Vy();U(()=>n.disabled=B(O)!==null),K(`click`,n,()=>A(F,B(t).id,!0)),g(e,n)};p(u,e=>{B(F)===B(t).id?e(d):e(m,-1)}),f(c),f(n),U(()=>{G(a,`${B(t).namespace??``}/${B(t).name??``}`),G(s,B(t).source.repository?`${B(t).source.repository}@${B(t).source.revision}`:B(t).source.uri),l.disabled=B(O)!==null}),K(`click`,l,()=>void ie(B(t))),g(e,n)}),f(t),g(e,t)};p(h,e=>{v.available&&B(D)?e(_):v.available&&B(E).length>0&&e(b,1)}),f(t),g(e,t)};p(n,e=>{_&&e(r)});var i=X(n,2),a=e=>{g(e,Gy())},o=e=>{var t=Ky(),n=R(t,!0);f(t),U(()=>G(n,v.available?_?`No manifolds installed. Import a .drowse or search Hugging Face.`:`No manifolds installed. Search Hugging Face to find compatible sources.`:`No manifolds installed.`)),g(e,t)},s=e=>{var t=Zy();m(t,21,()=>nr.catalog,e=>le(e),(e,t)=>{let n=c(()=>le(B(t))),r=c(()=>ue(B(t)));var i=Xy(),a=R(i),o=R(a),s=R(o,!0);f(o);var l=X(o,2),u=R(l),d=X(u),m=e=>{var t=qy(),n=R(t,!0);f(t),U(()=>{y(t,1,`fit-badge fit-${B(r)??``}`,`svelte-lozhsl`),G(n,B(r))}),g(e,t)};p(d,e=>{B(r)&&e(m)});var h=X(d,2),_=e=>{g(e,Jy())};p(h,e=>{B(t).fitted_for_session&&e(_)});var v=X(h,2),b=e=>{g(e,Yy())};p(v,e=>{B(t).stale&&e(b)}),f(l),f(a),f(i),U(()=>{S(i,`title`,B(t).description||B(n)),G(s,B(n)),G(u,`${B(t).domain_label??``} · ${B(t).node_count??``} nodes `)}),g(e,i)}),f(t),g(e,t)};p(i,e=>{nr.loading&&nr.catalog.length===0?e(a):nr.catalog.length===0?e(o,1):e(s,-1)}),g(e,t)},xe=e=>{var t=cb(),n=R(t),r=X(R(n),2);s(r),f(n);var a=X(n,2),_=e=>{g(e,$y())},v=c(()=>!B(i).trim()),b=e=>{g(e,eb())},x=e=>{var t=tb(),n=R(t,!0);f(t),U(()=>G(n,B(u))),g(e,t)},C=e=>{var t=nb(),n=R(t);f(t),U(e=>G(n,`No Hugging Face packs match “${e??``}”. Try a different search.`),[()=>B(i).trim()]),g(e,t)},w=e=>{var t=sb();m(t,21,()=>B(o),e=>le(e),(e,t)=>{let n=c(()=>le(B(t))),r=c(()=>B(d)===B(n)),i=c(()=>ue(B(t)));var a=ob(),o=R(a),s=R(o),l=R(s,!0);f(s);var u=X(s,2),m=R(u),_=X(m),v=e=>{var t=rb(),n=R(t,!0);f(t),U(()=>{y(t,1,`fit-badge fit-${B(i)??``}`,`svelte-lozhsl`),G(n,B(i))}),g(e,t)};p(_,e=>{B(i)&&e(v)});var b=X(_,2),x=e=>{var n=ib(),r=R(n);f(n),U(()=>G(r,`· ${B(t).tensor_models.length??``} fit${B(t).tensor_models.length===1?``:`s`}`)),g(e,n)};p(b,e=>{B(t).tensor_models.length>0&&e(x)}),f(u);var C=X(u,2),w=e=>{var t=ab(),n=R(t,!0);f(t),U(()=>G(n,B(h))),g(e,t)};p(C,e=>{B(r)&&B(h)&&e(w)}),f(o);var T=X(o,2),E=R(T),D=R(E,!0);f(E),f(T),f(a),U(()=>{S(a,`title`,B(t).description||B(n)),G(l,B(n)),G(m,`${B(t).domain_label??``} · ${B(t).node_count??``} nodes `),E.disabled=B(r),S(E,`title`,`install ${B(n)}`),G(D,B(r)?`…`:`install`)}),K(`click`,E,()=>void te(B(t))),g(e,a)}),f(t),g(e,t)};p(a,e=>{B(v)?e(_):B(l)?e(b,1):B(u)?e(x,2):B(o).length===0?e(C,3):e(w,-1)}),f(t),K(`input`,r,L),j(r,()=>B(i),e=>A(i,e)),g(e,t)};p(ye,e=>{B(r)===`installed`?e(be):e(xe,-1)}),f(ve),f(de),U(()=>{S(me,`aria-selected`,B(r)===`installed`),S(me,`tabindex`,B(r)===`installed`?0:-1),he=y(me,1,`svelte-lozhsl`,null,he,{active:B(r)===`installed`}),S(ve,`aria-labelledby`,B(r)===`installed`?`packs-tab-installed`:`packs-tab-search`)}),K(`click`,me,()=>H(`installed`)),K(`keydown`,me,ce),g(e,de),W()}H([`click`,`keydown`,`change`,`input`]);var db=I(`

                    select ≥2 generated nodes in Threads

                    `),fb=I(`

                    Comparing replies…

                    `),pb=I(`

                    `),mb=I(` `),hb=I(`
                    siblings
                    tagpreviewmean lprk1 unchangedmean ≈KL
                    `),gb=I(``),_b=I(` `),vb=I(` `),yb=I(` `),bb=I(` `),xb=I(` `),Sb=I(`
                    A
                    `),Cb=I(`+`),wb=I(``),Tb=I(` `),Eb=I(`
                    `),Db=I(`

                    Computing token probabilities…

                    `),Ob=I(``),kb=I(`

                    `),Ab=I(` `),jb=I(`
                    logprobs
                    postokenlp(A)lp(B)Δ lp(A)≈KLrk1Δ
                    `),Mb=I(`

                    no aligned tokens

                    `),Nb=I(`
                    `),Pb=I(`
                    Δ readings
                    `),Fb=I(`

                    no readings

                    `),Ib=I(`
                    `),Lb=I(`
                    A · anchor

                    `,1),Rb=I(`

                    Compare conversation branches

                    `);function zb(t,r){n(r,!0);let i=c(()=>{let e=r.params??Ze.params??{};return Array.isArray(e.node_ids)?e.node_ids.filter(Boolean):[]}),a=c(()=>B(i)[0]??null),o=J(V([])),s=J(V([])),l=J(!1),u=J(null),d=J(`side-by-side`),h=J(`magnitude`);async function _(){let e=B(i);if(e.length<2||!B(a)){A(o,[],!0),A(s,[],!0);return}A(l,!0);let t=Ot.replayCapabilities().catch(e=>({jointLogprobs:{available:!1,reason:je(e,`Token likelihood replay is unavailable in this runtime.`)}})),n=[];try{for(let t=1;t({kind:`unavailable`,message:n})),!0);return}A(s,t.slice(1).map(()=>({kind:`loading`})),!0);let n=[];for(let e=1;e{B(i),_()}),ne(()=>()=>{Ba()});function b(e){let t=(Q.nodes.get(e)?.text??``).replace(/\s+/g,` `).trim();return t?t.length>80?t.slice(0,80)+`…`:t:`(empty)`}function x(e){let t=[...e];return B(h)===`magnitude`?t.sort((e,t)=>Math.abs(t.delta)-Math.abs(e.delta)):t.sort((e,t)=>e.name.localeCompare(t.name)),t}function C(e,t=5){let n=[...e].sort((e,t)=>Math.abs(t.delta)-Math.abs(e.delta));return new Set(n.slice(0,t).map(e=>e.name))}function w(e){return e.filter(e=>e.a_index>=0)}function E(e){return e.filter(e=>e.b_index>=0)}function D(e){return`${e.delta>=0?`+`:``}${e.delta.toFixed(3)}`}function O(e){return e===0?`var(--fg-muted)`:e>=0?`var(--accent-green)`:`var(--accent-red)`}function k(e){return e===`insert`?`color-mix(in srgb, var(--accent-green) 18%, transparent)`:e===`delete`?`color-mix(in srgb, var(--accent-red) 18%, transparent)`:`transparent`}function j(e){return e.split(/(\s+)/)}function M(e){return!e.reading_deltas||e.reading_deltas.length===0?``:e.reading_deltas.slice(0,3).map(e=>`${e.name} ${D(e)}`).join(` · `)}function P(e){return e==null||!Number.isFinite(e)?`-`:e.toFixed(2)}function F(e,t){if(e==null||t==null||!Number.isFinite(e)||!Number.isFinite(t))return`-`;let n=e-t;return`${n>=0?`+`:``}${n.toFixed(2)}`}function I(e){return e==null||!Number.isFinite(e)?`-`:Math.abs(e)<.01?e.toExponential(1):e.toFixed(2)}function ee(e){return e.filter(e=>e.aligned)}let te=c(()=>{if(B(i).length<2)return[];let e=[];for(let t=0;t0){o.rank1Unchanged=1-e.data.n_rank1_changed/t.length;let n=0,r=0;for(let e of t)e.approx_kl!=null&&Number.isFinite(e.approx_kl)&&(n+=e.approx_kl,r+=1);o.klMean=r>0?n/r:null}o.jointReady=!0}else (e.kind===`err`||e.kind===`unavailable`)&&(o.jointReady=!0)}e.push(o)}return e});function z(e){return e==null||!Number.isFinite(e)?`-`:`${(e*100).toFixed(0)}%`}function re(e){return e==null||!Number.isFinite(e)?`-`:Math.abs(e)<.01?e.toExponential(1):e.toFixed(3)}var ie=Rb(),ae=R(ie),oe=R(ae),H=X(R(oe),2),ce=R(H),le=R(ce),ue=t=>{var n=e();U(()=>G(n,`${B(i).length??``} branch${B(i).length===1?``:`es`} selected`)),g(t,n)},de=t=>{g(t,e(`Select branches`))};p(le,e=>{B(i).length>=2?e(ue):e(de,-1)}),f(ce),f(H),f(oe),ft(X(oe,2),{get onclick(){return it}}),f(ae);var fe=X(ae,2),me=R(fe);hu(X(R(me),2),{options:[{value:`side-by-side`,label:`side-by-side`},{value:`unified`,label:`unified`}],ariaLabel:`Layout`,get value(){return B(d)},set value(e){A(d,e,!0)}}),f(me);var he=X(me,2);hu(X(R(he),2),{options:[{value:`magnitude`,label:`|Δ| desc`},{value:`name`,label:`name`}],ariaLabel:`Sort readings by`,get value(){return B(h)},set value(e){A(h,e,!0)}}),f(he),f(fe);var ge=X(fe,2),_e=R(ge),ve=e=>{g(e,db())},be=e=>{g(e,fb())},xe=e=>{var t=Lb(),n=q(t);let r;var l=R(n),h=R(l),_=R(h),v=R(_,!0);f(_),T(2),f(h);var ne=X(h,2),V=R(ne,!0);f(ne),f(l),m(X(l,2),18,()=>B(i).slice(1),e=>e,(e,t,n)=>{var r=pb(),a=R(r),o=R(a),s=R(o,!0);f(o);var c=X(o,2),l=R(c);f(c),f(a);var u=X(a,2),d=R(u,!0);f(u),f(r),U((e,t)=>{G(s,e),G(l,`B${B(i).length>2?B(n)+1:``}`),G(d,t)},[()=>t.slice(0,12),()=>b(t)]),g(e,r)}),f(n);var ie=X(n,2),ae=e=>{var t=hb(),n=R(t),r=X(R(n),2),i=R(r);f(r),f(n);var a=X(n,2),o=X(R(a));m(o,21,()=>B(te),e=>e.nodeId,(e,t)=>{var n=mb();let r;var i=R(n),a=R(i,!0);f(i);var o=X(i),s=R(o,!0);f(o);var c=X(o),l=R(c,!0);f(c);var u=X(c),d=R(u,!0);f(u);var p=X(u),m=R(p,!0);f(p),f(n),U((e,i,o)=>{r=y(n,1,`svelte-lzsal6`,null,r,{anchor:B(t).isAnchor}),G(a,B(t).label),G(s,B(t).preview),G(l,e),G(d,i),G(m,o)},[()=>P(B(t).meanLogprob),()=>B(t).isAnchor?`-`:B(t).jointReady?z(B(t).rank1Unchanged):`…`,()=>B(t).isAnchor?`-`:B(t).jointReady?re(B(t).klMean):`…`]),g(e,n)}),f(o),f(a),f(t),U(()=>G(i,`vs ${B(te)[0]?.label??`A`??``}`)),g(e,t)};p(ie,e=>{B(te).length>0&&e(ae)}),m(X(ie,2),17,()=>B(o),N,(e,t,n)=>{var r=L(),a=q(r),o=e=>{var n=gb(),r=R(n,!0);f(n),U(()=>G(r,B(t).message)),g(e,n)},l=e=>{let r=c(()=>B(t).diff),a=c(()=>C(B(r).readings,5)),o=c(()=>x(B(r).readings)),l=c(()=>B(s)[n]);var h=Ib(),_=R(h),v=R(_),b=R(v,!0);f(v);var T=X(v,2),te=e=>{var t=_b(),n=R(t);f(t),U(()=>G(n,`Δ recipe: ${(B(r).steering_delta||`none`)??``}`)),g(e,t)};p(T,e=>{(B(r).parent_applied_steering!==null||B(r).steering_delta)&&e(te)}),f(_);var z=X(_,2),ne=e=>{let t=c(()=>w(B(r).per_token)),a=c(()=>E(B(r).per_token));var o=Sb(),s=R(o),l=X(R(s),2),d=R(l),h=e=>{var n=L();m(q(n),17,()=>B(t),e=>`a-${e.a_index}`,(e,t)=>{var n=vb();let r;var i=R(n,!0);f(n),U(e=>{r=y(n,1,`tok svelte-lzsal6`,null,r,{"highlight-anchor":B(u)===B(t).a_index}),S(n,`title`,e),G(i,B(t).a_text)},[()=>M(B(t))]),ye(`mouseenter`,n,()=>A(u,B(t).a_index,!0)),ye(`mouseleave`,n,()=>A(u,null)),g(e,n)}),g(e,n)},_=e=>{var t=L();m(q(t),17,()=>j(B(r).a_text),N,(e,t)=>{var n=yb(),r=R(n,!0);f(n),U(()=>G(r,B(t))),g(e,n)}),g(e,t)};p(d,e=>{B(t).length>0?e(h):e(_,-1)}),f(l),f(s);var v=X(s,2),b=R(v),x=R(b);f(b);var C=X(b,2),T=R(C),D=e=>{var t=L();m(q(t),17,()=>B(a),e=>`b-${e.b_index}`,(e,t)=>{let n=c(()=>B(t).a_index>=0&&B(u)!==null&&B(t).a_index===B(u));var r=bb();let i;var a=R(r,!0);f(r),U(e=>{i=y(r,1,`tok svelte-lzsal6`,null,i,{"highlight-target":B(n)}),S(r,`title`,e),G(a,B(t).b_text)},[()=>M(B(t))]),g(e,r)}),g(e,t)},O=e=>{var t=L();m(q(t),17,()=>j(B(r).b_text),N,(e,t)=>{var n=xb(),r=R(n,!0);f(n),U(()=>G(r,B(t))),g(e,n)}),g(e,t)};p(T,e=>{B(a).length>0?e(D):e(O,-1)}),f(C),f(v),f(o),U(()=>G(x,`B${B(i).length>2?n+1:``}`)),g(e,o)},V=e=>{var t=Eb();m(t,21,()=>B(r).text,N,(e,t)=>{var n=Tb();let r;var i=R(n),a=e=>{g(e,Cb())},o=e=>{g(e,wb())};p(i,e=>{B(t).state===`insert`?e(a):B(t).state===`delete`&&e(o,1)});var s=X(i);f(n),U(e=>{r=y(n,1,`tok-span svelte-lzsal6`,null,r,{"span-equal":B(t).state===`equal`,"span-insert":B(t).state===`insert`,"span-delete":B(t).state===`delete`}),pe(n,e),G(s,`${B(t).text??``} `)},[()=>`background-color: ${k(B(t).state)}`]),g(e,n)}),f(t),g(e,t)};p(z,e=>{B(d)===`side-by-side`?e(ne):e(V,-1)});var re=X(z,2),ie=e=>{var t=L(),n=q(t),r=e=>{g(e,Db())},i=e=>{var t=Ob(),n=R(t);f(t),U(()=>G(n,`logprobs: ${B(l).message??``}`)),g(e,t)},a=e=>{var t=kb(),n=R(t);f(t),U(()=>G(n,`${B(l).message??``} Branch text and saved measurements remain available.`)),g(e,t)},o=e=>{let t=c(()=>ee(B(l).data.rows));var n=L(),r=q(n),i=e=>{var n=jb(),r=R(n),i=X(R(r),2),a=R(i),o=R(a,!0);f(a);var s=X(a);f(i),f(r);var c=X(r,2),u=X(R(c));m(u,21,()=>B(t),e=>`${e.a_index}-${e.b_index}`,(e,t)=>{var n=Ab();let r;var i=R(n),a=R(i,!0);f(i);var o=X(i),s=R(o),c=R(s,!0);f(s),f(o);var l=X(o),u=R(l,!0);f(l);var d=X(l),p=R(d,!0);f(d);var m=X(d),h=R(m,!0);f(m);var _=X(m),v=R(_,!0);f(_);var b=X(_),x=R(b,!0);f(b),f(n),U((e,i,o,s,l)=>{r=y(n,1,`svelte-lzsal6`,null,r,{"rank-flip":B(t).rank_changed}),G(a,B(t).a_index),G(c,e),G(u,i),G(p,o),G(h,s),G(v,l),G(x,B(t).rank_changed?`●`:``)},[()=>JSON.stringify(B(t).a_text),()=>P(B(t).lp_a_in_a),()=>P(B(t).lp_b_in_b),()=>F(B(t).lp_a_in_b,B(t).lp_a_in_a),()=>I(B(t).approx_kl)]),g(e,n)}),f(u),f(c),f(n),U(()=>{G(o,B(l).data.n_rank1_changed),G(s,` / ${B(t).length??``} rank-1 changes`)}),g(e,n)},a=e=>{g(e,Mb())};p(r,e=>{B(t).length>0?e(i):e(a,-1)}),g(e,n)};p(n,e=>{B(l).kind===`loading`?e(r):B(l).kind===`err`?e(i,1):B(l).kind===`unavailable`?e(a,2):e(o,-1)}),g(e,t)};p(re,e=>{B(l)&&e(ie)});var ae=X(re,2),oe=e=>{var t=Pb(),n=X(R(t),2);m(n,21,()=>B(o),e=>e.name,(e,t)=>{let n=c(()=>B(a).has(B(t).name));var r=Nb();let i;var o=R(r),s=R(o,!0);f(o);var l=X(o,2),u=R(l),d=R(u,!0);f(u);var p=X(u,4),m=R(p,!0);f(p),f(l);var h=X(l,2),_=R(h);f(h);var v=X(h,2),b=R(v,!0);f(v),f(r),U((e,a,o,c,l)=>{i=y(r,1,`reading-row svelte-lzsal6`,null,i,{"top-delta":B(n)}),G(s,B(t).name),G(d,e),G(m,a),pe(_,o),pe(v,c),G(b,l)},[()=>B(t).a_value.toFixed(3),()=>B(t).b_value.toFixed(3),()=>`width: ${Math.min(100,Math.abs(B(t).delta)*100)}%; background: ${O(B(t).delta)}`,()=>`color: ${O(B(t).delta)}`,()=>D(B(t))]),g(e,r)}),f(n),f(t),g(e,t)},H=e=>{g(e,Fb())};p(ae,e=>{B(o).length>0?e(oe):e(H,-1)}),f(h),U(()=>G(b,B(i).length===2?`A vs B`:`A vs B${n+1}`)),g(e,h)};p(a,e=>{B(t).kind===`err`?e(o):e(l,-1)}),g(e,r)}),U((e,t)=>{r=y(n,1,`columns svelte-lzsal6`,null,r,{unified:B(d)===`unified`}),G(v,e),G(V,t)},[()=>B(a)?.slice(0,12)??``,()=>b(B(a)??``)]),g(e,t)};p(_e,e=>{B(i).length<2?e(ve):B(l)&&B(o).length===0?e(be,1):e(xe,-1)}),f(ge);var Se=X(ge,2);Du(R(Se),{variant:`ghost`,size:`sm`,get onclick(){return it},children:(t,n)=>{T(),g(t,e(`close`))},$$slots:{default:!0}}),f(Se),f(ie),g(t,ie),W()}function Bb(e){let t=e.querySelector(`summary`),n=null,r=e.open,i=e.style.overflow,a=e.style.boxSizing;function o(){n?.cancel(),n=null,e.style.overflow=i,e.style.boxSizing=a,t.removeAttribute(`aria-expanded`)}function s(i){if(i.target.closest(`a, button, input`))return;i.preventDefault();let a=e.getBoundingClientRect().height;r=n?!r:!e.open,o(),e.style.boxSizing=`border-box`,e.open=r;let s=e.getBoundingClientRect().height,c=$l(r?250:150);if(!c||a===s){o();return}e.open=!0,t.setAttribute(`aria-expanded`,String(r)),e.style.overflow=`clip`,n=e.animate([{height:`${a}px`},{height:`${s}px`}],{duration:c,easing:r?`cubic-bezier(0.22, 1, 0.36, 1)`:`cubic-bezier(0.4, 0, 1, 1)`}),n.onfinish=()=>{e.open=r,o()}}return t.addEventListener(`click`,s),{destroy(){t.removeEventListener(`click`,s),o()}}}function Vb(e){let t=getComputedStyle(e),n=(e,n=`transparent`)=>t.getPropertyValue(e).trim()||n;return{fg:n(`--fg-strong`),fgDim:n(`--fg-dim`),muted:n(`--fg-muted`),border:n(`--glass-line`),accent:n(`--accent`),purple:n(`--pillar-manifold`),bg:n(`--bg-deep`),node:n(`--geom-node`,n(`--pillar-manifold`)),neutral:n(`--geom-neutral`,n(`--fg-subtle`)),live:n(`--live`),light:n(`--accent-light`)}}var Hb=`560 10px "Martian Mono", ui-monospace, monospace`,Ub=`560 9px "Martian Mono", ui-monospace, monospace`,Wb=28;function Gb(e){let t=e.getContext(`2d`);if(!t)return null;let n=e.getBoundingClientRect(),r=window.devicePixelRatio||1,i=Math.max(1,Math.floor(n.width)),a=Math.max(1,Math.floor(n.height));return e.width=Math.floor(i*r),e.height=Math.floor(a*r),t.setTransform(r,0,0,r,0,0),t.lineCap=`round`,t.lineJoin=`round`,t.clearRect(0,0,i,a),{ctx:t,w:i,h:a}}function Kb(e){let t=1/0,n=-1/0,r=1/0,i=-1/0;for(let[a,o]of e)an&&(n=a),oi&&(i=o);if(!Number.isFinite(t))return{minX:-1,maxX:1,minY:-1,maxY:1};let a=n-t||1,o=i-r||1;return{minX:t-a*.08,maxX:n+a*.08,minY:r-o*.08,maxY:i+o*.08}}function qb(e,t,n){let r=t-2*Wb,i=n-2*Wb,a=Math.max(e.maxX-e.minX,e.maxY-e.minY)||1,o=Math.min(r,i)/a,s=(e.minX+e.maxX)/2,c=(e.minY+e.maxY)/2;return(e,r)=>[t/2+(e-s)*o,n/2-(r-c)*o]}function Jb(e,t,n,r,i,a=1){e.globalAlpha=a,e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fillStyle=i,e.fill(),e.globalAlpha=1}function Yb(e,t,n,r){e.globalAlpha=.95,e.beginPath(),e.arc(t,n,6.5,0,Math.PI*2),e.strokeStyle=r.live,e.lineWidth=2,e.stroke(),e.beginPath(),e.arc(t,n,3.2,0,Math.PI*2),e.fillStyle=r.light,e.fill(),e.globalAlpha=1}function Xb(e,t,n,r,i,a){e.globalAlpha=.9,e.fillStyle=i,e.font=Hb;let o=e.measureText(r).width,s=t+5+o<=a-8?t+5:Math.max(8,t-5-o);e.fillText(r,s,n-4),e.globalAlpha=1}function Zb(e,t,n){if(!(t.length<2)){e.lineWidth=1.5,e.strokeStyle=n;for(let n=1;n{let n=t-2*Wb,r=u.maxX-u.minX||1;return Wb+(e-u.minX)/r*n};e.strokeStyle=i.border,e.lineWidth=1,e.beginPath(),e.moveTo(Wb,d),e.lineTo(t-Wb,d),e.stroke();let p=f(o.neutral_white[0]??0);a.push({screen:[p,d],label:`neutral`,point:o.neutral_white}),e.strokeStyle=i.neutral,e.beginPath(),e.moveTo(p,d-8),e.lineTo(p,d+8),e.stroke(),Xb(e,p,d-6,`neutral`,i.neutral,t),o.node_white.forEach((n,o)=>{let s=f(n[0]??0);a.push({screen:[s,d],label:r.nodeLabels[o]??`node ${o+1}`,point:n}),Jb(e,s,d,4,i.node),Xb(e,s,d+18,r.nodeLabels[o]??``,i.fgDim,t)}),c.forEach((t,n)=>{let r=.1+.7*(n/Math.max(1,c.length-1));Jb(e,f(t[0]??0),d,2.5,i.live,r)}),s&&Yb(e,f(s[0]??0),d,i),s&&a.push({screen:[f(s[0]??0),d],label:`live`,point:s})}function $b(e,t,n,r,i,a,o){let{geom:s,live:c,trail:l}=r,u=[];for(let e of s.node_white)u.push([e[0]??0,e[1]??0]);if(u.push([s.neutral_white[0]??0,s.neutral_white[1]??0]),s.overlay?.kind===`curve`)for(let e of s.overlay.points)u.push([e[0]??0,e[1]??0]);let d=qb(Kb(u),t,n);{let[r,a]=d(0,0);e.strokeStyle=i.border,e.lineWidth=1,e.globalAlpha=.35,e.beginPath(),e.moveTo(Wb,a),e.lineTo(t-Wb,a),e.moveTo(r,Wb),e.lineTo(r,n-Wb),e.stroke(),e.globalAlpha=.7,e.fillStyle=i.muted,e.font=Ub,e.fillText(`PC1`,t-Wb-22,a-4),e.fillText(`PC2`,r+4,38),e.globalAlpha=1}s.overlay?.kind===`curve`&&s.overlay.points.length>1&&(e.strokeStyle=i.purple,e.globalAlpha=.5,e.lineWidth=1.5,e.beginPath(),s.overlay.points.forEach((t,n)=>{let[r,i]=d(t[0]??0,t[1]??0);n===0?e.moveTo(r,i):e.lineTo(r,i)}),e.stroke(),e.globalAlpha=1);{let[t,n]=d(s.neutral_white[0]??0,s.neutral_white[1]??0);o.push({screen:[t,n],label:`neutral`,point:s.neutral_white}),e.strokeStyle=i.neutral,e.lineWidth=1.5,e.beginPath(),e.arc(t,n,4,0,Math.PI*2),e.stroke()}if(s.node_white.forEach((n,r)=>{let[s,c]=d(n[0]??0,n[1]??0);o.push({screen:[s,c],label:a(r),point:n}),Jb(e,s,c,3.5,i.node),Xb(e,s,c,a(r),i.fgDim,t)}),Zb(e,l.map(e=>d(e[0]??0,e[1]??0)),i.live),c){let[t,n]=d(c[0]??0,c[1]??0);o.push({screen:[t,n],label:`live`,point:c}),Yb(e,t,n,i)}}function ex(e,t){let n=0,r=0,i=0,a=Math.min(e.length,t.length);for(let o=0;oex(e,d)),h=ex(s.neutral_white,d),g=(s.overlay?.points??[]).map(e=>ex(e,d)),_=h,v=0;for(let e of[...m,h,...g]){let t=Math.hypot(e[0]-_[0],e[1]-_[1],e[2]-_[2]);t>v&&(v=t)}v||=1;let y=t-2*Wb,b=n-2*Wb,x=Math.min(y,b)/2/v*p,S=t/2,C=n/2,w=e=>{let t=ix(f,[e[0]-_[0],e[1]-_[1],e[2]-_[2]]);return{s:[S+t[0]*x,C-t[1]*x],z:t[2]}},T=m.map(w),E=w(h);o.push({screen:E.s,label:`neutral`,point:s.neutral_white});let D=g.map(w),O=l.map(e=>w(ex(e,d))),k=c?w(ex(c,d)):null,A=1/0,j=-1/0;for(let e of T)e.zj&&(j=e.z);let M=j-A||1,N=e=>(e-A)/M;{let t=v*1.1,n=[{dir:[1,0,0],name:`PC1`},{dir:[0,1,0],name:`PC2`},{dir:[0,0,1],name:`PC3`}];e.strokeStyle=i.border,e.lineWidth=1;for(let{dir:r,name:a}of n){let n=w([_[0]+r[0]*t,_[1]+r[1]*t,_[2]+r[2]*t]),o=w([_[0]-r[0]*t,_[1]-r[1]*t,_[2]-r[2]*t]);e.globalAlpha=.35,e.beginPath(),e.moveTo(o.s[0],o.s[1]),e.lineTo(n.s[0],n.s[1]),e.stroke(),e.globalAlpha=.7,e.fillStyle=i.muted,e.font=Ub,e.fillText(a,n.s[0]+3,n.s[1]-2)}e.globalAlpha=1}if(s.overlay&&D.length>1){if(e.strokeStyle=i.purple,e.lineWidth=1,s.overlay.kind===`curve`)e.globalAlpha=.4,e.beginPath(),D.forEach((t,n)=>{n===0?e.moveTo(t.s[0],t.s[1]):e.lineTo(t.s[0],t.s[1])}),e.stroke(),e.globalAlpha=1;else if(s.overlay.kind===`surface`&&s.overlay.grid_shape){let[t,n]=s.overlay.grid_shape;e.globalAlpha=.28;for(let r=0;r({i:t,z:e.z})).sort((e,t)=>e.z-t.z);for(let{i:n}of P){let r=T[n];o.push({screen:r.s,label:a(n),point:s.node_white[n]});let c=N(r.z);Jb(e,r.s[0],r.s[1],2.5+2.5*c,i.node,.4+.6*c),c>.55&&Xb(e,r.s[0],r.s[1],a(n),i.fgDim,t)}Zb(e,O.map(e=>e.s),i.live),k&&Yb(e,k.s[0],k.s[1],i),k&&c&&o.push({screen:k.s,label:`live`,point:c})}function cx(e,t){let n=Gb(e);if(!n)return[];let r=[],{ctx:i,w:a,h:o}=n,s=Vb(e),c=e=>t.nodeLabels[e]??``,l=t.geom.rank;return l<=1?Qb(i,a,o,t,s,r):l===2?$b(i,a,o,t,s,c,r):sx(i,a,o,t,s,c,r),r}function lx(e,t){let n=t.x-e.x,r=t.y-e.y;return{center:{x:e.x+n/2,y:e.y+r/2},distance:Math.hypot(n,r)}}function ux(e,t,n,r,i){return!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0?Math.min(i,Math.max(r,e)):Math.min(i,Math.max(r,e*n/t))}var dx=I(`rank varies by layer`),fx=I(` `,1),px=I(` `,1),mx=I(`No reading selected`),hx=I(`
                    Select a saved reading to see how it is measured.
                    `),gx=I(`
                    Loading probe geometry…
                    `),_x=I(`
                    `),vx=I(`
                    This probe has no fitted geometry.
                    `),yx=I(``),bx=I(`drag · scroll or pinch
                    `,1),xx=I(` `),Sx=I(`live trail unavailable here`),Cx=I(`run for live trail`),wx=I(`
                  • `),Tx=I(`

                    `),Ex=I(`

                    Geometry coordinates

                      `),Dx=I(``);function Ox(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let r=c(()=>Ze.params),i=c(()=>B(r)?.name??``),o=c(()=>B(i).split(`/`).pop()??B(i)),s=c(()=>Hr.entries.get(B(i))??null),l=We(`probe_subspace_trails`),u=J(null),d=J(!1),h=J(null),_=J(null),v=V({q:ox,zoom:1.6}),b=J(null),x=0,C=[],T=J(`Hover a node to see its whitened coordinates`),E=0,D=c(()=>B(u)?.is_affine===!1?`var(--pillar-manifold)`:`var(--pillar-subspace)`);async function O(e,t){if(!e){t===E&&(A(u,null),A(d,!1),A(h,null));return}A(d,!0),A(h,null),A(u,null);try{let n=await Tt.geometry(e);if(t!==E)return;A(u,n,!0);let r=null,i=-1/0;for(let e of Object.values(n.layers)){let t=Math.abs(e.mahalanobis_share);t>i&&(i=t,r=e.layer)}A(_,r,!0)}catch(e){if(t!==E)return;A(h,je(e,`Unable to load this direction map. Reattach the direction and try again.`),!0)}finally{t===E&&A(d,!1)}}Ce(()=>{let e=++E;return O(B(i),e),()=>{E===e&&(E+=1)}});let j=c(()=>B(u)?Object.values(B(u).layers).sort((e,t)=>e.layer-t.layer):[]),M=c(()=>B(u)&&B(_)!==null?B(u).layers[String(B(_))]??null:null),P=c(()=>B(j).reduce((e,t)=>Math.max(e,Math.abs(t.mahalanobis_share)),0)),F=c(()=>B(_)===null?``:String(B(_))),I=c(()=>{let e=B(s)?.subspaceTrail;return!e||e.length===0?null:e[e.length-1]?.perLayer[B(F)]??null}),L=c(()=>{let e=B(s)?.subspaceTrail??[],t=[];for(let n of e){let e=n.perLayer[B(F)];Array.isArray(e)&&t.push(e)}return t});Ce(()=>{let e=B(b),t=B(M),n=B(I),r=B(L),i=v.q,a=v.zoom,o=B(u)?.node_labels??[];if(!e||!t){x&&=(cancelAnimationFrame(x),0);return}let s=()=>{x&&cancelAnimationFrame(x),x=requestAnimationFrame(()=>{x=0,C=cx(e,{geom:t,nodeLabels:o,live:n,trail:r,orbit:{q:i,zoom:a}})})},c=new ResizeObserver(s);return c.observe(e),s(),()=>{c.disconnect(),x&&cancelAnimationFrame(x),x=0}});let ee=null,te=0,z=0,ne=new Map,re=null,ie=c(()=>(B(M)?.rank??0)>=3);function ae(e,t){try{e.setPointerCapture(t)}catch{}}function oe(e,t){if(e.hasPointerCapture(t))try{e.releasePointerCapture(t)}catch{}}function H(){let e=[...ne.values()];return e.length>=2?[e[0],e[1]]:null}function se(e){let t=H();if(!t)return;let{distance:n}=lx(t[0],t[1]);if(!(n<=0)){ee=null,re={distance:n,zoom:v.zoom};for(let t of ne.keys())ae(e,t)}}function le(e){if(B(ie)){if(e.pointerType===`touch`&&(ne.set(e.pointerId,{x:e.clientX,y:e.clientY}),ne.size>=2)){se(e.currentTarget),e.preventDefault();return}ee=e.pointerId,te=e.clientX,z=e.clientY,ae(e.currentTarget,e.pointerId),e.preventDefault()}}function ue(e){if(B(b)&&e.buttons===0){let t=B(b).getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top,i,a=16;for(let e of C){let t=Math.hypot(n-e.screen[0],r-e.screen[1]);t<=a&&(i=e,a=t)}A(T,i?`${i.label} · whitened coordinates [${i.point.map(e=>Il(e)).join(`, `)}]`:`Hover a node to see its whitened coordinates`,!0)}if(!B(ie))return;if(e.pointerType===`touch`&&ne.has(e.pointerId)){ne.set(e.pointerId,{x:e.clientX,y:e.clientY});let t=H();if(t&&re){v.zoom=ux(re.zoom,re.distance,lx(t[0],t[1]).distance,.3,6),e.preventDefault();return}}if(ee!==e.pointerId)return;let t=e.clientX-te,n=e.clientY-z;te=e.clientX,z=e.clientY,v.q=ax(v.q,t,n)}function de(e){let t=e.currentTarget;if(oe(t,e.pointerId),e.pointerType===`touch`){let n=re!==null;ne.delete(e.pointerId),n&&(ne.size>=2?se(t):re=null)}ee===e.pointerId&&(ee=null)}function fe(e){if(!B(ie))return;e.preventDefault();let t=Math.exp(-e.deltaY*.0015);v.zoom=Math.max(.3,Math.min(6,v.zoom*t))}function me(e,t){B(ie)&&(v.q=ax(v.q,e,t))}function he(e){v.zoom=Math.max(.3,Math.min(6,v.zoom*e))}function ge(){v.q=ox,v.zoom=1.6}function _e(e){return!e||e.length===0?`not available`:e.slice(0,3).map(e=>e.toFixed(3)).join(`, `)}function ve(){it()}function be(e){e.key===`Escape`&&(e.preventDefault(),ve())}let xe=c(()=>{let e=B(M)?.rank??0;return e<=1?`line · rank 1`:e===2?`2D scatter · rank 2`:`3D PCA scatter · rank ${e}`}),Se=c(()=>B(M)?`intrinsic dim ${B(M).intrinsic_dim}`:``);var we=Dx();ye(`keydown`,ce,be);let Te;var Ee=R(we),De=R(Ee),Oe=X(R(De),2),ke=R(Oe),Ae=e=>{var t=px(),n=X(q(t),2),r=R(n,!0);f(n);var a=X(n,2),s=e=>{var t=fx(),n=q(t),r=R(n);f(n);var i=X(n,2),a=e=>{g(e,dx())};p(i,e=>{B(u).rank_uniform||e(a)}),U(()=>G(r,`${B(xe)??``} · ${B(Se)??``}`)),g(e,t)};p(a,e=>{B(u)&&e(s)}),U(()=>{S(n,`title`,B(i)),G(r,B(o))}),g(e,t)},Me=e=>{g(e,mx())};p(ke,e=>{B(i)?e(Ae):e(Me,-1)}),f(Oe),f(De),ft(X(De,2),{onclick:ve}),f(Ee);var Y=X(Ee,2),Ne=e=>{g(e,hx())},Pe=e=>{g(e,gx())},Fe=e=>{var t=_x(),n=R(t),r=R(n);f(n),f(t),U(()=>G(r,`Probe geometry failed: ${B(h)??``}`)),g(e,t)},Ie=e=>{g(e,vx())},Le=e=>{var t=Ex(),n=R(t),r=X(R(n),2);m(r,21,()=>B(j),e=>e.layer,(e,t)=>{var n=yx();let r;var i=R(n),a=R(i);f(i);var o=X(i,2);{let e=c(()=>B(P)||1),n=c(()=>`Share ${Il(B(t).mahalanobis_share)} · ${Il(B(P)>0?Math.abs(B(t).mahalanobis_share)/B(P):0,!0)} of largest layer`);Vl(o,{get value(){return B(t).mahalanobis_share},get max(){return B(e)},width:200,height:8,color:`var(--family)`,get title(){return B(n)}})}var s=X(o,2),l=R(s,!0);f(s),f(n),U((e,i)=>{r=y(n,1,`row svelte-f3zez2`,null,r,{active:B(t).layer===B(_)}),S(n,`aria-pressed`,B(t).layer===B(_)),S(n,`title`,e),G(a,`L${B(t).layer??``}`),G(l,i)},[()=>`L${B(t).layer} · share ${Il(B(t).mahalanobis_share)} · ${Il(B(P)>0?Math.abs(B(t).mahalanobis_share)/B(P):0,!0)} of largest layer`,()=>B(t).mahalanobis_share.toFixed(3)]),K(`click`,n,()=>A(_,B(t).layer,!0)),g(e,n)}),f(r),f(n);var i=X(n,2),s=R(i);let d;var h=R(s),x=R(h);f(h),a(h,e=>A(b,e),()=>B(b));var C=X(h,2),E=R(C);f(C);var D=X(C,2),O=e=>{var t=bx(),n=X(q(t),2),r=R(n),i=X(r,2),a=X(i,2),o=X(a,2),s=X(o,2);Be(R(s),{name:`subtract`}),f(s);var c=X(s,2);Be(R(c),{name:`add`}),f(c);var l=X(c,2);f(n),K(`click`,r,()=>me(-18,0)),K(`click`,i,()=>me(18,0)),K(`click`,a,()=>me(0,-18)),K(`click`,o,()=>me(0,18)),K(`click`,s,()=>he(.8)),K(`click`,c,()=>he(1.25)),K(`click`,l,ge),g(e,t)};p(D,e=>{B(ie)&&e(O)});var k=X(D,2),F=e=>{var t=xx(),n=R(t);f(t),U(()=>G(n,`${B(L).length??``} trail pts`)),g(e,t)},ee=e=>{var t=Sx();U(()=>S(t,`title`,l.reason??void 0)),g(e,t)},te=e=>{g(e,Cx())};p(k,e=>{B(L).length>0?e(F):l.available?e(te,-1):e(ee,1)}),f(s);var z=X(s,2),ne=R(z);f(z);var V=X(z,2),re=X(R(V),2),ae=R(re);f(re);var oe=X(re,2);m(oe,21,()=>B(M).node_white,N,(e,t,n)=>{var r=wx(),i=R(r);f(r),U(e=>G(i,`${B(u).node_labels[n]??`node ${n+1}`??``}: [${e??``}]`),[()=>_e(B(t))]),g(e,r)}),f(oe),f(V),w(V,e=>Bb?.(e));var H=X(V,2),se=e=>{var t=Tx(),n=R(t);f(t),U(()=>G(n,`${l.reason??``}. The fitted geometry remains available.`)),g(e,t)};p(H,e=>{l.available||e(se)}),f(i),f(t),U((e,t,n,r,i)=>{d=y(s,1,`plot-wrap svelte-f3zez2`,null,d,{orbit:B(ie)}),S(h,`title`,B(T)),S(h,`aria-label`,`Whitened geometry for ${B(o)}, layer ${B(_)}`),S(h,`data-orbit-zoom`,e),G(x,`Whitened geometry for ${B(o)??``}, layer ${B(_)??``}.`),G(E,`L${B(_)??``}`),G(ne,`Neutral [${t??``}]; live point [${n??``}]; - ${B(M).node_white.length??``} node ${B(M).node_white.length===1?`centroid`:`centroids`}.`),G(ae,`Layer ${B(_)??``}; rank ${B(M).rank??``}; neutral [${r??``}]; - live point [${i??``}]. Coordinates show the first three whitened dimensions.`)},[()=>v.zoom.toFixed(2),()=>_e(B(M).neutral_white),()=>_e(B(I)),()=>_e(B(M).neutral_white),()=>_e(B(I))]),K(`pointerdown`,h,le),K(`pointermove`,h,ue),K(`pointerup`,h,de),ye(`pointercancel`,h,de),ye(`lostpointercapture`,h,de),ye(`wheel`,h,fe),g(e,t)};p(Y,e=>{B(i)?B(d)?e(Pe,1):B(h)?e(Fe,2):!B(u)||!B(M)||B(j).length===0?e(Ie,3):e(Le,-1):e(Ne)}),f(we),U(()=>Te=pe(we,``,Te,{"--family":B(D)})),g(e,we),W()}H([`click`,`pointerdown`,`pointermove`,`pointerup`]);var kx=[`epistemic`,`alignment`,`register`,`cultural`],Ax={epistemic:`Epistemic`,alignment:`Alignment`,register:`Register`,cultural:`Cultural`,other:`Other`},jx=new Set([`epistemic`]),Mx=new Set(kx);function Nx(e){if(Array.isArray(e)){for(let t of e)if(typeof t==`string`&&Mx.has(t))return t}return`other`}function Px(e){let t=e.indexOf(`.`);return t<0?{positive:e,negative:null}:{positive:e.slice(0,t),negative:e.slice(t+1)}}function Fx(e){let t=e.diagnostics;return t?`per_component_variance`in t&&Array.isArray(t.per_component_variance)?{kind:`pca`,...t}:`eigenvalues`in t&&Array.isArray(t.eigenvalues)?{kind:`spectral`,...t}:null:null}function Ix(e){let t=e.per_component_variance.reduce((e,t)=>Math.max(e,t),0);return e.per_component_variance.map((n,r)=>({index:r+1,value:n,frac:t>0?n/t:0,picked:r+1<=e.picked_k}))}function Lx(e){let t=e.eigenvalues.reduce((e,t)=>Math.max(e,t),0);return e.eigenvalues.map((n,r)=>({index:r+1,value:n,frac:t>0?n/t:0,picked:r+1<=e.picked_k}))}function Rx(e){if(e.kind===`pca`){let t=e.cumulative_variance,n=e.picked_k<=t.length?t[e.picked_k-1]:null,r=n===null?`?`:n.toFixed(3);return`pca · k=${e.picked_k} · cumvar@k=${r} (≥${e.threshold})`}let t=e.gap_magnitude.toExponential(2);return`spectral · k=${e.picked_k} · gap=${t} · σ=${e.bandwidth.toPrecision(3)} · k_nn=${e.k_nn}`}function zx(e){if(!e)return null;for(let t of e)if(t.fit_mode===`pca`||t.fit_mode===`spectral`||t.fit_mode===`auto`)return t;return null}var Bx=I(`

                      Authored geometry · not an automatic topology detection

                      `),Vx=I(`
                    • `),Hx=I(`

                      `),Ux=I(` `),Wx=I(`

                      `),Gx=I(`

                        `),Kx=I(`

                        fit for diagnostics

                        `),qx=I(` `,1);function Jx(e,t){n(t,!0);let r=c(()=>zx(t.manifold.fitted)),a=c(()=>B(r)?Fx(B(r)):null),o=c(()=>B(a)===null?[]:B(a).kind===`pca`?Ix(B(a)):Lx(B(a)));var s=qx(),l=q(s),u=e=>{var n=Bx(),r=R(n),i=R(r,!0);f(r),T(2),f(n),U(e=>G(i,e),[()=>X_(t.manifold.domain)]),g(e,n)},d=c(()=>X_(t.manifold.domain));p(l,e=>{B(d)&&e(u)});var h=X(l,2),_=e=>{var t=Gx(),n=R(t),s=R(n,!0);f(n);var l=X(n,2);m(l,21,()=>B(o),e=>e.index,(e,t)=>{var n=Vx();let r;var i=R(n),o=X(i,2),s=R(o,!0);f(o),f(n),U((e,a)=>{r=y(n,1,`bar svelte-ct8csj`,null,r,{picked:B(t).picked}),S(n,`title`,e),pe(i,`height: ${a??``}%`),G(s,B(t).index)},[()=>`#${B(t).index} · ${B(a).kind===`pca`?`${Il(B(t).value,!0)} variance`:`eigenvalue ${Il(B(t).value)}`} · ${Il(B(t).frac,!0)} of largest component${B(t).picked?` (kept)`:``}`,()=>Math.max(2,B(t).frac*100)]),g(e,n)}),f(l);var u=X(l,2),d=e=>{var t=Hx(),n=R(t);f(t),U(()=>G(n,`${B(a).component_count??``} components · raise k_nn or use pca`)),g(e,t)};p(u,e=>{B(a).kind===`spectral`&&B(a).component_count>1&&e(d)});var h=X(u,2),_=e=>{var t=Wx();m(t,21,()=>Object.entries(B(r).hyperparams),([e,t])=>e,(e,t)=>{var n=c(()=>i(B(t),2));let r=()=>B(n)[0],a=()=>B(n)[1];var o=Ux(),s=R(o);f(o),U(e=>G(s,`${r()??``}=${e??``}`),[()=>typeof a()==`number`?a().toString():a()]),g(e,o)}),f(t),g(e,t)};p(h,e=>{B(r)&&B(r).hyperparams&&e(_)}),f(t),U(e=>{S(t,`data-kind`,B(a).kind),G(s,e),S(l,`aria-label`,`${B(a).kind} diagnostics`)},[()=>Rx(B(a))]),g(e,t)},v=e=>{g(e,Kx())};p(h,e=>{B(a)===null?(t.manifold.fit_mode===`pca`||t.manifold.fit_mode===`spectral`)&&e(v,1):e(_)}),g(e,s),W()}var Yx=I(` `),Xx=I(`
                      1. `),Zx=I(`
                          `),Qx=I(`
                          `),$x=I(` `),eS=I(`persona`),tS=I(`stale`),nS=I(`

                          `),rS=I(`
                          fit
                          `,1),iS=I(`

                          Loading details…

                          `),aS=I(`

                          `),oS=I(`

                          `),sS=I(`
                          `),cS=I(`
                        • `),lS=I(` `),uS=I(`
                        • `),dS=I(``),fS=I(``),pS=I(`
                          `),mS=I(``),hS=I(`

                          Loading controls…

                          `),gS=I(`

                          `),_S=I(`
                            `),vS=I(`
                            `),yS=I(`

                            Fitted

                            `,1),bS=I(`
                              `),xS=I(`
                              `),SS=I(`

                              Unfitted

                              `,1),CS=I(`

                              no matches

                              `),wS=I(` `,1),TS=I(`

                              attach selector
                              `);function ES(t,r){n(r,!0);let i=c(()=>r.params?.returnToToken);function o(){B(i)?rt(`token_drilldown`,B(i)):it()}let l=c(()=>r.params&&typeof r.params==`object`&&r.params.family===`manifold`?`manifold`:`subspace`),u=c(()=>B(l)===`manifold`?`var(--pillar-manifold)`:`var(--accent)`),d=c(()=>B(i)?`Add a probe`:B(l)===`manifold`?`manifold`:`subspace`),_=c(()=>B(i)?`Create a concept`:`build manifold`),v=c(()=>B(i)?`Train a concept for this model`:`author a domain and node corpus`),b=Ke(`manifold_builder`).available,x=We(`fitting`),C=St.mode!==`http`,E=J(null),D=!1,O=new gt,k=new gt,M=new Map,N=new gt,P=new _t,F=new gt,I=new _t,ee=new Map,z=J(``),V=J(null),re=new gt,ie=new _t,ae=new gt([...jx].flatMap(e=>[`ft:${e}`,`un:${e}`]));ne(()=>(D=!0,yr(),ri(),queueMicrotask(()=>B(V)?.focus({preventScroll:!0})),()=>{D=!1;for(let e of M.values())window.clearTimeout(e);M.clear()}));function oe(e){return`${e.namespace}/${e.name}`}function H(e){return I_(e,_i.info?.model_id??null,C)}function se(e){return L_(H(e),ie.get(oe(e)))}function ce(e,t){ie.set(oe(e),t)}function le(e){let t=se(e);return t&&!t.available?t.unavailableReason??`The selected fit for ${oe(e)} is unavailable.`:null}let ue=c(()=>B(z).trim().length>0);function de(e,t){return e.toLowerCase().includes(t)}function fe(e,t){if(!t)return!0;let n=t.toLowerCase();if(oe(e).toLowerCase().includes(n)||e.name.toLowerCase().includes(n)||e.namespace.toLowerCase().includes(n)||e.description&&e.description.toLowerCase().includes(n))return!0;if(Array.isArray(e.tags)){for(let t of e.tags)if(typeof t==`string`&&t.toLowerCase().includes(n))return!0}return(e.node_labels??[]).some(e=>de(e,n))}function me(e){let t=e.node_labels??[],n=B(z).trim().toLowerCase();if(!n)return t;let r=t.filter(e=>de(e,n));return r.length>0?r:t}function he(e,t){let n=e.node_roles;if(!n)return null;let r=(e.node_labels??[]).indexOf(t);return r>=0?n[r]??null:null}function ge(e){return B(ue)||re.has(e)}function _e(e){re.has(e)?re.delete(e):re.add(e)}function ve(e){let t=e.fit_mode;if(t===`auto`){let n=e.resolved_fit_mode;if(n==null)return!0;t=n}return B(l)===`subspace`?t===`pca`||t===`baked`:t===`spectral`||t===`authored`}let be=c(()=>nr.catalog.filter(e=>ve(e)&&e.fitted_for_session&&fe(e,B(z).trim()))),xe=c(()=>nr.catalog.filter(e=>ve(e)&&!e.fitted_for_session&&fe(e,B(z).trim()))),Se=c(()=>nr.catalog.filter(e=>ve(e)).length);function Ce(e){let t=new Map;for(let n of e){let e=Nx(n.tags),r=t.get(e);r?r.push(n):t.set(e,[n])}for(let e of t.values())e.sort((e,t)=>e.name.localeCompare(t.name));return t}function we(e){return[...kx,`other`].filter(t=>(e.get(t)?.length??0)>0).map(t=>({cat:t,items:e.get(t)}))}let Te=c(()=>we(Ce(B(be)))),Ee=c(()=>we(Ce(B(xe))));function De(e){ae.has(e)?ae.delete(e):ae.add(e)}function Oe(e){return B(ue)||ae.has(e)}function ke(e){return[...nr.entries.keys()].some(t=>R_(t,e))}function Ae(e){let t=se(e);return t?[...Hr.entries.values()].some(n=>z_(n.info,e,n.request.selector)&&(n.info.family!==`geometry`||n.info.manifold===t.selector||n.request.selector===t.selector)):!1}function je(e){return V_(e,B_(e,nr.entries,Hr.entries))}function Me(e,t){if(!e.fitted_for_session)return;let n=se(e);if(!n||!n.available){Z(n?.unavailableReason??`No compatible fit is available for ${oe(e)}.`,{kind:`error`,ttlMs:null});return}let r=oe(e);B(l)===`subspace`?(gr(r,n.variant),fr(r,t)):(Cr(r,n.variant),Ir(r,t)),it()}function Y(e){if(ke(e))return;let t=se(e);if(!t||!t.available){Z(t?.unavailableReason??`No compatible fit is available for ${oe(e)}.`,{kind:`error`,ttlMs:null});return}B(l)===`subspace`?gr(oe(e),t.variant):Cr(oe(e),t.variant),it()}async function Ne(e){if(Ae(e)||O.has(oe(e)))return;let t=Ze.params,n=se(e);if(!n||!n.available){Z(n?.unavailableReason??`No compatible fit is available for ${oe(e)}.`,{kind:`error`,ttlMs:null});return}let r=oe(e);O.add(r);try{Z(`probe ${(await ii(n.selector)).name}`,{kind:`info`}),D&&Ze.params===t&&o()}catch(e){Z(`attach: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{O.delete(r)}}let Pe=J(``),Fe=J(``),Le=J(3),Re=J(!1);async function ze(e){if(e.preventDefault(),B(Re))return;let t=Ze.params,n=B(Pe).trim();if(!n){Z(`selector required`,{kind:`error`});return}if(C){let e=nr.catalog.find(e=>R_(n,e));if(e){let t=H(e),r=t.find(e=>e.selector===n),i=t.find(e=>!e.available&&e.unavailableReason!==null);if(r&&!r.available||!r&&i){Z(r?.unavailableReason??i.unavailableReason,{kind:`error`,ttlMs:null});return}}}A(Re,!0);try{let e={};B(Fe).trim()&&(e.name=B(Fe).trim()),B(Le)&&B(Le)>0&&(e.top_n=B(Le)),Z(`probe ${(await ii(n,e)).name}`,{kind:`info`}),A(Pe,``),A(Fe,``),B(i)&&D&&Ze.params===t&&o()}catch(e){Z(`attach: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{A(Re,!1)}}function Ve(e){if(!x.available){Z(x.reason??`Manifold fitting is unavailable.`,{kind:`error`,ttlMs:null});return}let t=oe(e);if(O.has(t))return;O.add(t),A(E,null);let n=Z(`fitting '${t}'…`,{kind:`info`,ttlMs:null});(async()=>{try{await At(e.namespace,e.name,{},e=>{if(e.event===`progress`){let t=e.data&&typeof e.data==`object`?e.data.message:null;t&&Ye(n,{detail:t})}}),P.delete(t),I.delete(t),ee.set(t,(ee.get(t)??0)+1),F.delete(t),await Promise.all([yr(),ri(),or()]),D&&N.has(t)&&(N.delete(t),await $e(e)),Xe(n),Z(`fitted ${t}`,{kind:`info`})}catch(e){if(Xe(n),oy(e)){Z(`Fitting ${t} cancelled.`,{kind:`info`});return}Z(`Couldn't fit '${t}': ${te(e)}`,{kind:`error`,ttlMs:null})}finally{O.delete(t)}})()}function He(e){let t=oe(e),n=je(e);if(n){Z(n,{kind:`error`,ttlMs:null});return}if(k.has(t)){let n=M.get(t);n!==void 0&&(window.clearTimeout(n),M.delete(t)),k.delete(t),Ue(e);return}k.add(t);let r=window.setTimeout(()=>{k.delete(t),M.delete(t)},3e3);M.set(t,r)}async function Ue(e){let t=oe(e);O.add(t),A(E,null);try{await Et.delete(e.namespace,e.name),await yr(),Z(e.namespace==="default"?`Deleted ${t}. This bundled item will return on restart.`:`deleted ${t}`,{kind:`info`})}catch(e){A(E,te(e),!0)}finally{O.delete(t)}}function Ge(){rt(`manifold_builder`,B(i)?{returnToToken:B(i),mode:`discover`}:null)}function qe(e){return e.fit_mode&&e.fit_mode!==`authored`?e.fit_mode:null}function Je(e){return(e.node_roles??[]).some(e=>e)}function Qe(e){return e.fit_mode===`pca`||e.fit_mode===`spectral`}async function $e(e){let t=oe(e);if(N.has(t)){N.delete(t);return}if(N.add(t),P.has(t))return;F.add(t),I.delete(t);let n=(ee.get(t)??0)+1;ee.set(t,n);try{let r=await Et.get(e.namespace,e.name);if(!D||ee.get(t)!==n)return;P.set(t,r)}catch(e){if(!D||ee.get(t)!==n)return;I.set(t,te(e))}finally{ee.get(t)===n&&F.delete(t)}}var et=TS();let tt,nt;var at=R(et),ot=R(at),st=R(ot,!0);f(ot);var ct=X(ot,2),lt=t=>{Du(t,{onclick:o,children:(t,n)=>{T(),g(t,e(`Back to token`))},$$slots:{default:!0}})};p(ct,e=>{B(i)&&e(lt)}),ft(X(ct,2),{get onclick(){return it}}),f(at);var dt=X(at,2);{let t=(t,n=Ie,r=Ie)=>{let i=c(()=>oe(n())),a=c(()=>(n().node_labels??[]).length),o=c(()=>me(n()));var s=L(),l=q(s),u=t=>{var s=Qx(),l=R(s),u=R(l),d=R(u,!0);f(u);var _=X(u,4),v=R(_,!0),y=X(v),b=t=>{var n=e();U(()=>G(n,`/${B(a)??``}`)),g(t,n)};p(y,e=>{B(o).length!==B(a)&&e(b)}),f(_),f(l);var x=X(l,2),C=e=>{var t=Zx();m(t,20,()=>B(o),e=>e,(e,t)=>{let a=c(()=>he(n(),t));var o=Xx(),s=R(o),l=R(s),u=R(l,!0);f(l);var d=X(l,2),m=e=>{var t=Yx(),n=R(t,!0);f(t),U(()=>G(n,B(a))),g(e,t)};p(d,e=>{B(a)&&e(m)}),f(s),f(o),U(()=>{s.disabled=!r(),S(s,`title`,r()?`steer ${B(i)} → ${t}`:`fit ${B(i)} first to steer to ${t}`),G(u,t)}),K(`click`,s,()=>Me(n(),t)),g(e,o)}),f(t),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)},w=c(()=>ge(B(i)));p(x,e=>{B(w)&&e(C)}),f(s),U((e,t,n)=>{S(l,`aria-expanded`,e),S(l,`title`,t),G(d,n),G(v,B(o).length)},[()=>ge(B(i)),()=>ge(B(i))?`collapse`:`expand`,()=>ge(B(i))?`▾`:`▸`]),K(`click`,l,()=>_e(B(i))),g(t,s)};p(l,e=>{B(a)>0&&e(u)}),g(t,s)},n=(e,n=Ie)=>{let r=c(()=>oe(n())),i=c(()=>O.has(B(r))),a=c(()=>k.has(B(r))),o=c(()=>N.has(B(r))),s=c(()=>qe(n())),l=c(()=>H(n())),u=c(()=>se(n())),d=c(()=>le(n())),m=c(()=>je(n()));var _=cS(),v=R(_),b=R(v),C=R(b),w=R(C,!0);f(C);var T=X(C,2),E=R(T),D=X(E),A=e=>{var t=$x(),n=R(t,!0);f(t),U(()=>{y(t,1,`fit-badge fit-${B(s)??``}`,`svelte-2t0ety`),G(n,B(s))}),g(e,t)};p(D,e=>{B(s)&&e(A)});var j=X(D,2),M=e=>{g(e,eS())},ee=c(()=>Je(n()));p(j,e=>{B(ee)&&e(M)});var te=X(j,2),z=e=>{g(e,tS())};p(te,e=>{n().stale&&e(z)}),f(T),f(b);var ne=X(b,2),V=R(ne),re=R(V);{let e=c(()=>B(o)?`down`:`info`);Be(re,{get name(){return B(e)}})}f(V);var ie=X(V,2),ae=X(ie,2),ue=X(ae,2),de=R(ue,!0);f(ue);var fe=X(ue,2);let pe;var me=R(fe,!0);f(fe),f(ne),f(v);var W=X(v,2),he=e=>{var t=rS(),i=q(t),a=X(R(i),2);{let e=c(()=>B(l).map(e=>({value:e.selector,label:e.label,disabled:!e.available}))),t=c(()=>`Fit for ${B(r)}`),i=c(()=>B(u).unavailableReason??`Use ${B(u).selector}`);hu(a,{get value(){return B(u).selector},get options(){return B(e)},get ariaLabel(){return B(t)},get title(){return B(i)},onchange:e=>ce(n(),e)})}var o=X(a,2),s=R(o,!0);f(o),f(i);var m=X(i,2),h=e=>{var t=nS(),n=R(t,!0);f(t),U(()=>G(n,B(d))),g(e,t)};p(m,e=>{B(d)&&e(h)}),U(()=>G(s,B(u).selector)),g(e,t)};p(W,e=>{B(l).length>0&&B(u)&&e(he)});var ge=X(W,2),_e=e=>{var t=sS(),n=R(t),i=e=>{g(e,iS())},a=c(()=>F.has(B(r))),o=e=>{var t=aS(),n=R(t,!0);f(t),U(e=>G(n,e),[()=>I.get(B(r))]),g(e,t)},s=c(()=>I.has(B(r))),l=e=>{let t=c(()=>P.get(B(r)));var n=L(),i=q(n),a=e=>{Jx(e,{get manifold(){return B(t)}})},o=c(()=>Qe(B(t))),s=e=>{var n=oS(),r=R(n);f(n),U(()=>G(r,`authored · ${B(t).domain_label??``} · dim ${B(t).intrinsic_dim??``}`)),g(e,n)};p(i,e=>{B(o)?e(a):e(s,-1)}),g(e,n)},u=c(()=>P.has(B(r)));p(n,e=>{B(a)?e(i):B(s)?e(o,1):B(u)&&e(l,2)}),f(t),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)};p(ge,e=>{B(o)&&e(_e)}),t(X(ge,2),n,()=>B(u)?.available===!0),f(_),U((e,t,s,c)=>{S(_,`title`,n().description||B(r)),G(w,B(r)),G(E,`${n().domain_label??``} · ${n().node_count??``} nodes `),S(V,`aria-expanded`,B(o)),S(V,`aria-label`,`${B(o)?`Hide`:`Show`} details for ${B(r)}`),S(V,`title`,B(o)?`hide`:`inspect`),ie.disabled=e,S(ie,`title`,t),ae.disabled=s,S(ae,`title`,c),ue.disabled=B(i)||!x.available,S(ue,`title`,x.available?`re-fit ${B(r)}`:x.reason??`Fitting unavailable`),G(de,B(i)?`…`:`re-fit`),pe=y(fe,1,`act del svelte-2t0ety`,null,pe,{confirm:B(a)}),fe.disabled=B(i),S(fe,`title`,B(m)??(B(a)?`click again to confirm`:`delete ${B(r)}`)),G(me,B(a)?`confirm?`:`delete`)},[()=>B(i)||ke(n())||B(u)===null||!B(u).available,()=>B(d)??(ke(n())?`${B(r)} already racked`:`steer with ${B(u)?.selector??B(r)}`),()=>B(i)||Ae(n())||B(u)===null||!B(u).available,()=>B(d)??(Ae(n())?`${B(r)} already attached`:`probe with ${B(u)?.selector??B(r)}`)]),K(`click`,V,()=>void $e(n())),K(`click`,ie,()=>Y(n())),K(`click`,ae,()=>void Ne(n())),K(`click`,ue,()=>Ve(n())),K(`click`,fe,()=>He(n())),g(e,_)},r=(e,n=Ie)=>{let r=c(()=>oe(n())),i=c(()=>O.has(B(r))),a=c(()=>k.has(B(r))),o=c(()=>qe(n())),s=c(()=>je(n()));var l=uS(),u=R(l),d=R(u),m=R(d),h=R(m,!0);f(m);var _=X(m,2),v=R(_),b=X(v),C=e=>{var t=lS(),n=R(t,!0);f(t),U(()=>{y(t,1,`fit-badge fit-${B(o)??``}`,`svelte-2t0ety`),G(n,B(o))}),g(e,t)};p(b,e=>{B(o)&&e(C)}),f(_),f(d);var w=X(d,2),T=R(w),E=R(T,!0);f(T);var D=X(T,2);let A;var j=R(D,!0);f(D),f(w),f(u),t(X(u,2),n,()=>!1),f(l),U(()=>{S(l,`title`,n().description||B(r)),G(h,B(r)),G(v,`${n().domain_label??``} · ${n().node_count??``} nodes `),T.disabled=B(i)||!x.available,S(T,`title`,x.available?`fit ${B(r)}`:x.reason??`Fitting unavailable`),G(E,B(i)?`…`:`fit`),A=y(D,1,`act del svelte-2t0ety`,null,A,{confirm:B(a)}),D.disabled=B(i),S(D,`title`,B(s)??(B(a)?`click again to confirm`:`delete ${B(r)}`)),G(j,B(a)?`confirm?`:`delete`)}),K(`click`,T,()=>Ve(n())),K(`click`,D,()=>He(n())),g(e,l)};var pt=R(dt),mt=e=>{var t=dS(),n=R(t,!0);f(t),U(()=>G(n,B(E))),g(e,t)};p(pt,e=>{B(E)&&e(mt)});var ht=X(pt,2),vt=X(R(ht),2),yt=R(vt),bt=X(R(yt),2);s(bt),f(yt);var xt=X(yt,2),Ct=X(R(xt),2);s(Ct),f(xt);var wt=X(xt,2),Tt=X(R(wt),2);s(Tt),f(wt);var Dt=X(wt,2);f(vt),f(ht),w(ht,e=>Bb?.(e));var Ot=X(ht,2),kt=e=>{var t=fS(),n=R(t);Be(R(n),{name:`add`}),f(n);var r=X(n,2),i=R(r,!0);f(r);var a=X(r,2),o=R(a,!0);f(a),f(t),U(()=>{G(i,B(_)),G(o,B(v))}),K(`click`,t,Ge),g(e,t)};p(Ot,e=>{(!B(i)||b)&&e(kt)});var jt=X(Ot,2),Mt=X(jt,2),Nt=e=>{var t=pS(),n=R(t);s(n),a(n,e=>A(V,e),()=>B(V));var r=X(n,2);Be(R(r),{name:`refresh`,get spin(){return nr.loading}}),f(r),f(t),U(()=>{S(n,`placeholder`,B(l)===`manifold`?`search manifolds & nodes…`:`search subspaces & nodes…`),S(n,`aria-label`,B(l)===`manifold`?`Search manifolds and nodes`:`Search subspaces and nodes`),r.disabled=nr.loading}),j(n,()=>B(z),e=>A(z,e)),K(`click`,r,()=>void yr()),g(e,t)};p(Mt,e=>{B(Se)>0&&e(Nt)});var Pt=X(Mt,2),Ft=e=>{var t=mS(),n=R(t,!0);f(t),U(()=>G(n,nr.error)),g(e,t)};p(Pt,e=>{nr.error&&e(Ft)});var It=X(Pt,2),Lt=e=>{g(e,hS())},Rt=e=>{var t=gS(),n=R(t,!0);f(t),U(()=>G(n,B(i)?`No saved concepts in this category yet.`:`none`)),g(e,t)},zt=e=>{var t=wS(),i=q(t),a=e=>{var t=yS(),r=X(q(t),2);m(r,21,()=>B(Te),({cat:e,items:t})=>e,(e,t)=>{let r=()=>B(t).cat,i=()=>B(t).items,a=c(()=>`ft:${r()}`),o=c(()=>Oe(B(a)));var s=vS(),l=R(s);let u;var d=R(l),_=R(d,!0);f(d);var v=X(d,2),b=R(v,!0);f(v);var x=X(v,2),C=R(x,!0);f(x),f(l);var w=X(l,2),T=e=>{var t=_S();m(t,21,i,e=>oe(e),(e,t)=>{n(e,()=>B(t))}),f(t),U(()=>S(t,`aria-label`,Ax[r()])),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)};p(w,e=>{B(o)&&e(T)}),f(s),U(()=>{u=y(l,1,`cat-header svelte-2t0ety`,null,u,{open:B(o)}),S(l,`aria-expanded`,B(o)),l.disabled=B(ue),G(_,B(o)?`▾`:`▸`),G(b,Ax[r()]),G(C,i().length)}),K(`click`,l,()=>De(B(a))),g(e,s)}),f(r),g(e,t)};p(i,e=>{B(Te).length>0&&e(a)});var o=X(i,2),s=e=>{var t=SS(),n=X(q(t),2);m(n,21,()=>B(Ee),({cat:e,items:t})=>e,(e,t)=>{let n=()=>B(t).cat,i=()=>B(t).items,a=c(()=>`un:${n()}`),o=c(()=>Oe(B(a)));var s=xS(),l=R(s);let u;var d=R(l),_=R(d,!0);f(d);var v=X(d,2),b=R(v,!0);f(v);var x=X(v,2),C=R(x,!0);f(x),f(l);var w=X(l,2),T=e=>{var t=bS();m(t,21,i,e=>oe(e),(e,t)=>{r(e,()=>B(t))}),f(t),U(()=>S(t,`aria-label`,Ax[n()])),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)};p(w,e=>{B(o)&&e(T)}),f(s),U(()=>{u=y(l,1,`cat-header svelte-2t0ety`,null,u,{open:B(o)}),S(l,`aria-expanded`,B(o)),l.disabled=B(ue),G(_,B(o)?`▾`:`▸`),G(b,Ax[n()]),G(C,i().length)}),K(`click`,l,()=>De(B(a))),g(e,s)}),f(n),g(e,t)};p(o,e=>{B(Ee).length>0&&e(s)});var l=X(o,2),u=e=>{g(e,CS())};p(l,e=>{B(be).length===0&&B(xe).length===0&&e(u)}),g(e,t)};p(It,e=>{nr.loading&&B(Se)===0?e(Lt):B(Se)===0?e(Rt,1):e(zt,-1)}),f(dt),U(e=>{bt.disabled=B(Re),Ct.disabled=B(Re),Tt.disabled=B(Re),Dt.disabled=e},[()=>B(Re)||!B(Pe).trim()]),ye(`submit`,vt,ze),j(bt,()=>B(Pe),e=>A(Pe,e)),j(Ct,()=>B(Fe),e=>A(Fe,e)),j(Tt,()=>B(Le),e=>A(Le,e)),K(`click`,jt,()=>rt(`surface_geometry`))}f(et),U(e=>{tt=y(et,1,`drawer-shell svelte-2t0ety`,null,tt,{"fam-manifold":B(l)===`manifold`}),S(et,`aria-label`,B(l)===`manifold`?`Manifolds`:`Subspaces`),nt=pe(et,``,nt,{"--family-accent":B(u)}),G(st,B(d))},[()=>B(Re)||!B(Pe).trim()]),g(t,et),W()}H([`click`]);var DS=I(``),OS=I(``),kS=I(`
                              `);function AS(e,r){let i=E();n(r,!0);let o=Y(r,`value`,3,`purple`),l=Y(r,`disabled`,3,!1),u=c(()=>Rs(o())),d=J(`purple`),h=J(!1),_=J(null),v=J(null),b=J(null),x=J(``),C,w=du();Ce(()=>{A(d,o())});function T(){if(!B(h)||!B(_)||!B(v))return;let e=B(_).getBoundingClientRect(),t=window.visualViewport,n=t?.offsetLeft??0,r=t?.offsetTop??0,i=t?.width??window.innerWidth,a=r+(t?.height??window.innerHeight),o=Math.min(432,i-16),s=Math.max(n+8,Math.min(e.left,n+i-o-8)),c=B(b)?.scrollHeight??0,l=e.bottom+8+c>a-8&&e.top-c-8>=r+8,u=l?e.top-c-8:e.bottom+8,d=B(v).getBoundingClientRect(),f=getComputedStyle(B(v)),p=parseFloat(f.left)-d.left,m=parseFloat(f.top)-d.top;A(x,`left:${s+p}px;top:${u+m}px;width:${o}px;max-height:${Math.max(0,a-u-8)}px`),B(b)&&(B(b).dataset.origin=l?`bottom-left`:`top-left`)}async function D(e){l()||(clearTimeout(C),A(h,!0),w.mount(),await xe(),!(!B(h)||!B(v))&&(B(v).showPopover(),T(),await xe(),!(!B(h)||!B(v)||!B(b))&&(w.show(B(b)),e&&B(v).querySelector(`input:checked`)?.focus({preventScroll:!0}))))}function O(e=!1){A(h,!1),e&&B(_)?.focus({preventScroll:!0}),w.close(B(b))}function k(e){if(!B(h))return;let t=e.target;!B(_)?.contains(t)&&!B(v)?.contains(t)&&O()}function j(e){if(B(h)){if(e.key===`Tab`&&!B(_)?.contains(e.target)){C=setTimeout(()=>O(),0);return}e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),O(!0))}}ne(()=>(document.addEventListener(`pointerdown`,k,!0),document.addEventListener(`focusin`,k),document.addEventListener(`keydown`,j,!0),window.addEventListener(`resize`,T),window.addEventListener(`scroll`,T,!0),window.visualViewport?.addEventListener(`resize`,T),window.visualViewport?.addEventListener(`scroll`,T),()=>{A(h,!1),clearTimeout(C),document.removeEventListener(`pointerdown`,k,!0),document.removeEventListener(`focusin`,k),document.removeEventListener(`keydown`,j,!0),window.removeEventListener(`resize`,T),window.removeEventListener(`scroll`,T,!0),window.visualViewport?.removeEventListener(`resize`,T),window.visualViewport?.removeEventListener(`scroll`,T),w.destroy()}));async function M(e){A(d,e,!0),await r.onchange(e),A(d,o())}var P=kS(),F=R(P),I=R(F);let L;var ee=X(I,2),te=X(R(ee)),z=R(te);f(te),f(ee);var V=X(ee,2);Be(R(V),{name:`down`,size:16}),f(V),f(F),a(F,e=>A(_,e),()=>B(_));var re=X(F,2),ie=e=>{var n=OS(),r=R(n),o=R(r);m(X(R(o),2),17,()=>Fs,N,(e,n)=>{var r=DS(),a=R(r);s(a);var o=X(a,2);let c;var l=R(o);let u;Be(R(l),{name:`check`,size:16}),f(l),f(o);var p=X(o,2),m=R(p,!0);f(p),f(r),U(()=>{S(a,`name`,`chat-accent-${i}`),t(a,B(n).id),me(a,B(d)===B(n).id),c=pe(o,``,c,{background:B(n).dark}),u=y(l,1,`swatch-check svelte-9lpm3w`,null,u,{chosen:B(d)===B(n).id}),G(m,B(n).name)}),K(`change`,a,()=>void M(B(n).id)),g(e,r)}),f(o),f(r),a(r,e=>A(b,e),()=>B(b)),f(n),a(n,e=>A(v,e),()=>B(v)),U(()=>{S(n,`id`,`${i}-colors`),pe(n,B(x)),n.inert=!B(h),o.disabled=l()}),g(e,n)};p(re,e=>{w.mounted&&e(ie)}),f(P),U(()=>{F.disabled=l(),S(F,`aria-expanded`,B(h)),S(F,`aria-controls`,w.mounted?`${i}-colors`:void 0),L=pe(I,``,L,{background:B(u).dark}),G(z,`· ${B(u).name??``}`)}),K(`click`,F,e=>B(h)?O():void D(e.detail===0)),g(e,P),W()}H([`click`,`change`]);var jS=I(`

                              Wait for the current reply to finish before saving.

                              `),MS=I(``),NS=I(``),PS=I(`

                              Keep the full loom, response settings, and readings on this device.

                              Click for a new avatar

                              Stored in this browser. Drowse removes a saved chat only after you confirm Delete.

                              `);function FS(e,t){n(t,!0);let r=Y(t,`embedded`,3,!1),i=J(null),a=J(``),o=J(V(rc())),l=J(`purple`),u=J(null),d=J(!0),m=J(!1),h=J(`Current model`),_=J(0);ne(()=>{v()});async function v(){A(d,!0),A(u,null);try{await Dc().catch(()=>void 0);let e=n_();A(h,nc(e.model_id),!0),A(_,e.tree.nodes.filter(e=>e.parent_id!==null).length,!0),A(a,tc(),!0);let t=wc.activeId;if(t)try{let n=await Cc.get(t);n.modelId===e.model_id?(A(i,n,!0),A(a,n.name,!0),A(o,n.avatarSeed,!0),A(l,n.accent??`purple`,!0)):(wc.activeId=null,wc.avatarSeed=null,wc.accent=`purple`)}catch(e){if(e instanceof qs&&e.code===`NOT_FOUND`)wc.activeId=null,wc.avatarSeed=null,wc.accent=`purple`;else throw e}}catch(e){A(u,je(e,`This conversation is not ready to save yet.`),!0)}finally{A(d,!1)}}function b(){A(o,rc(),!0)}async function x(e=!1){if(A(u,null),$.active){A(u,`Wait for the current reply to finish before saving.`);return}A(m,!0);try{await Dc().catch(()=>void 0);let t=await Oc(),n=n_(),s=B(i)?.id??wc.activeId,c=s&&!e?await Cc.update(s,{name:B(a),avatarSeed:B(o),accent:B(l),snapshot:n}):await Cc.create({name:B(a),avatarSeed:B(o),accent:B(l),snapshot:n});A(i,c,!0),A(a,c.name,!0),A(o,c.avatarSeed,!0),wc.activeId=c.id,wc.avatarSeed=c.avatarSeed,wc.accent=c.accent??`purple`,wc.status=`saved`,wc.error=null,Z(t===!1?`Saved “${c.name}”. Browser cleanup protection is off.`:`Saved “${c.name}”.`,{kind:t===!1?`warning`:`info`}),r()||it()}catch(e){A(u,je(e,`This conversation could not be saved.`),!0)}finally{A(m,!1)}}async function C(){if(!(B(m)||B(d)||$.active)){A(m,!0),A(u,null);try{let e=n_(),t=Date.now(),n={schemaVersion:1,id:B(i)?.id??crypto.randomUUID(),name:B(a).trim()||tc(t),avatarSeed:B(o),accent:B(l),modelId:e.model_id,createdAt:B(i)?.createdAt??t,updatedAt:Math.max(B(i)?.updatedAt??t,t),snapshot:e};t_(new Blob([await Zg(n)],{type:`application/json`}),n.name)}catch(e){A(u,je(e,`A backup copy could not be created.`),!0)}finally{A(m,!1)}}}var w=PS();let E;var D=R(w),O=R(D),k=R(O),M=R(k,!0);f(k),T(2),f(O);var N=X(O,2),P=e=>{ft(e,{get onclick(){return it}})};p(N,e=>{r()||e(P)}),f(D);var F=X(D,2),I=R(F),L=R(I),ee=R(L);bg(R(ee),{get name(){return B(o)},size:76,background:`circle`,alt:``}),f(ee),T(2),f(L);var te=X(L,2),z=X(R(te),2);s(z),f(te),f(I);var re=X(I,2),ie=R(re),ae=R(ie,!0);f(ie);var oe=X(ie,2),H=R(oe);f(oe),f(re);var se=X(re,2);{let e=c(()=>B(d)||B(m));AS(se,{get value(){return B(l)},get disabled(){return B(e)},onchange:e=>{A(l,e,!0)}})}var ce=X(se,4),le=e=>{g(e,jS())};p(ce,e=>{$.active&&e(le)});var ue=X(ce,2),de=e=>{var t=MS(),n=R(t,!0);f(t),U(()=>G(n,B(u))),g(e,t)};p(ue,e=>{B(u)&&e(de)}),f(F);var fe=X(F,2),pe=R(fe),me=X(pe,2),he=R(me),ge=e=>{var t=NS();U(()=>t.disabled=B(d)||B(m)||$.active),K(`click`,t,()=>void x(!0)),g(e,t)};p(he,e=>{B(i)&&e(ge)});var _e=X(he,2);let ve;var ye=R(_e,!0);f(_e),f(me),f(fe),f(w),U(e=>{E=y(w,1,`drawer-shell svelte-1e766n7`,null,E,{embedded:r()}),S(w,`aria-label`,r()?`Save and name chat`:`Save conversation drawer`),G(M,r()?`Save and name chat`:B(i)?`Update saved chat`:`Save chat`),z.disabled=B(d)||B(m),G(ae,B(h)),G(H,`${B(_)??``} ${B(_)===1?`turn`:`turns`}`),pe.disabled=B(d)||B(m)||$.active,ve=y(_e,1,`button primary svelte-1e766n7`,null,ve,{"loading-pulse":B(m)}),S(_e,`aria-busy`,B(m)),_e.disabled=e,G(ye,B(m)?`Saving…`:B(i)?`Update`:`Save`)},[()=>B(d)||B(m)||$.active||!B(a).trim()]),K(`click`,ee,b),j(z,()=>B(a),e=>A(a,e)),K(`click`,pe,C),K(`click`,_e,()=>void x(!1)),g(e,w),W()}H([`click`]);var IS=I(`

                              Preparing your backup…

                              `),LS=I(`

                              This is a copy. Your saved chat’s name stays unchanged.

                              `,1),RS=I(``),zS=I(``),BS=I(``),VS=I(`

                              Download chat

                              All messages, Loom branches, settings, and recorded readings. Model files aren’t included.

                              `);function HS(e,t){n(t,!0);let r=J(``),i=J(null),a=J(null),o=J(!0),l=J(!1),u=c(()=>e_(B(r)));ne(()=>{d()});async function d(){A(o,!0),A(a,null),A(i,null);try{if($.active)throw Error(`Wait for the reply to finish, then try again.`);let e=n_(),t=wc.activeId,n=null;if(t)try{n=await Cc.get(t)}catch(e){if(!(e instanceof qs&&e.code===`NOT_FOUND`))throw e}n?.modelId!==e.model_id&&(n=null);let a=Date.now(),o={schemaVersion:1,id:n?.id??crypto.randomUUID(),name:n?.name??tc(a),avatarSeed:n?.avatarSeed??rc(),accent:n?.accent??wc.accent,modelId:e.model_id,createdAt:n?.createdAt??a,updatedAt:Math.max(n?.updatedAt??a,a),snapshot:e};A(r,o.name,!0),A(i,new Blob([await Zg(o)],{type:`application/json`}),!0)}catch(e){A(a,je(e,`This chat could not be prepared for download.`),!0)}finally{A(o,!1)}}function m(e){if(e.preventDefault(),!(!B(i)||!B(r).trim()||B(l))){A(l,!0);try{t_(B(i),B(r)),it()}catch(e){A(a,je(e,`The download could not start. Try again.`),!0),A(l,!1)}}}var h=VS(),_=R(h);ft(X(R(_),2),{get onclick(){return it}}),f(_);var v=X(_,4),y=e=>{g(e,IS())},b=e=>{var t=LS(),n=q(t),a=X(R(n),2);s(a),f(n);var o=X(n,2),c=R(o),l=R(c,!0);f(c);var d=X(c,2),p=R(d);f(d),f(o),T(2),U(e=>{G(l,B(u)),S(d,`data-bytes`,B(i).size),G(p,`${e??``} bytes`)},[()=>B(i).size.toLocaleString()]),j(a,()=>B(r),e=>A(r,e)),g(e,t)};p(v,e=>{B(o)?e(y):B(i)&&e(b,1)});var x=X(v,2),C=e=>{var t=RS(),n=R(t,!0);f(t),U(()=>G(n,B(a))),g(e,t)};p(x,e=>{B(a)&&e(C)});var w=X(x,2),E=R(w),D=X(E,2),O=e=>{var t=zS();U(()=>t.disabled=B(o)),K(`click`,t,()=>void d()),g(e,t)},k=e=>{var t=BS();U(e=>t.disabled=e,[()=>!B(i)||!B(r).trim()||B(l)]),g(e,t)};p(D,e=>{B(a)&&!B(i)?e(O):e(k,-1)}),f(w),f(h),ye(`submit`,h,m),K(`click`,E,function(...e){it?.apply(this,e)}),g(e,h),W()}H([`click`]);var US=I(``),WS=I(`
                              Select Refresh sessions to list the models running on this server.
                              `),GS=I(`Current session`),KS=I(`
                              `),qS=I(`

                              API access

                              Changes apply only to this tab until you reload.

                              Server sessions

                              `);function JS(e,t){let r=E();n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let i=J(V(Se()??``)),a=J(V([])),o=J(!1),c=J(null),l=J(!1);async function u(){A(o,!0),A(c,null);try{A(a,(await Ct.list()).sessions,!0)}catch(e){A(c,je(e,`Unable to load server sessions. Check the server connection and try again.`),!0)}finally{A(o,!1)}}async function d(){le(B(i)),A(l,!0),await bi(),await u()}var h=qS(),_=R(h);ft(X(R(_),2),{get onclick(){return it}}),f(_);var v=X(_,2),b=R(v),x=R(b),C=R(x);f(x);var w=X(x,2),T=R(w);s(T);var D=X(T,4);f(w);var O=X(w,4),M=R(O,!0);f(O),f(b);var N=X(b,2),P=R(N),F=X(R(P),2);let I;var ee=R(F,!0);f(F),f(P);var te=X(P,2),z=e=>{var t=US(),n=R(t,!0);f(t),U(()=>G(n,B(c))),g(e,t)};p(te,e=>{B(c)&&e(z)});var ne=X(te,2),re=R(ne),ie=e=>{g(e,WS())},ae=e=>{var t=L();m(q(t),17,()=>B(a),e=>e.id,(e,t)=>{var n=KS();let r;var i=R(n),a=R(i,!0);f(i);var o=X(i,2),s=e=>{g(e,GS())};p(o,e=>{_i.info?.id===B(t).id&&e(s)});var c=X(o,2),l=R(c,!0);f(c);var u=X(c,2),d=R(u);f(u),f(n),U(()=>{r=y(n,1,`svelte-1aevcja`,null,r,{active:_i.info?.id===B(t).id}),G(a,B(t).id),G(l,B(t).model_id),G(d,`${B(t).device??``}/${B(t).dtype??``} · ${B(t).profiles.length??``} profiles · ${B(t).probes.length??``} probes`)}),g(e,n)}),g(e,t)};p(re,e=>{B(a).length===0?e(ie):e(ae,-1)}),f(ne),f(N),f(v),f(h),U(()=>{S(C,`for`,r),S(T,`id`,r),G(M,B(l)?`API key updated for this tab.`:``),S(F,`aria-busy`,B(o)),F.disabled=B(o),I=y(F,1,`svelte-1aevcja`,null,I,{"loading-pulse":B(o)}),G(ee,B(o)?`Loading…`:`Refresh sessions`)}),ye(`submit`,w,e=>{e.preventDefault(),d()}),K(`input`,T,()=>A(l,!1)),j(T,()=>B(i),e=>A(i,e)),K(`click`,D,()=>{A(i,``),d()}),K(`click`,F,u),g(e,h),W()}H([`input`,`click`]);var YS=I(``),XS=I(`

                              System prompt

                              Sets the default system prompt for new generations in this session. - Per-request OpenAI or Ollama system messages take precedence. Leaving it - empty clears the system prompt.

                              `);function ZS(e,t){n(t,!0),k(t,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{t.params});let r=J(V(_i.info?.config.system_prompt??``)),i=J(!1),a=J(null);async function o(){if(!B(i)){A(i,!0),A(a,null);try{await ki({system_prompt:B(r)}),it()}catch(e){e instanceof se?A(a,je(e,`Unable to save the system prompt. ${e.body&&typeof e.body==`object`&&`detail`in e.body?String(e.body.detail):e.message}`),!0):A(a,je(e,`Unable to save the system prompt. Try again.`),!0)}finally{A(i,!1)}}}var s=XS(),c=R(s);ft(X(R(c),2),{get onclick(){return it}}),f(c);var l=X(c,2),u=X(R(l),2),d=X(R(u),2);_e(d);var m=X(d,2),h=R(m);f(m),f(u);var _=X(u,2),v=e=>{var t=YS(),n=R(t,!0);f(t),U(()=>G(n,B(a))),g(e,t)};p(_,e=>{B(a)&&e(v)}),f(l);var b=X(l,2),x=R(b),C=X(x,2);let w;var T=R(C,!0);f(C),f(b),f(s),U(()=>{d.disabled=B(i),G(h,`${B(r).length??``} char${B(r).length===1?``:`s`}`),x.disabled=B(i),w=y(C,1,`btn primary svelte-ao4ksi`,null,w,{"loading-pulse":B(i)}),S(C,`aria-busy`,B(i)),C.disabled=B(i),G(T,B(i)?`Saving…`:`Save system prompt`)}),j(d,()=>B(r),e=>A(r,e)),K(`click`,x,function(...e){it?.apply(this,e)}),K(`click`,C,o),g(e,s),W()}H([`click`]);function QS(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``)}var $S=/^[a-z][a-z0-9_-]{0,63}$/;function eC(e,t={}){let n=t.contextLabel??`context`,r=[],i=e.slot.trim();i||r.push(`slot required`);let a=e.values.filter(e=>e.trim());a.length<2&&r.push(`≥ 2 values`);let o=new Set;for(let e of a){let t=QS(e);$S.test(t)?o.has(t)?r.push(`value "${e}" collides with another value's label`):o.add(t):r.push(`value "${e}" is not a valid node label`)}return e.contexts.length===0&&r.push(`at least one ${n} required`),e.contexts.forEach((e,t)=>{let a=`${n} ${t+1}`;e.turns.length===0?r.push(`${a}: needs a history turn`):(e.turns.some(e=>!e.content.trim())&&r.push(`${a}: every history turn needs text`),e.turns[e.turns.length-1].role!==`user`&&r.push(`${a}: last turn must be user`),i&&e.turns.some(e=>e.content.includes(i))&&r.push(`${a}: slot must not appear in a history turn`)),e.assistant.trim()?i&&e.assistant.split(i).length-1!=1&&r.push(`${a}: slot must appear once in the assistant turn`):r.push(`${a}: assistant turn required`)}),r}var tC=I(`

                              Loading templates…

                              `),nC=I(`

                              no templates

                              `),rC=I(`
                              `),iC=I(` `,1),aC=I(`
                              `),oC=I(`
                              `),sC=I(`
                              `,1),cC=I(`

                              Compare the model's preference among a fixed set of answers.

                              `,1),lC=I(``),uC=I(``),dC=I(`
                              `),fC=I(`
                              `),pC=I(`
                            • `),mC=I(`
                                `),hC=I(`
                                contexts
                                `),gC=I(`

                                `),_C=I(`
                                `),vC=I(`
                                installed
                                `),yC=I(`

                                Prompt template lab

                                `);function bC(t,r){n(r,!0);let i=J(V(De(()=>r.params?.tab===`build`?`build`:`score`))),o=[{value:`score`,label:`score`,title:`restricted-choice scores`},{value:`build`,label:`build`,title:`new template`}],l=J(V([])),u=J(!1),d=J(null),h=J(!1);async function _(){A(u,!0);try{A(l,(await Dt.list()).templates,!0)}catch(e){Z(`couldn't load templates: ${te(e)}`,{kind:`error`})}finally{A(u,!1)}}ne(_);let v=J(``),y=J(``),b=J(!1),x=J(`sum`),C=J(null),w=J(null),E=J(``),D=J(!1),O=re(),k=c(()=>B(l).find(e=>`${e.namespace}/${e.name}`===B(v))??null);function M(e){return B(x)===`sum`?e.prob_sum:e.prob_mean}async function P(){if(!B(k)||B(b))return;A(b,!0),A(D,!1),A(C,null),A(w,null);let{namespace:e,name:t}=B(k);try{A(C,(await Dt.score(e,t,null)).contexts,!0);let n=B(y).trim();n&&A(w,(await Dt.score(e,t,n)).contexts,!0),A(E,B(v),!0)}catch(e){A(C,null),A(w,null),A(E,``),oy(e)?Z(`scoring cancelled`,{kind:`info`}):Z(`scoring failed: ${te(e)}`,{kind:`error`})}finally{A(b,!1),A(D,!1)}}async function F(){if(!(!O||!B(b)||B(D))){A(D,!0);try{await O.cancelFitting()}catch(e){Z(`couldn't cancel scoring: ${te(e)}`,{kind:`error`,ttlMs:null})}finally{A(D,!1)}}}function I(e){let t=B(C)?.[e];if(!t)return[];let n=B(w)?.[e]??null,r=t.choices.map((e,t)=>({label:e.label,base:M(e),steer:n?M(n.choices[t]):null}));return r.sort((e,t)=>Math.max(t.base,t.steer??-1)-Math.max(e.base,e.steer??-1)),r}let ee=J(``),z=J(`[DAY]`),ie=J(``),ae=J(V([{turns:[{role:`user`,content:``}],assistant:``}])),oe=J(!1),H=J(!1),se=J(null),ce=c(()=>B(ie).split(/[\n,]+/).map(e=>e.trim()).filter(Boolean));function le(){A(ae,[...B(ae),{turns:[{role:`user`,content:``}],assistant:``}],!0)}function ue(e){A(ae,B(ae).filter((t,n)=>n!==e),!0)}function de(e){let t=B(ae)[e],n=t.turns[t.turns.length-1]?.role===`user`?`assistant`:`user`;t.turns=[...t.turns,{role:n,content:``}],A(ae,[...B(ae)],!0)}function fe(e,t){B(ae)[e].turns=B(ae)[e].turns.filter((e,n)=>n!==t),A(ae,[...B(ae)],!0)}let me=c(()=>({slot:B(z),values:B(ce),contexts:B(ae).map(e=>({turns:e.turns.filter(e=>e.content.trim()),assistant:e.assistant}))})),he=c(()=>[...B(ee).trim()?[]:[`name required`],...eC(B(me))]),ge=c(()=>!B(ee).trim()),ve=c(()=>B(he).includes(`slot required`)),be=c(()=>B(he).some(e=>e===`≥ 2 values`||e.startsWith(`value "`))),Se=e=>B(he).some(t=>t.startsWith(`context ${e+1}:`)),Ce=e=>B(H)&&e?`template-build-errors`:void 0;async function we(e){if(e.preventDefault(),B(he).length){A(H,!0),await xe(),B(se)?.querySelector(`[aria-invalid="true"]`)?.focus();return}A(oe,!0);try{await Dt.create({namespace:`local`,name:B(ee).trim(),slot:B(z).trim(),values:B(ce),contexts:B(me).contexts}),Z(`template ${B(ee).trim()} created`,{kind:`info`}),await _(),A(v,`local/${B(ee).trim()}`),A(i,`score`)}catch(e){Z(`create failed: ${te(e)}`,{kind:`error`})}finally{A(oe,!1)}}async function Te(e){if(!B(h)){A(h,!0);try{await Dt.delete(e.namespace,e.name),Z(`removed ${e.namespace}/${e.name}`,{kind:`info`}),B(v)===`${e.namespace}/${e.name}`&&A(v,``),await _(),A(d,null)}catch(e){Z(`delete failed: ${te(e)}`,{kind:`error`})}finally{A(h,!1)}}}var Ee=yC(),Oe=R(Ee);ft(X(R(Oe),2),{get onclick(){return it}}),f(Oe);var ke=X(Oe,2);Fc(R(ke),{get items(){return o},ariaLabel:`Template lab view`,get value(){return B(i)},set value(e){A(i,e,!0)}}),f(ke);var Ae=X(ke,2),je=R(Ae),Me=t=>{var n=cC(),r=X(q(n),2),i=e=>{g(e,tC())},a=e=>{g(e,nC())},o=t=>{var n=sC(),r=q(n),i=X(R(r),2);{let e=c(()=>[{value:``,label:`Select…`},...B(l).map(e=>({value:`${e.namespace}/${e.name}`,label:`${e.namespace}/${e.name} · ${e.n_values} values × ${e.n_contexts} ctx`}))]);hu(i,{get disabled(){return B(b)},ariaLabel:`Template`,get options(){return B(e)},get value(){return B(v)},set value(e){A(v,e,!0)}})}f(r);var a=X(r,2),o=X(R(a),2);s(o),f(a);var u=X(a,2),d=R(u);hu(X(R(d),2),{ariaLabel:`Rank by`,options:[{value:`sum`,label:`sum`},{value:`mean`,label:`mean`}],get value(){return B(x)},set value(e){A(x,e,!0)}}),f(d);var h=X(d,2),_=t=>{Du(t,{variant:`ghost`,get disabled(){return B(D)},onclick:F,children:(t,n)=>{T();var r=e();U(()=>G(r,B(D)?`cancelling…`:`cancel`)),g(t,r)},$$slots:{default:!0}})};p(h,e=>{O&&B(b)&&e(_)});var M=X(h,2);{let t=c(()=>!B(k)||B(b));Du(M,{variant:`solid`,get busy(){return B(b)},get disabled(){return B(t)},onclick:P,children:(t,n)=>{T();var r=e();U(()=>G(r,B(b)?`scoring…`:`score`)),g(t,r)},$$slots:{default:!0}})}f(u);var ee=X(u,2),te=e=>{var t=L();m(q(t),17,()=>B(C),N,(e,t,n)=>{var r=oC(),i=R(r),a=R(i);f(i),m(X(i,2),17,()=>I(n),e=>e.label,(e,t)=>{var n=aC(),r=R(n),i=R(r,!0);f(r);var a=X(r,2),o=R(a),s=X(o,2),c=e=>{var n=rC();U(e=>pe(n,e),[()=>`width:${(B(t).steer*100).toFixed(1)}%`]),g(e,n)};p(s,e=>{B(t).steer!==null&&e(c)}),f(a);var l=X(a,2),u=R(l),d=X(u),m=e=>{var n=iC(),r=X(q(n));U(e=>G(r,`${e??``}%`),[()=>(B(t).steer*100).toFixed(0)]),g(e,n)};p(d,e=>{B(t).steer!==null&&e(m)}),f(l),f(n),U((e,n)=>{S(r,`title`,B(t).label),G(i,B(t).label),pe(o,e),G(u,`${n??``}%`)},[()=>`width:${(B(t).base*100).toFixed(1)}%`,()=>(B(t).base*100).toFixed(0)]),g(e,n)}),f(r),U(()=>G(a,`context ${n+1}${B(w)?` · base → steered`:``}`)),g(e,r)}),g(e,t)};p(ee,e=>{B(C)&&B(E)===B(v)&&e(te)}),U(()=>o.disabled=B(b)),j(o,()=>B(y),e=>A(y,e)),g(t,n)};p(r,e=>{B(u)?e(i):B(l).length===0?e(a,1):e(o,-1)}),g(t,n)},Y=t=>{var n=hC(),r=R(n),i=X(R(r),2);s(i),f(r);var o=X(r,2),l=X(R(o),2);s(l),f(o);var u=X(o,2),d=X(R(u),2);_e(d),S(d,`placeholder`,`Monday -Tuesday -Wednesday`),f(u);var h=X(u,2),_=R(h),v=X(R(_)),y=R(v);f(v),f(_);var b=X(_,2);m(b,17,()=>B(ae),N,(e,t,n)=>{var r=fC(),i=R(r),a=R(i);a.textContent=`context ${n+1}`;var o=X(a,2),l=e=>{var t=lC();S(t,`aria-label`,`Remove context ${n+1}`),K(`click`,t,()=>ue(n)),g(e,t)};p(o,e=>{B(ae).length>1&&e(l)}),f(i);var u=X(i,2);m(u,17,()=>B(t).turns,N,(e,r,i)=>{var a=dC(),o=R(a);{let e=c(()=>B(H)&&Se(n)),t=c(()=>Ce(Se(n)));hu(o,{get disabled(){return B(oe)},ariaLabel:`Context ${n+1}, turn ${i+1} role`,get invalid(){return B(e)},get ariaDescribedby(){return B(t)},options:[{value:`user`,label:`user`},{value:`assistant`,label:`assistant`},{value:`system`,label:`system`}],get value(){return B(r).role},set value(e){B(r).role=e}})}var l=X(o,2);s(l),S(l,`aria-label`,`Context ${n+1}, turn ${i+1} content`);var u=X(l,2),d=e=>{var t=uC();S(t,`aria-label`,`Remove turn ${i+1} from context ${n+1}`),Be(R(t),{name:`dismiss`}),f(t),K(`click`,t,()=>fe(n,i)),g(e,t)};p(u,e=>{B(t).turns.length>1&&e(d)}),f(a),U((e,t)=>{l.disabled=B(oe),S(l,`aria-invalid`,e),S(l,`aria-describedby`,t)},[()=>B(H)&&Se(n),()=>Ce(Se(n))]),j(l,()=>B(r).content,e=>B(r).content=e),g(e,a)});var d=X(u,2);S(d,`aria-label`,`Add turn to context ${n+1}`);var h=X(d,2),_=X(R(h),2);s(_),f(h),f(r),U((e,t)=>{S(_,`placeholder`,`today is ${B(z)}`),_.disabled=B(oe),S(_,`aria-invalid`,e),S(_,`aria-describedby`,t)},[()=>B(H)&&Se(n),()=>Ce(Se(n))]),K(`click`,d,()=>de(n)),j(_,()=>B(t).assistant,e=>B(t).assistant=e),g(e,r)});var x=X(b,2);f(h);var C=X(h,2),w=e=>{var t=mC();m(t,20,()=>B(he),e=>e,(e,t)=>{var n=pC(),r=R(n,!0);f(n),U(()=>G(r,t)),g(e,n)}),f(t),g(e,t)};p(C,e=>{B(H)&&B(he).length&&e(w)});var E=X(C,2),D=R(E);Du(D,{variant:`ghost`,get onclick(){return it},children:(t,n)=>{T(),g(t,e(`cancel`))},$$slots:{default:!0}}),Du(X(D,2),{type:`submit`,variant:`solid`,get busy(){return B(oe)},get disabled(){return B(oe)},children:(t,n)=>{T();var r=e();U(()=>G(r,B(oe)?`creating…`:`create template`)),g(t,r)},$$slots:{default:!0}}),f(E),f(n),a(n,e=>A(se,e),()=>B(se)),U((e,t,r)=>{S(n,`aria-busy`,B(oe)),i.disabled=B(oe),S(i,`aria-invalid`,B(H)&&B(ge)),S(i,`aria-describedby`,e),l.disabled=B(oe),S(l,`aria-invalid`,B(H)&&B(ve)),S(l,`aria-describedby`,t),d.disabled=B(oe),S(d,`aria-invalid`,B(H)&&B(be)),S(d,`aria-describedby`,r),G(y,`(${B(ae).length??``})`)},[()=>Ce(B(ge)),()=>Ce(B(ve)),()=>Ce(B(be))]),ye(`submit`,n,we),j(i,()=>B(ee),e=>A(ee,e)),j(l,()=>B(z),e=>A(z,e)),j(d,()=>B(ie),e=>A(ie,e)),K(`click`,x,le),g(t,n)};p(je,e=>{B(i)===`score`?e(Me):e(Y,-1)});var Ne=X(je,2),Pe=t=>{var n=vC();m(X(R(n),2),17,()=>B(l),e=>`${e.namespace}/${e.name}`,(t,n)=>{var r=_C(),i=R(r),a=R(i);f(i);var o=X(i,2),s=R(o);f(o);var l=X(o,2),u=t=>{var r=gC(),i=R(r),a=R(i);f(i);var o=X(i,2);Du(o,{variant:`ghost`,size:`sm`,get disabled(){return B(h)},onclick:()=>A(d,null),children:(t,n)=>{T(),g(t,e(`Cancel`))},$$slots:{default:!0}}),Du(X(o,2),{variant:`danger`,size:`sm`,get disabled(){return B(h)},onclick:()=>Te(B(n)),children:(t,n)=>{T();var r=e();U(()=>G(r,B(h)?`Deleting…`:`Delete template`)),g(t,r)},$$slots:{default:!0}}),f(r),U(()=>G(a,`Delete ${B(n).namespace??``}/${B(n).name??``}? This removes the saved template and cannot be undone.`)),g(t,r)},m=t=>{{let r=c(()=>`Delete template ${B(n).namespace}/${B(n).name}`);Du(t,{variant:`danger`,size:`sm`,get disabled(){return B(h)},get ariaLabel(){return B(r)},onclick:()=>A(d,`${B(n).namespace}/${B(n).name}`),children:(t,n)=>{T(),g(t,e(`Delete…`))},$$slots:{default:!0}})}};p(l,e=>{B(d)===`${B(n).namespace}/${B(n).name}`?e(u):e(m,-1)}),f(r),U(()=>{G(a,`${B(n).namespace??``}/${B(n).name??``}`),G(s,`${B(n).slot??``} · ${B(n).n_values??``}×${B(n).n_contexts??``}`)}),g(t,r)}),f(n),g(t,n)};p(Ne,e=>{B(l).length>0&&e(Pe)}),f(Ae),f(Ee),g(t,Ee),W()}H([`click`]);var xC=I(``),SC=I(`
                                `,1),CC=I(`

                                Export the active conversation path, or end at a specific node.

                                `),wC=I(``),TC=I(`
                              • `),EC=I(``),DC=I(`

                                imported · leaf

                                `),OC=I(`

                                Import a Drowse transcript from a local YAML file or pasted text.

                                place imported turns
                                `),kC=I(`

                                Conversation transcript

                                `);function AC(e,r){n(r,!0),k(r,[`$$slots`,`$$events`,`$$legacy`]),Ce(()=>{r.params});let i=J(`export`);function o(e){A(i,e,!0)}function c(e){let t=[`export`,`import`],n=t.indexOf(B(i)),r=n;if(e.key===`ArrowRight`)r=(n+1)%t.length;else if(e.key===`ArrowLeft`)r=(n-1+t.length)%t.length;else if(e.key===`Home`)r=0;else if(e.key===`End`)r=t.length-1;else return;e.preventDefault(),o(t[r]),document.getElementById(`transcript-${t[r]}-tab`)?.focus()}let l=J(``),u=J(``),d=J(null),h=J(!1),_=J(null);async function v(){if(!B(h)){A(h,!0),A(d,null),A(u,``),A(_,null);try{let e=B(l).trim(),t=null;if(e){let n=C(e);if(n.id)t=n.id;else if(n.matches.length===0){A(d,`no node matches prefix "${e}"`);return}else{let e=n.matches.slice(0,6).map(e=>e.slice(0,8)).join(`, `);A(d,`ambiguous: ${n.matches.length} matches (${e}`+(n.matches.length>6?`, …`:``)+`)`);return}}let n=await Ot.transcriptExport(t);A(u,n.yaml,!0),A(_,n.node_id,!0)}catch(e){A(d,te(e),!0)}finally{A(h,!1)}}}function b(){if(!B(u))return;let e=new Blob([B(u)],{type:`application/yaml;charset=utf-8`}),t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`drowse-transcript-${B(_)?B(_).slice(0,8):`active`}.yaml`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}async function x(){if(B(u))try{await navigator.clipboard.writeText(B(u))}catch{}}function C(e){let t=e.trim();if(!t)return{id:null,matches:[]};if(t===`root`){let e=Q.root_id;return e?{id:e,matches:[e]}:{id:null,matches:[]}}let n=[];for(let e of Q.nodes.keys()){if(e===t)return{id:e,matches:[e]};e.startsWith(t)&&n.push(e)}return n.length===1?{id:n[0],matches:n}:{id:null,matches:n}}let E=J(``),D=J(`default`),O=J(!1),M=J(null),N=J(!1),P=J(V([])),F=J(null),I=J(null);async function L(e){let t=e.target.files?.[0];t&&A(E,await t.text(),!0)}async function ee(){if(B(N))return;let e=B(E).trim();if(!e){A(M,`paste a transcript YAML or upload a file`);return}A(N,!0),A(M,null),A(P,[],!0),A(F,null);try{let t=await Ot.transcriptLoad(e,B(D),B(O));A(P,t.guards,!0),A(F,t.leaf_id,!0),await go()}catch(e){A(M,te(e),!0)}finally{A(N,!1)}}var z=kC(),ne=R(z),re=X(R(ne),2),ie=R(re);let ae;var oe=X(ie,2);let H;f(re),w(re,e=>Ac?.(e)),ft(X(re,2),{get onclick(){return it}}),f(ne);var se=X(ne,2),ce=R(se),le=e=>{var n=CC(),r=X(R(n),2),i=X(R(r),2);s(i),f(r);var a=X(r,2),o=R(a),c=R(o,!0);f(o),f(a);var m=X(a,2),_=e=>{var t=xC(),n=R(t,!0);f(t),U(()=>G(n,B(d))),g(e,t)};p(m,e=>{B(d)&&e(_)});var y=X(m,2),C=e=>{var n=SC(),r=q(n);_e(r);var i=X(r,2),a=R(i),o=X(a,2);f(i),U(()=>t(r,B(u))),K(`click`,a,x),K(`click`,o,b),g(e,n)};p(y,e=>{B(u)&&e(C)}),f(n),U(e=>{S(i,`placeholder`,e),o.disabled=B(h),G(c,B(h)?`preparing…`:`preview YAML`)},[()=>`Active node · ${Q.active_node_id?.slice(0,12)??`-`}`]),j(i,()=>B(l),e=>A(l,e)),K(`click`,o,v),g(e,n)},ue=e=>{var t=OC(),n=X(R(t),2),r=X(R(n),2);gv(r,{value:`default`,label:`start a new path at the root`,get group(){return B(D)},set group(e){A(D,e,!0)}});var i=X(r,2);gv(i,{value:`here`,label:`continue from the active node`,get group(){return B(D)},set group(e){A(D,e,!0)}}),gv(X(i,2),{value:`merge`,label:`merge after the deepest matching turn`,get group(){return B(D)},set group(e){A(D,e,!0)}}),f(n);var o=X(n,2);tv(R(o),{label:`Require matching reading settings`,get checked(){return B(O)},set checked(e){A(O,e,!0)}}),f(o);var s=X(o,2),c=X(R(s),2);a(c,e=>A(I,e),()=>B(I)),f(s);var l=X(s,2);_e(l);var u=X(l,2),d=R(u),h=R(d,!0);f(d),f(u);var _=X(u,2),v=e=>{var t=wC(),n=R(t,!0);f(t),U(()=>G(n,B(M))),g(e,t)};p(_,e=>{B(M)&&e(v)});var y=X(_,2),b=e=>{var t=EC(),n=X(R(t),2);m(n,20,()=>B(P),e=>e,(e,t)=>{var n=TC(),r=R(n,!0);f(n),U(()=>G(r,t)),g(e,n)}),f(n),T(2),f(t),g(e,t)};p(y,e=>{B(P).length>0&&e(b)});var x=X(y,2),S=e=>{var t=DC(),n=X(R(t)),r=R(n,!0);f(n),f(t),U(e=>G(r,e),[()=>B(F).slice(0,12)]),g(e,t)};p(x,e=>{B(F)&&!B(M)&&e(S)}),f(t),U(()=>{d.disabled=B(N),G(h,B(N)?`importing…`:`import`)}),K(`change`,c,L),j(l,()=>B(E),e=>A(E,e)),K(`click`,d,ee),g(e,t)};p(ce,e=>{B(i)===`export`?e(le):e(ue,-1)}),f(se);var de=X(se,2),fe=R(de);f(de),f(z),U(()=>{ae=y(ie,1,`tab svelte-1yqeqxz`,null,ae,{active:B(i)===`export`}),S(ie,`aria-selected`,B(i)===`export`),S(ie,`tabindex`,B(i)===`export`?0:-1),H=y(oe,1,`tab svelte-1yqeqxz`,null,H,{active:B(i)===`import`}),S(oe,`aria-selected`,B(i)===`import`),S(oe,`tabindex`,B(i)===`import`?0:-1)}),K(`click`,ie,()=>o(`export`)),K(`keydown`,ie,c),K(`click`,oe,()=>o(`import`)),K(`keydown`,oe,c),K(`click`,fe,function(...e){it?.apply(this,e)}),g(e,z),W()}H([`click`,`keydown`,`change`]);var jC=[{key:`manifolds`,label:`Shape responses`},{key:`analysis`,label:`Understand responses`},{key:`session`,label:`Settings and help`}],MC={appearance:{component:_p,narrow:!0,launcher:{group:`session`,label:`Appearance…`,keywords:`theme background wallpaper image pixel dither`}},surface_geometry:{component:Ty,narrow:!0,launcher:{group:`analysis`,label:`Inspect surface geometry…`,keywords:`topology manifold Klein bottle projective plane sphere torus`}},manifold_builder:{component:yy,narrow:!0,launcher:{group:`manifolds`,label:`Create a concept or scale…`,keywords:`extract author create concept vector fit`}},manifold_merge:{component:My,launcher:{group:`manifolds`,label:`Combine response controls…`,keywords:`union corpora`}},manifold_pack:{component:ub,launcher:{group:`manifolds`,label:`Manage downloaded controls…`,keywords:`pack packs install search huggingface hub catalog`}},template_lab:{component:bC,launcher:{group:`manifolds`,label:`Test prompt templates…`,keywords:`score completion slot restricted choice`}},cast:{component:Ep,launcher:{group:`manifolds`,label:`Role settings…`,keywords:`role behavior guidance speaker`}},correlation:{component:em,launcher:{group:`analysis`,label:`Compare saved readings…`,keywords:`cosine similarity vectors`}},compare:{component:Hp,launcher:{group:`analysis`,label:`Compare controls by layer…`,keywords:`cross-layer cosine`}},health:{component:gm,launcher:{group:`session`,label:`Model health…`,keywords:`device dtype`}},session_admin:{component:JS,launcher:{group:`session`,label:`API access…`,keywords:`auth api key bearer`}},local_runtime:{component:A_,launcher:{group:`session`,label:`Model settings…`,keywords:`local device model storage gpu webgpu offline delete unload switch diagnostics`}},help:{component:xm,launcher:{group:`session`,label:`Help and shortcuts…`,keywords:`keyboard grammar cheatsheet`}},subspace:{component:ES,params:{family:`subspace`},narrow:!0,launcher:null,via:`the steering and probe racks' "+ add" buttons`},manifolds:{component:ES,params:{family:`manifold`},narrow:!0,launcher:null,via:`the steering and probe racks' "+ add" buttons`},save_conversation:{component:FS,narrow:!0,launcher:{group:`session`,label:`Save current chat…`,keywords:`conversation name local storage backup`}},download_chat:{component:HS,narrow:!0,launcher:null,via:`the workbench header download button`},load_conversation:{component:O_,narrow:!0,launcher:{group:`session`,label:`Saved chats…`,keywords:`conversation library open rename avatar delete import backup`}},system_prompt:{component:ZS,narrow:!0,launcher:null,via:`the sampling strip's system-prompt button`},advanced_sampling:{component:cp,launcher:null,via:`the sampling strip's advanced button`},token_drilldown:{component:jf,launcher:null,via:`selecting a transcript or raw-buffer token`},probe_inspector:{component:Ox,launcher:null,via:`a probe card's ⓘ button`},node_compare:{component:zb,launcher:null,via:`the loom sidebar's compare actions`},transcript:{component:AC,launcher:{group:`analysis`,label:`Conversation transcript…`,keywords:`transcript export import yaml conversation`}}};function NC(e,t){let n=MC[e].params;return n?{...t,...n}:t}var PC=jC.map(e=>{let t=[];for(let[n,r]of Object.entries(MC))r.launcher===null||r.launcher.group!==e.key||St.mode===`http`&&n===`local_runtime`||St.mode!==`http`&&n===`health`||St.mode!==`http`&&n===`session_admin`||Ke(n).available&&t.push({label:r.launcher.label,drawer:n,keywords:r.launcher.keywords});return{key:e.key,label:e.label,tools:t}}),FC=I(``);function IC(e,r){n(r,!0);let i=Y(r,`value`,15),a=Y(r,`min`,3,0),o=Y(r,`max`,3,1),c=Y(r,`step`,3,.01),l=Y(r,`disabled`,3,!1);function u(e){let t=parseFloat(e.currentTarget.value);Number.isFinite(t)&&(i(t),r.oninput?.(t))}let d=null;function f(e){if(!d||e.pointerId!==d.id||l())return;let t=e.currentTarget,n=t.getBoundingClientRect(),s=Math.max(1,n.width-20),u=getComputedStyle(t).direction===`rtl`,f=Math.max(0,Math.min(1,(e.clientX-n.left-10-d.offset)/s)),p=a()+(u?1-f:f)*(o()-a());t.value=String(Math.max(a(),Math.min(o(),a()+Math.round((p-a())/c())*c()))),i(t.valueAsNumber),r.oninput?.(i())}function p(e){if(l()||e.button!==0||!e.isPrimary)return;e.preventDefault();let t=e.currentTarget,n=t.getBoundingClientRect(),r=o()===a()?0:(i()-a())/(o()-a()),s=n.left+10+(getComputedStyle(t).direction===`rtl`?1-r:r)*(n.width-20),c=e.clientX-s;d={id:e.pointerId,offset:Math.abs(c)<=12?c:0},t.focus({preventScroll:!0}),t.setPointerCapture(e.pointerId),f(e)}function m(e){if(d?.id!==e.pointerId)return;d=null;let t=e.currentTarget;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId)}var h=FC();s(h),U(()=>{S(h,`min`,a()),S(h,`max`,o()),S(h,`step`,c()),t(h,i()),h.disabled=l(),S(h,`title`,r.title),S(h,`aria-label`,r.ariaLabel)}),K(`input`,h,u),K(`pointerdown`,h,p),K(`pointermove`,h,f),K(`pointerup`,h,m),ye(`pointercancel`,h,m),ye(`lostpointercapture`,h,m),g(e,h),W()}H([`input`,`pointerdown`,`pointermove`,`pointerup`]);var LC=I(`

                                `),RC=I(``),zC=I(`
                                `);function BC(e,t){n(t,!0);let r=Y(t,`locked`,3,!1),i=c(()=>{let e=t.manifold.domain;if(e.type===`klein`)return[{name:`u (rad)`,lo:0,hi:2*Math.PI,periodic:!1},{name:`v (rad)`,lo:0,hi:2*Math.PI,periodic:!1}];if(e.type===`projective`)return[{name:`Polar (rad)`,lo:0,hi:Math.PI,periodic:!1},{name:`Azimuth (rad)`,lo:0,hi:2*Math.PI,periodic:!1}];if(e.type===`box`)return e.axes.map(e=>({name:e.name,lo:e.lo,hi:e.hi,periodic:e.periodic}));let n=t.manifold.intrinsic_dim,r=t.manifold.node_coords??[];return Array.from({length:n},(e,t)=>{let n=1;if(r.length>0){let e=0;for(let n of r){let r=n?.[t];if(Number.isFinite(r)){let t=Math.abs(r);t>e&&(e=t)}}e>0&&(n=Math.max(1,Math.ceil(e)))}return{name:`c${t}`,lo:-n,hi:n,periodic:!1}})});function a(e,t){let n=e.hi-e.lo;if(n<=0)return e.lo;if(e.periodic){let r=(t-e.lo)%n;return r<0&&(r+=n),e.lo+r}return Math.min(e.hi,Math.max(e.lo,t))}function o(e,n){let r=t.coords.slice();r[e]=a(B(i)[e],n),t.onchange(r)}function s(e){return Number.isFinite(e)?e.toFixed(2):`0.00`}var l=zC();let u;var d=R(l),h=e=>{var n=LC(),r=R(n,!0);f(n),U(e=>G(r,e),[()=>X_(t.manifold.domain)]),g(e,n)},_=c(()=>X_(t.manifold.domain));p(d,e=>{B(_)&&e(h)});var v=X(d,2);m(v,21,()=>B(i),N,(e,n,i)=>{var a=RC(),l=R(a),u=R(l);f(l);var d=X(l,2);{let e=c(()=>t.coords[i]??B(n).lo),a=c(()=>(B(n).hi-B(n).lo)/100||.01);IC(d,{get value(){return B(e)},get min(){return B(n).lo},get max(){return B(n).hi},get step(){return B(a)},oninput:e=>o(i,e),get ariaLabel(){return`${B(n).name??``} coordinate`},get disabled(){return r()}})}var p=X(d,2),m=R(p,!0);f(p),f(a),U(e=>{G(u,`${B(n).name??``}${B(n).periodic?` ↻`:``}`),G(m,e)},[()=>s(t.coords[i]??B(n).lo)]),g(e,a)}),f(v),f(l),U(()=>u=y(l,1,`xypad svelte-199ax72`,null,u,{locked:r()})),g(e,l),W()}var VC=[`BOTH`,`BEFORE`,`AFTER`,`THINKING`,`RESPONSE`,`PROMPT`,`GENERATED`],HC={BOTH:`both`,BEFORE:`before`,AFTER:`after`,THINKING:`thinking`,RESPONSE:`response`,PROMPT:`prompt`,GENERATED:`generated`},UC={BOTH:`both: steer the whole turn (default)`,BEFORE:`before: steer thinking and response`,AFTER:`after: steer the after-thinking response only`,THINKING:`thinking: steer the chain-of-thought only`,RESPONSE:`response: steer the generated response only`,PROMPT:`prompt (alias of before)`,GENERATED:`generated (alias of response)`};function WC(e){return VC[(VC.indexOf(e)+1)%VC.length]}var GC=I(`unfitted`),KC=I(`stale`),qC=I(` `,1),JC=I(`
                                `),YC=I(``),XC=I(`

                                removes this direction from the current activation

                                `),ZC=I(`
                                along
                                onto
                                `,1),QC=I(`

                                Uses shared subspace α

                                `),$C=I(` `,1),ew=I(`

                                metadata unavailable

                                `),tw=I(`
                                Trigger
                                `,1);function nw(e,t){n(t,!0);let r=c(()=>t.entry.mode===`subspace`?t.entry:null),i=c(()=>t.entry.mode===`manifold`?t.entry:null),a=c(()=>t.entry.mode===`subspace`),o=c(()=>B(a)?`--accent`:`--pillar-manifold`),s=c(()=>t.name.split(`/`).pop()??t.name),l=c(()=>br(t.name)),u=c(()=>B(l)?.fitted_for_session===!0),d=c(()=>B(l)?.stale===!0),m=c(()=>B(l)?.node_count===1||B(l)?.node_count===2);function h(){let e=WC(t.entry.trigger);t.entry.mode===`subspace`?pr(t.name,e):Lr(t.name,e)}function _(){t.entry.mode===`subspace`?mr(t.name,!t.entry.enabled):Rr(t.name,!t.entry.enabled)}function v(){t.entry.mode===`subspace`?_r(t.name):wr(t.name)}function b(e){let n=e===``?null:e;t.entry.mode===`subspace`?fr(t.name,n):Ir(t.name,n)}function x(e){t.entry.mode===`subspace`?dr(t.name,e):Fr(t.name,e)}let C=c(()=>{let e=B(l)?.node_labels??[],t=B(l)?.node_roles;return[{value:``,label:`(free position)`},...e.map((e,n)=>{let r=t?.[n];return{value:e,label:e+(r?` [role=${r}]`:``)}})]}),T=c(()=>B(r)?.label??B(i)?.label??null),E=c(()=>B(r)?.coords??B(i)?.coords??[]);function D(e){Number.isFinite(e)&&Nr(t.name,e)}function O(e){Number.isFinite(e)&&Pr(t.name,e)}{let n=e=>{var n=qC(),r=q(n);let i;var o=R(r);{let e=c(()=>B(a)?`circle`:`diamond`);Tu(o,{get shape(){return B(e)},get filled(){return t.entry.enabled}})}f(r);var m=X(r,2);let h;var b=R(m,!0);f(m);var x=X(m,2),C=e=>{g(e,GC())},w=e=>{g(e,KC())};p(x,e=>{!B(u)&&B(l)?e(C):B(d)&&e(w,1)});var T=X(x,2);Be(R(T),{name:`dismiss`}),f(T),U(()=>{i=y(r,1,`enable svelte-6dkc1y`,null,i,{off:!t.entry.enabled}),S(r,`aria-pressed`,t.entry.enabled),S(r,`aria-label`,`Toggle steering for ${t.name??``}`),h=y(m,1,`name svelte-6dkc1y`,null,h,{struck:!t.entry.enabled}),S(m,`title`,B(a)?`subspace ${t.name}`:`manifold ${t.name}`),G(b,B(s)),S(T,`aria-label`,`remove ${t.name??``}`)}),K(`click`,r,_),K(`click`,T,v),g(e,n)},k=e=>{var n=tw(),a=q(n),o=X(R(a),2),s=R(o,!0);f(o),f(a);var u=X(a,2),d=e=>{var n=$C(),a=q(n),o=e=>{var n=JC(),i=R(n);let a;var o=X(i,2);let s;f(n),w(n,e=>Ac?.(e)),U(()=>{S(n,`aria-label`,`steering operation for ${t.name??``}`),S(i,`aria-pressed`,!B(r).ablate),a=y(i,1,`svelte-6dkc1y`,null,a,{active:!B(r).ablate}),S(o,`aria-pressed`,B(r).ablate),s=y(o,1,`svelte-6dkc1y`,null,s,{active:B(r).ablate})}),K(`click`,i,()=>hr(t.name,!1)),K(`click`,o,()=>hr(t.name,!0)),g(e,n)};p(a,e=>{B(r)&&B(m)&&e(o)});var s=X(a,2),u=e=>{var t=YC(),n=X(R(t),2),r=R(n);{let e=c(()=>B(T)??``);hu(r,{get value(){return B(e)},get options(){return B(C)},onchange:b,ariaLabel:`snap to node`})}f(n),f(t),g(e,t)};p(s,e=>{!B(r)?.ablate&&B(l).node_labels.length>0&&e(u)});var d=X(s,2),h=e=>{{let t=c(()=>B(T)!==null);BC(e,{get manifold(){return B(l)},get coords(){return B(E)},onchange:x,get locked(){return B(t)}})}};p(d,e=>{B(r)?.ablate||e(h)});var _=X(d,2),v=e=>{g(e,XC())},k=e=>{var n=ZC(),r=q(n),a=X(R(r),2);IC(a,{get value(){return B(i).blend},min:0,max:1,step:.05,oninput:D,get ariaLabel(){return`along fraction for ${t.name??``}`}});var o=X(a,2);Fl(R(o),{get value(){return B(i).blend},digits:2}),f(o),f(r);var s=X(r,2),c=X(R(s),2);IC(c,{get value(){return B(i).onto},min:0,max:1,step:.05,oninput:O,get ariaLabel(){return`onto fraction for ${t.name??``}`}});var l=X(c,2);Fl(R(l),{get value(){return B(i).onto},digits:2}),f(l),f(s),g(e,n)},A=e=>{g(e,QC())};p(_,e=>{B(r)?.ablate?e(v):B(i)?e(k,1):e(A,-1)}),g(e,n)},_=e=>{g(e,ew())};p(u,e=>{B(l)?e(d):e(_,-1)}),U(()=>{S(o,`aria-label`,`trigger for ${t.name??``}: ${t.entry.trigger??``}`),S(o,`title`,UC[t.entry.trigger]),G(s,HC[t.entry.trigger])}),K(`click`,o,h),g(e,n)},A=c(()=>!t.entry.enabled);Cu(e,{get accent(){return B(o)},get disabled(){return B(A)},statline:n,body:k,$$slots:{statline:!0,body:!0}})}W()}H([`click`]);var rw=I(` `),iw=I(` `),aw=I(``),ow=I(`
                                `);function sw(e,t){n(t,!0);let r=Y(t,`live`,3,null),i=Y(t,`liveBusy`,3,!1),a=Y(t,`liveTitle`,3,``),o=Y(t,`sortOptions`,19,()=>[]),s=Y(t,`sortAriaLabel`,3,`Sort cards by`),l=c(()=>t.sortValue!==void 0&&o().length>0),u=c(()=>t.liveLabel??`${t.title} live readings`);var d=ow(),m=R(d),h=R(m),_=R(h,!0);f(h);var v=X(h,2),b=e=>{{let n=c(()=>`About ${t.title}`);tp(e,{get text(){return t.help},get label(){return B(n)}})}};p(v,e=>{t.help&&e(b)});var x=X(v,2),C=e=>{var n=rw(),o=R(n);let s;var l=R(o,!0);f(o);var d=X(o,2),m=e=>{{let n=c(()=>`About ${B(u)}`);tp(e,{get text(){return t.liveHelp},get label(){return B(n)}})}};p(d,e=>{t.liveHelp&&e(m)}),f(n),U(()=>{s=y(o,1,`toggle svelte-nvd0ay`,null,s,{on:r()}),o.disabled=i(),S(o,`title`,a()),S(o,`aria-label`,`${r()?`Turn off`:`Turn on`} ${B(u)}`),S(o,`aria-pressed`,r()),G(l,r()?`Live on`:`Live off`)}),K(`click`,o,function(...e){t.onLiveToggle?.apply(this,e)}),g(e,n)};p(x,e=>{r()!==null&&e(C)});var w=X(x,2),T=e=>{var n=iw(),r=R(n,!0);f(n),U(()=>G(r,t.count)),g(e,n)};p(w,e=>{t.count&&e(T)}),f(m);var E=X(m,2),D=e=>{var n=aw(),r=R(n);hu(R(r),{get value(){return t.sortValue},get options(){return o()},get onchange(){return t.onSortChange},get ariaLabel(){return s()}}),f(r),f(n),g(e,n)};p(E,e=>{B(l)&&e(D)}),f(d),U(()=>G(_,t.title)),g(e,d),W()}H([`click`]);var cw=I(`
                                Subspace α
                                `),lw=I(`
                                `),uw=I(`

                                `),dw=I(``),fw=I(``),pw=I(`
                                `);function mw(e,t){n(t,!0);let r=c(()=>{let e=[...nr.entries.entries()].filter(([,e])=>e.mode===t.family);return e.sort((e,t)=>e[0].localeCompare(t[0])),e}),a=c(()=>B(r).length),o=c(()=>_i.info?.is_base_model?`completion`:`reply`);function s(e){Number.isFinite(e)&&ur(e)}var l=pw(),u=R(l);{let e=c(()=>`${B(a)} term${B(a)===1?``:`s`}`);sw(u,{title:`Steering`,get count(){return B(e)}})}var d=X(u,2),h=e=>{var n=lw(),a=R(n),o=e=>{var t=cw(),n=X(R(t),2);IC(n,{get value(){return nr.subspaceAlong},min:0,max:2,step:.05,oninput:s,ariaLabel:`Subspace steering strength`});var r=X(n,2),i=R(r,!0);f(r),f(t),U(e=>G(i,e),[()=>nr.subspaceAlong.toFixed(2)]),g(e,t)};p(a,e=>{t.family===`subspace`&&e(o)}),m(X(a,2),17,()=>B(r),([e,t])=>e,(e,t)=>{var n=c(()=>i(B(t),2));let r=()=>B(n)[0],a=()=>B(n)[1];nw(e,{get name(){return r()},get entry(){return a()}})}),f(n),g(e,n)},_=e=>{var t=uw(),n=R(t);f(t),U(()=>G(n,`Add a direction to steer the next ${B(o)??``}.`)),g(e,t)};p(d,e=>{B(a)>0?e(h):e(_,-1)});var v=X(d,2);let b;var x=R(v),S=e=>{var t=dw();K(`click`,t,()=>rt(`subspace`)),g(e,t)},C=e=>{var t=fw();K(`click`,t,()=>rt(`manifolds`)),g(e,t)};p(x,e=>{t.family===`subspace`?e(S):e(C,-1)}),f(v),f(l),U(()=>b=y(v,1,`actions svelte-1y71dj`,null,b,{empty:B(a)===0})),g(e,l),W()}H([`click`]);function hw(e,t,n,r){if(e.length===0||!Number.isFinite(r)||r<=0)return{line:``,area:``};let i=e=>(r-Math.max(-r,Math.min(r,e)))/(2*r)*n;if(e.length===1){let n=e[0];if(n===null||!Number.isFinite(n))return{line:``,area:``};let r=i(n).toFixed(2);return{line:`M 0 ${r} L ${t} ${r}`,area:``}}let a=t/(e.length-1),o=[],s=[],c=[],l=0,u=0,d=()=>{o.push(...c),c.length>1&&s.push(...c,`L ${u.toFixed(2)} ${n.toFixed(2)}`,`L ${l.toFixed(2)} ${n.toFixed(2)} Z`),c=[]};for(let t=0;t
                                `),_w=ee(``),vw=ee(` `);function yw(e,t){n(t,!0);let r=Y(t,`width`,3,60),i=Y(t,`height`,3,16),a=Y(t,`cap`,3,1),o=Y(t,`percentage`,3,!1),s=c(()=>t.color??`var(--fg-dim)`),l=c(()=>hw(t.points,r(),i(),a())),u=c(()=>{let e=t.points.filter(e=>e!==null&&Number.isFinite(e));return e.length?`Latest ${Il(e[e.length-1],o())} · range ${Il(Math.min(...e),o())} to ${Il(Math.max(...e),o())} · ${e.length} readings`:`No readings yet`}),d=J(!1);ne(()=>{A(d,!0)});var m=vw(),h=R(m),_=R(h,!0);f(h);var v=X(h),b=e=>{var t=gw();U(()=>{S(t,`d`,B(l).area),S(t,`fill`,B(s))}),g(e,t)};p(v,e=>{B(l).area&&e(b)});var x=X(v),C=e=>{var t=_w();let n;U(()=>{n=y(t,0,`sparkline-line svelte-m9792i`,null,n,{draw:B(d)}),S(t,`d`,B(l).line),S(t,`stroke`,B(s))}),g(e,t)};p(x,e=>{B(l).line&&e(C)}),f(m),U(()=>{S(m,`width`,r()),S(m,`height`,i()),S(m,`viewBox`,`0 0 ${r()??``} ${i()??``}`),S(m,`aria-label`,B(u)),G(_,B(u))}),g(e,m),W()}var bw=ee(``),xw=ee(` `),Sw=ee(` `),Cw=ee(` `),ww=I(`
                                `);function Tw(e,t){n(t,!0);let r=Y(t,`size`,3,168),i=c(()=>{let e=t.info.domain;if(e?.type!==`box`||!Array.isArray(e.axes)||e.axes.length!==2)throw Error(`probe ${t.info.name} has invalid 2D box geometry`);return[e.axes[0],e.axes[1]]});function a(e){let[t]=B(i),n=t.hi-t.lo;return n<=0?0:Math.min(1,Math.max(0,(e-t.lo)/n))}function o(e){let[,t]=B(i),n=t.hi-t.lo;return n<=0?0:1-Math.min(1,Math.max(0,(e-t.lo)/n))}let s=c(()=>{let e=[],n=t.info.node_coords??[];for(let s=0;s{if(!t.trajectory||t.trajectory.length===0)return``;let e=[];for(let n=0;n!t.settled||t.settled.length<2||!Number.isFinite(t.settled[0])||!Number.isFinite(t.settled[1])?null:{cx:a(t.settled[0])*r(),cy:o(t.settled[1])*r()}),d=c(()=>{if(t.settled||!t.trajectory||t.trajectory.length===0)return null;let e=t.trajectory[t.trajectory.length-1];return!Array.isArray(e)||e.length<2||!Number.isFinite(e[0])||!Number.isFinite(e[1])?null:{cx:a(e[0])*r(),cy:o(e[1])*r()}});function h(e){return Number.isFinite(e)?e.toFixed(2):`0.00`}var _=ww();let v;var y=R(_),b=R(y),x=X(b),C=X(x),w=e=>{var t=bw();U(()=>S(t,`d`,B(l))),g(e,t)};p(C,e=>{B(l)&&e(w)});var T=X(C);m(T,17,()=>B(s),e=>e.label,(e,t)=>{var n=xw(),r=R(n),i=R(r,!0);f(r);var a=X(r),o=X(a),s=R(o,!0);f(o),f(n),U(()=>{G(i,B(t).tip),S(a,`cx`,B(t).cx),S(a,`cy`,B(t).cy),S(o,`x`,B(t).cx+5),S(o,`y`,B(t).cy-4),G(s,B(t).label)}),g(e,n)});var E=X(T),D=e=>{var n=Sw(),r=R(n),i=R(r);f(r),f(n),U(e=>{S(n,`cx`,B(d).cx),S(n,`cy`,B(d).cy),G(i,`Live coordinates [${e??``}]`)},[()=>t.trajectory[t.trajectory.length-1].map(e=>Il(e)).join(`, `)]),g(e,n)};p(E,e=>{B(d)&&e(D)});var O=X(E),k=e=>{var n=Cw(),r=R(n),i=R(r);f(r),f(n),U(e=>{S(n,`cx`,B(u).cx),S(n,`cy`,B(u).cy),G(i,`Final coordinates [${e??``}]`)},[()=>t.settled?.map(e=>Il(e)).join(`, `)]),g(e,n)};p(O,e=>{B(u)&&e(k)}),f(y);var A=X(y,2),j=R(A),M=R(j);f(j);var N=X(j,2),P=R(N);f(N),f(A),f(_),U((e,n,a,o,s,c,l,u)=>{v=pe(_,``,v,{"--map-size":`${r()??``}px`}),S(y,`width`,r()),S(y,`height`,r()),S(y,`viewBox`,`0 0 ${r()??``} ${r()??``}`),S(y,`aria-label`,`Manifold ${t.info.name??``} 2D layout`),S(b,`x1`,e),S(b,`x2`,n),S(b,`y2`,r()),S(x,`y1`,a),S(x,`y2`,o),S(x,`x2`,r()),G(M,`${B(i)[0].name??``} ${s??``}…${c??``}`),G(P,`${B(i)[1].name??``} ${l??``}…${u??``}`)},[()=>a(0)*r(),()=>a(0)*r(),()=>o(0)*r(),()=>o(0)*r(),()=>h(B(i)[0].lo),()=>h(B(i)[0].hi),()=>h(B(i)[1].lo),()=>h(B(i)[1].hi)]),g(e,_),W()}var Ew=I(``);function Dw(e,t){let n=Y(t,`disabled`,3,!1);var r=Ew();let i;var a=R(r);let o;Tu(R(a),{get shape(){return t.shape}}),f(a);var s=X(a,2);let c;Tu(R(s),{get shape(){return t.shape},filled:!0}),f(s),f(r),U(()=>{i=y(r,1,`pin svelte-157t8te`,null,i,{pinned:t.pinned}),r.disabled=n(),S(r,`title`,t.title),S(r,`aria-label`,t.ariaLabel),S(r,`aria-pressed`,t.pinned),o=y(a,1,`pin-icon svelte-157t8te`,null,o,{visible:!t.pinned}),c=y(s,1,`pin-icon svelte-157t8te`,null,c,{visible:t.pinned})}),K(`click`,r,function(...e){t.onclick?.apply(this,e)}),g(e,r)}H([`click`]);var Ow=I(`±`,1),kw=I(`@`),Aw=I(` `,1),jw=I(`subspace`),Mw=I(` d=`,1),Nw=I(`-`),Pw=I(``),Fw=I(``),Iw=I(``),Lw=I(` `),Rw=I(` `),zw=I(``),Bw=I(``),Vw=I(`
                                residual
                                `),Hw=I(`
                                `),Uw=I(` `,1);function Ww(t,r){n(r,!0);let i=c(()=>r.entry.info),a=c(()=>B(i).is_affine),o=c(()=>B(a)?`--accent`:`--pillar-manifold`),s=c(()=>B(a)?Tn(B(i).node_coords,0):1),l=c(()=>r.entry.aggregate??r.entry.reading),u=c(()=>B(l)?.fraction??r.entry.savedFraction??null),d=c(()=>B(l)?.coords??r.entry.savedCoordinates??(B(a)&&r.entry.savedAggregate!==null?[r.entry.savedAggregate]:[])),h=c(()=>B(i).intrinsic_dim>0?B(i).intrinsic_dim:B(d).length),_=c(()=>Array.from({length:B(h)},(e,t)=>({i:t,value:B(d)[t]??0,scale:Tn(B(i).node_coords,t)}))),v=c(()=>B(a)&&B(h)===1&&B(i).node_count<=2),b=c(()=>r.entry.sparkline??[]),x=c(()=>fi.target!==null&&pn(fi.target).base===r.name),C=c(()=>r.name.split(`/`).pop()??r.name),w=c(()=>Px(B(i).manifold||r.name)),T=c(()=>B(w).negative===null),E=c(()=>r.entry.nearest.length>0?r.entry.nearest[0]:null),D=c(()=>B(E)?.[0]??``),O=c(()=>B(E)?.[1]??null),k=c(()=>r.entry.aggregate??null),A=c(()=>B(k)?.residual??null),j=c(()=>r.entry.trajectory??[]),M=c(()=>B(l)?.depth_com?.[0]??null),N=c(()=>B(l)?.depth_spread?.[0]??null),P=c(()=>B(i).intrinsic_dim!==2||B(i).domain?.type!==`box`?!1:!!B(i).node_coords&&B(i).node_coords.length>0),F=c(()=>r.entry.perLayer?Object.keys(r.entry.perLayer).sort((e,t)=>Number(e)-Number(t)):[]);function I(e){let t=r.entry.perLayer?.[e];return typeof t!=`number`||!Number.isFinite(t)?`L${e} · no reading`:`L${e} · ${B(a)&&t>=0?`+`:``}${t.toFixed(3)}`}let ee=c(()=>B(F).map(e=>({layer:Number(e),value:r.entry.perLayer?.[e],title:I(e)})));function te(e){return Number.isFinite(e)?e.toFixed(2):`0.00`}function z(e){return e!==null&&Number.isFinite(e)?e.toFixed(2):`-`}function ne(){pi(B(x)?null:r.name)}function V(){rt(`probe_inspector`,{name:r.name})}async function re(){try{await ai(r.name),Z(`detached probe ${r.name}`,{kind:`info`})}catch(e){Z(je(e,`Unable to detach ${r.name}. Try again.`),{kind:`error`,ttlMs:null})}}Cu(t,{get accent(){return B(o)},disabled:!1,get active(){return B(x)},statline:e=>{var t=Aw(),n=q(t);{let e=c(()=>B(a)?`circle`:`diamond`),t=c(()=>`Detach probe ${r.name}`);Dw(n,{get shape(){return B(e)},pinned:!0,onclick:()=>void re(),title:`detach`,get ariaLabel(){return B(t)}})}var i=X(n,2),o=R(i,!0);f(i);var s=X(i,2),l=e=>{var t=kw(),n=X(R(t));{let e=c(()=>Number.isFinite(B(M))?B(M):0);Fl(n,{get value(){return B(e)},digits:2})}var r=X(n),i=e=>{var t=Ow(),n=X(q(t));{let e=c(()=>Number.isFinite(B(N))?B(N):0);Fl(n,{get value(){return B(e)},digits:2})}g(e,t)};p(r,e=>{B(N)!==null&&e(i)}),f(t),g(e,t)};p(s,e=>{B(M)!==null&&e(l)});var u=X(s,4);Be(R(u),{name:`info`}),f(u);var d=X(u,2);let m;var h=R(d,!0);f(d);var _=X(d,2);{let e=c(()=>B(a)?void 0:1);yw(_,{get points(){return B(b)},width:56,height:14,get cap(){return B(e)},color:`var(--card-accent)`})}U(()=>{S(i,`title`,`probe ${r.name??``}`),G(o,B(C)),S(u,`aria-label`,`Inspect probe ${r.name??``}`),m=y(d,1,`highlight-action svelte-1c2updv`,null,m,{on:B(x)}),S(d,`aria-pressed`,B(x)),S(d,`aria-label`,B(x)?`Deselect ${r.name} as transcript highlight target`:`Select ${r.name} as transcript highlight target`),G(h,B(x)?`highlighted`:`highlight`)}),K(`click`,u,V),K(`click`,d,ne),g(e,t)},body:t=>{var n=Uw(),o=q(n);{let t=e=>{g(e,jw())},n=e=>{var t=L(),n=q(t),r=e=>{Vl(e,{percentage:!0,get value(){return B(u)},max:1,width:160,height:8,color:`var(--fg)`})};p(n,e=>{B(u)!==null&&e(r)}),g(e,t)},r=t=>{var n=Pw(),r=R(n),i=t=>{var n=Mw(),r=q(n),i=R(r,!0);f(r);var a=X(r,2),o=X(R(a)),s=e=>{Fl(e,{get value(){return B(O)},digits:2})},l=c(()=>B(O)!==null&&Number.isFinite(B(O))),u=t=>{g(t,e(`-`))};p(o,e=>{B(l)?e(s):e(u,-1)}),f(a),U(()=>G(i,B(D))),g(t,n)},a=e=>{g(e,Nw())};p(r,e=>{B(E)?e(i):e(a,-1)}),f(n),U(e=>S(n,`title`,e),[()=>B(E)?`nearest · ${B(D)} · d ${z(B(O))}`:`awaiting first token`]),g(t,n)},i=t=>{var n=Fw(),r=R(n),i=e=>{Fl(e,{get value(){return B(u)},digits:2})},a=t=>{g(t,e(`-`))};p(r,e=>{B(u)===null?e(a,-1):e(i)}),f(n),g(t,n)},a=c(()=>B(u)===null?`Subspace fraction unavailable`:`Subspace fraction ${te(B(u))}${B(E)?`, nearest ${B(D)}`:``}`);xu(o,{get ariaLabel(){return B(a)},left:t,bar:n,middle:r,right:i,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var l=X(o,2);m(l,17,()=>B(_),e=>e.i,(t,n)=>{{let r=t=>{var r=L(),i=q(r),a=t=>{var n=Iw(),r=R(n),i=t=>{var n=e();U(()=>G(n,B(w).negative)),g(t,n)};p(r,e=>{B(T)||e(i)}),f(n),U(()=>S(n,`aria-hidden`,B(T))),g(t,n)},o=e=>{var t=Lw(),r=R(t);f(t),U(()=>G(r,`c${B(n).i??``}`)),g(e,t)};p(i,e=>{B(v)?e(a):e(o,-1)}),g(t,r)},i=e=>{Vl(e,{get value(){return B(n).value},get max(){return B(n).scale},width:160,height:8,bipolar:!0})},a=e=>{var t=L(),n=q(t),r=e=>{var t=Rw(),n=R(t,!0);f(t),U(()=>{S(t,`title`,`positive pole (${B(w).positive})`),G(n,B(w).positive)}),g(e,t)},i=e=>{g(e,zw())};p(n,e=>{B(v)?e(r):e(i,-1)}),g(e,t)},o=e=>{var t=Bw();let r;Fl(R(t),{get value(){return B(n).value},digits:2,signed:!0}),f(t),U(()=>r=y(t,1,`value svelte-1c2updv`,null,r,{pos:B(n).value>0,neg:B(n).value<0})),g(e,t)},s=c(()=>`Coordinate ${B(n).i}, ${B(n).value.toFixed(2)}`);xu(t,{get ariaLabel(){return B(s)},left:r,bar:i,middle:a,right:o,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}});var d=X(l,2),h=e=>{var t=Vw(),n=R(t),r=X(R(n));{let e=c(()=>Number.isFinite(B(A))?B(A):0);Fl(r,{get value(){return B(e)},digits:2})}f(n),f(t),g(e,t)};p(d,e=>{!B(a)&&B(A)!==null&&e(h)});var b=X(d,2);{let e=c(()=>`Per-layer readings for ${r.name}`),t=c(()=>r.entry.savedAggregate!==null||(r.entry.savedCoordinates?.length??0)>0?`saved aggregate; per-layer detail was not retained`:`no data yet, generate a token first`);Yl(b,{get cells(){return B(ee)},get scale(){return B(s)},get ariaLabel(){return B(e)},get emptyMessage(){return B(t)}})}var x=X(b,2),C=e=>{var t=Hw(),n=R(t);{let e=c(()=>B(k)?.coords??null);Tw(n,{get info(){return B(i)},get trajectory(){return B(j)},get settled(){return B(e)}})}f(t),g(e,t)};p(x,e=>{B(P)&&e(C)}),g(t,n)},$$slots:{statline:!0,body:!0}}),W()}H([`click`]);var Gw=I(`
                                `),Kw=I(`
                                `),qw=I(``),Jw=I(``),Yw=I(`
                                `);function Xw(e,t){n(t,!0);let r=c(()=>Hr.sortMode),i=c(()=>fa.enabled),a=c(()=>_i.info?.is_base_model?`completion`:`reply`);function o(){pa(!B(i))}let s=c(()=>ei().filter(e=>!e.startsWith(`jlens/`)&&!e.startsWith(`sae/`)&&u(Hr.entries.get(e)?.info)===(t.family===`subspace`))),l=c(()=>B(s).length);function u(e){return e?.family===`geometry`?e.is_affine:void 0}let d=[{value:`name`,label:`name`},{value:`value`,label:`value`},{value:`change`,label:`change`}];function h(e){oi(e)}function _(){rt(`subspace`)}function v(){rt(`manifolds`)}var b=Yw(),x=R(b);{let e=c(()=>`${B(l)} probe${B(l)===1?``:`s`}`),t=c(()=>B(i)?`Stop word-by-word readings; final ${B(a)} readings stay available`:`Measure every generated word while the model writes`),n=c(()=>`word-by-word ${B(a)} readings`),s=c(()=>`Live measures every generated word. When it is off, saved readings update after the ${B(a)}.`);sw(x,{title:`Probes`,get count(){return B(e)},get live(){return B(i)},get liveBusy(){return fa.busy},get liveTitle(){return B(t)},get liveLabel(){return B(n)},get liveHelp(){return B(s)},onLiveToggle:o,get sortValue(){return B(r)},get sortOptions(){return d},sortAriaLabel:`Sort probes by`,onSortChange:h})}var S=X(x,2);let C;var w=R(S),T=e=>{var t=Gw(),n=R(t);f(t),U(()=>G(n,`No readings added. Readings observe the ${B(a)??``} without changing it.`)),g(e,t)};p(w,e=>{B(l)===0&&e(T)}),m(X(w,2),16,()=>B(s),e=>e,(e,t)=>{let n=c(()=>Gr(t));var r=L(),i=q(r),a=e=>{var r=Kw();Ww(R(r),{get name(){return t},get entry(){return B(n)}}),f(r),g(e,r)};p(i,e=>{B(n)&&e(a)}),g(e,r)}),f(S);var E=X(S,2),D=R(E),O=e=>{var t=qw();K(`click`,t,_),g(e,t)},k=e=>{var t=Jw();K(`click`,t,v),g(e,t)};p(D,e=>{t.family===`subspace`?e(O):e(k,-1)}),f(E),f(b),U(()=>C=y(S,1,`strips svelte-1t0dt4u`,null,C,{"is-empty":B(l)===0})),g(e,b),W()}H([`click`]);var Zw=en(`sae`,`train`,{label:`SAE train`,intervalMs:1500,successMessage:`SAE trained · live`,onSettled:async()=>{await bi(),await ra(),await ri()}}),Qw=en(`lens`,`fit`,{label:`J-lens fit`,intervalMs:3e3,successMessage:`J-lens fitted · live`,onSettled:async()=>{await bi(),await Ri()}}),$w=I(``),eT=I(`

                                `),tT=I(`
                                `),nT=I(`
                                `),rT=I(` `),iT=I(`
                                `),aT=I(`
                                `),oT=I(`
                                `),sT=I(`
                                `),cT=I(`
                                `),lT=I(`
                                `);function uT(t,i){n(i,!0);let a=Y(i,`value`,15),o=Y(i,`busy`,3,!1),s=Y(i,`sourceError`,3,null),l=Y(i,`working`,3,!1),u=Y(i,`allowLocal`,3,!0),d=Y(i,`selectionCurrent`,3,!0),m=Y(i,`providerPlaceholder`,3,`provider source`),h=Y(i,`localSectionLabel`,3,null),_=Y(i,`localActionLabel`,3,``),v=Y(i,`localActionDisabled`,3,!1),y=Y(i,`onlocal`,3,()=>void 0),b=Y(i,`unavailableMessage`,3,null),x=J(!1),S=c(()=>{let e=new Map(i.sources.map(e=>[e.source,e])),t=new Set(i.providerOptions.map(e=>e.value)),n=i.providerOptions.map(t=>({...t,value:e.get(t.value)?.source??t.value}));for(let e of i.sources)t.has(e.source)||!u()&&(e.kind===`local`||e.source===`local`||e.source.startsWith(`local:`))||n.push({value:e.source,label:e.source});return u()&&!e.has(`local`)&&n.push({value:`local`,label:`local`}),n});Ce(()=>{let e=new Set(B(S).map(e=>e.value)),t=i.sources.find(t=>t.active&&e.has(t.source))?.source;if(!B(x)&&t){a(t);return}a()&&e.has(a())||a(t??i.sources.find(t=>e.has(t.source))?.source??B(S)[0]?.value??``)});let C=c(()=>a()===`local`),w=c(()=>i.sources.find(e=>e.source===a())),E=c(()=>i.providerOptions.find(e=>e.value===a())),D=c(()=>B(S).find(e=>e.value===a()));function O(){if(a()){if(B(C)){y()();return}B(w)?B(w).active&&!i.ready&&B(E)?i.onfetch(a()):i.onuse(a()):i.onfetch(a())}}var k=lT(),j=R(k);{let e=c(()=>i.ready?`installed`:`needed`);sw(j,{title:`Compatible data`,help:`Features and layer predictions use a pack built for this model. Packs stay on this device.`,get count(){return B(e)}})}var M=X(j,2),N=e=>{var t=$w(),n=R(t,!0);f(t),U(()=>G(n,s())),g(e,t)};p(M,e=>{s()&&e(N)});var P=X(M,2),F=e=>{var t=eT(),n=R(t,!0);f(t),U(()=>G(n,b())),g(e,t)};p(P,e=>{B(S).length===0&&!u()&&b()&&e(F)});var I=X(P,2),L=e=>{var t=tT();r(R(t),()=>i.progress),f(t),g(e,t)},ee=t=>{var n=oT(),s=R(n),l=R(s),u=R(l),y=R(u);{let e=c(()=>o()||B(S).length===0);hu(y,{get options(){return B(S)},get placeholder(){return m()},get disabled(){return B(e)},ariaLabel:`Compatible data pack`,onchange:()=>A(x,!0),get value(){return a()},set value(e){a(e)}})}f(u);var b=X(u,2),k=R(b);{let t=c(()=>o()||!a()||(B(C)?v():B(D)?.disabled===!0||B(w)?.active===!0&&d()&&(i.ready||B(E)===void 0)));Du(k,{size:`sm`,variant:`solid`,get busy(){return o()},get disabled(){return B(t)},onclick:O,children:(t,n)=>{T();var r=e();U(()=>G(r,o()?`Preparing…`:B(C)?_():B(w)?.active?i.ready&&d()?`In use`:i.ready?`Use pack`:B(E)?`Download again`:`Unavailable`:B(w)?`Use pack`:`Download`)),g(t,r)},$$slots:{default:!0}})}f(b),f(l);var j=X(l,2),M=e=>{var t=nT(),n=R(t);r(R(n),()=>i.sourceControls),f(n),f(t),g(e,t)};p(j,e=>{i.sourceControls&&e(M)}),f(s);var N=X(s,2),P=e=>{var t=aT(),n=R(t),a=e=>{var t=rT(),n=R(t,!0);f(t),U(()=>G(n,h())),g(e,t)};p(n,e=>{h()&&e(a)});var o=X(n,2),s=e=>{var t=iT(),n=R(t);r(R(n),()=>i.localControls),f(n),f(t),g(e,t)};p(o,e=>{i.localControls&&e(s)}),f(t),g(e,t)};p(N,e=>{B(C)&&e(P)}),f(n),g(t,n)};p(I,e=>{l()&&i.progress?e(L):e(ee,-1)});var te=X(I,2),z=e=>{var t=sT();r(R(t),()=>i.warning),f(t),g(e,t)};p(te,e=>{i.warning&&e(z)});var ne=X(te,2),V=e=>{var t=cT();r(R(t),()=>i.messages),f(t),g(e,t)};p(ne,e=>{i.messages&&e(V)}),f(k),g(t,k),W()}var dT=I(` `,1),fT=I(`

                                `),pT=I(` `),mT=I(`

                                `),hT=I(``),gT=I(``),_T=I(``),vT=I(` `,1);function yT(t,r){n(r,!0);let i=c(()=>_i.info?.jlens_fitted===!0),a=We(`jlens_fitting`).available,o=c(()=>vi(`lens`)?.capabilities.preparations.includes(`fetch`)===!0),l=c(()=>vi(`lens`)?.capabilities.source_switch===!0),u=c(()=>B(l)?Li.sources:Li.sources.filter(e=>e.active===!0)),d=c(()=>Li.loading||Li.busy||_a.state.running||a&&Qw.state.running),m=c(()=>B(o)?[{value:`workspace-r`,label:`workspace-r (RelP)`},{value:`neuronpedia`,label:`neuronpedia`},{value:`workspace-j`,label:`workspace-j`}]:[]),h=J(100),_=J(`all`),v=J(!0),b=J(!1),x=J(``),C=c(()=>Number.isInteger(B(h))&&B(h)>=1&&B(h)<=5e3&&B(_).trim().length>0),w=c(()=>(Qw.state.message??``).startsWith(`streaming `));function E(){if(a){if(!B(b)){A(b,!0);return}A(b,!1),Qw.start({prompts:B(h),layers:B(_).trim(),relp:B(v)})}}ne(()=>{a&&Qw.check(),B(o)&&_a.check(),Ri()}),Ce(()=>{B(x)!==`local`&&A(b,!1)});{let n=e=>{var t=dT(),n=q(t),r=X(R(n),2);s(r),f(n);var i=X(n,2),a=X(R(i),2);s(a),f(i);var o=X(i,2),c=X(R(o),2);let l;var u=R(c,!0);f(c),f(o),U(()=>{l=y(c,1,`add-input relp-toggle svelte-17w4okt`,null,l,{"relp-on":B(v)}),S(c,`aria-pressed`,B(v)),G(u,B(v)?`relp (R-lens)`:`standard`)}),j(r,()=>B(h),e=>A(h,e)),j(a,()=>B(_),e=>A(_,e)),K(`click`,c,()=>A(v,!B(v))),g(e,t)},r=t=>{var n=L(),r=q(n),i=e=>{var t=fT(),n=R(t,!0);f(t),U(()=>G(n,_a.state.message??`fetching official lens…`)),g(e,t)},a=t=>{var n=mT(),r=R(n),i=R(r),a=R(i,!0);f(i);var o=X(i,2),s=e=>{var t=pT(),n=R(t);f(t),U(()=>G(n,`${Qw.state.current??``}/${Qw.state.total??``}`)),g(e,t)};p(o,e=>{Qw.state.total>0&&e(s)}),f(r);var l=X(r,2),u=R(l);{let e=c(()=>Math.max(Qw.state.total,1));Vl(u,{get value(){return Qw.state.current},get max(){return B(e)},width:160,height:8,color:`var(--pillar-lens)`})}f(l);var d=X(l,2),m=R(d),h=t=>{g(t,e(`stopping background work…`))},_=t=>{g(t,e(`generation available during corpus setup`))},v=t=>{g(t,e(`generation paused during model fitting`))};p(m,e=>{Qw.state.cancelling?e(h):B(w)?e(_,1):e(v,-1)}),f(d),Du(X(d,2),{size:`sm`,variant:`danger`,get disabled(){return Qw.state.cancelling},onclick:()=>void Qw.cancel(),children:(t,n)=>{T();var r=e();U(()=>G(r,Qw.state.cancelling?`cancelling…`:`cancel`)),g(t,r)},$$slots:{default:!0}}),f(n),U(e=>{G(a,Qw.state.message??`fitting…`),S(l,`aria-valuemax`,e),S(l,`aria-valuenow`,Qw.state.current)},[()=>Math.max(Qw.state.total,1)]),g(t,n)};p(r,e=>{_a.state.running?e(i):e(a,-1)}),g(t,n)},o=e=>{var t=L(),n=q(t),r=e=>{g(e,hT())};p(n,e=>{B(b)&&!Qw.state.running&&e(r)}),g(e,t)},l=e=>{var t=vT(),n=q(t),r=e=>{var t=gT(),n=R(t);f(t),U(()=>G(n,`local fit: ${Qw.state.error??``}`)),g(e,t)};p(n,e=>{Qw.state.error&&e(r)});var i=X(n,2),a=e=>{var t=_T(),n=R(t);f(t),U(()=>G(n,`official fetch: ${_a.state.error??``}`)),g(e,t)};p(i,e=>{_a.state.error&&e(a)}),g(e,t)},D=c(()=>_a.state.running||a&&Qw.state.running),O=c(()=>B(b)?`confirm fit`:`fit`),k=c(()=>B(d)||!B(C));uT(t,{get ready(){return B(i)},get sources(){return B(u)},get busy(){return B(d)},get sourceError(){return Li.error},get working(){return B(D)},get allowLocal(){return a},onuse:e=>void zi(e),get providerOptions(){return B(m)},providerPlaceholder:`lens provider`,onfetch:e=>void _a.start({source:e}),unavailableMessage:`Word insights are missing. Switch models, then download this one again.`,localSectionLabel:`Create on this device`,get localActionLabel(){return B(O)},get localActionDisabled(){return B(k)},onlocal:E,get value(){return B(x)},set value(e){A(x,e,!0)},localControls:n,progress:r,warning:o,messages:l,$$slots:{localControls:!0,progress:!0,warning:!0,messages:!0}})}W()}H([`click`]);var bT=I(``);function xT(e,t){n(t,!0);let r=c(()=>fi.target===t.name);function i(){pi(B(r)?null:t.name)}var a=bT();let o;var s=R(a,!0);f(a),U(()=>{o=y(a,1,`highlight-action svelte-1u9jmvd`,null,o,{on:B(r)}),S(a,`aria-pressed`,B(r)),S(a,`aria-label`,B(r)?`Deselect ${t.name} as transcript highlight target`:`Select ${t.name} as transcript highlight target`),G(s,B(r)?`highlighted`:`highlight`)}),K(`click`,a,i),g(e,a),W()}H([`click`]);var ST=I(`±`,1),CT=I(`@`),wT=I(` `,1),TT=I(`Not measured`),ET=I(`strength`),DT=I(``),OT=I(``),kT=I(` `,1);function AT(e,t){n(t,!0);let r=Y(t,`busy`,3,!1),i=c(()=>t.token.trim()||JSON.stringify(t.token)),a=c(()=>t.token.length>0&&t.token===t.token.trim()),o=c(()=>t.probeName??`jlens/${B(i)}`),s=c(()=>fi.target===B(o)),l=c(()=>Math.max(...t.cells.map(e=>e.p??0),1e-12)),u=c(()=>t.cells.map(e=>({layer:e.layer,value:e.p,title:e.p===null?`L${e.layer} · below top-k`:`L${e.layer} · ${Il(e.p,!0)} · p ${e.p.toPrecision(3)}`}))),d=J(!1);async function m(){if(B(d))return;A(d,!0);let e=B(o);try{await ai(e),Z(`unpinned ${e}`,{kind:`info`})}catch(t){Z(je(t,`Unable to unpin ${e}. Try again.`),{kind:`error`,ttlMs:null})}finally{A(d,!1)}}{let n=e=>{var n=wT(),s=q(n);{let e=c(()=>t.pinned?B(d):r()||!B(a)),n=c(()=>t.pinned?`unpin`:B(a)?`pin`:`This token includes whitespace. Use Watch word to add a separate word probe.`),i=c(()=>`${t.pinned?`Unpin`:`Pin`} probe ${B(o)}`);Dw(s,{shape:`square`,get pinned(){return t.pinned},get disabled(){return B(e)},onclick:()=>t.pinned?void m():t.onpin?.(t.token),get title(){return B(n)},get ariaLabel(){return B(i)}})}var l=X(s,2),u=R(l,!0);f(l);var h=X(l,2),_=e=>{var n=CT(),r=X(R(n));{let e=c(()=>Number.isFinite(t.com)?t.com:0);Fl(r,{get value(){return B(e)},digits:2})}var i=X(r),a=e=>{var n=ST(),r=X(q(n));{let e=c(()=>Number.isFinite(t.spread)?t.spread:0);Fl(r,{get value(){return B(e)},digits:2})}g(e,n)};p(i,e=>{t.spread!==null&&e(a)}),f(n),g(e,n)};p(h,e=>{t.com!==null&&e(_)});var v=X(h,4),y=e=>{xT(e,{get name(){return B(o)}})};p(v,e=>{t.pinned&&e(y)}),yw(X(v,2),{percentage:!0,get points(){return t.series},width:56,height:14,color:`var(--card-accent)`}),U(()=>{S(l,`title`,t.pinned?`probe ${B(o)}`:`"${t.token}": averaged across fitted layers`),G(u,B(i))}),g(e,n)},h=e=>{var n=kT(),r=q(n),a=e=>{g(e,TT())},o=e=>{{let n=e=>{g(e,ET())},r=e=>{var n=L(),r=q(n),i=e=>{Vl(e,{percentage:!0,get value(){return t.strength},max:1,width:160,height:8,color:`var(--card-accent)`})};p(r,e=>{t.strength!==null&&e(i)}),g(e,n)},i=e=>{g(e,DT())},a=e=>{var n=OT(),r=R(n);{let e=c(()=>({useGrouping:!1,minimumSignificantDigits:3,maximumSignificantDigits:3,notation:t.strength!==0&&(Math.abs(t.strength)<1e-6||Math.abs(t.strength)>=1e3)?`scientific`:`standard`}));Fl(r,{get value(){return t.strength},get format(){return B(e)}})}f(n),g(e,n)},o=c(()=>t.strength===null?`Not measured`:`Strength ${t.strength.toPrecision(3)}`);xu(e,{get ariaLabel(){return B(o)},left:n,bar:r,middle:i,right:a,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}};p(r,e=>{t.strength===null?e(a):e(o,-1)});var s=X(r,2);{let e=c(()=>`Per-layer strength for ${B(i)}`),n=c(()=>t.pinned?void 0:`no layer data`);Yl(s,{get cells(){return B(u)},get scale(){return B(l)},get ariaLabel(){return B(e)},get emptyMessage(){return B(n)},positiveColor:`var(--layer-cell-lens)`})}g(e,n)},_=c(()=>t.pinned&&B(s));Cu(e,{accent:`--pillar-lens`,disabled:!1,get active(){return B(_)},statline:n,body:h,$$slots:{statline:!0,body:!0}})}W()}function jT(e,t,n,{numericNames:r=!1}={}){let i=r?(e,t)=>e.localeCompare(t,void 0,{numeric:!0}):(e,t)=>e.localeCompare(t),a=[...e,...t];return n===`name`?a.sort((e,t)=>i(e.sortName,t.sortName)||t.strength-e.strength):n===`depth`?a.sort((e,t)=>(e.com??1/0)-(t.com??1/0)||t.strength-e.strength):a.sort((e,t)=>t.strength-e.strength||i(e.sortName,t.sortName)),a}var MT=I(` `,1),NT=I(`
                                Trigger
                                α
                                `,1);function PT(e,t){n(t,!0);let r={jlens:{accent:`--pillar-lens`,marker:`square`,noun:`j-lens token atom`},sae:{accent:`--pillar-sae`,marker:`triangle`,noun:`SAE decoder-row atom`}},i=c(()=>r[t.mode]),a=c(()=>kr(t.mode)),o=c(()=>t.name.slice(Er[t.mode].length));function s(){B(a).setTrigger(t.name,WC(t.entry.trigger))}{let n=e=>{var n=MT(),r=q(n);let s;Tu(R(r),{get shape(){return B(i).marker},get filled(){return t.entry.enabled}}),f(r);var c=X(r,2);let l;var u=R(c,!0);f(c);var d=X(c,2);Be(R(d),{name:`dismiss`}),f(d),U(()=>{s=y(r,1,`enable svelte-xx08kj`,null,s,{off:!t.entry.enabled}),S(r,`aria-pressed`,t.entry.enabled),S(r,`aria-label`,`Toggle steering for ${t.name??``}`),l=y(c,1,`name svelte-xx08kj`,null,l,{struck:!t.entry.enabled}),S(c,`title`,`${B(i).noun??``} ${t.name??``}`),G(u,B(o)),S(d,`aria-label`,`remove ${t.name??``}`)}),K(`click`,r,()=>B(a).setEnabled(t.name,!t.entry.enabled)),K(`click`,d,()=>B(a).remove(t.name)),g(e,n)},r=e=>{var n=NT(),r=q(n),i=X(R(r),2),o=R(i,!0);f(i),f(r);var c=X(r,2),l=R(c);let u;var d=X(l,2);let p;f(c),w(c,e=>Ac?.(e));var m=X(c,2),h=X(R(m),2);IC(h,{get value(){return t.entry.alpha},min:0,max:1,step:.05,get ariaLabel(){return`alpha for ${t.name??``}`},oninput:e=>Number.isFinite(e)&&B(a).setAlpha(t.name,e)});var _=X(h,2);Fl(R(_),{get value(){return t.entry.alpha},digits:2}),f(_),f(m),U(()=>{S(i,`title`,UC[t.entry.trigger]),S(i,`aria-label`,`trigger for ${t.name??``}: ${t.entry.trigger??``}`),G(o,HC[t.entry.trigger]),S(c,`aria-label`,`steering operation for ${t.name??``}`),S(l,`aria-pressed`,!t.entry.ablate),u=y(l,1,`svelte-xx08kj`,null,u,{active:!t.entry.ablate}),S(d,`aria-pressed`,t.entry.ablate),p=y(d,1,`svelte-xx08kj`,null,p,{active:t.entry.ablate})}),K(`click`,i,s),K(`click`,l,()=>B(a).setAblate(t.name,!1)),K(`click`,d,()=>B(a).setAblate(t.name,!0)),g(e,n)},l=c(()=>!t.entry.enabled);Cu(e,{get accent(){return B(i).accent},get disabled(){return B(l)},statline:n,body:r,$$slots:{statline:!0,body:!0}})}W()}H([`click`]);var FT=I(`
                                `),IT=I(`
                                `),LT=I(`

                                No word direction added. Enter a word below, then choose Add word.

                                `),RT=I(`
                                `),zT=I(`
                                `),BT=I(`

                                reading hovered token…

                                `),VT=I(``),HT=I(`

                                no J-lens score for this token

                                `),UT=I(`

                                select a token for layers

                                `),WT=I(`

                                Pin a word, then send a message to track its prediction strength.

                                `),GT=I(`

                                Live is off. Turn it on to see predicted words while the model writes, or pin a word below.

                                `),KT=I(`
                                `,1),qT=I(`
                                `);function JT(e,t){n(t,!0);let r=c(()=>_i.info?.jlens_fitted===!0),a=c(()=>Ii.layers!==null),o=c($i),l=c(ea),u=c(()=>Hi.active?Object.keys(B(o)??{}).map(Number).sort((e,t)=>e-t):Ii.layers??[]),d=c(()=>{let e=[...nr.entries.entries()].filter(e=>e[1].mode===`jlens`);return e.sort((e,t)=>e[0].localeCompare(t[0])),e}),h=J(``),_=J(!1);function v(e){return e.trim().replace(/^jlens\//,``)}async function y(e){e.preventDefault();let t=B(h),n=v(t);if(!(!n||B(_))){A(_,!0);try{jr((await kt.validateLensToken(n)).word),B(h)===t&&A(h,``)}catch(e){Z(`Couldn't steer toward jlens/${n}: ${te(e)}`,{kind:`error`})}finally{A(_,!1)}}}let b=[{value:`strength`,label:`strength`},{value:`name`,label:`name`},{value:`depth`,label:`depth`}];function x(e){let t=e.perLayer;return t?Object.keys(t).sort((e,t)=>Number(e)-Number(t)).map(e=>({layer:Number(e),p:t[e]??null})):[]}function S(e){return B(u).map(t=>{let n=B(o)?.[String(t)];if(!n||n.length===0)return{layer:t,p:null};let r=n.find(([t])=>t===e);return{layer:t,p:r?r[1]:null}})}let C=c(()=>{let e=[];for(let t of ei()){let n=Gr(t);if(n?.info.family!==`lens`)continue;let r=n.aggregate??n.reading,i=n.info.word;e.push({key:t,sortName:i,token:i,strength:r?.value??n.current??0,measured:r!==null||n.sparkline.length>0,com:r?.depth?.center?.[0]??null,spread:r?.depth?.spread?.[0]??null,series:n.sparkline??[],cells:x(n),pinned:!0})}return e}),w=c(()=>{let e=B(l);if(!e||e.length===0)return[];let t=Hi.active?[]:Ii.aggHistory;return e.filter(([e])=>!B(C).some(t=>t.token===e)).map(([e,n,r,i])=>({key:`aggregate:${e}`,sortName:e.trim(),token:e,strength:n,measured:!0,com:r,spread:i,series:Hi.active?[n]:t.map(t=>t.find(([t])=>t===e)?.[1]??null),cells:S(e),pinned:!1}))}),T=c(()=>jT(B(C),B(a)||Hi.active?B(w):[],Ii.workspaceSortMode)),E=J(``),D=J(!1);async function O(e){let t=v(e);if(!t||B(D))return!1;let n=`jlens/${t}`;if(Hr.active.includes(n))return!0;A(D,!0);try{let e=`jlens/${(await kt.validateLensToken(t)).word}`;return await ii(e),Z(`pinned ${e}`,{kind:`info`}),!0}catch(e){return Z(`Couldn't pin ${n}: ${te(e)}`,{kind:`error`}),!1}finally{A(D,!1)}}async function k(e){e.preventDefault();let t=B(E);await O(t)&&B(E)===t&&A(E,``)}function M(){ga(!B(a))}function N(){window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`conversation`}))}var P=qT(),F=R(P);yT(F,{});var I=X(F,2),ee=e=>{var t=KT(),n=q(t),r=R(n);{let e=c(()=>`${B(d).length} term${B(d).length===1?``:`s`}`);sw(r,{title:`J-lens steering`,help:`This steers the model toward predicting one tokenizer word. Lower strengths are usually easier to control.`,get count(){return B(e)}})}var o=X(r,2),l=e=>{var t=IT();m(t,21,()=>B(d),([e,t])=>e,(e,t)=>{var n=c(()=>i(B(t),2));let r=()=>B(n)[0],a=()=>B(n)[1];var o=FT();PT(R(o),{mode:`jlens`,get name(){return r()},get entry(){return a()}}),f(o),g(e,o)}),f(t),g(e,t)},u=e=>{g(e,LT())};p(o,e=>{B(d).length>0?e(l):e(u,-1)});var v=X(o,2),x=R(v),S=X(R(x),2);s(S),f(x);var P=X(x,2);f(v),f(n);var F=X(n,2),I=R(F);{let e=c(()=>`${B(C).length} pinned`),t=c(()=>B(a)?`turn live readout off`:`turn live readout on`);sw(I,{title:`J-lens readout`,get count(){return B(e)},get live(){return B(a)},get liveBusy(){return Ii.busy},get liveTitle(){return B(t)},liveLabel:`live predicted-word readings`,liveHelp:`Update predicted words while the model writes. Pinned words stay visible when it finishes.`,onLiveToggle:M,get sortValue(){return Ii.workspaceSortMode},get sortOptions(){return b},sortAriaLabel:`Sort prediction words by`,get onSortChange(){return Bi}})}var ee=X(I,2),te=R(ee),z=e=>{var t=zT();m(t,21,()=>B(T),e=>e.key,(e,t)=>{var n=RT(),r=R(n);{let e=c(()=>B(t).pinned?B(t).key:void 0),n=c(()=>B(t).measured?B(t).strength:null);AT(r,{get token(){return B(t).token},get probeName(){return B(e)},get strength(){return B(n)},get com(){return B(t).com},get spread(){return B(t).spread},get series(){return B(t).series},get cells(){return B(t).cells},get pinned(){return B(t).pinned},get busy(){return B(D)},onpin:O})}f(n),g(e,n)}),f(t),g(e,t)};p(te,e=>{B(T).length>0&&e(z)});var ne=X(te,2),V=e=>{var t=L(),n=q(t),r=e=>{g(e,BT())},i=e=>{var t=VT(),n=R(t,!0);f(t),U(()=>G(n,Hi.lensError)),g(e,t)},a=e=>{g(e,HT())};p(n,e=>{Hi.lensLoading?e(r):Hi.lensError?e(i,1):B(w).length===0&&e(a,2)}),g(e,t)},re=e=>{var t=L(),n=q(t),r=e=>{g(e,UT())},i=e=>{var t=WT(),n=X(R(t),2);f(t),K(`click`,n,N),g(e,t)};p(n,e=>{B(w).length>0?e(r):e(i,-1)}),g(e,t)},ie=e=>{g(e,GT())};p(ne,e=>{Hi.active?e(V):B(a)?e(re,1):e(ie,-1)}),f(ee);var ae=X(ee,2),oe=R(ae),H=X(R(oe),2);s(H),f(oe);var se=X(oe,2);f(ae),f(F),U((e,t)=>{P.disabled=e,se.disabled=t},[()=>B(_)||!B(h).trim(),()=>B(D)||!B(E).trim()]),ye(`submit`,v,y),j(S,()=>B(h),e=>A(h,e)),ye(`submit`,ae,k),j(H,()=>B(E),e=>A(E,e)),g(e,t)};p(I,e=>{B(r)&&e(ee)}),f(P),g(e,P),W()}H([`click`]);var YT=I(` `,1),XT=I(`
                                `),ZT=I(``),QT=I(`

                                `),$T=I(``),eE=I(``),tE=I(``),nE=I(` `,1);function rE(t,r){n(r,!0);let i=c(yi),a=We(`sae_training`).available,o=c(()=>vi(`sae`)?.capabilities.preparations.includes(`fetch`)===!0),l=c(()=>vi(`sae`)?.capabilities.source_switch===!0),u=c(()=>B(l)?na.sources:na.sources.filter(e=>e.active===!0)),d=c(()=>vi(`sae`)?.source??null),m=c(()=>{let e=na.sources.find(e=>e.active);if(e?.layer!=null)return e.layer;let t=vi(`sae`)?.live;return t&&`layer`in t?t.layer:null}),h=J(``),_=J(``),v=J(``),y=J(`my-sae`),b=J(1e6),x=J(``),S=J(!1),C=J(V([])),w=J(null),E=c(()=>(B(o)?B(C):[]).map(e=>({value:`saelens:${e.release}`,label:e.release}))),D=c(()=>na.loading||na.busy||ua.state.running||a&&Zw.state.running),O=c(()=>na.sources.find(e=>e.source===B(h))),k=c(()=>B(h).startsWith(`saelens:`)?B(h).slice(8):B(h)),M=c(()=>{let e=B(C).find(e=>e.release===B(k))?.layers??(B(O)?.layer==null?[]:[B(O).layer]);return[...new Set(e)].sort((e,t)=>e-t)}),N=c(()=>B(M).map(e=>({value:String(e),label:`layer ${e}`}))),P=c(()=>B(i)&&B(d)!==null&&B(h)===B(d)),F=c(()=>B(_)===``?null:Number(B(_))),I=c(()=>B(P)&&B(F)===B(m));ne(()=>{ra(),a&&Zw.check(),B(o)&&ua.check()}),Ce(()=>{let e=B(h),t=B(M);if(e!==B(v)){A(v,e,!0);let n=B(P)?B(m):null,r=B(O)?.layer??null,i=n!=null&&t.includes(n)?n:r!=null&&t.includes(r)?r:te(t);A(_,i==null?``:String(i),!0)}else if(t.length>0&&(B(_)===``||!t.includes(Number(B(_))))){let e=te(t);A(_,e==null?``:String(e),!0)}}),Ce(()=>{B(h)!==`local`&&A(S,!1)}),Ce(()=>{B(C).length>0||kt.sources(`sae`).then(e=>{A(C,(e.releases??[]).filter(e=>e.source!==`local`),!0),!B(h)&&B(C).length>0&&A(h,`saelens:${B(C)[0].release}`)}).catch(e=>{A(w,je(e,`Unable to check available feature packs. Check your connection and try again.`),!0)})});function ee(){if(!a||!B(y).trim()||Zw.state.running)return;if(!B(S)){A(S,!0);return}A(S,!1);let e=B(x).trim()===``?null:Number(B(x));Zw.start({name:B(y).trim(),tokens:B(b),layer:e!=null&&Number.isInteger(e)?e:null})}function te(e){if(e.length===0)return null;let t=Math.max(...e,1),n=e.filter(e=>{let n=e/t;return n>=.4&&n<=.9}),r=n.length>0?n:e,i=.65*t;return[...r].sort((e,t)=>Math.abs(e-i)-Math.abs(t-i)||e-t)[0]??null}function z(e){da(e,B(F))}{let n=e=>{{let t=c(()=>B(D)||B(N).length===0);hu(e,{get options(){return B(N)},placeholder:`layer`,get disabled(){return B(t)},ariaLabel:`SAE measurement layer`,get value(){return B(_)},set value(e){A(_,e,!0)}})}},r=e=>{var t=YT(),n=q(t),r=X(R(n),2);s(r),f(n);var i=X(n,2),a=X(R(i),2);s(a),f(i);var o=X(i,2),c=X(R(o),2);s(c),f(o),j(r,()=>B(y),e=>A(y,e)),j(a,()=>B(b),e=>A(b,e)),j(c,()=>B(x),e=>A(x,e)),g(e,t)},o=t=>{var n=XT(),r=R(n),i=R(r),a=R(i,!0);f(i);var o=X(i,2),s=R(o);f(o),f(r);var l=X(r,2);{let e=c(()=>Math.max(Zw.state.total,1));Vl(l,{get value(){return Zw.state.current},get max(){return B(e)},width:160,height:8,color:`var(--pillar-sae)`})}Du(X(l,2),{size:`sm`,variant:`danger`,get disabled(){return Zw.state.cancelling},onclick:()=>void Zw.cancel(),children:(t,n)=>{T();var r=e();U(()=>G(r,Zw.state.cancelling?`cancelling…`:`cancel`)),g(t,r)},$$slots:{default:!0}}),f(n),U((e,t)=>{G(a,Zw.state.message??`training…`),G(s,`${e??``}/${t??``}`)},[()=>Zw.state.current.toLocaleString(),()=>Zw.state.total.toLocaleString()]),g(t,n)},l=e=>{var t=L(),n=q(t),r=e=>{g(e,ZT())};p(n,e=>{B(S)&&e(r)}),g(e,t)},d=e=>{var t=nE(),n=q(t),r=e=>{var t=QT(),n=R(t,!0);f(t),U(()=>G(n,ua.state.message)),g(e,t)};p(n,e=>{ua.state.running&&ua.state.message&&e(r)});var i=X(n,2),a=e=>{var t=$T(),n=R(t,!0);f(t),U(()=>G(n,ua.state.error)),g(e,t)};p(i,e=>{ua.state.error&&e(a)});var o=X(i,2),s=e=>{var t=eE(),n=R(t);f(t),U(()=>G(n,`local train: ${Zw.state.error??``}`)),g(e,t)};p(o,e=>{Zw.state.error&&e(s)});var c=X(o,2),l=e=>{var t=tE(),n=R(t);f(t),U(()=>G(n,`registry: ${B(w)??``}`)),g(e,t)};p(c,e=>{B(w)&&e(l)}),g(e,t)},m=c(()=>a&&Zw.state.running),v=c(()=>B(S)?`confirm train`:`train`),C=c(()=>!B(y).trim()||B(D));uT(t,{get ready(){return B(i)},get sources(){return B(u)},get busy(){return B(D)},get sourceError(){return na.error},get working(){return B(m)},get allowLocal(){return a},get selectionCurrent(){return B(I)},onuse:z,get providerOptions(){return B(E)},providerPlaceholder:`SAELens release`,onfetch:z,unavailableMessage:`This model has no compatible SAE pack installed. Add one in Model settings if a pack is available.`,localSectionLabel:`Create on this device`,get localActionLabel(){return B(v)},get localActionDisabled(){return B(C)},onlocal:ee,get value(){return B(h)},set value(e){A(h,e,!0)},sourceControls:n,localControls:r,progress:o,warning:l,messages:d,$$slots:{sourceControls:!0,localControls:!0,progress:!0,warning:!0,messages:!0}})}W()}var iE=I(` `),aE=I(` `,1),oE=I(`Not measured`),sE=I(`strength`),cE=I(``),lE=I(``),uE=I(`activation`),dE=I(``),fE=I(``);function pE(e,t){n(t,!0);let r=Y(t,`measured`,3,!0),i=Y(t,`label`,3,null),a=Y(t,`maxAct`,3,null),o=Y(t,`valueIsStrength`,3,!1),s=Y(t,`fallbackScale`,3,1),l=Y(t,`busy`,3,!1),u=c(()=>t.probeName??`sae/${t.id}`),d=c(()=>fi.target===B(u)),m=c(()=>o()?t.value:a()!=null&&a()>0?t.value/a():null),h=c(()=>o()&&a()!=null?t.value*a():t.value),_=J(!1);async function v(){if(B(_))return;A(_,!0);let e=B(u);try{await ai(e),Z(`unpinned ${e}`,{kind:`info`})}catch(t){Z(je(t,`Unable to unpin ${e}. Try again.`),{kind:`error`,ttlMs:null})}finally{A(_,!1)}}Cu(e,{accent:`--pillar-sae`,disabled:!1,get active(){return B(d)},statline:e=>{var n=aE(),r=q(n);{let e=c(()=>t.pinned?B(_):l()),n=c(()=>t.pinned?`unpin`:`pin`),i=c(()=>`${t.pinned?`Unpin`:`Pin`} probe ${B(u)}`);Dw(r,{shape:`triangle`,get pinned(){return t.pinned},get disabled(){return B(e)},onclick:()=>t.pinned?void v():t.onpin?.(t.id),get title(){return B(n)},get ariaLabel(){return B(i)}})}var a=X(r,2),o=R(a);f(a);var s=X(a,2),d=e=>{var n=iE(),r=R(n);f(n),U(()=>G(r,`L${t.layer??``}`)),g(e,n)};p(s,e=>{t.layer!==null&&e(d)});var m=X(s,4),h=e=>{xT(e,{get name(){return B(u)}})};p(m,e=>{t.pinned&&e(h)}),yw(X(m,2),{get points(){return t.series},width:56,height:14,color:`var(--card-accent)`}),U(()=>{S(a,`title`,`probe ${B(u)??``}`),G(o,`${t.id??``}${i()?` · ${i()}`:``}`)}),g(e,n)},body:e=>{var t=L(),n=q(t),i=e=>{g(e,oE())},a=e=>{{let t=e=>{g(e,sE())},n=e=>{{let t=c(()=>Math.max(B(m),0));Vl(e,{get value(){return B(t)},max:1,width:160,height:8,color:`var(--card-accent)`})}},r=e=>{g(e,cE())},i=e=>{var t=lE();Fl(R(t),{get value(){return B(m)},digits:2}),f(t),g(e,t)},a=c(()=>`Strength ${B(m).toFixed(2)}`);xu(e,{get ariaLabel(){return B(a)},left:t,bar:n,middle:r,right:i,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}},o=e=>{{let t=e=>{g(e,uE())},n=e=>{{let t=c(()=>Math.max(B(h),0)),n=c(()=>Math.max(s(),1));Vl(e,{get value(){return B(t)},get max(){return B(n)},width:160,height:8,color:`var(--card-accent)`})}},r=e=>{g(e,dE())},i=e=>{var t=fE();Fl(R(t),{get value(){return B(h)},digits:2}),f(t),g(e,t)},a=c(()=>`Activation ${B(h).toFixed(2)}`);xu(e,{get ariaLabel(){return B(a)},left:t,bar:n,middle:r,right:i,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}};p(n,e=>{r()?B(m)===null?e(o,-1):e(a,1):e(i)}),g(e,t)},$$slots:{statline:!0,body:!0}}),W()}var mE=I(`
                                `),hE=I(`
                                `),gE=I(`

                                No feature direction added. Enter a feature number below, then choose Add feature.

                                `),_E=I(`
                                `),vE=I(`
                                `),yE=I(`

                                reading hovered token…

                                `),bE=I(``),xE=I(`

                                no SAE score for this token

                                `),SE=I(`

                                Pin a feature, then send a message to track its activity.

                                `),CE=I(`

                                Live is off. Turn it on to see active features while the model writes, or pin one below.

                                `),wE=I(`
                                `,1),TE=I(`
                                `);function EE(e,t){n(t,!0);let r=c(yi),a=c(ta),o=c(()=>{let e=vi(`sae`)?.live;return e&&`layer`in e?e.layer:null}),l=c(()=>{let e=[...nr.entries.entries()].filter(e=>e[1].mode===`sae`);return e.sort((e,t)=>Number(e[0].slice(4))-Number(t[0].slice(4))),e}),u=c(()=>ei().map(e=>({name:e,entry:Gr(e)})).filter(e=>e.entry?.info.family===`sae`)),d=c(()=>B(a).filter(e=>!B(u).some(({entry:t})=>t?.info.family===`sae`&&t.info.feature_id===e.id)).map(e=>{let t=Hi.active?void 0:Vi.meta.get(e.id);return{...e,label:e.label??t?.label??null,max_act:e.max_act??t?.max_act??null}})),h=c(Qr),_=[{value:`strength`,label:`strength`},{value:`name`,label:`name`}];function v(e,t){return t!=null&&t>0?e/t:e/B(h)}let y=c(()=>B(u).map(e=>{let t=e.entry,n=t.info,r=t.aggregate??t.reading,i=r?.value??t.current;return{kind:`pinned`,key:e.name,name:e.name,entry:t,sortName:n.label||String(n.feature_id),strength:r?.unit===`activation_over_max`?i:i/B(h)}})),b=c(()=>B(d).map(e=>({kind:`discovery`,key:`sae/${e.id}`,feature:e,sortName:e.label||String(e.id),strength:v(e.activation,e.max_act??null)}))),x=c(()=>jT(B(y),Vi.live||Hi.active?B(b):[],Vi.sortMode,{numericNames:!0})),S=J(``),C=J(``),w=J(!1);async function T(e){let t=Number(e.trim().replace(/^sae\//,``));return!Number.isInteger(t)||t<0?(Z(`Enter a feature number of 0 or greater.`,{kind:`error`}),null):(await kt.validateSaeFeature(t)).id}async function E(e){if(e.preventDefault(),!B(w)){A(w,!0);try{let e=await T(B(S));e!==null&&(Mr(e),A(S,``))}catch(e){Z(je(e,`Unable to add that feature control. Try again.`),{kind:`error`})}finally{A(w,!1)}}}async function D(e){if(!(B(w)||Hr.active.includes(`sae/${e}`))){A(w,!0);try{await kt.validateSaeFeature(e),await ii(`sae/${e}`)}catch(e){Z(je(e,`Unable to pin that feature. Try again.`),{kind:`error`})}finally{A(w,!1)}}}async function O(e){if(e.preventDefault(),!B(w)){A(w,!0);try{let e=await T(B(C));e!==null&&(await ii(`sae/${e}`),A(C,``))}catch(e){Z(je(e,`Unable to add that feature reading. Try again.`),{kind:`error`})}finally{A(w,!1)}}}function k(){window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`conversation`}))}var M=TE(),N=R(M);rE(N,{});var P=X(N,2),F=e=>{var t=wE(),n=q(t),r=R(n);{let e=c(()=>`${B(l).length} term${B(l).length===1?``:`s`}`);sw(r,{title:`SAE steering`,get count(){return B(e)}})}var a=X(r,2),v=e=>{var t=hE();m(t,21,()=>B(l),([e,t])=>e,(e,t)=>{var n=c(()=>i(B(t),2));let r=()=>B(n)[0],a=()=>B(n)[1];var o=mE();PT(R(o),{mode:`sae`,get name(){return r()},get entry(){return a()}}),f(o),g(e,o)}),f(t),g(e,t)},y=e=>{g(e,gE())};p(a,e=>{B(l).length>0?e(v):e(y,-1)});var b=X(a,2),T=R(b),M=X(R(T),2);s(M),f(T);var N=X(T,2);f(b),f(n);var P=X(n,2),F=R(P);{let e=c(()=>`${B(u).length} pinned`),t=c(()=>Vi.live?`turn live readout off`:`turn live readout on`);sw(F,{title:`SAE readout`,get count(){return B(e)},get live(){return Vi.live},get liveBusy(){return Vi.busy},get liveTitle(){return B(t)},liveLabel:`live model-feature readings`,liveHelp:`Update feature activity while the model writes. Pinned features stay visible when it finishes.`,onLiveToggle:()=>void la(!Vi.live),get sortValue(){return Vi.sortMode},get sortOptions(){return _},sortAriaLabel:`Sort model features by`,get onSortChange(){return ia}})}var I=X(F,2),ee=R(I),te=e=>{var t=vE();m(t,21,()=>B(x),e=>e.key,(e,t)=>{var n=_E(),r=R(n),i=e=>{let n=c(()=>B(t).entry.aggregate??B(t).entry.reading),r=c(()=>B(t).entry.info);{let i=c(()=>B(n)?.value??B(t).entry.current??0),a=c(()=>B(n)!==null||B(t).entry.sparkline.length>0),s=c(()=>B(n)?.unit===`raw_activation`?null:B(r).max_act),l=c(()=>B(n)?.unit===`activation_over_max`);pE(e,{get id(){return B(r).feature_id},get probeName(){return B(t).name},get label(){return B(r).label},get layer(){return B(o)},get value(){return B(i)},get measured(){return B(a)},get maxAct(){return B(s)},get valueIsStrength(){return B(l)},get fallbackScale(){return B(h)},get series(){return B(t).entry.sparkline},pinned:!0})}},a=e=>{{let n=c(()=>Hi.active?[B(t).feature.activation]:Vi.history.get(B(t).feature.id)??[]);pE(e,{get id(){return B(t).feature.id},get label(){return B(t).feature.label},get layer(){return B(o)},get value(){return B(t).feature.activation},get maxAct(){return B(t).feature.max_act},get fallbackScale(){return B(h)},get series(){return B(n)},pinned:!1,get busy(){return B(w)},onpin:e=>void D(e)})}};p(r,e=>{B(t).kind===`pinned`?e(i):e(a,-1)}),f(n),g(e,n)}),f(t),g(e,t)};p(ee,e=>{B(x).length>0&&e(te)});var z=X(ee,2),ne=e=>{var t=L(),n=q(t),r=e=>{g(e,yE())},i=e=>{var t=bE(),n=R(t,!0);f(t),U(()=>G(n,Hi.saeError)),g(e,t)},a=e=>{g(e,xE())};p(n,e=>{Hi.saeLoading?e(r):Hi.saeError?e(i,1):B(x).length===0&&e(a,2)}),g(e,t)},V=e=>{var t=L(),n=q(t),r=e=>{var t=SE(),n=X(R(t),2);f(t),K(`click`,n,k),g(e,t)};p(n,e=>{B(d).length===0&&e(r)}),g(e,t)},re=e=>{g(e,CE())};p(z,e=>{Hi.active?e(ne):Vi.live?e(V,1):e(re,-1)}),f(I);var ie=X(I,2),ae=R(ie),oe=X(R(ae),2);s(oe),f(ae);var H=X(ae,2);f(ie),f(P),U((e,t)=>{N.disabled=e,H.disabled=t},[()=>B(w)||!B(S).trim(),()=>B(w)||!B(C).trim()]),ye(`submit`,b,E),j(M,()=>B(S),e=>A(S,e)),ye(`submit`,ie,O),j(oe,()=>B(C),e=>A(C,e)),g(e,t)};p(P,e=>{B(r)&&e(F)}),f(M),g(e,M),W()}H([`click`]);var DE=I(``),OE=I(``),kE=I(``),AE=I(` `);function jE(e,t){n(t,!0);let i=Y(t,`muted`,3,!1),a=Y(t,`removeLabel`,3,`Remove chip`);var o=AE();let s,c;var l=R(o),u=e=>{var n=DE();r(R(n),()=>t.children),f(n),K(`click`,n,function(...e){t.onclick?.apply(this,e)}),g(e,n)},d=e=>{var n=OE();r(R(n),()=>t.children),f(n),g(e,n)};p(l,e=>{t.onclick?e(u):e(d,-1)});var m=X(l,2),h=e=>{var n=kE();Be(R(n),{name:`dismiss`}),f(n),U(()=>S(n,`aria-label`,a())),K(`click`,n,e=>{e.stopPropagation(),t.onremove(e)}),g(e,n)};p(m,e=>{t.onremove&&e(h)}),f(o),U(()=>{s=y(o,1,`sk-chip svelte-py53oc`,null,s,{muted:i(),clickable:!!t.onclick}),S(o,`title`,t.title),S(o,`role`,t.onremove?`group`:void 0),c=pe(o,``,c,{"--chip-c":t.color})}),g(e,o),W()}H([`click`]);var ME=I(`custom `),NE=I(`
                                `),PE=I(``),FE=I(`
                                Steering
                                `);function IE(t,r){n(r,!0);function i(e,t){switch(t.mode){case`subspace`:return{name:e,text:jn(e,t,nr.subspaceAlong),color:`var(--pillar-subspace)`,tab:`subspace`,order:0,enabled:t.enabled,remove:()=>_r(e)};case`manifold`:return{name:e,text:Ln(e,t),color:`var(--pillar-manifold)`,tab:`manifold`,order:2,enabled:t.enabled,remove:()=>wr(e)};case`jlens`:return{name:e,text:Fn(e,t),color:`var(--pillar-lens)`,tab:`lens`,order:1,enabled:t.enabled,remove:()=>kr(`jlens`).remove(e)};case`sae`:return{name:e,text:In(e,t),color:`var(--pillar-sae)`,tab:`sae`,order:1,enabled:t.enabled,remove:()=>kr(`sae`).remove(e)}}}let a=c(()=>{let e=[...nr.entries.entries()].map(([e,t])=>i(e,t));return e.sort((e,t)=>e.order-t.order||e.name.localeCompare(t.name)),e}),o=c(vr),s=c(()=>nr.customExpression!==null);async function l(){if(B(o))try{await navigator.clipboard.writeText(B(o)),Z(`Response recipe copied`,{kind:`info`})}catch{Z(`Could not copy the recipe. Select its text and copy it manually.`,{kind:`error`})}}var u=L(),d=q(u),h=t=>{var n=FE(),r=X(R(n),2),i=e=>{var t=ME(),n=X(R(t),2),r=R(n,!0);f(n),f(t),U(()=>G(r,B(o))),g(e,t)},u=t=>{var n=NE();m(n,21,()=>B(a),e=>e.name,(t,n)=>{{let r=c(()=>!B(n).enabled),i=c(()=>B(n).enabled?void 0:`Disabled`),a=c(()=>`Remove ${B(n).name} from steering recipe`);jE(t,{get color(){return B(n).color},get muted(){return B(r)},get title(){return B(i)},onclick:()=>ha(B(n).tab),get onremove(){return B(n).remove},get removeLabel(){return B(a)},children:(t,r)=>{T();var i=e();U(()=>G(i,B(n).text)),g(t,i)},$$slots:{default:!0}})}}),f(n),g(t,n)};p(r,e=>{B(s)?e(i):e(u,-1)});var d=X(r,2),h=e=>{var t=PE();Be(R(t),{name:`copy`}),f(t),K(`click`,t,l),g(e,t)};p(d,e=>{B(o)&&e(h)}),f(n),g(t,n)},_=c(()=>B(s)?B(o).trim():B(a).length>0);p(d,e=>{B(_)&&e(h)}),g(t,u),W()}H([`click`]);var LE=I(`
                                `),RE=I(``),zE=I(`
                                Temperature
                                Top P
                                Max tokens
                                `);function BE(e,t){n(t,!0);let r={temperature:1,top_p:1,max_tokens:512},i={temperature:`Temperature controls randomness. Higher values vary the token choices. Lower values make them more predictable.`,topP:`Top P limits sampling to the smallest set of tokens whose probabilities add up to this value. Lower values narrow the choices.`,maxTokens:`Max tokens is the maximum number of tokens the model may generate. A token is usually a word or part of a word.`,thinking:`When supported, Thinking lets the model use a separate reasoning phase before it writes the visible reply.`};function a(e,t){let n=t,r=null,i=()=>{r=e.querySelector(`input`),r?.setAttribute(`aria-describedby`,n)};return queueMicrotask(i),{update(e){r?.getAttribute(`aria-describedby`)===n&&r.removeAttribute(`aria-describedby`),n=e,i()},destroy(){r?.getAttribute(`aria-describedby`)===n&&r.removeAttribute(`aria-describedby`)}}}let o=c(()=>_i.info!==null&&!tm.busy),s=c(()=>_i.info?.supports_thinking??!1),l=c(()=>_i.info?.thinking_is_optional===!0),u=c(()=>B(s)&&!B(l)),d=c(()=>xi.temperature??r.temperature),m=c(()=>xi.top_p??r.top_p),h=c(()=>an(he()?.signals)),_=c(()=>Math.min(xi.max_tokens||r.max_tokens,B(h))),v=c(()=>xi.thinking??!1);async function b(e){try{await ki(e)}catch(e){console.warn(`[sampling] patch failed`,e)}}function x(e){Si(`temperature`,e),b({temperature:e})}function S(e){Si(`top_p`,e),b({top_p:e})}function C(e){if(e===null)return;let t=Math.max(1,Math.min(B(h),Math.floor(e)));Si(`max_tokens`,t),b({max_tokens:t})}function T(e){Si(`thinking`,e),b({thinking:e})}function E(){rt(`system_prompt`)}function D(){rt(`advanced_sampling`)}var O=zE(),k=R(O),A=R(k),j=R(A);tp(X(R(j),2),{get text(){return i.temperature},label:`About Temperature`}),f(j);var M=X(j,2),N=R(M);{let e=c(()=>!B(o));IC(N,{get value(){return B(d)},min:0,max:2,step:.05,get disabled(){return B(e)},oninput:x,ariaLabel:`Temperature`})}f(M);var P=X(M,2);Fl(R(P),{get value(){return B(d)},digits:2}),f(P);var F=X(P,2),I=R(F,!0);f(F),f(A),w(A,(e,t)=>a?.(e,t),()=>`sampling-temperature-help`);var L=X(A,2),ee=R(L);tp(X(R(ee),2),{get text(){return i.topP},label:`About Top P`}),f(ee);var te=X(ee,2),z=R(te);{let e=c(()=>!B(o));IC(z,{get value(){return B(m)},min:0,max:1,step:.01,get disabled(){return B(e)},oninput:S,ariaLabel:`Top P`})}f(te);var ne=X(te,2);Fl(R(ne),{get value(){return B(m)},digits:2}),f(ne);var V=X(ne,2),re=R(V,!0);f(V),f(L),w(L,(e,t)=>a?.(e,t),()=>`sampling-top-p-help`),f(k);var ie=X(k,2),ae=R(ie),oe=R(ae);tp(X(R(oe),2),{get text(){return i.maxTokens},label:`About Max tokens`}),f(oe);var H=X(oe,2),se=R(H);{let e=c(()=>!B(o));$f(se,{get value(){return B(_)},min:1,get max(){return B(h)},step:1,get disabled(){return B(e)},onchange:C,ariaLabel:`Max tokens`})}f(H);var ce=X(H,2),le=R(ce,!0);f(ce),f(ae),w(ae,(e,t)=>a?.(e,t),()=>`sampling-max-tokens-help`);var ue=X(ae,2),de=e=>{var t=LE();let n;var r=R(t),s=R(r),d=R(s);f(s);var p=X(s,2);{let e=c(()=>B(l)?i.thinking:`This model always uses its reasoning phase, so this setting cannot be changed.`);tp(p,{get text(){return B(e)},label:`About Thinking`})}f(r);var m=X(r,2);{let e=c(()=>B(u)?!0:B(v)),t=c(()=>!B(o)||B(u));tv(m,{get checked(){return B(e)},get disabled(){return B(t)},onchange:T,ariaLabel:`Thinking`})}var h=X(m,2),_=R(h,!0);f(h),f(t),w(t,(e,t)=>a?.(e,t),()=>`sampling-thinking-help`),U(()=>{n=y(t,1,`control toggle svelte-a6qk0e`,null,n,{forced:B(u)}),G(d,`Thinking${B(u)?` (always on)`:``}`),G(_,B(l)?i.thinking:`This model always uses its reasoning phase, so this setting cannot be changed.`)}),g(e,t)};p(ue,e=>{B(s)&&e(de)}),f(ie);var fe=X(ie,2),pe=R(fe),me=X(pe,2),ge=e=>{var t=RE();U(()=>t.disabled=!B(o)),K(`click`,t,E),g(e,t)};p(me,e=>{_i.info?.is_base_model||e(ge)}),f(fe),cm(X(fe,2),{}),f(O),U(()=>{G(I,i.temperature),G(re,i.topP),G(le,i.maxTokens),pe.disabled=!B(o)}),K(`click`,pe,D),g(e,O),W()}H([`click`]);var VE=I(`
                                Selected word
                                `),HE=I(`
                                `),UE=I(`
                                `),WE=I(``);function GE(e,t){n(t,!0);let r=[{value:`subspace`,label:`Subspace`,color:`var(--pillar-subspace)`},{value:`manifold`,label:`Manifold`,color:`var(--pillar-manifold)`},{value:`sae`,label:`SAE`,color:`var(--pillar-sae)`},{value:`lens`,label:`J-lens`,color:`var(--pillar-lens)`}],i=c(()=>ma.tab),a=c(()=>Hi.tokenText.replace(/\n/g,`↵`).replace(/\t/g,`⇥`).replace(/ /g,`·`)||`∅`),o=c(()=>new Set([...Object.keys(Hi.probeReadings??{}),...Object.keys(Hi.probes??{}),...Object.keys(Hi.coordsByProbe??{})]).size),s=c(()=>Hi.lensAggregate?.length??0),l=c(()=>Hi.saeReadout?.length??0);var u=WE(),d=R(u);IE(d,{});var m=X(d,2),h=R(m);BE(X(R(h),2),{}),f(h);var _=X(h,2),v=X(R(_),2),y=R(v),b=R(y);{let e=c(()=>_i.info?.is_base_model?`Completion guidance type`:`Response guidance type`);Fc(b,{get items(){return r},get value(){return B(i)},onchange:e=>ha(e),fill:!0,get ariaLabel(){return B(e)}})}f(y);var x=X(y,2),C=e=>{var t=VE(),n=X(R(t),4),r=R(n,!0);f(n);var i=X(n,2),c=R(i);f(i),f(t),U(()=>{S(n,`title`,Hi.tokenText),G(r,B(a)),G(c,`${B(o)??``} readings - · ${Hi.lensLoading?`predictions…`:`${B(s)} predictions`} - · ${Hi.saeLoading?`features…`:`${B(l)} features`}`)}),g(e,t)};p(x,e=>{Hi.active&&e(C)}),f(v);var w=X(v,2),T=R(w),E=e=>{JT(e,{})},D=e=>{EE(e,{})},O=e=>{var t=HE(),n=R(t);mw(n,{family:`manifold`}),Xw(X(n,2),{family:`manifold`}),f(t),g(e,t)},k=e=>{var t=UE(),n=R(t);mw(n,{family:`subspace`}),Xw(X(n,2),{family:`subspace`}),f(t),g(e,t)};p(T,e=>{B(i)===`lens`?e(E):B(i)===`sae`?e(D,1):B(i)===`manifold`?e(O,2):e(k,-1)}),f(w),f(_),f(m),f(u),U(()=>S(y,`aria-label`,_i.info?.is_base_model?`Completion guidance`:`Response guidance`)),g(e,u),W()}var KE=I(`
                                `);function qE(e,t){n(t,!0);let r=Y(t,`section`,15),i=c(()=>_i.info?.is_base_model?`Completion`:`Response`),a=c(()=>[{value:`response`,label:B(i),title:`Choose how the next ${B(i).toLowerCase()} is generated, shaped, and measured.`},{value:`model`,label:`Model`,title:`Manage the active model, its tools, and local storage.`},{value:`chat`,label:`Chat`}]),o=MC[St.mode===`browser`?`local_runtime`:`health`];var s=KE(),l=R(s);Fc(R(l),{get items(){return B(a)},ariaLabel:`Controls section`,get value(){return r()},set value(e){r(e)}}),f(l);var u=X(l,2);let d;var m=R(u),h=e=>{GE(e,{})},_=e=>{var t=L();Fe(q(t),()=>o.component,(e,t)=>{t(e,{params:{embedded:!0}})}),g(e,t)},v=e=>{FS(e,{embedded:!0})};p(m,e=>{r()===`response`?e(h):r()===`model`?e(_,1):e(v,-1)}),f(u),f(s),U(()=>{S(s,`aria-label`,`${B(i)}, model, and chat controls`),d=y(u,1,`controls-body svelte-ibpk0f`,null,d,{"chat-section":r()===`chat`}),S(u,`aria-label`,r()===`response`?`${B(i)} controls`:r()===`model`?`Model controls`:`Chat controls`)}),g(e,s),W()}var JE=I(``),YE=I(``);function XE(e,t){let n=Y(t,`size`,3,18);var r=YE();let i;m(r,20,()=>t.icons,e=>e,(e,r)=>{var i=JE();let a;Be(R(i),{get name(){return r},get size(){return n()}}),f(i),U(()=>a=y(i,1,`variant svelte-k1ygnu`,null,a,{active:t.name===r})),g(e,i)}),f(r),U(()=>i=pe(r,``,i,{width:`${n()}px`,height:`${n()}px`})),g(e,r)}var ZE=I(`Edit saved`),QE=I(` Ready`,1),$E=I(`Preparing continuation… `,1),eD=I(` `,1),tD=I(` `),nD=I(` `),rD=I(` `),iD=I(` `,1),aD=I(` `),oD=I(`
                                `);function sD(e,t){n(t,!0);let r=Y(t,`savedEdit`,3,!1),i=c(()=>qn.queue.length),a=c(()=>B(i)===1?`1 queued`:`${B(i)} queued`),o=J(V(performance.now()));Ce(()=>{if(!$.active)return;let e=setInterval(()=>{A(o,performance.now(),!0)},100);return()=>clearInterval(e)});let s=c(()=>{if(!$.startedAt)return 0;let e=$.active?B(o):$.finishedAt??$.startedAt;return Math.max(0,(e-$.startedAt)/1e3)}),l=c(()=>$.tokPerSec),u=c(()=>$.active&&$.replay!=null&&$.replay.completed<$.replay.total),d=c(()=>Qo($)),m=c(()=>$.startedAt!==null),h=c(()=>!$.finishReason||$.finishReason===`stop`?null:$.finishReason===`length`?`Token limit`:$.finishReason===`cancelled`?`Stopped`:$.finishReason);var _=oD(),v=R(_),y=R(v),b=e=>{g(e,ZE())},x=e=>{var t=QE();T(2),g(e,t)},C=e=>{var t=iD(),n=q(t),r=e=>{var t=$E(),n=X(q(t),2);Vl(R(n),{get value(){return $.replay.completed},get max(){return $.replay.total},width:120,height:6,color:`var(--accent)`}),f(n),g(e,t)},i=e=>{var t=eD(),n=q(t),r=R(n);f(n);var i=X(n,2),a=R(i);{let e=c(()=>$.maxTokens||Math.max($.tokensSoFar,1));Vl(a,{get value(){return $.tokensSoFar},get max(){return B(e)},width:120,height:6,color:`var(--accent-green)`})}f(i),U(()=>G(r,`${$.replay?`Continuing`:`Writing`} ${$.tokensSoFar??``}/${($.maxTokens||`?`)??``} tokens`)),g(e,t)},a=e=>{var t=tD(),n=R(t);f(t),U(()=>G(n,`${B(h)??($.finishReason===`stop`?`Complete`:`Ended`)??``} · ${$.tokensSoFar??``} tokens`)),g(e,t)};p(n,e=>{B(u)?e(r):$.active?e(i,1):e(a,-1)});var o=X(n,2),m=e=>{var t=nD(),n=R(t);f(t),U(e=>G(n,`${e??``} tokens/s`),[()=>B(l).toFixed(1)]),g(e,t)};p(o,e=>{B(u)||e(m)});var _=X(o,2),v=R(_);f(_);var y=X(_,2),b=e=>{var t=rD(),n=R(t);f(t),U(e=>G(n,`uncertainty ${e??``}`),[()=>B(d).toFixed(2)]),g(e,t)},x=c(()=>B(d)!==null&&Number.isFinite(B(d)));p(y,e=>{B(x)&&e(b)}),U(e=>G(v,`${e??``}s`),[()=>B(s).toFixed(1)]),g(e,t)};p(y,e=>{r()?e(b):!B(m)&&!$.active?e(x,1):e(C,-1)});var w=X(y,2),E=e=>{var t=aD(),n=R(t);f(t),U(()=>{S(t,`title`,B(a)),G(n,`${B(i)??``} queued`)}),g(e,t)};p(w,e=>{B(i)>0&&e(E)}),f(v),tp(X(v,2),{label:`About generation status`,text:`Tokens are pieces of text, and speed is shown in tokens per second. Lower uncertainty means the model was more sure of its wording.`}),f(_),g(e,_),W()}var cD=I(``),lD=I(` `),uD=I(`
                                `),dD=I(`
                                `);function fD(e,t){n(t,!0);let r=c(()=>qn.queue),i=c(()=>Rn.pulledSlot);function a(e,t){if(e===null)return``;let n=e.replace(/\n/g,` ⏎ `);return n.length<=t?n:n.slice(0,t-1)+`…`}var o=L(),s=q(o),l=e=>{var t=dD();m(t,23,()=>B(r),e=>e.id,(e,t,n)=>{var r=uD();let o;var s=R(r),c=e=>{g(e,cD())};p(s,e=>{B(n)===B(i)&&e(c)});var l=X(s,2),u=R(l,!0);f(l);var d=X(l,2),m=e=>{var n=lD(),r=R(n,!0);f(n),U(e=>{S(n,`title`,B(t).text),G(r,e)},[()=>a(B(t).text,80)]),g(e,n)};p(d,e=>{B(t).text!==null&&e(m)});var h=X(d,2);Be(R(h),{name:`dismiss`}),f(h),f(r),U(()=>{o=y(r,1,`bubble svelte-10vlmqx`,null,o,{editing:B(n)===B(i)}),G(u,B(t).label),S(h,`aria-label`,`Cancel pending ${B(t).label??``}`)}),K(`click`,h,()=>Qn(B(t).id)),g(e,r)}),f(t),g(e,t)};p(s,e=>{B(r).length>0&&e(l)}),g(e,o),W()}H([`click`]);function pD(e,t,n){let r=t,i=Math.max(0,n);for(let t of e){if(i===0)break;let e=t.text??``;if(!t.nodeId)throw Error(`The selected text is not saved yet.`);if(i({id:t.id,text:t.text,logprob:t.logprob,chosen:e.tokenId!=null&&t.id===e.tokenId}));return!t.some(e=>e.chosen)&&e.logprob!=null&&t.push({id:e.tokenId??-1,text:e.text,logprob:e.logprob,chosen:!0}),t.sort((e,t)=>t.logprob-e.logprob)}function hD(e){return e.replace(/ /g,`␣`).replace(/\n/g,`↵`).replace(/\t/g,`⇥`)||`∅`}var gD=I(`

                                Recorded before your edit, using the original preceding text.

                                `),_D=I(`this token`),vD=I(` `),yD=I(`
                                TokenProbability
                                `),bD=I(`

                                Alternative probabilities weren’t recorded for this token.

                                `),xD=I(``);function SD(t,r){let i=E();n(r,!0);let o=Y(r,`source`,3,`Model token`),s=Y(r,`contextChanged`,3,!1),l=De(()=>r.anchor),u=c(()=>mD(r.token)),d=cn(ke().mode),_,v=J(``),b=!1;function x(e=!0){b||(b=!0,_.inert=!0,e&&l.isConnected&&l.focus({preventScroll:!0}),r.onclose())}function C(){if(b)return;let e=window.visualViewport,t=e?.offsetLeft??0,n=e?.offsetTop??0,r=e?.width??innerWidth,i=e?.height??innerHeight;_.style.maxWidth=`${r-16}px`,_.style.maxHeight=`${i-16}px`;let a=l.getBoundingClientRect(),o=_.getBoundingClientRect(),s=Math.max(t+8,Math.min(a.left,t+r-o.width-8)),c=Math.max(0,n+i-a.bottom-14),u=Math.max(0,a.top-n-14),d=o.height<=c||c>=u,f=Math.min(i-16,d?c:u),p=Math.min(o.height,f);A(v,`left:${s}px;top:${Math.max(n+8,Math.min(d?a.bottom+6:a.top-p-6,n+i-p-8))}px;max-width:${r-16}px;max-height:${f}px;`)}ne(()=>{_.showPopover(),C(),_.focus({preventScroll:!0});let e=e=>{b||e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),x())},t=e=>{!b&&!_.contains(e.target)&&!l.contains(e.target)&&x(!1)},n=e=>{!b&&!_.contains(e.target)&&!l.contains(e.target)&&x(!1)};return document.addEventListener(`keydown`,e,!0),document.addEventListener(`pointerdown`,t,!0),document.addEventListener(`focusin`,n),window.addEventListener(`resize`,C),window.addEventListener(`scroll`,C,!0),window.visualViewport?.addEventListener(`resize`,C),window.visualViewport?.addEventListener(`scroll`,C),()=>{document.removeEventListener(`keydown`,e,!0),document.removeEventListener(`pointerdown`,t,!0),document.removeEventListener(`focusin`,n),window.removeEventListener(`resize`,C),window.removeEventListener(`scroll`,C,!0),window.visualViewport?.removeEventListener(`resize`,C),window.visualViewport?.removeEventListener(`scroll`,C)}});var w=xD(),D=R(w),O=R(D),k=R(O),j=R(k,!0);f(k);var M=X(k),P=R(M,!0);f(M),f(O),Du(X(O,2),{ariaLabel:`Close token probabilities`,onclick:()=>x(),children:(t,n)=>{T(),g(t,e(`Close`))},$$slots:{default:!0}}),f(D);var F=X(D,2),I=e=>{g(e,gD())};p(F,e=>{s()&&e(I)});var L=X(F,2),ee=e=>{var t=yD(),n=X(R(t));m(n,21,()=>B(u),N,(e,t)=>{var n=vD();let r;var i=R(n),a=R(i),o=R(a,!0);f(a);var s=X(a),c=e=>{g(e,_D())};p(s,e=>{B(t).chosen&&e(c)}),f(i);var l=X(i),u=R(l,!0);f(l),f(n),U((e,i,a)=>{r=y(n,1,`svelte-139pzr0`,null,r,{chosen:B(t).chosen}),G(o,e),S(l,`title`,i),G(u,a)},[()=>hD(B(t).text),()=>`log probability ${B(t).logprob.toFixed(4)}`,()=>Math.exp(B(t).logprob)>=.001?Math.exp(B(t).logprob).toFixed(3):Math.exp(B(t).logprob).toExponential(2)]),g(e,n)}),f(n),f(t),g(e,t)};p(L,e=>{B(u).length&&e(ee)});var te=X(L,2),z=e=>{g(e,bD())};p(te,e=>{r.token.topAlts?.length||e(z)});var V=X(te,2),re=t=>{Du(t,{onclick:()=>xi.return_top_k=d,children:(t,n)=>{T(),g(t,e(`Record alternatives for future tokens`))},$$slots:{default:!0}})};p(V,e=>{!r.token.topAlts?.length&&d>0&&xi.return_top_k===0&&e(re)});var ie=X(V,4),ae=t=>{Du(t,{onclick:()=>{l.focus({preventScroll:!0}),r.ondetails?.(),r.onclose()},children:(t,n)=>{T(),g(t,e(`Full token details`))},$$slots:{default:!0}})};p(ie,e=>{r.ondetails&&e(ae)}),f(w),a(w,e=>_=e,()=>_),U(e=>{S(w,`aria-labelledby`,`${i}-title`),pe(w,B(v)),G(j,o()),S(M,`id`,`${i}-title`),G(P,e)},[()=>hD(r.token.text)]),ye(`outrostart`,w,()=>{b=!0,_.inert=!0}),h(5,w,()=>ct,ou),h(6,w,()=>ct,su),g(t,w),W()}function CD(e){return e.flatMap((e,t)=>{let n=e.generated?`model`:`user`,r={nodeId:e.nodeId??null,source:n,contextChanged:!1,isThinking:!1};return e.tokens?.length&&e.tokens.map(e=>e.text).join(``)===e.text?e.tokens.map((e,n)=>({...r,text:e.text,turnIdx:t,tokenIdx:n,tok:e})):[{...r,text:e.text,turnIdx:null,tokenIdx:0,tok:null}]})}function wD(e,t){let n=e.map(e=>e.text).join(``);if(t===n)return e;let r=0;for(;r0&&/[\uD800-\uDBFF]/.test(t[r-1])&&r--;let i=0;for(;i0&&/[\uDC00-\uDFFF]/.test(t[t.length-i])&&i--;let a=e=>({text:e,turnIdx:null,nodeId:null,tokenIdx:0,isThinking:!1,tok:null,source:`draft`,contextChanged:!1}),o=(t,n,r)=>{let i=0;return e.flatMap(e=>{let o=i;i+=e.text.length;let s=Math.max(t,o),c=Math.min(n,i);if(c<=s)return[];if(s===o&&c===i)return[{...e,contextChanged:e.contextChanged||r}];let l=e.text.slice(s-o,c-o);return[e.tok?a(l):{...e,text:l}]})},s=t.slice(r,t.length-i);return[...o(0,r,!1),...s?[a(s)]:[],...o(n.length-i,n.length,!0)]}var TD=I(` `),ED=I(`Unsaved edit`),DD=I(`
                                User text Model tokens
                                `),OD=I(`

                                Original recorded text. Your current text and unsaved edits are unchanged.

                                `),kD=I(`
                                Inspect
                                `,1),AD=I(` `),jD=I(` `),MD=I(`
                                `),ND=I(` `),PD=I(``),FD=I(` `,1),ID=I(`
                                `),LD=I(`

                                `),RD=I(``),zD=I(`
                                Unsaved edit
                                `),BD=I(`

                                `);function VD(r,i){n(i,!0);let o=c(()=>Ko.turns.map(e=>e.text??``).join(``)),s=J(``),l=J(!1),u=J(!1),d=J(null),h=J(null),_=J(null),v=J(null),b=J(null),x=J(null),C=J(!1);Ce(()=>{let e=B(o);if(!B(C)){if(B(u)){if(!e.startsWith(B(s))){!$.active&&$.finishedAt!==null&&$.finishedAt!==B(d)&&(A(u,!1),A(l,!0));return}A(u,!1)}B(l)||(A(s,e,!0),A(b,null))}});function w(e){A(x,null),A(_,null);let t=e.currentTarget.value;A(b,t===B(o)?null:wD(B(b)??B(z),t),!0),A(s,t,!0),A(l,B(s)!==B(o)),A(u,!1)}function E(){!B(h)||$.active||B(u)||B(C)||A(x,{start:B(h).selectionStart,end:B(h).selectionEnd,text:B(s),nodeId:B(O)},!0)}async function D(e=!1){if(!B(k)||!B(x)||$.active||B(u)||B(C)||B(l)||qn.queue.length||!Q.root_id)return;let t=e?B(x).start:B(x).end,n=B(s),r=B(O),i=Q.root_id;A(C,!0),A(_,null),A(v,document.activeElement,!0);try{let e=pD(Ko.turns,Q.root_id,t),r=e.parentNodeId;if(e.branch?r=(await Ot.branch(e.branch.nodeId,e.branch.text,void 0,`user`)).node_id:await Ot.navigate(r),await go(),Q.root_id!==i||Q.active_node_id!==r)throw Error(`The selected completion point changed. Select the text again.`);A(s,n.slice(0,t),!0),A(b,null),A(x,null),A(Me,!1),A(u,!0),A(d,$.finishedAt,!0),await $a({raw:!0,parent_node_id:r,append_same_role:!1,n:1})}catch(e){if(Q.root_id!==i){A(u,!1);return}if(A(s,n,!0),r)try{await Ot.navigate(r),await go()}catch{}I(e)}finally{A(C,!1)}}Ce(()=>{if(!B(v)||B(u)||$.active||B(C))return;let e=B(v);A(v,null),xe().then(()=>{(document.activeElement===e||document.activeElement===document.body)&&B(h)?.focus({preventScroll:!0})})});let O=c(()=>Q.loaded?Q.active_node_id??null:null),k=c(()=>B(x)!==null&&B(x).text===B(s)&&B(x).nodeId===B(O));function j(){if(!B(l))return{tail:``,parentNodeId:void 0};let e=Ko.turns,t=0;for(let n=0;nB(h)?.focus({preventScroll:!0}))}function te(e){if(e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&!e.isComposing){e.preventDefault(),M();return}e.key===`Escape`&&$.active&&(e.preventDefault(),no())}let z=c(()=>CD(Ko.turns)),V=c(()=>B(b)??B(z)),re=c(()=>[...Q.nodes.values()].filter(e=>e.recipe&&e.tokens?.length&&!Q.activePath.includes(e.id)).sort((e,t)=>t.created_at-e.created_at)),ie=J(`current`),ae=c(()=>[{value:`current`,label:B(l)?`Current draft`:`Current text`},...B(l)&&B(z).some(e=>e.tok)?[{value:`recorded`,label:`Original text before edit`}]:[],...B(re).map((e,t)=>({value:e.id,label:`Earlier generation ${B(re).length-t} · ${e.text.slice(0,48).replace(/\s+/g,` `)}`}))]),oe=c(()=>{if(B(ie)===`recorded`)return B(z);let e=B(re).find(e=>e.id===B(ie));return e?CD([{nodeId:e.id,role:e.role,text:e.text,generated:!0,tokens:e.tokens.map(ao)}]).map(e=>({...e,turnIdx:null})):B(V)});Ce(()=>{B(ae).some(e=>e.value===B(ie))||A(ie,`current`)});let H=J(null),se=J(`edit`),ce=c(()=>B(se)===`edit`&&!B(u)&&(B(l)||fi.target!==null&&B(V).some(e=>e.tok))&&B(V).map(e=>e.text).join(``)===(B(l)?B(s):B(o))),le=c(()=>{if(!fi.target)return null;if(B(l))return`Retained tokens keep their original readings; edited text has no recorded probabilities.`;if(B(u)||!B(ue))return null;let e=[fi.target,...fi.compareTwo&&fi.compareTarget?[fi.compareTarget]:[]],t=B(z).flatMap(({tok:t})=>e.flatMap(e=>{let n=t?Jc(t,e):void 0;return n===void 0?[]:[n]}));return t.length===0?`No readings were recorded for this color.`:t.some(e=>e!==0)?null:`Recorded ${e.length>1?`values are`:fi.target===`__surprise__`?`token surprisal is`:fi.target===`__entropy__`?`sampler entropy is`:`values are`} zero, so these tokens stay uncolored.`}),ue=c(()=>B(V).some(e=>e.tok!==null)),de=c(()=>B(oe).flatMap((e,t)=>e.tok===null?[]:[t])),fe=J(-1);Ce(()=>{let e=B(de);e.length===0?A(fe,-1):e.includes(B(fe))||A(fe,e[0],!0)});let me=c(()=>B(ue)||B(z).some(e=>e.tok)||B(re).length>0),he=c(()=>B(me)&&!B(u)&&!$.active&&!B(C)),ge=c(()=>[{value:`edit`,label:`Edit text`,title:`Edit the completion text`},{value:`inspect`,label:`Inspect tokens`,disabled:B(se)!==`inspect`&&!B(he),title:B(he)||B(se)===`inspect`?`Choose a token to inspect readings or branch`:$.active?`Stop or finish generation before inspecting`:B(u)?`Wait for the edit to finish saving`:`Continue text to record tokens`}]);Ce(()=>{B(se)===`inspect`&&!B(me)&&A(se,`edit`)});function ve(e){A(H,null),e===`inspect`&&!B(ue)&&A(ie,B(z).some(e=>e.tok)&&B(l)?`recorded`:B(re)[0]?.id??`current`,!0),A(se,e,!0)}function be(e){let t=e.tok;if(!t)return``;let n=[],r=Jc(t,fi.target);r!==void 0&&fi.target&&(fi.target===`__surprise__`?t.logprob!=null&&n.push(`token surprisal ${(-t.logprob).toFixed(3)} nats`):fi.target===`__probability__`&&t.logprob!=null?n.push(`token probability ${(Math.exp(Math.min(0,t.logprob))*100).toFixed(1)}%`):fi.target===`__entropy__`&&t.samplerEntropy!=null?n.push(`sampler entropy ${t.samplerEntropy.toFixed(3)} nats`):n.push(`${fi.target} ${r>=0?`+`:``}${r.toFixed(3)}`));let i=t.topAlts?.length??0;return n.push(i>0?`Select to see ${i} alternatives`:`Select to see the recorded probability`),n.join(` · `)}function Se(e){let t=e.text.trim()||`whitespace`,n=e.tok?.topAlts?.length??0;return n>0?`Inspect token ${t}, ${n} alternatives`:`Inspect token ${t}`}function we(e){A(fe,e,!0),queueMicrotask(()=>{B(ke)?.querySelector(`[data-token-view-index="${e}"]`)?.focus()})}function Te(e,t,n){if(e.key===`Enter`||e.key===` `){e.preventDefault(),De(n,e.currentTarget);return}let r=B(de).indexOf(t);if(r<0)return;let i=r;if(e.key===`ArrowRight`||e.key===`ArrowDown`)i=(r+1)%B(de).length;else if(e.key===`ArrowLeft`||e.key===`ArrowUp`)i=(r-1+B(de).length)%B(de).length;else if(e.key===`Home`)i=0;else if(e.key===`End`)i=B(de).length-1;else return;e.preventDefault(),we(B(de)[i])}function Ee(e){e.turnIdx!==null&&rt(`token_drilldown`,{turnIdx:e.turnIdx,tokenIdx:e.tokenIdx,isThinking:e.isThinking,initialTab:`logits`})}function De(e,t){if(e.tok){if($e.docked&&e.turnIdx!==null){A(H,null),rt(`token_drilldown`,{turnIdx:e.turnIdx,tokenIdx:e.tokenIdx,isThinking:e.isThinking});return}A(H,{view:e,anchor:t},!0)}}function Oe(e){e.tok&&Zi(e.tok,e.nodeId??void 0)}let ke=J(null),Ae=J(null),Me=J(!1);function Y(){!B(Ae)||!B(h)||(B(Ae).scrollTop=B(h).scrollTop,B(Ae).scrollLeft=B(h).scrollLeft)}function Ne(e){let t=e.currentTarget;A(Me,t.scrollHeight-t.scrollTop-t.clientHeight>=8),B(se)===`edit`&&Y()}function Pe(){A(Me,!1);let e=B(se)===`edit`?B(h):B(ke);e&&(e.scrollTop=e.scrollHeight),Y()}Ce(()=>{B(ce)&&xe().then(Y)}),Ce(()=>{B(o),!B(l)&&!B(Me)&&xe().then(()=>{!B(l)&&!B(Me)&&Pe()})}),ne(()=>{A(s,B(o),!0)});var Fe=BD(),Ie=R(Fe),Le=R(Ie),Re=X(R(Le),2),ze=e=>{Cm(e,{})};p(Re,e=>{_i.info?.is_base_model&&e(ze)}),f(Le),Fc(X(Le,2),{get value(){return B(se)},onchange:ve,get items(){return B(ge)},ariaLabel:`Buffer mode`}),f(Ie);var Be=X(Ie,2),Ve=R(Be,!0),He=X(Ve),Ue=e=>{var t=TD(),n=R(t,!0);f(t),U(()=>G(n,B(le))),g(e,t)};p(He,e=>{B(le)&&e(Ue)}),f(Be);var We=X(Be,2),Ge=e=>{var t=DD(),n=X(R(t),4),r=e=>{g(e,ED())};p(n,e=>{B(l)&&e(r)}),f(t),g(e,t)};p(We,e=>{(B(me)||B(l))&&e(Ge)});var Ke=X(We,2),qe=e=>{var t=kD(),n=q(t);hu(X(R(n),2),{get value(){return B(ie)},get options(){return B(ae)},ariaLabel:`Text to inspect`,onchange:e=>{A(H,null),A(ie,e,!0)}}),f(n);var r=X(n,2),i=e=>{g(e,OD())};p(r,e=>{B(ie)!==`current`&&e(i)}),g(e,t)};p(Ke,e=>{B(se)===`inspect`&&B(ae).length>1&&e(qe)});var Je=X(Ke,2);let Z;var Ye=R(Je),Xe=e=>{var t=MD();m(t,21,()=>B(oe),N,(e,t,n)=>{var r=L(),i=q(r),a=e=>{var n=AD();let r;var i=R(n,!0);f(n),U(()=>{r=y(n,1,`seg plain svelte-riacu3`,null,r,{"origin-user":B(t).source===`user`,"origin-draft":B(t).source===`draft`}),S(n,`title`,B(t).source===`draft`?`Unsaved user edit · no recorded probabilities`:B(t).source===`model`?`Model text · no recorded probabilities`:`User text · no recorded probabilities`),G(i,B(t).text)}),g(e,n)},o=e=>{var r=jD();let i;S(r,`data-token-view-index`,n);var a=R(r,!0);f(r),U((e,o,s,c)=>{i=y(r,1,`seg tok clickable svelte-riacu3`,null,i,{"origin-user":B(t).source===`user`,"origin-model":B(t).source===`model`,"context-changed":B(t).contextChanged,tinted:fi.target!==null,"has-alts":(B(t).tok?.topAlts?.length??0)>0}),pe(r,e),S(r,`title`,o),S(r,`tabindex`,n===B(fe)?0:-1),S(r,`aria-label`,s),S(r,`aria-expanded`,c),G(a,B(t).text)},[()=>B(t).tok?Zc(B(t).tok):``,()=>be(B(t)),()=>Se(B(t)),()=>B(H)?.anchor.dataset.tokenViewIndex===String(n)]),ye(`pointerenter`,r,()=>Oe(B(t))),ye(`pointerleave`,r,function(...e){Qi?.apply(this,e)}),ye(`focus`,r,()=>Oe(B(t))),ye(`blur`,r,function(...e){Qi?.apply(this,e)}),K(`click`,r,e=>{A(fe,n,!0),De(B(t),e.currentTarget)}),K(`keydown`,r,e=>Te(e,n,B(t))),g(e,r)};p(i,e=>{B(t).tok?e(o,-1):e(a)}),g(e,r)}),f(t),U(()=>t.dir=t.dir),g(e,t)},Ze=e=>{var n=FD(),r=q(n),i=e=>{var t=PD(),n=R(t);m(n,17,()=>B(V),N,(e,t)=>{var n=ND();let r;var i=R(n,!0);f(n),U(e=>{pe(n,e),r=y(n,1,`svelte-riacu3`,null,r,{"origin-draft":B(t).source===`draft`}),G(i,B(t).text)},[()=>B(t).tok?Zc(B(t).tok):``]),g(e,n)});var r=X(n);r.textContent=`​`,f(t),a(t,e=>A(Ae,e),()=>B(Ae)),U(()=>t.dir=t.dir),g(e,t)};p(r,e=>{B(ce)&&e(i)});var o=X(r,2);_e(o),a(o,e=>A(h,e),()=>B(h)),U(()=>{t(o,B(s)),S(o,`aria-describedby`,B(_)?`completion-hint completion-error`:`completion-hint`),S(o,`aria-invalid`,B(_)?!0:void 0),o.readOnly=$.active||B(u)||B(C),o.dir=o.dir}),K(`input`,o,w),K(`keydown`,o,te),ye(`select`,o,E),K(`keyup`,o,E),K(`pointerup`,o,E),ye(`scroll`,o,Ne),g(e,n)};p(Ye,e=>{B(se)===`inspect`?e(Xe):e(Ze,-1)});var Qe=X(Ye,2),et=t=>{var n=ID();Du(R(n),{onclick:()=>{Pe(),B(h)?.focus({preventScroll:!0})},children:(t,n)=>{T(),g(t,e(`Jump to latest text`))},$$slots:{default:!0}}),f(n),g(t,n)};p(Qe,e=>{B(Me)&&!B(l)&&B(se)===`edit`&&e(et)}),f(Je),a(Je,e=>A(ke,e),()=>B(ke));var tt=X(Je,2),nt=t=>{var n=LD(),r=R(n),i=R(r);{let t=c(()=>B(l)||$.active||B(u)||B(C)||qn.queue.length>0);Du(i,{onclick:()=>D(),get disabled(){return B(t)},children:(t,n)=>{T();var r=e();U(()=>G(r,B(x).start===B(x).end?`Continue from cursor`:`Continue after selection`)),g(t,r)},$$slots:{default:!0}})}var a=X(i,2),o=t=>{{let n=c(()=>B(l)||$.active||B(u)||B(C)||qn.queue.length>0);Du(t,{onclick:()=>D(!0),get disabled(){return B(n)},children:(t,n)=>{T(),g(t,e(`Re-complete from selection`))},$$slots:{default:!0}})}};p(a,e=>{B(x).start!==B(x).end&&e(o)}),f(r);var s=X(r,2),d=R(s,!0);f(s),f(n),U(()=>G(d,B(l)?`Save your edit first to complete from this point.`:B(x).start===B(x).end?`Text after the cursor is regenerated in a new branch. The original stays saved.`:`Continue keeps the selection; re-complete starts before it. Text after that point is regenerated in a new branch.`)),g(t,n)};p(tt,e=>{B(se)===`edit`&&B(k)&&B(x)&&B(s).length>0&&e(nt)});var it=X(tt,2),at=e=>{let t=c(()=>B(H).view);var n=L();F(q(n),()=>B(H).anchor,e=>{{let n=c(()=>B(ie)===`current`?B(H).view.source===`user`?`User text · recorded`:`Model token`:`Original recorded token`),r=c(()=>B(t).turnIdx===null?void 0:()=>Ee(B(t)));SD(e,{get token(){return B(H).view.tok},get anchor(){return B(H).anchor},get source(){return B(n)},get contextChanged(){return B(H).view.contextChanged},onclose:()=>A(H,null),get ondetails(){return B(r)}})}}),g(e,n)};p(it,e=>{B(H)?.view.tok&&e(at)});var ot=X(it,2),st=e=>{var t=RD(),n=R(t);f(t),U(()=>G(n,`${B(_)??``} Your text is still here.`)),g(e,t)};p(ot,e=>{B(_)&&e(st)});var ct=X(ot,2);{let e=c(()=>!$.active&&$.finishReason===`stop`&&$.tokensSoFar===0&&Ko.turns.at(-1)?.generated===!1);sD(ct,{get savedEdit(){return B(e)}})}var lt=X(ct,2);fD(lt,{});var ut=X(lt,2),dt=R(ut),ft=t=>{var n=zD(),r=X(R(n),2);{let t=c(()=>$.active||B(u)||B(C));Du(r,{onclick:()=>void P(),get disabled(){return B(t)},title:`Save this edit without generating`,children:(t,n)=>{T(),g(t,e(`Save edit`))},$$slots:{default:!0}})}var i=X(r,2);{let t=c(()=>$.active||B(u)||B(C));Du(i,{onclick:ee,get disabled(){return B(t)},children:(t,n)=>{T(),g(t,e(`Discard edit`))},$$slots:{default:!0}})}f(n),g(t,n)};p(dt,e=>{B(l)&&e(ft)});var pt=X(dt,2),mt=X(R(pt),2);{let t=c(()=>$.active||B(u)||B(C)),n=c(()=>B(u)&&!$.active);Du(mt,{variant:`solid`,onclick:M,get disabled(){return B(t)},get busy(){return B(n)},title:`Continue text (Cmd/Ctrl+Enter)`,children:(t,n)=>{T(),g(t,e(`Continue text`))},$$slots:{default:!0}})}var ht=X(mt,2);{let t=c(()=>!$.active);Du(ht,{variant:`danger`,get onclick(){return no},get disabled(){return B(t)},title:`Esc`,children:(t,n)=>{T(),g(t,e(`Stop`))},$$slots:{default:!0}})}f(pt),f(ut),f(Fe),U(()=>{G(Ve,B(se)===`inspect`?`Click a recorded token to see its probabilities. Arrow keys move between tokens; editing stays in Edit text.`:`Continue from the end, or place the cursor or select text to complete from another point. The original stays saved in Loom.`),Z=y(Je,1,`surface svelte-riacu3`,null,Z,{inspecting:B(se)===`inspect`,"loading-pulse":$.active})}),ye(`scroll`,Je,function(...e){(B(se)===`inspect`?Ne:void 0)?.apply(this,e)}),g(r,Fe),W()}H([`click`,`keydown`,`input`,`keyup`,`pointerup`]);var HD=I(`
                              • `),UD=I(`
                              • `),WD=I(`
                                  `),GD=I(`
                                  `);function KD(e,t){let r=E();n(t,!0);let i=Y(t,`value`,15),o=Y(t,`placeholder`,3,``),l=Y(t,`disabled`,3,!1),u=Y(t,`invalid`,3,!1),d=Y(t,`spellcheck`,3,!1),h=J(!1),_=du(),v=J(!1),b=J(-1),x=J(null),C=J(null),w=J(``);Ce(()=>{l()&&B(h)&&O()});let T=c(()=>{if(!B(v)||!i().trim())return t.options;let e=i().trim().toLowerCase();return t.options.filter(t=>t.label.toLowerCase().includes(e))});async function D(e=!1){if(!l()&&(A(v,e,!0),A(h,!0),_.mount(),A(b,B(T).findIndex(e=>e.value===i()),!0),B(b)<0&&B(T).length>0&&A(b,0),await xe(),B(h))){try{B(C)?.showPopover()}catch{}F(),await xe(),B(h)&&B(C)&&_.show(B(C))}}function O(){B(h)&&(A(h,!1),_.close(B(C)))}async function k(e){let n=B(T)[e];n&&(i(n.value),t.onchange?.(i()),O(),await xe(),B(x)?.focus(),B(x)?.setSelectionRange(i().length,i().length))}function M(e){i(e.currentTarget.value),t.onchange?.(i()),D(!0)}function N(e){B(T).length!==0&&(A(b,(B(b)+e+B(T).length)%B(T).length),(B(C)?.children[B(b)])?.scrollIntoView({block:`nearest`}))}function P(e){e.key===`ArrowDown`||e.key===`ArrowUp`?(e.preventDefault(),B(h)?N(e.key===`ArrowDown`?1:-1):D(!1)):e.key===`Enter`&&B(h)?(e.preventDefault(),B(b)>=0?k(B(b)):O()):e.key===`Escape`&&B(h)?(e.preventDefault(),e.stopPropagation(),O()):e.key===`Tab`&&O()}function F(){if(!B(x)||!B(C))return;let e=B(x).parentElement?.getBoundingClientRect()??B(x).getBoundingClientRect(),t=window.visualViewport,n=t?.offsetLeft??0,r=t?.offsetTop??0,i=t?.width??window.innerWidth,a=r+(t?.height??window.innerHeight),o=Math.min(240,Math.max(32,B(C).scrollHeight)),s=a-e.bottom-8-2,c=e.top-r-8-2,l=ss,u=Math.max(32,Math.min(240,l?c:s)),d=Math.min(o,u),f=Math.min(e.width,i-16);A(w,`left:${Math.max(n+8,Math.min(e.left,n+i-f-8))}px;top:${l?Math.max(r+8,e.top-d-2):Math.min(a-d-8,e.bottom+2)}px;width:${f}px;max-height:${u}px`),B(C).dataset.origin=l?`bottom-left`:`top-left`}function I(e){if(!B(h))return;let t=e.target;B(x)?.parentElement?.contains(t)||B(C)?.contains(t)||O()}function L(){B(h)&&F()}ne(()=>(document.addEventListener(`pointerdown`,I,!0),window.addEventListener(`resize`,L),window.addEventListener(`scroll`,L,!0),window.visualViewport?.addEventListener(`resize`,L),window.visualViewport?.addEventListener(`scroll`,L),()=>{document.removeEventListener(`pointerdown`,I,!0),window.removeEventListener(`resize`,L),window.removeEventListener(`scroll`,L,!0),window.visualViewport?.removeEventListener(`resize`,L),window.visualViewport?.removeEventListener(`scroll`,L),_.destroy()}));var ee=GD();let te;var z=R(ee);s(z),a(z,e=>A(x,e),()=>B(x));var V=X(z,2);Be(R(V),{name:`down`}),f(V);var re=X(V,2),ie=e=>{var n=WD();m(n,23,()=>B(T),e=>e.value,(e,t,n)=>{var a=HD();let o;var s=R(a,!0);f(a),U(()=>{S(a,`id`,`${r}-option-${B(n)}`),S(a,`aria-selected`,B(t).value===i()),o=y(a,1,`svelte-n6fnqg`,null,o,{highlight:B(n)===B(b),active:B(t).value===i()}),G(s,B(t).label)}),ye(`pointerenter`,a,()=>A(b,B(n),!0)),K(`pointerdown`,a,e=>e.preventDefault()),K(`keydown`,a,e=>{(e.key===`Enter`||e.key===` `)&&k(B(n))}),K(`click`,a,()=>void k(B(n))),g(e,a)},e=>{var t=UD(),n=R(t);f(t),U(e=>G(n,`Custom role: “${e??``}”`),[()=>i().trim()]),g(e,t)}),f(n),a(n,e=>A(C,e),()=>B(C)),U(()=>{S(n,`id`,`${r}-listbox`),pe(n,B(w)),S(n,`aria-label`,t.ariaLabel)}),g(e,n)};p(re,e=>{_.mounted&&e(ie)}),f(ee),U(()=>{te=y(ee,1,`sk-combobox field-focus svelte-n6fnqg`,null,te,{"is-open":B(h),"is-invalid":u()}),S(z,`placeholder`,o()),z.disabled=l(),S(z,`title`,t.title),S(z,`spellcheck`,d()),S(z,`aria-label`,t.ariaLabel),S(z,`aria-describedby`,t.ariaDescribedby),S(z,`aria-expanded`,B(h)),S(z,`aria-controls`,B(h)?`${r}-listbox`:void 0),S(z,`aria-activedescendant`,B(h)&&B(b)>=0?`${r}-option-${B(b)}`:void 0),S(z,`aria-invalid`,u()),S(V,`aria-label`,`Choose ${t.ariaLabel??`value`}`),V.disabled=l()}),K(`input`,z,M),K(`keydown`,z,P),j(z,i),K(`click`,V,()=>B(h)?O():void D(!1)),g(e,ee),W()}H([`input`,`keydown`,`click`,`pointerdown`]);var qD=(e,t=Ie,n)=>{let r=u(()=>O(n?.(),!0));var i=ZD(),a=R(i),o=e=>{var t=L(),n=q(t),i=e=>{var t=JD(),n=R(t);{let e=c(()=>wc.avatarSeed??_i.info?.model_id??`drowse`);bg(n,{get name(){return B(e)},size:32,background:`circle`,alt:``})}f(t),K(`click`,t,()=>window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:{view:`controls`,section:`model`}}))),g(e,t)},a=e=>{var t=YD(),n=R(t);{let e=c(()=>wc.avatarSeed??_i.info?.model_id??`drowse`);bg(n,{get name(){return B(e)},size:32,background:`circle`,alt:``})}f(t),g(e,t)};p(n,e=>{B(r)?e(i):e(a,-1)}),g(e,t)},s=e=>{g(e,XD())};p(a,e=>{t().role===`assistant`?e(o):e(s,-1)});var l=X(a,2),d=R(l,!0);f(l),f(i),U(e=>G(d,e),[()=>qo(t().role,t().roleLabel)]),g(e,i)},JD=I(``),YD=I(``),XD=I(``),ZD=I(` `),QD=I(`
                                  `),$D=I(`(unsteered)`),eO=I(` `),tO=I(` `),nO=I(` `),rO=I(`
                                  `),iO=I(`
                                  `),aO=I(` `),oO=I(` `),sO=I(`
                                  `),cO=I(``),lO=I(``),uO=I(``),dO=I(` `,1),fO=I(`
                                  `,1),pO=I(`
                                  `),mO=I(`

                                  Type a prompt to get started

                                  `),hO=I(`
                                  pinned
                                  `,1),gO=I(``),_O=I(`
                                  `),vO=I(`
                                  You
                                  Model
                                  `),yO=I(``),bO=I(``),xO=I(`

                                  This model uses it for one turn only.

                                  `),SO=I(`
                                  `),CO=I(`
                                  `),wO=I(` `,1),TO=I(`Stop`,1),EO=I(``),DO=I(`

                                  Use arrow keys to resize. Double-click to reset.

                                  `,1),OO=I(`
                                  Model
                                  `),kO=I(`
                                  `);function AO(r,i){n(i,!0);let o=(t,n=Ie,r=Ie,i=Ie)=>{var a=L(),o=q(a),s=e=>{var t=QD();let r;var a=R(t,!0);f(t),U(()=>{r=y(t,1,`stage svelte-o5nz21`,null,r,{shadow:i()}),G(a,n().text),t.dir=t.dir}),h(1,t,()=>lt,ou),g(e,t)},l=t=>{var a=sO();let o;var s=R(a),l=R(s);qD(l,n);var u=X(l,2),d=e=>{{let t=c(()=>`Reroll ${qo(n().role,n().roleLabel)} message`);Du(e,{size:`sm`,variant:`flat`,onclick:()=>kt(n()),title:`reroll this message`,get ariaLabel(){return B(t)},children:(e,t)=>{Be(e,{name:`refresh`})},$$slots:{default:!0}})}};p(u,e=>{n().nodeId&&e(d)});var _=X(u,2),v=t=>{{let i=c(()=>`Inspect tokens in ${qo(n().role,n().roleLabel)} message`);Du(t,{size:`sm`,variant:`flat`,onclick:()=>en(n(),r()),get ariaLabel(){return B(i)},children:(t,n)=>{T(),g(t,e(`inspect tokens`))},$$slots:{default:!0}})}};p(_,e=>{((n().tokens?.length??0)>0||(n().thinkingTokens?.length??0)>0)&&e(v)});var b=X(_,2),x=e=>{g(e,$D())};p(b,e=>{i()&&!B(Mt)&&e(x)});var C=X(b,2),w=e=>{var t=eO(),r=R(t,!0);f(t),U(()=>G(r,(n().tokens?.length??0)>0?`Writing…`:(n().thinkingTokens?.length??0)>0?`Thinking…`:`Preparing reply…`)),g(e,t)};p(C,e=>{$.active&&(i()?as.pendingTurnIdx===r():!as.processingAb&&Ko.pendingIndex===r())&&e(w)});var E=X(C,2),D=e=>{var t=tO(),r=R(t);f(t),U(e=>G(r,`seq ppl ${e??``}`),[()=>Math.exp(-n().meanLogprob).toFixed(1)]),g(e,t)},O=c(()=>n().meanLogprob!=null&&Number.isFinite(n().meanLogprob));p(E,e=>{B(O)&&e(D)}),f(s);var k=X(s,2),A=e=>{var t=iO();let i;var a=R(t),o=R(a);let s;Be(R(o),{name:`down`}),f(o);var l=X(o,2),u=R(l);f(l),f(a);var d=X(a,2),_=e=>{var t=rO();m(t,21,()=>n().thinkingTokens??[],N,(e,t,i)=>{var a=nO();let o;var s=R(a,!0);f(a),U((e,n,r)=>{o=y(a,1,`tok svelte-o5nz21`,null,o,{tinted:fi.target!==null}),pe(a,e),S(a,`tabindex`,n),S(a,`aria-label`,r),G(s,B(t).text)},[()=>Zc(B(t)),()=>i===(Zt.get(`${n().nodeId??r()}:thinking`)??0)?0:-1,()=>`Inspect token ${B(t).text.trim()||`whitespace`}`]),ye(`pointerenter`,a,()=>Zi(B(t),n().nodeId)),ye(`pointerleave`,a,function(...e){Qi?.apply(this,e)}),ye(`focus`,a,()=>{Zt.set(`${n().nodeId??r()}:thinking`,i),Zi(B(t),n().nodeId)}),ye(`blur`,a,function(...e){Qi?.apply(this,e)}),K(`click`,a,e=>Qt(r(),i,e,!0)),K(`keydown`,a,e=>$t(e,r(),i,!0)),g(e,a)}),f(t),U(()=>t.dir=t.dir),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)},v=c(()=>!It(r(),n()));p(d,e=>{B(v)&&e(_)}),f(t),U((e,n,r,c)=>{i=y(t,1,`thinking-block svelte-o5nz21`,null,i,e),S(a,`aria-expanded`,n),s=y(o,1,`caret svelte-o5nz21`,null,s,r),G(u,`thinking${c??``}`)},[()=>({collapsed:It(r(),n())}),()=>!It(r(),n()),()=>({collapsed:It(r(),n())}),()=>It(r(),n())?`…`:``]),K(`click`,a,()=>Lt(r())),g(e,t)};p(k,e=>{((n().thinkingTokens?.length??0)>0||n().thinking)&&e(A)});var j=X(k,2),M=R(j),P=e=>{var t=L();m(q(t),19,()=>Yt(n().tokens??[]),({tok:e,originalIdx:t})=>t,(e,t,i)=>{let a=()=>B(t).tok,o=()=>B(t).originalIdx;var s=aO();let c;var l=R(s,!0);f(s),U((e,t,n)=>{c=y(s,1,`tok svelte-o5nz21`,null,c,{tinted:fi.target!==null}),pe(s,e),S(s,`tabindex`,t),S(s,`aria-label`,n),G(l,a().text)},[()=>Zc(a()),()=>(Zt.has(`${n().nodeId??r()}:response`)?Zt.get(`${n().nodeId??r()}:response`)===o():B(i)===0)?0:-1,()=>`Inspect token ${a().text.trim()||`whitespace`}`]),ye(`pointerenter`,s,()=>Zi(a(),n().nodeId)),ye(`pointerleave`,s,function(...e){Qi?.apply(this,e)}),ye(`focus`,s,()=>{Zt.set(`${n().nodeId??r()}:response`,o()),Zi(a(),n().nodeId)}),ye(`blur`,s,function(...e){Qi?.apply(this,e)}),K(`click`,s,e=>Qt(r(),o(),e,!1)),K(`keydown`,s,e=>$t(e,r(),o())),g(e,s)}),g(e,t)},F=e=>{var t=oO(),r=R(t,!0);f(t),U(e=>G(r,e),[()=>tn(n())]),g(e,t)};p(M,e=>{(n().tokens?.length??0)>0?e(P):e(F,-1)}),f(j),f(a),U(()=>{o=y(a,1,`msg svelte-o5nz21`,null,o,{shadow:i(),"generation-active":$.active&&(i()?as.pendingTurnIdx===r():!as.processingAb&&Ko.pendingIndex===r())}),j.dir=j.dir}),h(1,a,()=>lt,ou),g(t,a)};p(o,e=>{n().role===`system`?e(s):e(l,-1)}),g(t,a)},l=Y(i,`headersVisible`,3,!0);function u(){return typeof window<`u`&&window.matchMedia(`(max-width: 720px), (max-height: 600px), (pointer: coarse) and (max-width: 1120px)`).matches}let d=J(``),_=J(null),v=J(null),b=J(!1),x=J(!1),C=J(null),w=null,E=J(null),D=J(420),O=J(!1),k=J(null),M=J(V((u(),64))),P=J(V(u()?72:80)),I=c(()=>Math.round(Math.max(B(M),Math.min(B(D),B(E)??B(P))))),ee=c(()=>Q.root_id!==null&&Q.active_node_id!==Q.root_id);function te(){if(!B(b)){A(b,!0);return}A(b,!1),Xo()}function z(){let e=B(v);if(!e)return;if(B(O)&&B(E)!==null){e.style.height=`${B(E)}px`,e.style.overflowY=e.scrollHeight>e.clientHeight?`auto`:`hidden`;return}e.style.height=`auto`;let t=Math.min(132,B(D)),n=Math.min(Math.max(e.scrollHeight,B(P)),t);e.style.height=`${n}px`,e.style.overflowY=e.scrollHeight>t?`auto`:`hidden`}function re(){if(!B(_))return;let e=B(_).clientHeight<560||B(_).clientWidth<=620||(window.visualViewport?.height??window.innerHeight)<600;A(M,64,!0),A(P,e?72:80,!0);let t=e?190:300;A(D,Math.max(B(M),Math.min(480,Math.floor(B(_).clientHeight-t))),!0),B(E)!==null&&B(E)>B(D)&&A(E,B(D),!0),queueMicrotask(z)}function ie(e){return Math.max(B(M),Math.min(B(D),e))}function ae(e){A(O,!0),A(E,ie(e),!0),queueMicrotask(z)}function oe(e){if(e.button!==0||!B(v))return;let t=e.currentTarget;re(),A(k,{pointerId:e.pointerId,y:e.clientY,height:B(v).getBoundingClientRect().height},!0),t.setPointerCapture(e.pointerId),e.preventDefault()}function H(e){!B(k)||B(k).pointerId!==e.pointerId||ae(B(k).height+B(k).y-e.clientY)}function se(e){if(!B(k)||B(k).pointerId!==e.pointerId)return;let t=e.currentTarget;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId),A(k,null)}function ce(e){let t=B(v)?.getBoundingClientRect().height??B(E)??B(P),n=null;e.key===`ArrowUp`?n=t+24:e.key===`ArrowDown`?n=t-24:e.key===`Home`?n=B(M):e.key===`End`&&(n=B(D)),n!==null&&(e.preventDefault(),ae(n))}function le(){A(O,!1),A(E,null),queueMicrotask(z)}Ce(()=>{B(d),z()});let ue=c(()=>($o.mode,es())),de=c(()=>Q.loaded?Q.active_node_id??null:null),fe=c(()=>_i.info?.scene_mode??!1),me=/^[a-z0-9._-]+$/,he=J(`user`),ge=J(`assistant`);Ce(()=>{B(fe)||(B(he)!==`user`&&A(he,`user`),B(ge)===`user`&&A(ge,`assistant`))});let ve=c(()=>B(ge)===`none`?null:B(ge)),be=c(()=>_i.info?.default_user_role||`user`),Se=c(()=>_i.info?.default_assistant_role||`assistant`),we=c(()=>xi.user_role.trim()||B(be)),Te=c(()=>xi.assistant_role.trim()||B(Se)),Ee=c(()=>B(he)===`user`?B(we):B(Te)),Oe=c(()=>B(he)===`user`?xi.user_role:xi.assistant_role),ke=c(()=>B(ge)===`user`?xi.user_role:xi.assistant_role),Ae=c(()=>_i.info?.is_base_model===!1&&_i.info?.user_role_supported===!0),je=c(()=>_i.info?.is_base_model===!1&&_i.info?.role_substitution_supported===!0),Me=c(()=>{let e=new Set(Object.keys(ro.roster).filter(e=>e!==`user`&&e!==`assistant`&&e!==B(be)&&e!==B(Se)));return B(we)!==B(be)&&B(we)!==B(Se)&&e.add(B(we)),B(Te)!==B(be)&&B(Te)!==B(Se)&&e.add(B(Te)),[...e].sort((e,t)=>e.localeCompare(t))}),Ne=c(()=>[...new Set([B(be),B(Se),...B(Me)])].map(e=>({value:e,label:e})));function Pe(e){let t=e.trim();return t===``||me.test(t)}let Fe=c(()=>Pe(B(Oe))),Le=c(()=>B(ge)===`none`||Pe(B(ke))),Re=c(()=>B(Fe)&&B(Le)),ze=c(()=>B(ve)===null?`${B(Ee)} only`:`${B(Ee)} → ${B(ve)===`user`?B(we):B(Te)}`);Ce(()=>{B(Re)||A(x,!0)});async function Ve(e){if(B(x)===e)return;let t=B(C),n=t?.getBoundingClientRect().height??0,r=!!t?.contains(document.activeElement);if(w?.cancel(),w=null,t?.style.removeProperty(`overflow`),A(x,e,!0),await xe(),!t)return;r&&t.querySelector(e?`.plan-minimize`:`.turn-plan-summary`)?.focus({preventScroll:!0});let i=$l(220);if(i===0)return;let a=t.getBoundingClientRect().height,o=getComputedStyle(t).getPropertyValue(`--ease-move`).trim()||`ease-in-out`;t.style.overflow=`hidden`;let s=t.animate([{height:`${n}px`},{height:`${a}px`}],{duration:i,easing:o});w=s;let c=()=>{w===s&&(w=null,t.style.removeProperty(`overflow`))};s.onfinish=c,s.oncancel=c}function He(e){return B(e===`user`?Ae:je)}let Ue=c(()=>B(ge)!==`none`&&He(B(ge)));function Ge(e,t){e===`user`?xi.user_role=t:xi.assistant_role=t}function Ke(e){Ge(B(he),e)}function qe(e){B(ge)!==`none`&&Ge(B(ge),e)}function Je(e){if(!e){A(ge,`none`);return}A(ge,B(fe)&&B(he)===`assistant`?`user`:`assistant`,!0)}let Z=c(()=>B(fe)&&B(ve)!==null&&B(ve)!==B(he));function Ye(){if(!B(Z)||B(ve)===null)return;let e=B(he);A(he,B(ve),!0),A(ge,e,!0)}let Xe=c(()=>_i.info?.thinking_input_supported??!1),Ze=c(()=>_i.info?.strips_history_thinking??!1),Qe=J(!1),et=J(``),tt=c(()=>B(d).trim()!==``),nt=c(()=>B(ve)===null),it=c(()=>!Q.loaded||!B(Re)||!B(tt)&&B(ve)===null),at=c(()=>`Write as ${B(Ee)}…`),ot=c(()=>B(nt)?`Add message`:B(tt)?`Send`:`Generate reply`);function st(){let e=B(tt)?B(d):``,t=Kn();if(!e){if(t!==null){Qn(qn.queue[t]?.id??``);return}if(B(ve)===null)return}let n=tr()?`active@drain`:B(de),r=e&&B(et).trim()!==``?B(et):null;r!==null&&(A(et,``),A(Qe,!1)),e&&(Vn(e),A(d,``)),Za(e||null,e?B(he):null,B(ve),{parent_node_id:n,replaceSlot:t,raw:B(ue),authored_thinking:r}),A(Wt,!1),Jt(),queueMicrotask(z)}function ct(e){let t=e.value,n=e.selectionStart??0,r=t.indexOf(` -`);return r===-1||n<=r}function dt(e){let t=e.value,n=e.selectionEnd??t.length,r=t.lastIndexOf(` -`);return r===-1||n>r}function ft(e){A(d,e,!0),queueMicrotask(()=>{let e=B(v);e&&(e.setSelectionRange(e.value.length,e.value.length),z())})}function pt(e){if(e.key===`Enter`){if(e.shiftKey)return;e.preventDefault(),st();return}if(e.key===`Escape`){if($.active){e.preventDefault(),no();return}if(Rn.pulledSlot!==null){e.preventDefault();let t=Gn();t!==null&&(A(d,t,!0),queueMicrotask(z));return}}if(e.key===`ArrowUp`||e.key===`ArrowDown`){let t=B(v);if(!t)return;let n=e.key===`ArrowUp`;if((n?!ct(t):!dt(t))||!n&&Rn.index===null&&Rn.pulledSlot===null)return;let r=Hn(n?-1:1,B(d));if(r===null)return;e.preventDefault(),ft(r)}}let mt=c(()=>[...Hr.active]);function ht(e){pi(e===``?null:e)}function gt(e){mi(e===``?null:e)}function vt(){if(!fi.compareTwo){let e=B(wt)[0]?.value??null;if(e===null)return;mi(e)}hi()}function yt(e){let t=Hr.entries.get(e)?.info,n=t?.intrinsic_dim??0,r=t?.family===`geometry`?t.is_affine:!0,i=e.split(`/`).pop()??e;return r&&n>1?Array.from({length:n},(t,n)=>({value:n===0?e:`${e}[${n}]`,label:`${i}[${n}]`})):[{value:e,label:i}]}let bt=c(()=>Ko.turns.some(e=>[...e.thinkingTokens??[],...e.tokens??[]].some(e=>e.samplerEntropy!=null&&Number.isFinite(e.samplerEntropy)))),xt=c(()=>Ko.turns.some(e=>(e.thinkingTokens?.length??0)>0||(e.tokens?.length??0)>0)),St=c(()=>[{value:dn,label:`Token surprisal`},...B(bt)?[{value:fn,label:`Sampler entropy`}]:[]]),Ct=c(()=>{let e=[{value:``,label:`No color`},...B(St)];for(let t of B(mt))e.push(...yt(t));return e}),wt=c(()=>{let e=B(St).filter(e=>e.value!==fi.target);for(let t of B(mt))for(let n of yt(t))n.value!==fi.target&&e.push(n);return e}),Tt=c(()=>B(xt)&&fi.target!==null&&B(wt).length>0);Ce(()=>{if(!B(Tt)){fi.compareTwo&&gi(!1),fi.compareTarget!==null&&mi(null);return}fi.compareTwo&&!B(wt).some(e=>e.value===fi.compareTarget)&&mi(B(wt)[0]?.value??null)});let Et=[{value:`unsteered`,label:`Original behavior`},{value:`inverted`,label:`Opposite guidance`},{value:`reseed`,label:`New random seed`},{value:`cool`,label:`More focused`},{value:`hot`,label:`More varied`},{value:`custom`,label:`Custom recipe…`}],Dt=We(`generation`),Ot=c(()=>Dt.available&&_i.info!==null&&_i.info.is_base_model!==!0&&!B(ue));Ce(()=>{!B(Ot)&&us.enabled&&fs()});function kt(e){let t=e.nodeId;t&&(tr()?Xn({label:`regen`,text:null,apply:()=>void Do(t,1),awaitsGen:!0,rebuild:null,endsOnUserNode:e.role===`user`}):Do(t,1))}function At(e){ps(e)}let jt=c(()=>us.enabled&&(as.processingAb||Ko.turns.some(e=>e.abPair!==void 0))),Mt=c(()=>Fa.nodeId!==null&&Q.nodes.has(Fa.nodeId)),Nt=c(()=>{if(!B(Mt)||!Fa.nodeId)return[];let e=[],t=Fa.nodeId,n=new Set;for(;t&&!n.has(t);){n.add(t);let r=Q.nodes.get(t);if(!r)break;r.parent_id===null&&r.role===`system`&&!r.text||e.push({role:r.role,text:r.text??``,roleLabel:r.role_label,nodeId:r.id,generated:r.recipe!==null,appliedSteering:r.applied_steering??null,aggregateReadings:r.aggregate_readings??void 0,finishReason:r.finish_reason??void 0}),t=r.parent_id}return e.reverse()}),Pt=c(()=>B(Mt)||B(jt)),Ft=V(new _t);function It(e,t){let n=Ft.get(e);return n===void 0?!(Ko.pendingIndex===e&&(t.thinkingTokens?.length??0)>0):n}function Lt(e){let t=Ft.get(e)??!0;Ft.set(e,!t)}let Rt=J(``),zt=!1,Bt=!1,Vt=0;Ce(()=>{let e=$.active,t=$.finishReason,n=Ko.pendingIndex,r=Ko.turns.length;De(()=>{zt?e&&!Bt?A(Rt,B(ue)?`Updating completion.`:`Generating response.`,!0):!e&&Bt?A(Rt,t===`cancelled`?`Generation stopped.`:t===null?`Generation ended.`:B(ue)?$.tokensSoFar===0&&Ko.turns.at(-1)?.generated===!1?`Edit saved.`:t===`length`?`Token limit reached.`:`Completion finished.`:`Response complete.`,!0):!e&&n===null&&r!==Vt&&A(Rt,B(ue)?`Completion updated.`:`Conversation updated. ${r} ${r===1?`message`:`messages`}.`,!0):zt=!0,Bt=e,Vt=r})});let Ht=J(0);Ce(()=>{zn.rev!==B(Ht)&&(A(Ht,zn.rev,!0),A(d,zn.text,!0),queueMicrotask(z))});let Ut=J(null),Wt=J(!1);function Gt(e){let t=e.currentTarget;A(Wt,!(t.scrollHeight-t.scrollTop-t.clientHeight<8))}function Kt(){let e=B(Ut);e&&(e.scrollTop=e.scrollHeight)}let qt=!1;function Jt(){qt||(qt=!0,queueMicrotask(()=>{qt=!1,B(Wt)||Kt()}))}Ce(()=>{Ko.turns.length;let e=Ko.turns[Ko.turns.length-1];e?.tokens?.length,e?.thinkingTokens?.length,e?.text,De(()=>Jt())}),ne(()=>{z(),Kt(),window.matchMedia(`(pointer: coarse)`).matches||B(v)?.focus(),re();let e=typeof ResizeObserver>`u`?null:new ResizeObserver(re);return B(_)&&e?.observe(B(_)),window.visualViewport?.addEventListener(`resize`,re),()=>{e?.disconnect(),window.visualViewport?.removeEventListener(`resize`,re),w?.cancel()}});function Yt(e){let t=0;for(;t({tok:e,originalIdx:t+n}))}let Xt=J(null),Zt=new _t;function Qt(e,t,n,r=!1){n.stopPropagation();let i=Ko.turns[e],a=(r?i?.thinkingTokens:i?.tokens)?.[t];if(a){if($e.docked){A(Xt,null),rt(`token_drilldown`,{turnIdx:e,tokenIdx:t,isThinking:r});return}A(Xt,{token:a,anchor:n.currentTarget,turnIdx:e,tokenIdx:t,isThinking:r},!0)}}function $t(e,t,n,r=!1){if(e.key===`Enter`||e.key===` `){e.preventDefault(),Qt(t,n,e,r);return}if(![`ArrowLeft`,`ArrowRight`,`Home`,`End`].includes(e.key))return;let i=e.currentTarget,a=[...i.parentElement.querySelectorAll(`.tok`)],o=a.indexOf(i),s=e.key===`Home`?0:e.key===`End`?a.length-1:(o+(e.key===`ArrowRight`?1:-1)+a.length)%a.length;e.preventDefault(),a[s].focus()}function en(e,t){let n=Yt(e.tokens??[])[0];if(n){rt(`token_drilldown`,{turnIdx:t,tokenIdx:n.originalIdx});return}if((e.thinkingTokens?.length??0)>0){rt(`token_drilldown`,{turnIdx:t,tokenIdx:0,isThinking:!0});return}(e.tokens?.length??0)>0&&rt(`token_drilldown`,{turnIdx:t,tokenIdx:0})}function tn(e){return!e.tokens||e.tokens.length===0?(e.text??``).replace(/^\s+/,``):Yt(e.tokens).map(({tok:e})=>e.text).join(``)}var nn=kO(),rn=R(nn),an=e=>{var n=pO(),r=R(n),i=R(r),a=R(i),o=X(R(a),2),u=R(o);{let e=c(()=>fi.target??``),t=c(()=>B(ue)?`Color completion tokens by`:`Color generated words by`);hu(u,{get value(){return B(e)},get options(){return B(Ct)},onchange:ht,get ariaLabel(){return B(t)}})}f(o),f(a);var d=X(a,2);{let e=c(()=>B(ue)?`Colors show recorded readings in both editing and inspection views, and pause for unsaved edits. Open Inspect tokens for exact values. Surprisal and entropy use the sampling distribution; greedy decoding can record zero for both.`:`Color words by token surprisal, sampler entropy, or an attached model reading. Select a word for its exact value.`);tp(d,{label:`About word colors`,get text(){return B(e)}})}f(i);var m=X(i,2),_=e=>{var t=cO();let n;var r=R(t,!0);f(t),U(()=>{n=y(t,1,`compare-color svelte-o5nz21`,null,n,{active:fi.compareTwo}),S(t,`aria-pressed`,fi.compareTwo),G(r,fi.compareTwo?`Use one color`:`Compare colors`)}),K(`click`,t,vt),g(e,t)};p(m,e=>{B(Tt)&&e(_)});var v=X(m,2),b=e=>{var t=lO(),n=X(R(t),2),r=R(n);{let e=c(()=>fi.compareTarget??``),t=c(()=>!fi.compareTwo);hu(r,{get value(){return B(e)},get options(){return B(wt)},onchange:gt,get disabled(){return B(t)},ariaLabel:`Second word color`})}f(n),f(t),g(e,t)};p(v,e=>{fi.compareTwo&&e(b)}),f(r);var x=X(r,2),C=R(x),w=e=>{var n=fO(),r=q(n),i=R(r);tv(R(i),{get checked(){return us.enabled},get onchange(){return ds},label:`Compare replies`}),f(i),tp(X(i,2),{label:`About automatic comparison`,text:`Create a second version after every reply using the comparison settings.`}),f(r);var a=X(r,2),o=e=>{var n=dO(),r=q(n);hu(R(r),{get value(){return us.mode},get options(){return Et},onchange:At,get disabled(){return as.processingAb},ariaLabel:`Automatic comparison style`}),f(r);var i=X(r,2),a=e=>{var n=uO();s(n),U(()=>{t(n,us.custom),n.disabled=as.processingAb}),K(`input`,n,e=>ms(e.currentTarget.value)),g(e,n)};p(i,e=>{us.mode===`custom`&&e(a)}),g(e,n)};p(a,e=>{us.enabled&&e(o)}),g(e,n)};p(C,e=>{B(Ot)&&e(w)}),f(x),f(n),U(()=>n.inert=!l()),h(1,n,()=>ut,lu),h(2,n,()=>ut,uu),g(e,n)};p(rn,e=>{l()&&e(an)});var on=X(rn,2),sn=R(on),cn=R(sn,!0);f(sn);var ln=X(sn,2),un=e=>{VD(e,{})},pn=n=>{var r=DO(),i=q(r);let l;var u=R(i),_=e=>{var t=mO();h(1,t,()=>lt,()=>ou(8)),h(2,t,()=>lt,su),g(e,t)},w=e=>{var t=_O(),n=R(t);m(n,21,()=>Ko.turns,N,(e,t,n)=>{o(e,()=>B(t),()=>n,()=>!1)}),f(n);var r=X(n,2),i=R(r),a=e=>{var t=hO(),n=q(t),r=X(R(n),2),i=R(r,!0);f(r);var a=X(r,2);f(n),m(X(n,2),17,()=>B(Nt),N,(e,t,n)=>{o(e,()=>B(t),()=>n,()=>!0)}),U(e=>G(i,e),[()=>Fa.nodeId?.slice(0,12)]),K(`click`,a,function(...e){La?.apply(this,e)}),g(e,t)},s=e=>{var t=L();m(q(t),17,()=>Ko.turns,N,(e,t,n)=>{var r=L(),i=q(r),a=e=>{o(e,()=>B(t),()=>n,()=>!1)},s=e=>{o(e,()=>B(t).abPair,()=>n,()=>!0)},c=e=>{var r=gO(),i=R(r);qD(R(i),()=>B(t),()=>!1),T(2),f(i);var a=X(i,2),o=R(a,!0);f(a),f(r),U(()=>G(o,as.pendingTurnIdx===n?`Generating comparison…`:`Not compared`)),g(e,r)};p(i,e=>{!B(t).generated||B(t).role===`system`?e(a):B(t).abPair?e(s,1):e(c,-1)}),g(e,r)}),g(e,t)};p(i,e=>{B(Mt)?e(a):e(s,-1)}),f(r),f(t),g(e,t)},E=e=>{var t=L();m(q(t),17,()=>Ko.turns,N,(e,t,n)=>{o(e,()=>B(t),()=>n,()=>!1)}),g(e,t)};p(u,e=>{Ko.turns.length===0?e(_):B(Pt)?e(w,1):e(E,-1)}),f(i),a(i,e=>A(Ut,e),()=>B(Ut));var O=X(i,2);let P;var F=R(O);s(F),T(4),f(O);var z=X(O,2);sD(z,{});var ne=X(z,2);fD(ne,{});var V=X(ne,2),re=R(V),ie=t=>{var n=vO(),r=R(n),i=X(R(r),2);{let e=c(()=>!He(B(he))),t=c(()=>!B(Fe)),n=c(()=>B(he)===`user`?B(be):B(Se)),r=c(()=>B(Fe)?void 0:`role-label-error`);KD(i,{get value(){return B(Oe)},get options(){return B(Ne)},onchange:Ke,get disabled(){return B(e)},get invalid(){return B(t)},get placeholder(){return B(n)},ariaLabel:`You write as`,get ariaDescribedby(){return B(r)}})}f(r);var a=X(r,2),o=X(R(a),2);{let e=c(()=>B(ge)===`none`?``:B(ke)),t=c(()=>!B(Ue)),n=c(()=>!B(Le)),r=c(()=>B(ge)===`user`?B(be):B(Se)),i=c(()=>B(Le)?void 0:`role-label-error`);KD(o,{get value(){return B(e)},get options(){return B(Ne)},onchange:qe,get disabled(){return B(t)},get invalid(){return B(n)},get placeholder(){return B(r)},ariaLabel:`Model writes as`,get ariaDescribedby(){return B(i)}})}f(a);var s=X(a,2),l=R(s);{let t=c(()=>!B(Z));Du(l,{variant:`flat`,size:`sm`,get disabled(){return B(t)},onclick:Ye,ariaLabel:`Swap writer roles`,children:(t,n)=>{T(),g(t,e(`Swap`))},$$slots:{default:!0}})}var u=X(l,2),d=R(u);{let e=c(()=>B(ve)!==null);tv(d,{get checked(){return B(e)},onchange:Je,ariaLabel:`Generate a model reply`})}T(2),f(u);var p=X(u,2);{let t=c(()=>!B(Re));Du(p,{size:`sm`,variant:`flat`,get disabled(){return B(t)},onclick:()=>rt(`cast`),children:(t,n)=>{T(),g(t,e(`Role settings`))},$$slots:{default:!0}})}var m=X(p,2);f(s),f(n),K(`click`,m,()=>Ve(!1)),h(1,n,()=>lt,()=>ou(2)),g(t,n)},ae=e=>{var t=yO(),n=X(R(t),2),r=R(n,!0);f(n),T(2),f(t),U(()=>G(r,B(ze))),K(`click`,t,()=>Ve(!0)),h(1,t,()=>lt,()=>ou(2)),g(e,t)};p(re,e=>{B(x)?e(ie):e(ae,-1)}),f(V),a(V,e=>A(C,e),()=>B(C));var ue=X(V,2),de=e=>{g(e,bO())};p(ue,e=>{B(Re)||e(de)});var fe=X(ue,2),pe=t=>{var n=CO(),r=R(n),i=R(r);{let t=c(()=>B(et).trim()===``?void 0:`var(--pillar-manifold)`);Du(i,{variant:`flat`,size:`sm`,get accent(){return B(t)},onclick:()=>A(Qe,!B(Qe)),title:`Add private reasoning text to the next authored line`,children:(t,n)=>{T();var r=e();U(()=>G(r,B(Qe)?`Hide reasoning`:`Add reasoning`)),g(t,r)},$$slots:{default:!0}})}f(r);var a=X(r,2),o=e=>{var t=SO(),n=R(t);_e(n);var r=X(n,2),i=e=>{g(e,xO())};p(r,e=>{B(Ze)&&e(i)}),f(t),U(()=>n.dir=n.dir),j(n,()=>B(et),e=>A(et,e)),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)};p(a,e=>{B(Qe)&&e(o)}),f(n),g(t,n)};p(fe,e=>{B(Xe)&&e(pe)});var me=X(fe,2),W=R(me);_e(W),a(W,e=>A(v,e),()=>B(v));var xe=X(W,2);let Ce;var we=R(xe);{let e=c(()=>B(nt)?`Enter · add your message only`:`Enter · send and generate a reply`);Du(we,{type:`submit`,variant:`solid`,get disabled(){return B(it)},get title(){return B(e)},children:(e,t)=>{var n=wO(),r=q(n);{let e=c(()=>B(nt)?`add`:B(tt)?`send`:`conversation`);XE(r,{icons:[`add`,`send`,`conversation`],get name(){return B(e)}})}var i=X(r,1,!0);U(()=>G(i,B(ot))),g(e,n)},$$slots:{default:!0}})}var Te=X(we,2);{let e=c(()=>!$.active);Du(Te,{variant:`danger`,get onclick(){return no},get disabled(){return B(e)},title:`Escape · stop the current reply`,children:(e,t)=>{var n=TO();Be(q(n),{name:`stop`}),T(),g(e,n)},$$slots:{default:!0}})}var De=X(Te,2),Ae=e=>{var t=EO();let n;var r=R(t,!0);f(t),U(()=>{n=y(t,1,`clear-conversation svelte-o5nz21`,null,n,{"confirm-clear":B(b)}),S(t,`title`,B(b)?`Clear the current view and start a new path`:`Start a blank conversation; existing branches remain available`),S(t,`aria-label`,B(b)?`Confirm clear conversation`:`Clear conversation`),G(r,B(b)?`Confirm clear`:`Clear conversation`)}),K(`click`,t,te),ye(`blur`,t,()=>A(b,!1)),K(`keydown`,t,e=>{e.key===`Escape`&&A(b,!1)}),g(e,t)};p(De,e=>{B(ee)&&e(Ae)}),f(xe),f(me),U(()=>{l=y(i,1,`log svelte-o5nz21`,null,l,{ab:B(Pt)}),P=y(O,1,`composer-resizer-shell svelte-o5nz21`,null,P,{dragging:B(k)!==null}),S(F,`min`,B(M)),S(F,`max`,B(D)),t(F,B(I)),S(F,`aria-valuetext`,`${B(I)} pixel writing area`),S(W,`placeholder`,B(at)),S(W,`aria-label`,`Compose as ${B(Ee)}`),W.dir=W.dir,Ce=y(xe,1,`input-actions svelte-o5nz21`,null,Ce,{"has-clear":B(ee)})}),ye(`scroll`,i,Gt),K(`pointerdown`,F,oe),K(`pointermove`,F,H),K(`pointerup`,F,se),ye(`pointercancel`,F,se),K(`keydown`,F,ce),K(`dblclick`,F,le),ye(`submit`,me,e=>{e.preventDefault(),st()}),K(`keydown`,W,pt),j(W,()=>B(d),e=>A(d,e)),g(n,r)};p(ln,e=>{B(ue)?e(un):e(pn,-1)}),f(on),a(on,e=>A(_,e),()=>B(_));var mn=X(on,2),hn=e=>{var t=OO(),n=X(R(t),2),r=R(n,!0);f(n),f(t),U(e=>{S(t,`title`,_i.info.model_id),G(r,e)},[()=>_i.info.model_id.split(`/`).at(-1)]),g(e,t)};p(mn,e=>{_i.info?.model_id&&e(hn)});var gn=X(mn,2),_n=e=>{let t=c(()=>B(Xt));var n=L();F(q(n),()=>B(t).anchor,e=>{{let n=c(()=>Ko.turns[B(t).turnIdx]?.generated?`Model token`:`User text · recorded`);SD(e,{get token(){return B(t).token},get anchor(){return B(t).anchor},get source(){return B(n)},onclose:()=>A(Xt,null),ondetails:()=>rt(`token_drilldown`,{turnIdx:B(t).turnIdx,tokenIdx:B(t).tokenIdx,isThinking:B(t).isThinking,initialTab:`logits`})})}}),g(e,n)};p(gn,e=>{B(Xt)&&e(_n)}),f(nn),U(()=>{S(on,`aria-label`,B(ue)?`Text completion`:`Chat`),G(cn,B(Rt))}),g(r,nn),W()}H([`click`,`keydown`,`input`,`pointerdown`,`pointermove`,`pointerup`,`dblclick`]);function jO(e){return{text:e.text,...e.tokenId==null?{}:{token_id:e.tokenId},...e.rawIndex==null?{}:{raw_index:e.rawIndex},logprob:e.logprob??null,perplexity:e.perplexity??null,...e.samplerEntropy==null?{}:{sampler_entropy:e.samplerEntropy},...e.topAlts?{top_alts:e.topAlts}:{},...e.measurements?{measurements:e.measurements}:{}}}function MO(e,t){if(t.nodeId!==e.id||e.finish_reason!==null)return e;let n=t.tokens?.map(jO)??e.tokens,r=t.thinkingTokens?.map(jO)??e.thinking_tokens,i=[...e.raw_token_ids??[]],a=[...n??[],...r??[]].filter(e=>e.raw_index!=null&&e.token_id!=null).sort((e,t)=>e.raw_index-t.raw_index),o=!0;for(let e of a){if(e.raw_index>i.length){o=!1;break}i[e.raw_index]=e.token_id}return{...e,text:t.text??e.text,tokens:n,thinking_tokens:r,thinking_text:r?.map(e=>e.text).join(``)??e.thinking_text,raw_token_ids:o?i:null}}function NO(e){return Object.prototype.toString.call(e)===`[object Date]`}function PO(e,t,n,r){if(typeof n==`number`||NO(n)){let i=r-n,a=(n-t)/(e.dt||1/60),o=(a+(e.opts.stiffness*i-e.opts.damping*a)*e.inv_mass)*e.dt;return Math.abs(o)PO(e,t[a],n[a],r[a]));else if(typeof n==`object`){let i={};for(let a in n)i[a]=PO(e,t[a],n[a],r[a]);return i}else throw Error(`Cannot spring ${typeof n} values`)}var FO=class e{#e=J(.15);#t=J(.8);#n=J(.01);#r;#i;#a=void 0;#o=0;#s=1;#c=0;#l=null;#u=null;constructor(e,t={}){this.#r=J(e),this.#i=J(e),typeof t.stiffness==`number`&&(this.#e.v=IO(t.stiffness,0,1)),typeof t.damping==`number`&&(this.#t.v=IO(t.damping,0,1)),typeof t.precision==`number`&&(this.#n.v=t.precision)}static of(t,n){let r=new e(t(),n);return oe(()=>{r.set(t())}),r}#d(e){if(A(this.#i,e),this.#r.v??=e,this.#a??=this.#r.v,!this.#l){this.#o=D.now();var t=1e3/(this.#c*60);this.#l??=_(e=>{this.#s=Math.min(this.#s+t,1);let n=Math.min(e-this.#o,1e3/30),r={inv_mass:this.#s,opts:{stiffness:this.#e.v,damping:this.#t.v,precision:this.#n.v},settled:!0,dt:n*60/1e3};var i=PO(r,this.#a,this.#r.v,this.#i.v);return this.#a=this.#r.v,this.#o=e,A(this.#r,i),r.settled&&(this.#l=null),!r.settled})}return this.#l.promise}set(e,t){if(this.#u?.reject(Error(`Aborted`)),t?.instant||this.#r.v===void 0)return this.#l?.abort(),this.#l=null,A(this.#r,A(this.#i,e)),this.#a=e,Promise.resolve();t?.preserveMomentum&&(this.#s=0,this.#c=t.preserveMomentum);var n=this.#u=v();return n.promise.catch(Ie),this.#d(e).then(()=>{n===this.#u&&n.resolve(void 0)}),n.promise}get current(){return B(this.#r)}get damping(){return B(this.#t)}set damping(e){A(this.#t,IO(e,0,1))}get precision(){return B(this.#n)}set precision(e){A(this.#n,e)}get stiffness(){return B(this.#e)}set stiffness(e){A(this.#e,IO(e,0,1))}get target(){return B(this.#i)}set target(e){this.set(e)}};function IO(e,t,n){return Math.max(t,Math.min(n,e))}var LO=new xt(`(prefers-reduced-motion: reduce)`),RO=/[.!?…](?:["'”’)\]}]+)?$/u;function zO(e){let t=[],n=0;for(let r=0;re.text).join(``)}),n=r+1)}return ne.text).join(``)}),t}var BO=I(``),VO=I(`Writing…`),HO=I(` `),UO=I(`current`),WO=I(``),GO=I(` `,1),KO=I(``),qO=I(`
                                  `),JO=I(`
                                  `),YO=I(` `),XO=I(` `),ZO=I(` `),QO=I(` `),$O=I(` `),ek=I(``),tk=I(` `),nk=I(``),rk=I(` `),ik=I(`
                                  `);function ak(e,t){n(t,!0);let r=Y(t,`tokenStart`,3,0),i=Y(t,`sharedCount`,3,0),a=Y(t,`sharedUsesActivePath`,3,!1),o=Y(t,`sentenceBranchAvailable`,3,!1),s=Y(t,`collapsed`,3,!1),l=Y(t,`ring`,3,null),u=Y(t,`weightBadge`,3,null),d=Y(t,`steerLabel`,3,null),h=Y(t,`forkLabel`,3,null);function _(e){let n=0,r=0,i=()=>{if(n=0,!e.clientWidth)return;let i=getComputedStyle(e),a=[...e.children].filter(e=>getComputedStyle(e).display!==`none`),o=parseFloat(i.paddingTop)+parseFloat(i.paddingBottom)+Math.max(0,a.length-1)*parseFloat(i.rowGap);for(let e of a)if(e.classList.contains(`token-field`)){let t=getComputedStyle(e),n=[...e.children];o+=parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)+Math.max(0,n.length-1)*parseFloat(t.rowGap)+n.reduce((e,t)=>e+t.offsetHeight,0)}else o+=e.offsetHeight;o=Math.ceil(o),o!==r&&(r=o,t.onmeasure?.(o))},a=()=>{n||=requestAnimationFrame(i)},o=new ResizeObserver(a),s=()=>{o.disconnect(),o.observe(e),e.querySelectorAll(`:scope > *, .sentence-node`).forEach(e=>o.observe(e)),a()},c=new MutationObserver(s);return c.observe(e,{childList:!0,subtree:!0,characterData:!0}),s(),{destroy(){o.disconnect(),c.disconnect(),cancelAnimationFrame(n)}}}let v=new FO({x:0,y:0},{stiffness:.2,damping:.85,precision:.01});function b(e){if(e.pointerType!==`mouse`||e.buttons||LO.current||!window.matchMedia(`(hover: hover) and (pointer: fine)`).matches)return;let t=e.currentTarget.getBoundingClientRect();v.target={x:Math.max(-1,Math.min(1,((e.clientX-t.left)/t.width-.5)*2)),y:Math.max(-1,Math.min(1,((e.clientY-t.top)/t.height-.5)*2))}}function x(){v.target={x:0,y:0}}Ce(()=>{LO.current&&v.set({x:0,y:0},{instant:!0})}),Pe(()=>{v.set({x:0,y:0},{instant:!0})});function C(e){return Jo(e.role,e.role_label)}let T=c(()=>{let e=(t.node.text??``).replace(/\s+/g,` `).trim();return e?e.length>600?e.slice(0,600)+`…`:e:t.node.role===`system`&&!t.node.parent_id?`root`:`(empty)`}),E=c(()=>t.node.role_label?.trim()||t.node.role),D=c(()=>t.node.tokens?.slice(r(),t.tokenEnd)??[]),O=c(()=>zO(B(D)).map(e=>({...e,start:e.start+r(),end:e.end+r()})));function k(e){return e.replace(/\n/g,`↵`).replace(/\t/g,`⇥`).trim()||`whitespace`}function A(e,t,n){if(typeof n!=`number`||!Number.isFinite(n))return`Token ${e+1}: ${k(t)}`;let r=Math.min(1,Math.max(0,Math.exp(n)));return`Token ${e+1}: ${k(t)} · ${(r*100).toFixed(1)}%`}let j=c(()=>l()===null?null:l()>=0?`var(--accent-green)`:`var(--accent-red)`);var M=ik();let N,P;var F=R(M),I=R(F),L=R(I),ee=R(L,!0);f(L);var te=X(L,2),z=R(te,!0);f(te);var ne=X(te,2),V=e=>{var t=BO();U(()=>pe(t,`border-color: ${B(j)??``}`)),g(e,t)};p(ne,e=>{B(j)&&e(V)}),f(I);var re=X(I,2),ie=R(re),ae=e=>{g(e,VO())};p(ie,e=>{t.streaming&&e(ae)});var oe=X(ie,2),H=e=>{var t=HO(),n=R(t);f(t),U(()=>G(n,`${i()??``} paths`)),g(e,t)};p(oe,e=>{i()&&e(H)});var se=X(oe,2),ce=e=>{g(e,UO())};p(se,e=>{t.current&&e(ce)});var le=X(se,2),ue=e=>{var n=GO(),r=q(n),i=e=>{var t=WO();Be(R(t),{name:`star`}),f(t),g(e,t)};p(r,e=>{t.node.starred&&e(i)});var a=X(r,2);U(()=>S(a,`aria-label`,`Actions for ${B(E)}: ${B(T)}`)),K(`click`,a,e=>{e.stopPropagation(),t.onactions?.(e)}),g(e,n)};p(le,e=>{i()||e(ue)}),f(re),f(F);var de=X(F,2),fe=e=>{var n=JO();m(n,23,()=>B(O),e=>`${e.start}:${e.end}`,(e,n,r)=>{let a=c(()=>t.node.tokens[B(n).end]),s=c(()=>o()&&B(a)?.raw_index!=null&&B(a)?.token_id!=null);var l=qO(),u=R(l);m(u,23,()=>t.node.tokens.slice(B(n).start,B(n).end+1),(e,t)=>`${e.raw_index??B(n).start+t}:${e.token_id??e.text}`,(e,r,a)=>{let o=c(()=>B(n).start+B(a));var s=KO(),l=R(s,!0);f(s),U((e,n,i)=>{pe(s,e),S(s,`data-loom-token-node`,t.node.id),S(s,`data-token-index`,B(o)),S(s,`data-raw-index`,B(r).raw_index??void 0),S(s,`title`,n),S(s,`aria-label`,i),G(l,B(r).text||`∅`)},[()=>i()?``:Zc(ao(B(r))),()=>`${A(B(o),B(r).text,i()?null:B(r).logprob)} · Open branch-point tools`,()=>`Open token ${B(o)+1}: ${k(B(r).text)}`]),K(`click`,s,e=>{e.stopPropagation(),t.onselecttoken?.(B(o),e)}),g(e,s)}),f(u);var d=X(u,2);f(l),U(e=>{S(l,`data-loom-sentence`,B(r)),S(l,`data-sentence-start`,B(n).start),S(l,`data-sentence-end`,B(n).end),d.disabled=!B(s),S(d,`title`,B(s)?`Keep this sentence and generate a different continuation`:`This saved reply does not have an exact replay boundary`),S(d,`aria-label`,e)},[()=>`Branch after sentence ${B(r)+1}: ${B(n).text.trim()}`]),K(`click`,d,e=>{e.stopPropagation(),B(s)&&t.onbranchsentence?.(B(n).end,e)}),g(e,l)}),f(n),U(()=>S(n,`aria-label`,`${B(O).length} sentence branch points`)),g(e,n)},me=e=>{var n=YO(),i=R(n,!0);f(n),U(()=>G(i,t.streaming?`Preparing continuation…`:r()>0?`End of reply`:B(T))),g(e,n)};p(de,e=>{t.node.tokens&&B(D).length>0?e(fe):e(me,-1)});var he=X(de,2),ge=e=>{var t=XO(),n=R(t);f(t),U(()=>G(n,`Token tools use ${a()?`the current`:`the first listed`} path’s readings.`)),g(e,t)};p(he,e=>{i()&&e(ge)});var _e=X(he,2),ve=e=>{var n=tk(),r=R(n),i=e=>{var t=ZO(),n=R(t,!0);f(t),U(()=>G(n,h())),g(e,t)};p(r,e=>{h()&&e(i)});var a=X(r,2),o=e=>{var t=QO(),n=R(t,!0);f(t),U(()=>G(n,d())),g(e,t)};p(a,e=>{d()&&e(o)});var s=X(a,2),c=e=>{var t=$O(),n=X(R(t));f(t),U(e=>G(n,` ${e??``}`),[()=>u().toFixed(2)]),g(e,t)};p(s,e=>{u()!=null&&e(c)});var l=X(s,2),m=e=>{var n=ek();U(()=>S(n,`title`,t.node.notes)),g(e,n)};p(l,e=>{t.node.notes&&e(m)}),f(n),g(e,n)};p(_e,e=>{!i()&&(h()||d()||u()!=null||t.node.notes)&&e(ve)});var be=X(_e,2),xe=e=>{var n=rk(),r=R(n),i=X(r,2),a=X(i,2),o=e=>{var n=nk(),r=R(n,!0);f(n),U(()=>{S(n,`title`,s()?`Show paths after this point`:`Hide paths after this point`),S(n,`aria-label`,s()?`Show child paths`:`Hide child paths`),S(n,`aria-pressed`,s()),G(r,s()?`Show`:`Hide`)}),K(`click`,n,e=>{e.stopPropagation(),t.ontogglechildren?.(e)}),g(e,n)};p(a,e=>{t.hasChildren&&e(o)}),f(n),U(()=>{S(r,`aria-label`,`Generate another path from ${B(E)}`),S(i,`aria-label`,`Write an alternative to ${B(E)}`)}),K(`click`,r,e=>{e.stopPropagation(),t.ongrow?.(e)}),K(`click`,i,e=>{e.stopPropagation(),t.onbranch?.(e)}),g(e,n)};p(be,e=>{i()||e(xe)}),f(M),w(M,e=>_?.(e)),U(e=>{N=y(M,1,`node svelte-179j6vw`,null,N,{shared:i()>0,active:t.onActivePath,focused:t.focused,dead:t.dead,streaming:t.streaming,"generation-active":t.streaming,starred:!i()&&t.node.starred,user:t.node.role===`user`,assistant:t.node.role===`assistant`,system:t.node.role===`system`}),S(M,`aria-label`,i()?`Shared prefix across ${i()} replies`:void 0),S(M,`aria-level`,t.level),S(M,`aria-expanded`,!i()&&t.hasChildren?!s():void 0),S(M,`aria-current`,t.current?`true`:void 0),S(M,`aria-selected`,i()?void 0:t.selected),S(M,`tabindex`,t.focused?0:-1),S(M,`data-node-id`,t.displayId??t.node.id),S(M,`data-cursor`,t.oncontextmenu?`context-menu`:void 0),P=pe(M,``,P,{"--glow-x":`${v.current.x*14}px`,"--glow-y":`${v.current.y*3}px`,"--glow-angle":`${v.current.x*4}deg`}),G(ee,e),G(z,i()?`shared prefix`:B(E))},[()=>C(t.node)]),ye(`pointerenter`,M,b),K(`pointermove`,M,b),ye(`pointerleave`,M,x),ye(`pointercancel`,M,x),K(`pointerdown`,M,x),K(`click`,M,function(...e){t.onclick?.apply(this,e)}),ye(`focus`,M,function(...e){t.onfocus?.apply(this,e)}),K(`keydown`,M,function(...e){t.onkeydown?.apply(this,e)}),K(`contextmenu`,M,function(...e){t.oncontextmenu?.apply(this,e)}),g(e,M),W()}H([`pointermove`,`pointerdown`,`click`,`keydown`,`contextmenu`]);function ok(e,t){let n=new Set(e.map(e=>e.id)),r=new Map,i=new Map;for(let t of e){let e=t.parent_id&&n.has(t.parent_id)?t.parent_id:null,a=r.get(e)??[];if(a.push(t),r.set(e,a),t.role!==`assistant`||!t.recipe||!t.raw_token_ids?.length||!t.tokens?.length)continue;let o=-1,s=[];for(let e of t.tokens){let n=e.raw_index;if(n==null||!Number.isInteger(n)||n<=o||e.token_id==null||t.raw_token_ids[n]!==e.token_id)break;s.push(JSON.stringify([t.role_label,e.text,t.raw_token_ids.slice(o+1,n+1)])),o=n}s.length===t.tokens.length&&i.set(t.id,s)}let a=[],o=[{nodes:r.get(null)??[],parentId:null,depth:0,start:0}];for(;o.length;){let e=o.pop(),n=new Map;for(let t of e.nodes){let r=JSON.stringify([t.parent_id,i.get(t.id)?.[e.start]??`terminal:${t.id}`]),a=n.get(r)??[];a.push(t),n.set(r,a)}let s=[];for(let o of n.values()){let n=o.find(e=>t.has(e.id))??o[0];if(o.length>1){let t=e.start+1,r=i.get(n.id);for(;ti.get(e.id)?.[t]===r[t]);)t+=1;let c=`shared:${JSON.stringify([o[0].id,e.start])}`;a.push({id:c,parentId:e.parentId,depth:e.depth,node:n,memberIds:o.map(e=>e.id),start:e.start,end:t,shared:!0}),s.push({nodes:o,parentId:c,depth:e.depth+1,start:t})}else{a.push({id:n.id,parentId:e.parentId,depth:e.depth,node:n,memberIds:[n.id],start:e.start,end:n.tokens?.length??0,shared:!1});let t=r.get(n.id);t?.length&&s.push({nodes:t,parentId:n.id,depth:e.depth+1,start:0})}}o.push(...s.reverse())}return a}var sk=I(`

                                  Type a prompt to get started.

                                  `),ck=I(`branch point`),lk=I(``),uk=I(`
                                  `),dk=I(`
                                  `),fk=I(`
                                  `),pk=I(``),mk=I(`
                                  `),hk=I(` `,1),gk=I(``),_k=I(`

                                  No continuations at this point yet. Generate some to explore.

                                  `),vk=I(`Writing…`),yk=I(`chosen`),bk=I(`
                                  `),xk=I(`

                                  Current text

                                  Continuations

                                  `);function Sk(e,t){n(t,!0);let r=J(null),i=J(3),o=J(``),s=J(null),l=new gt,u=J(!1),d=J(``),h,_=c(()=>B(u)||$.active),v=c(()=>B(r)?Q.nodes.get(B(r)):void 0),b=c(()=>(B(r)?Q.children_of.get(B(r))??[]:[]).map(e=>Q.nodes.get(e)).filter(e=>!!e)),x=c(()=>Q.activePath.map(e=>Q.nodes.get(e)).filter(e=>!!e&&!(e.parent_id===null&&!e.text))),C=c(()=>B(x).length===0),T=c(()=>B(b).find(e=>Q.activePath.includes(e.id))),E=c(()=>B(v)?.parent_id?Q.nodes.get(B(v).parent_id):void 0);Ce(()=>{if(!t.active||B(r)&&Q.nodes.has(B(r)))return;let e=De(()=>Q.nodes.get(Q.active_node_id??``));A(r,e?.recipe&&e.parent_id?e.parent_id:e?.id??Q.root_id,!0)});function D(e){return e.role_label||e.role}async function O(e){A(r,e.id,!0),A(d,``),await xe(),h?.focus({preventScroll:!0}),h?.scrollIntoView({block:`nearest`})}async function k(e){if(!B(_)){A(u,!0);try{await bo(e.id)}finally{A(u,!1)}}}async function M(e){if(e?.preventDefault(),!(B(_)||!B(r))){A(u,!0),A(d,``);try{if(B(C)){if(!B(o).trim()){A(d,`Enter some starting text before generating alternatives.`);return}A(s,B(o),!0),await Za(B(o),`user`,`assistant`,{parent_node_id:B(r),n:B(i),raw:es()})}else{let e=B(b).find(e=>e.recipe!==null)?.role;await $a({parent_node_id:B(r),n:B(i),raw:es(),append_same_role:!1,generate_seat:e===`user`?`user`:`assistant`})}}catch(e){A(s,null),A(d,je(e,`Could not generate alternatives. Please try again.`),!0)}finally{A(u,!1)}}}function P(e){let t=(e.tokens?.length??0)-1,n=e.tokens?.[t];return e.recipe&&n?.raw_index!=null&&n.token_id!=null?t:-1}async function F(e){let t=e.tokens?.[P(e)];if(!(B(_)||t?.raw_index==null||t.token_id==null)){A(u,!0),A(d,``);try{await eo(e.id,t.raw_index,t.token_id,!0)}catch(e){A(d,je(e,`Could not continue this text. Please try again.`),!0)}finally{A(u,!1)}}}Ce(()=>{if(B(s)===null)return;let e=B(b).find(e=>e.role===`user`&&e.text===B(s));e&&(A(r,e.id,!0),A(o,``),A(s,null))});var I=xk();let L;var ee=R(I),te=R(ee),z=X(R(te),2),ne=R(z);f(z),f(te);var V=X(te,2),re=e=>{g(e,sk())},ie=e=>{var n=fk();m(n,23,()=>B(x),e=>e.id,(e,n,i)=>{var a=dk();let o;var s=R(a),c=R(s),u=R(c,!0);f(c);var d=X(c,2),h=e=>{g(e,ck())};p(d,e=>{B(r)===B(n).id&&e(h)});var v=X(d,2);f(s);var b=X(s,2),x=R(b,!0);f(b);var C=X(b,2),w=e=>{var r=()=>l.has(B(n).id),i=e=>{e?l.add(B(n).id):l.delete(B(n).id)};ip(e,{summary:`Token branch points`,flush:!0,get expanded(){return r()},set expanded(e){i(e)},children:(e,r)=>{var i=uk();m(i,21,()=>B(n).tokens,N,(e,r,i)=>{var a=lk(),o=R(a,!0);f(a),U(e=>{a.disabled=B(_),S(a,`aria-label`,e),G(o,B(r).text||`∅`)},[()=>`Inspect token ${i+1}: ${B(r).text.trim()||`whitespace`}`]),K(`click`,a,()=>t.oninspect(B(n),i)),g(e,a)}),f(i),g(e,i)},$$slots:{default:!0}})};p(C,e=>{B(n).tokens?.length&&e(w)}),f(a),U(e=>{o=y(a,1,`passage svelte-1lf2ogq`,null,o,{"branch-point":B(r)===B(n).id}),S(a,`data-weave-passage`,B(n).id),G(u,e),S(v,`aria-label`,`Explore here after turn ${B(i)+1}`),S(v,`aria-pressed`,B(r)===B(n).id),G(x,B(n).text),b.dir=b.dir},[()=>D(B(n))]),K(`click`,v,()=>void O(B(n))),g(e,a)}),f(n),g(e,n)};p(V,e=>{B(C)?e(re):e(ie,-1)}),f(ee);var ae=X(ee,2),oe=R(ae),H=R(oe);a(H,e=>h=e,()=>h);var se=X(H,2),ce=e=>{var t=pk();K(`click`,t,()=>void O(B(E))),g(e,t)};p(se,e=>{B(E)&&e(ce)}),f(oe);var le=X(oe,2),ue=e=>{var t=mk(),n=R(t),r=R(n);f(n);var i=X(n,2),a=R(i,!0);f(i),f(t),w(t,e=>Bb?.(e)),U((e,t)=>{G(r,`After ${e??``} · ${t??``}${B(v).text.length>70?`…`:``}`),G(a,B(v).text)},[()=>D(B(v)),()=>B(v).text.slice(0,70)||`Start of conversation`]),g(e,t)};p(le,e=>{!B(C)&&B(v)&&e(ue)});var de=X(le,2),fe=R(de),pe=e=>{var t=hk(),n=X(q(t),2);_e(n),U(()=>{n.disabled=B(_),n.dir=n.dir}),K(`keydown`,n,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),e.currentTarget.form?.requestSubmit())}),j(n,()=>B(o),e=>A(o,e)),g(e,t)};p(fe,e=>{B(C)&&e(pe)});var me=X(fe,2),he=R(me),ge=X(R(he));{let e=c(()=>[1,2,3,4,6,8].map(e=>({value:e,label:String(e)})));hu(ge,{get disabled(){return B(_)},ariaLabel:`Alternatives`,get options(){return B(e)},get value(){return B(i)},set value(e){A(i,e,!0)}})}f(he);var ve=X(he,2),be=R(ve);f(ve);var Se=X(ve,2);f(me),f(de);var we=X(de,2),Te=R(we,!0);f(we);var Ee=X(we,2),Oe=e=>{var t=gk(),n=R(t,!0);f(t),U(()=>G(n,B(d))),g(e,t)};p(Ee,e=>{B(d)&&e(Oe)});var ke=X(Ee,2),Ae=e=>{g(e,_k())};p(ke,e=>{!B(C)&&B(b).length===0&&e(Ae)});var Me=X(ke,2);m(Me,23,()=>B(b),e=>e.id,(e,n,r)=>{var i=bk();let a;var o=R(i),s=R(o),c=R(s);f(s);var l=X(s,2),u=e=>{g(e,vk())};p(l,e=>{$.active&&Q.pendingNodeId===B(n).id&&e(u)});var d=X(l,2),m=e=>{g(e,yk())};p(d,e=>{B(T)?.id===B(n).id&&e(m)});var h=X(d,2),v=R(h,!0);f(h),f(o);var b=X(o,2),x=R(b,!0);f(b);var C=X(b,2),w=R(C),E=R(w,!0);f(w);var A=X(w,2),j=X(A,2),M=X(j,2);f(C),f(i),U((e,t,o)=>{a=y(i,1,`choice svelte-1lf2ogq`,null,a,{chosen:B(T)?.id===B(n).id,"generation-active":$.active&&Q.pendingNodeId===B(n).id}),S(i,`data-weave-choice`,B(n).id),G(c,`Option ${B(r)+1} · ${e??``}`),S(h,`aria-label`,`${B(n).starred?`Starred`:`Star`} option ${B(r)+1}`),S(h,`aria-pressed`,B(n).starred),G(v,B(n).starred?`Starred`:`Star`),G(x,B(n).text||($.active?`Generating…`:`Empty turn`)),b.dir=b.dir,w.disabled=B(_)||B(T)?.id===B(n).id,G(E,B(T)?.id===B(n).id?`Chosen`:`Choose`),A.disabled=B(_),j.disabled=t,S(j,`title`,o),M.disabled=B(_)||!B(n).parent_id},[()=>D(B(n)),()=>B(_)||P(B(n))<0,()=>P(B(n))<0?`This turn has no saved token boundary to continue from`:`Keep every existing token and sample more text with this turn’s saved settings; the original stays intact`]),K(`click`,h,()=>void To(B(n).id,!B(n).starred)),K(`click`,w,()=>void k(B(n))),K(`click`,A,async()=>{await k(B(n)),Q.active_node_id===B(n).id&&await O(B(n))}),K(`click`,j,()=>void F(B(n))),K(`click`,M,e=>t.onwrite(B(n),e.currentTarget)),g(e,i)}),f(Me),f(ae),f(I),U(()=>{L=y(I,1,`weave svelte-1lf2ogq`,null,L,{empty:B(C)}),G(ne,`${B(x).length??``} ${B(x).length===1?`turn`:`turns`}`),ve.disabled=B(_)||!Q.loaded,G(be,`Generate ${B(i)??``}`),Se.disabled=!$.active,G(Te,$.active?`Generating alternatives…`:`${B(b).length} available${B(T)?` · one chosen`:``}`)}),ye(`submit`,de,M),K(`click`,Se,function(...e){no?.apply(this,e)}),g(e,I),W()}H([`click`,`keydown`]);var Ck=28,wk=44;function Tk(e,t=0){let n=e.length+t*6;return n>900?680:n>450?552:n>180?414:276}function Ek(e){if(e.length===0)return{nodes:[],edges:[],width:0,height:0};let t=new Map(e.map(e=>[e.id,e])),n=new Map,r=[];for(let i of e)if(i.parentId&&t.has(i.parentId)){let e=n.get(i.parentId)??[];e.push(i.id),n.set(i.parentId,e)}else r.push(i.id);let i=e=>{let n=t.get(e)?.height;return typeof n==`number`&&Number.isFinite(n)&&n>0?n:168},a=Ck,o=new Map,s=new Set;function c(e){let t=[{id:e,expanded:!1}];for(;t.length>0;){let{id:e,expanded:r}=t.pop(),c=n.get(e)??[];if(r)o.set(e,(o.get(c[0])+o.get(c.at(-1)))/2),s.delete(e);else if(!o.has(e)){if(c.length===0||s.has(e)){let t=i(e);o.set(e,a+t/2),a+=t+wk;continue}s.add(e),t.push({id:e,expanded:!0});for(let e=c.length-1;e>=0;--e)t.push({id:c[e],expanded:!1})}}}for(let e of r)c(e);for(let t of e)c(t.id);let l=e.reduce((e,t)=>Math.min(e,t.depth),1/0),u=new Map(e.map(e=>[e.id,typeof e.width==`number`&&Number.isFinite(e.width)&&e.width>0?e.width:276])),d=new Map;for(let t of e)d.set(t.depth,Math.max(d.get(t.depth)??0,u.get(t.id)));let f=new Map,p=Ck;for(let e of[...d.keys()].sort((e,t)=>e-t))f.set(e,p),p+=d.get(e)+112;let m=e.map(e=>{let t=i(e.id);return{...e,height:t,width:u.get(e.id),depth:e.depth-l,x:f.get(e.depth),y:o.get(e.id)-t/2}}),h=m.reduce((e,t)=>Math.min(e,t.y),1/0),g=Math.max(0,Ck-h),_=g===0?m:m.map(e=>({...e,y:e.y+g})),v=new Map(_.map(e=>[e.id,e])),y=[];for(let e of _){if(!e.parentId)continue;let t=v.get(e.parentId);if(!t)continue;let n=t.x+t.width,r=t.y+t.height/2,i=e.x,a=e.y+e.height/2,o=n+(i-n)*.5;y.push({parentId:t.id,childId:e.id,path:`M ${n} ${r} C ${o} ${r}, ${o} ${a}, ${i} ${a}`})}let b=_.reduce((e,t)=>Math.max(e,t.x+t.width),0),x=_.reduce((e,t)=>Math.max(e,t.y+t.height),0);return{nodes:_,edges:y,width:b+Ck,height:x+Ck}}function Dk(e){let t=new Map;for(let n of e.edges)t.set(n.parentId,(t.get(n.parentId)??0)+1);return e.nodes.filter(e=>(t.get(e.id)??0)>1).map(e=>({id:e.id,x:e.x+e.width+112*.52,y:e.y+e.height/2}))}var Ok=.05,kk=1.4;function Ak(e){return Math.min(kk,Math.max(Ok,e))}function jk(e,t,n=48){if(e.width<=0||e.height<=0||t.width<=0||t.height<=0)return{x:0,y:0,zoom:1};let r=Math.max(1,e.width-n*2),i=Math.max(1,e.height-n*2),a=Ak(Math.min(1,r/t.width,i/t.height)),o=t.width*a,s=t.height*a;return{x:o<=r?(e.width-o)/2:n,y:s<=i?(e.height-s)/2:n,zoom:a}}function Mk(e,t,n){let r=Ak(n);return{x:e.width/2-(t.x+t.width/2)*r,y:e.height/2-(t.y+t.height/2)*r,zoom:r}}function Nk(e,t,n){return{x:e.x+(n.width-t.width)/2,y:e.y+(n.height-t.height)/2,zoom:e.zoom}}function Pk(e,t,n){let r=Ak(t),i=(n.x-e.x)/e.zoom,a=(n.y-e.y)/e.zoom;return{x:n.x-i*r,y:n.y-a*r,zoom:r}}var Fk=I(`
                                  Conversation loom Explore, branch, and return to any point.
                                  `),Ik=I(` `,1),Lk=I(``),Rk=I(`
                                  `),zk=I(`

                                  `,1),Bk=I(`

                                  Combine filters with commas. A branch must match every filter.

                                  • text:<words> searches message text
                                  • starred shows saved branches
                                  • <measurement> > <number> filters by a reading
                                  • agg:, any:, or last: chooses where to measure
                                  • sort:surprise or sort:confidence changes reply order

                                  Examples

                                  • agg:angry.calm > 0.4
                                  • starred, text:fox
                                  • sort:surprise, agg:honest < 0
                                  `),Vk=I(`
                                  `),Hk=I(`
                                  `),Uk=I(`

                                  tree unavailable

                                  `),Wk=I(`

                                  No branches yet

                                  Send a message in Conversation to create the first path.

                                  `),Gk=I(` `,1),Kk=ee(``,1),qk=ee(``,1),Jk=I(`
                                  `),Yk=I(`
                                  Conversation map current path
                                  %

                                  Drag to move · pinch to zoom

                                  `,1),Xk=I(``),Zk=I(` `),Qk=I(`current`),$k=I(``),eA=I(`
                                  `),tA=I(``),nA=I(``),rA=I(`
                                  `),iA=I(`

                                  Current path

                                  Each generated sentence is a branch point. Choose one to keep it and explore a different continuation.

                                  `),aA=I(``),oA=I(`
                                  `),sA=I(`
                                  No alternatives here yet

                                  Generate another reply to make this point branch.

                                  `),cA=I(`current`),lA=I(`saved`),uA=I(`
                                  `),dA=I(`
                                  `),fA=I(`

                                  Next options

                                  `),pA=I(`

                                  `),mA=I(`

                                  `),hA=I(`
                                  `),gA=I(`
                                  `),_A=I(`

                                  Starred points

                                  Keep useful branches close without changing the current conversation.

                                  `),vA=I(``),yA=I(` `,1),bA=I(`
                                  `),xA=I(`

                                  Uses the current model settings.

                                  `,1),SA=I(`

                                  Remove this turn and every continuation below it?

                                  Earlier turns and sibling branches stay. This also updates the saved chat and cannot be undone. Download a copy first if you want a backup.

                                  `,1),CA=I(`

                                  Save this conversation and start with an empty loom?

                                  The full conversation, including all branches, stays in Saved chats. Model files and response settings are kept.

                                  `,1),wA=I(``),TA=I(`

                                  Enter a comma-separated list, linspace(), or start:stop:step.

                                  `,1),EA=I(`

                                  Keeps this branch's settings and applies the selected variation.

                                  `,1),DA=I(`

                                  ⌃⏎ / ⌘⏎

                                  `,1),OA=I(``),kA=I(` `,1),AA=I(` `,1);function jA(r,i){n(i,!0);let o=Y(i,`active`,3,!0),l=Y(i,`headersVisible`,3,!0),u=c(()=>new Set(Q.activePath)),d=c(()=>new Set(Ra.ids)),_=new gt,v=c(()=>{let e=Q.active_node_id,t=e?Q.nodes.get(e)??null:null;return t?t.recipe===null?t.role===`system`?null:t.id:t.parent_id:null}),x=c(()=>B(v)?(Q.children_of.get(B(v))??[]).map(e=>Q.nodes.get(e)).filter(e=>e!=null&&e.recipe!==null):[]);function C(){!B(v)||B(x).length<2||rt(`node_compare`,{node_ids:B(x).map(e=>e.id),parent_id:B(v)})}function E(e){let t=Q.children_of.get(e)??[],n=wa.siblingSort;if(n==="default"||t.length<2)return t;let r=n===`surprise`?1:-1,i=t.map((e,t)=>({id:e,idx:t,lp:Q.nodes.get(e)?.mean_logprob??null}));return i.sort((e,t)=>{if(e.lp===null&&t.lp===null)return e.idx-t.idx;if(e.lp===null)return 1;if(t.lp===null)return-1;let n=r*(e.lp-t.lp);return n===0?e.idx-t.idx:n}),i.map(e=>e.id)}let D=c(()=>{let e=[];if(!Q.root_id)return e;let t=Aa.matchingIds,n=$.active&&Ko.pendingIndex!==null?Ko.turns[Ko.pendingIndex]:null;wa.siblingSort;let r=[{id:Q.root_id,depth:0,deadAncestor:!1}];for(;r.length;){let{id:i,depth:a,deadAncestor:o}=r.pop(),s=Q.nodes.get(i);if(!s)continue;let c=n&&Q.pendingNodeId===i?MO(s,n):s,l=B(u).has(i),d=o||!l;if(!(c.parent_id===null&&c.role===`system`&&!c.text)){let n=t!==null&&!t.has(i);e.push({node:c,depth:a,isActivePath:l,isDead:d&&!l,filteredOut:n})}let f=t===null&&_.has(i)?[]:E(i);for(let e=f.length-1;e>=0;e--)r.push({id:f[e],depth:a+(c.parent_id===null&&c.role===`system`&&!c.text?0:1),deadAncestor:o||!l&&c.parent_id!==null})}return e}),O=c(()=>new Map(B(D).map(e=>[e.node.id,e]))),k=new xt(`(pointer: coarse)`);function M(e,t){if(e.tokens&&e.tokens.length>0){let n=t-60,r=zO(e.tokens),i=0;for(let t of r){i+=1;let r=0;for(let a of e.tokens.slice(t.start,t.end+1)){let e=(a.text||`∅`).replace(/\s/g,` `),t=Math.min(n,Math.max(k.current?24:18,16+e.length*7));r>0&&r+3+t>n?(i+=1,r=t):r+=(r>0?3:0)+t}}return k.current?120+i*47+r.length*56:105+i*27+r.length*38}let n=(e.text??``).trim().length;return 98+Math.min(6,Math.max(1,Math.ceil(n/Math.max(1,(t-40)/7))))*18}let N=c(()=>ok(B(D).map(e=>e.node),B(u))),P=new _t;Ce(()=>{let e=new Set(B(N).map(e=>e.id));for(let t of P.keys())e.has(t)||P.delete(t)});let I=c(()=>new Map(B(N).map(e=>[e.id,e]))),ee=c(()=>new Map(B(N).map(e=>{let t=e.node.tokens?.slice(e.start,e.end);return[e.id,Tk(t?.length?t.map(e=>e.text).join(``):e.node.text??``,t?.length??0)]}))),te=c(()=>new Map(B(N).map(e=>[e.id,{...B(O).get(e.node.id),depth:e.depth,isActivePath:e.memberIds.some(e=>B(u).has(e)),isDead:e.memberIds.every(e=>B(O).get(e).isDead),filteredOut:e.memberIds.every(e=>B(O).get(e).filteredOut)}]))),z=c(()=>Ek(B(N).map(e=>({id:e.id,parentId:e.parentId,depth:e.depth,width:B(ee).get(e.id),height:P.has(e.id)?P.get(e.id):M({...e.node,tokens:e.node.tokens?.slice(e.start,e.end)??null},B(ee).get(e.id))})))),re=c(()=>Dk(B(z)).length),ie=c(()=>B(N).reduce((e,t)=>e+t.end-t.start,0)),ae=c(()=>Dk(B(z)));Ce(()=>{if(!o()||wa.view!==`map`||$.active)return;Q.rev;let e=B(D);De(()=>{for(let t of e)t.node.parent_id&&t.node.recipe!==null&&Oa(t.node.parent_id,t.node.id)})});function oe(e){return!!(B(te).get(e.parentId)?.isActivePath&&B(te).get(e.childId)?.isActivePath)}function H(e){return B(te).get(e.childId)?.filteredOut??!1}function se(e){let t=Q.nodes.get(e.childId)?.mean_logprob;if(typeof t!=`number`||!Number.isFinite(t)||t>0)return``;let n=1-Math.exp(t);return`--edge-width:${(1.25+1.75*n).toFixed(2)}px;--edge-opacity:${(.42+.5*n).toFixed(3)}`}function le(e){if(!e.parent_id||!e.raw_token_ids?.length)return null;let t=(Q.children_of.get(e.parent_id)??[]).map(e=>Q.nodes.get(e)).filter(t=>t!=null&&t.id!==e.id&&!!t.raw_token_ids?.length);if(t.length===0)return null;let n=0;for(let r of t){let t=r.raw_token_ids,i=Math.min(e.raw_token_ids.length,t.length),a=0;for(;ae.raw_index===n)?.text.trim();return r?`fork · “${r.replace(/\s+/g,` `).slice(0,16)}”`:`fork · token ${n+1}`}function ue(e){let t=fi.target;if(!t)return null;let n=e.aggregate_readings;if(!n)return null;let r=n[t];return typeof r==`number`?r:null}function de(e){let t=e.mean_logprob;return typeof t==`number`&&Number.isFinite(t)?t:null}function fe(e){return!e.parent_id||e.recipe===null?null:Ta.get(`${e.parent_id}|${e.id}`)??null}let me=J(null),he=J(null),ge=J(null),ve=J(V(Q.root_id)),be=c(()=>Aa.matchingIds===null?[]:B(D).filter(e=>!e.filteredOut&&(wa.view!==`saved`||e.node.starred))),Se=c(()=>B(be).findIndex(e=>e.node.id===B(he))),we=c(()=>B(be)[Math.max(0,B(Se))]?.node??null),Te=c(()=>B(we)?Ca(B(we).text??``,Aa.mode===`text`?Aa.expr:``):null);Ce(()=>{Aa.expr,Aa.mode,A(he,null),A(ge,null)}),Ce(()=>{let e=Q.root_id;Q.rev,De(()=>{e===B(ve)?Aa.expr.trim()&&Na(Aa.expr):(A(ve,e,!0),Pa())})});function Ee(e){Pa(),Aa.expr=e,Aa.mode===`text`&&Na(e)}function Oe(e){let t=Aa.expr;Pa(),Aa.mode=e===`advanced`?`advanced`:`text`,Aa.expr=t,Aa.mode===`text`&&Na(t)}async function ke(e=0){if(!B(be).length)return;let t=B(Se)<0?e<0?B(be).length-1:0:e===0?B(Se):(B(Se)+e+B(be).length)%B(be).length,n=B(be)[t].node;A(he,n.id,!0),wa.view=`map`,await xe();let r=B(N).filter(e=>e.memberIds.includes(n.id)),i=r.find(e=>Aa.mode===`text`&&Sa(e.node.tokens?.slice(e.start,e.end).map(e=>e.text).join(``)||e.node.text||``,Aa.expr))??r.find(e=>e.id===n.id)??r[0];if(!i)return;A(ge,i.id,!0),wt(i.id),await xe();let a=B(Re)?.querySelector(`[data-node-id="${CSS.escape(i.id)}"]`),o=[...a?.querySelectorAll(`.sentence-node`)??[]].find(e=>Aa.mode===`text`&&Sa(e.querySelector(`.sentence-tokens`)?.textContent??``,Aa.expr)),s=B(z).nodes.find(e=>e.id===i.id);if(o&&a&&s&&B(Re)){let e=o.getBoundingClientRect(),t=a.getBoundingClientRect(),n=t.width/s.width;A(Ve,Mk($e(),{x:s.x+(e.left-t.left)/n,y:s.y+(e.top-t.top)/n,width:e.width/n,height:e.height/n},B(Ve).zoom),!0)}}function Ae(e){e.isComposing||(e.key===`Enter`?(e.preventDefault(),e.stopPropagation(),Aa.mode===`advanced`&&Aa.matchingIds===null?Na(Aa.expr):ke(e.shiftKey?-1:1)):e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),Pa()))}let Me=J(null),Ne=c(()=>{let e=B(Me)??Q.active_node_id;return e?Q.nodes.get(e)??null:null}),Pe=c(()=>Q.activePath.map(e=>B(O).get(e)).filter(e=>e!=null)),Fe=c(()=>{let e=[];for(let t of B(Pe)){let n=t.node,r=zO(n.tokens??[]);if(r.length===0){e.push({key:n.id,node:n,sentenceIndex:null,start:0,end:-1,text:n.text});continue}for(let t=0;t{let e=B(Ne);return e?E(e.recipe!==null&&e.parent_id?e.parent_id:e.id).map(e=>Q.nodes.get(e)).filter(e=>e!=null):[]}),Le=c(()=>B(D).filter(e=>e.node.starred&&!e.filteredOut)),Re=J(null),ze={width:0,height:0},Ve=J(V({x:0,y:0,zoom:1})),He=J(!1),Ue=J(!1),We=null,Ge=J(!1),Ke=null,qe={x:0,y:0,cameraX:0,cameraY:0},Je=new Map,Ye=null,Xe=0,Ze=c(()=>{let e=1+(B(Ve).zoom-1)*.32,t=1+(B(Ve).zoom-1)*.12,n=40*e,r=76*t;return[`--loom-grid-size:${n.toFixed(3)}px`,`--loom-grid-x:${(B(Ve).x*.32%n).toFixed(3)}px`,`--loom-grid-y:${(B(Ve).y*.32%n).toFixed(3)}px`,`--loom-far-size:${r.toFixed(3)}px`,`--loom-far-x:${(B(Ve).x*.12%r).toFixed(3)}px`,`--loom-far-y:${(B(Ve).y*.12%r).toFixed(3)}px`].join(`;`)});function Qe(e){We!==null&&(clearTimeout(We),We=null),A(Ue,e,!0),e&&(We=setTimeout(()=>{A(Ue,!1),We=null},220))}function $e(){return{width:B(Re)?.clientWidth??0,height:B(Re)?.clientHeight??0}}function et(){!B(Re)||B(z).nodes.length===0||(Qe(B(He)),A(Ve,jk($e(),B(z)),!0),A(He,!0),ze=$e())}function tt(){!o()||wa.view!==`map`||!B(Re)||(B(Ve).zoom=.9,Q.active_node_id?wt(Q.active_node_id):et())}function nt(e,t,n=!0){let r=$e();Qe(n),A(Ve,Pk(B(Ve),e,t??{x:r.width/2,y:r.height/2}),!0),A(He,!0)}function it(e){if(e.preventDefault(),e.ctrlKey||e.metaKey){let t=B(Re)?.getBoundingClientRect();if(!t)return;let n=Math.exp(-e.deltaY*.002);nt(B(Ve).zoom*n,{x:e.clientX-t.left,y:e.clientY-t.top},!1);return}Qe(!1),B(Ve).x-=e.shiftKey&&e.deltaX===0?e.deltaY:e.deltaX,B(Ve).y-=e.shiftKey?0:e.deltaY,A(He,!0)}function at(e){let t=B(Re)?.getBoundingClientRect();return t?{x:e.clientX-t.left,y:e.clientY-t.top}:null}function ot(e){if(B(Re))try{B(Re).setPointerCapture(e)}catch{}}function st(e){if(B(Re)?.hasPointerCapture(e))try{B(Re).releasePointerCapture(e)}catch{}}function dt(){let e=[...Je.values()];return e.length>=2?[e[0],e[1]]:null}function ft(){let e=dt();if(!e)return;let t=lx(e[0],e[1]);if(!(t.distance<=0)){Qe(!1),A(Ge,!1),Ke=null,Ye={distance:t.distance,zoom:B(Ve).zoom,worldX:(t.center.x-B(Ve).x)/B(Ve).zoom,worldY:(t.center.y-B(Ve).y)/B(Ve).zoom},Xe=performance.now()+350;for(let e of Je.keys())ot(e)}}function pt(){let e=dt();if(!e||!Ye)return;let t=lx(e[0],e[1]),n=ux(Ye.zoom,Ye.distance,t.distance,Ok,kk);A(Ve,{x:t.center.x-Ye.worldX*n,y:t.center.y-Ye.worldY*n,zoom:n},!0),A(He,!0)}function mt(e){if(e.button!==0)return;let t=e.target;if(e.pointerType===`touch`){let t=at(e);if(!t)return;if(Je.set(e.pointerId,t),Je.size>=2){ft(),e.preventDefault();return}}t?.closest(`.tree-node-wrap, .loom-view-controls`)||(Qe(!1),A(Ge,!0),Ke=e.pointerId,qe={x:e.clientX,y:e.clientY,cameraX:B(Ve).x,cameraY:B(Ve).y},ot(e.pointerId),e.preventDefault())}function ht(e){if(e.pointerType===`touch`&&Je.has(e.pointerId)){let t=at(e);if(t&&Je.set(e.pointerId,t),Ye&&Je.size>=2){pt(),Xe=performance.now()+350,e.preventDefault();return}}!B(Ge)||Ke!==e.pointerId||(B(Ve).x=qe.cameraX+e.clientX-qe.x,B(Ve).y=qe.cameraY+e.clientY-qe.y,A(He,!0),e.preventDefault())}function vt(e){if(st(e.pointerId),e.pointerType===`touch`){let t=Ye!==null;Je.delete(e.pointerId),t&&(Je.size>=2?ft():Ye=null)}Ke===e.pointerId&&(A(Ge,!1),Ke=null)}function yt(e){_.has(e)?_.delete(e):_.add(e),xe().then(et)}let bt=0;Ce(()=>{let e=B(Re);if(!o()||wa.view!==`map`||!e)return;let t=new ResizeObserver(()=>{let e=$e();e.width===0||e.height===0||(B(He)?ze.width>0&&ze.height>0&&(Qe(!1),A(Ve,Nk(B(Ve),ze,e),!0)):tt(),ze=e)});return t.observe(e),()=>t.disconnect()}),Ce(()=>{if(!o()||wa.view!==`map`)return;let e=B(z).nodes.length;B(z).width,B(z).height;let t=bt;if(bt=e,e===0){A(He,!1);return}xe().then(()=>{!B(He)||t===0?tt():e!==t&&Tt()})}),Ce(()=>{let e=Q.active_node_id,t=e!==null&&B(D).some(t=>t.node.id===e);B(Me)!==null&&B(D).some(e=>e.node.id===B(Me))||A(Me,t?e:B(D)[0]?.node.id??null,!0)});function St(){return B(Me)?B(D).findIndex(e=>e.node.id===B(Me)):-1}async function Ct(e,t=!0){A(Me,e,!0),await xe();let n=B(Re)?.querySelector(`[data-node-id="${CSS.escape(e)}"]`);n&&(n.focus({preventScroll:!0}),t&&wt(e))}function wt(e){let t=B(z).nodes.find(t=>t.id===e);!t||!B(Re)||(Qe(B(He)),A(Ve,Mk($e(),{x:t.x,y:t.y,width:t.width,height:t.height},B(Ve).zoom),!0),A(He,!0),ze=$e())}function Tt(){Q.active_node_id&&wt(Q.active_node_id)}function Et(e){wa.view=e,Jt(!1),e===`map`&&xe().then(()=>{Q.active_node_id&&Ct(Q.active_node_id,!1),tt()})}function Dt(e){return(e.text??``).replace(/\s+/g,` `).trim()||`Empty turn`}function kt(e){return e.role_label?.trim()||e.role}async function At(e){A(Me,e.id,!0),Q.active_node_id!==e.id&&await bo(e.id)}function jt(e){let t=St(),n=B(D)[t+e];n&&Ct(n.node.id)}function Mt(){if(!B(Me))return;let e=Q.nodes.get(B(Me))?.parent_id;e&&B(D).some(t=>t.node.id===e)&&Ct(e)}function Nt(){if(!B(Me))return;let e=E(B(Me))[0];e&&B(D).some(t=>t.node.id===e)&&Ct(e)}let Pt=J(V({open:!1,nodeId:null})),Ft=J(null),It=J(V({x:12,y:12})),Lt=J(!1),Rt=null,zt=null;function Bt(e){return document.body.appendChild(e),{destroy:()=>e.remove()}}function Vt(e,t){e.preventDefault(),e.stopPropagation(),Ht(t,e.currentTarget??B(Re)?.querySelector(`[data-node-id="${CSS.escape(t)}"]`)??null)}async function Ht(e,t){Rt=t,A(Lt,!1),A(Me,e,!0),Qe(!1),await xe(),A(Pt,{open:!0,nodeId:e},!0),await xe(),await new Promise(e=>requestAnimationFrame(()=>e())),Ut(),await xe(),A(Lt,!0),Wt(),await xe(),Kt()[0]?.focus()}function Ut(){if(!B(Ft)||!B(Pt).nodeId)return;let e=(B(Re)?.querySelector(`[data-node-id="${CSS.escape(B(Pt).nodeId)}"]`)??(Rt?.isConnected?Rt:null))?.getBoundingClientRect(),t={width:B(Ft).offsetWidth,height:B(Ft).offsetHeight},n=e??{left:12,right:12,top:12,bottom:12},r=n.right+12,i=n.top;r+t.width>window.innerWidth-12&&(r=n.left-t.width-12),r<12&&(r=n.left,i=n.bottom+12),i+t.height>window.innerHeight-12&&(i=Math.max(12,window.innerHeight-t.height-12));let a=Math.max(12,Math.min(r,window.innerWidth-t.width-12)),o=Math.max(12,i);(Math.abs(B(It).x-a)>.5||Math.abs(B(It).y-o)>.5)&&A(It,{x:a,y:o},!0)}function Wt(){zt!==null&&cancelAnimationFrame(zt);let e=()=>{if(!B(Pt).open){zt=null;return}Ut(),zt=requestAnimationFrame(e)};zt=requestAnimationFrame(e)}function Gt(e){Ht(e,B(Re)?.querySelector(`[data-node-id="${CSS.escape(e)}"]`)??null)}function Kt(){return B(Ft)?Array.from(B(Ft).querySelectorAll(`[role="menuitem"]:not(:disabled)`)):[]}function qt(e){if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),Jt();return}if(e.key===`Tab`){Jt(!1);return}let t=Kt();if(t.length===0)return;let n=Math.max(0,t.indexOf(document.activeElement)),r=-1;e.key===`ArrowDown`?r=(n+1)%t.length:e.key===`ArrowUp`?r=(n-1+t.length)%t.length:e.key===`Home`?r=0:e.key===`End`&&(r=t.length-1),r>=0&&(e.preventDefault(),e.stopPropagation(),t[r].focus())}function Jt(e=!0){let t=Rt,n=B(Pt).nodeId;A(Pt,{open:!1,nodeId:null},!0),A(Lt,!1),zt!==null&&cancelAnimationFrame(zt),zt=null,A(Ft,null),e&&xe().then(()=>{t?.isConnected?t.focus({preventScroll:!0}):n&&Ct(n,!1)})}let Yt=J(0);Ce(()=>{let e=wa.modalRequest;e.seq!==B(Yt)&&e.kind&&(A(Yt,e.seq,!0),sn(e.kind,e.nodeId,e.text,e.n))});let Xt=J(V({kind:null,nodeId:null,text:``,n:1,vector:``,mode:`unsteered`,error:``})),Zt=J(null),Qt=J(null),$t=J(null),en=null,tn=J(null),nn=[];function rn(){if(nn.length>0)return;let e=B(tn)?.closest(`.loom-zone`),t=e?.parentElement;if(!(!e||!t)){nn=Array.from(t.children).filter(t=>t instanceof HTMLElement&&t!==e).map(e=>({element:e,inert:e.hasAttribute(`inert`),ariaHidden:e.getAttribute(`aria-hidden`)}));for(let e of nn)e.element.setAttribute(`inert`,``),e.element.setAttribute(`aria-hidden`,`true`)}}function an(){for(let e of nn)e.element.isConnected&&(e.inert||e.element.removeAttribute(`inert`),e.ariaHidden===null?e.element.removeAttribute(`aria-hidden`):e.element.setAttribute(`aria-hidden`,e.ariaHidden));nn=[]}function on(){B(Zt)?(B(Zt).focus(),B(Zt).select?.()):B($t)?.focus()}async function sn(e,t,n=``,r=1,i){if(e===`delete`&&t&&yo(t)){Z(vo,{kind:`warning`});return}en=i??(document.activeElement instanceof HTMLElement?document.activeElement:null),A(Zt,null),A(Xt,{kind:e,nodeId:t,text:n,n:r,vector:``,mode:`unsteered`,error:``},!0),await xe(),on(),B(tn)?.setAttribute(`inert`,``),B(tn)?.setAttribute(`aria-hidden`,`true`),rn()}function cn(){let e=en;B(tn)?.removeAttribute(`inert`),B(tn)?.removeAttribute(`aria-hidden`),an(),A(Xt,{kind:null,nodeId:null,text:``,n:1,vector:``,mode:`unsteered`,error:``},!0),A(Zt,null),A(Qt,null),A($t,null),en=null,xe().then(()=>{if(e?.isConnected)e.focus({preventScroll:!0});else{let e=B(Me)&&B(D).some(e=>e.node.id===B(Me))?B(Me):Q.active_node_id??B(D)[0]?.node.id??null;e&&Ct(e,!1)}})}function ln(){return B(Qt)?Array.from(B(Qt).querySelectorAll(`button:not(:disabled), input:not(:disabled), textarea:not(:disabled), select:not(:disabled), [tabindex]:not([tabindex="-1"])`)):[]}function un(e){if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),cn();return}if(e.key!==`Tab`)return;let t=ln();if(t.length===0){e.preventDefault(),B(Qt)?.focus();return}let n=document.activeElement,r=n?t.indexOf(n):-1;e.shiftKey&&r<=0?(e.preventDefault(),t[t.length-1].focus()):!e.shiftKey&&(r<0||r===t.length-1)&&(e.preventDefault(),t[0].focus())}function dn(e){A(Xt,{...B(Xt),error:e},!0)}let fn=J(!1);async function pn(){if(!B(fn)){A(fn,!0);try{await mn()}finally{A(fn,!1)}}}async function mn(){let e=B(Xt);if(!e.kind||!e.nodeId)return cn();switch(e.kind){case`clear`:if($.active){dn(`Stop the current reply before clearing the loom.`);return}try{await Dc(),await Ot.reset(),wc.activeId=null,wc.avatarSeed=null,wc.accent=`purple`,await go(),Ba(),Pa(),Z(`Loom cleared. The previous conversation is still in Saved chats.`,{kind:`info`})}catch(e){dn(je(e,`The loom could not be cleared. Your saved chats were not deleted.`));return}break;case`regenerate`:await Oo(Math.max(1,Math.floor(e.n)));break;case`edit`:await xo(e.nodeId,e.text);break;case`branch`:{let t=await So(e.nodeId,e.text);t&&await bo(t);break}case`delete`:if(yo(e.nodeId)){dn(vo);return}if(!await wo(e.nodeId)){dn(Q.error??`The branch could not be removed. Try again.`);return}break;case`note`:await Eo(e.nodeId,e.text);break;case`navpicker`:{let t=gn(e.text);if(t.id){await bo(t.id);break}if(t.matches.length===0){dn(`no node matches '${e.text}'`);return}let n=t.matches.slice(0,6).map(e=>e.slice(0,8)).join(`, `);dn(`ambiguous: ${t.matches.length} matches (${n}`+(t.matches.length>6?`, …`:``)+`)`);return}case`search`:if(await Na(e.text,`text`),!Aa.matchingIds?.size){dn(`No text match for '${e.text}'.`);return}cn(),wa.view=`map`,await xe(),B(me)?.focus(),await ke();return;case`fanout`:{let t=(e.vector??``).trim();if(!t){dn(`vector name required`);return}let n=hn(e.text);if(n.length===0){dn(`couldn't parse alphas, try a comma list (0.0, 0.3, 0.7) or linspace(-1, 1, 5)`);return}let r=e.nodeId;for(let e of n)await ko(r,{n:1,recipe_override:`steering=${e} ${t}`});break}case`regen_mode`:{let t=Q.nodes.get(e.nodeId),n=(e.mode??`unsteered`).trim(),r=Math.max(1,Math.floor(e.n));t?.recipe===null?await ko(e.nodeId,{n:r,recipe_override:n}):(Q.active_node_id!==e.nodeId&&await bo(e.nodeId),await Oo(r,{recipe_override:n}));break}}cn()}function hn(e){let t=e.trim();if(!t)return[];let n=t.match(/^linspace\s*\(\s*([^,]+?)\s*,\s*([^,]+?)\s*,\s*([^,)]+?)\s*\)\s*$/i);if(n){let e=Number(n[1]),t=Number(n[2]),r=Number(n[3]);if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isInteger(r)||r<1)return[];if(r===1)return[e];let i=(t-e)/(r-1),a=[];for(let t=0;te.trim());if(e.length!==3)return[];let n=Number(e[0]),r=Number(e[1]),i=Number(e[2]);if(![n,r,i].every(Number.isFinite)||i===0||(r-n)*i<0)return[];let a=[],o=Math.abs(i)*1e-9,s=i>0,c=n,l=0;for(;(s?c<=r+o:c>=r-o)&&l++<1e4;)a.push(Number.parseFloat(c.toPrecision(12))),c+=i;return l>=1e4?[]:a}let r=[];for(let e of t.split(`,`)){let t=e.trim();if(!t)continue;let n=Number(t);if(!Number.isFinite(n))return[];r.push(n)}return r}function gn(e){let t=e.trim();if(!t)return{id:null,matches:[]};if(t===`root`){let e=Q.root_id;return e?{id:e,matches:[e]}:{id:null,matches:[]}}let n=[];for(let e of Q.nodes.keys()){if(e===t)return{id:e,matches:[e]};e.startsWith(t)&&n.push(e)}return n.length===1?{id:n[0],matches:n}:{id:null,matches:n}}function _n(e,t){if(performance.now()t.nodeId===e.id);if(n<0){Z(`That branch could not be opened for token editing.`,{kind:`error`});return}rt(`token_drilldown`,{turnIdx:n,tokenIdx:t,initialTab:`logits`})}function Sn(e){let t=e;if(!t)return!1;let n=t.tagName;return n===`INPUT`||n===`TEXTAREA`||n===`SELECT`||t.isContentEditable}function Cn(e){if(B(Xt).kind!==null||B(Pt).open)return;let t=e.target,n=t?.closest(`[role="treeitem"]`)??null;if(!n||!B(Re)?.contains(n)||t!==n&&t?.closest(`button, a, [role='button'], [role='menuitem']`))return;let r=e.key;if(!(r!==`Escape`&&Sn(e.target))){if(r===`ArrowDown`||r===`j`){e.preventDefault(),jt(1);return}if(r===`ArrowUp`||r===`k`){e.preventDefault(),jt(-1);return}if(r===`ArrowLeft`||r===`h`){e.preventDefault(),Mt();return}if(r===`ArrowRight`||r===`l`){e.preventDefault(),Nt();return}if(r===`Home`&&B(D).length>0){e.preventDefault(),Ct(B(D)[0].node.id);return}if(r===`End`&&B(D).length>0){e.preventDefault(),Ct(B(D)[B(D).length-1].node.id);return}if(r===`ContextMenu`||r===`F10`&&e.shiftKey){B(Me)&&(e.preventDefault(),Gt(B(Me)));return}if(r===`Enter`||r===` `){B(Me)&&(e.preventDefault(),bo(B(Me)));return}if(r===`s`&&B(Me)){e.preventDefault();let t=Q.nodes.get(B(Me));To(B(Me),!t?.starred);return}if(r===`n`&&B(Me)){e.preventDefault();let t=Q.nodes.get(B(Me));sn(`note`,B(Me),t?.notes??``);return}if(r===`/`){e.preventDefault(),sn(`search`,B(Me)??Q.active_node_id);return}if(r===`Escape`){wa.filterHelpOpen&&=(e.preventDefault(),!1);return}}}function wn(e){if(!B(Pt).open)return;let t=e.target;t&&t.closest(`.loom-menu`)||Jt(!1)}function Tn(e){if(e.key===`Escape`){if(B(Pt).open){Jt(),e.preventDefault();return}if(B(Xt).kind){cn(),e.preventDefault();return}}}async function En(){let e=B(Pt).nodeId,t=Rt;Jt(!1),e&&(Q.active_node_id!==e&&await bo(e),await sn(`regenerate`,e,``,1,t))}async function Dn(){let e=B(Pt).nodeId,t=Rt;Jt(!1),e&&await sn(`edit`,e,Q.nodes.get(e)?.text??``,1,t)}async function On(){let e=B(Pt).nodeId,t=Rt;Jt(!1),e&&await sn(`branch`,e,Q.nodes.get(e)?.text??``,1,t)}async function kn(){let e=B(Pt).nodeId;if(Jt(),!e)return;let t=await Co(e);t&&await bo(t)}async function An(){let e=B(Pt).nodeId;Jt(),e&&await bo(e)}async function jn(){let e=B(Pt).nodeId,t=Rt;Jt(!1),e&&await sn(`delete`,e,``,1,t)}async function Mn(){let e=B(Pt).nodeId;Jt(),e&&await To(e,!Q.nodes.get(e)?.starred)}async function Nn(){let e=B(Pt).nodeId,t=Rt;Jt(!1),e&&await sn(`note`,e,Q.nodes.get(e)?.notes??``,1,t)}function Pn(){let e=B(Pt).nodeId;Jt(),e&&Ia(e)}function Fn(){let e=B(Pt).nodeId,t=Rt;if(Jt(!1),!e)return;let n=Q.nodes.get(e),r=e;n&&n.recipe!==null&&n.parent_id&&(r=n.parent_id),sn(`fanout`,r,`0.0, 0.3, 0.6`,1,t)}function In(){let e=B(Pt).nodeId;if(Jt(!1),!e)return;let t=Q.nodes.get(e),n=null;if(t&&t.recipe===null&&t.role!==`system`?n=e:t&&t.recipe!==null&&(n=t.parent_id),!n)return;let r=(Q.children_of.get(n)??[]).filter(e=>Q.nodes.get(e)?.recipe!==null);r.length<2||rt(`node_compare`,{node_ids:r,parent_id:n})}function Ln(){let e=B(Pt).nodeId;Jt(),e&&za(e)}function Rn(){B(Pt).open&&Jt(!1),!(Ra.ids.length<2)&&rt(`node_compare`,{node_ids:[...Ra.ids]})}function zn(){let e=B(Pt).nodeId,t=Rt;Jt(!1),e&&sn(`regen_mode`,e,``,1,t)}function Bn(){go()}ne(()=>{let e=B(Me)??Q.active_node_id??B(D)[0]?.node.id;return e&&B(D).some(t=>t.node.id===e)&&Ct(e,!1),xe().then(tt),()=>{We!==null&&clearTimeout(We),zt!==null&&cancelAnimationFrame(zt),Je.clear(),an()}});var Vn=AA();ye(`click`,ce,wn),ye(`keydown`,ce,Tn),ye(`resize`,ce,Ut);var Hn=q(Vn),Un=R(Hn),Wn=e=>{var t=Fk(),n=X(R(t),2),r=X(n,2),i=X(r,2),a=X(i,2),o=X(a,2),s=X(o,2),c=R(s,!0);f(s);var u=X(s,2);Be(R(u),{name:`refresh`}),f(u),f(t),U(e=>{t.inert=!l(),r.disabled=$.active||!Q.loaded||Q.nodes.size<=1,i.disabled=e,s.disabled=B(x).length<2,G(c,B(x).length>=2?`Compare ${B(x).length}`:`Compare`)},[()=>!Q.active_node_id||Q.active_node_id===Q.root_id||yo(Q.active_node_id)]),K(`click`,n,function(...e){Xo?.apply(this,e)}),K(`click`,r,()=>void sn(`clear`,Q.root_id)),K(`click`,i,()=>void sn(`delete`,Q.active_node_id)),K(`click`,a,()=>rt(`save_conversation`)),K(`click`,o,()=>rt(`load_conversation`)),K(`click`,s,C),K(`click`,u,Bn),h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)};p(Un,e=>{l()&&e(Wn)});var Gn=X(Un,2),Kn=R(Gn);let qn;var Jn=X(Kn,2);let Yn;var Xn=X(Jn,2);let Zn;var Qn=X(R(Xn)),$n=R(Qn);f(Qn),f(Xn);var er=X(Xn,2);let tr;var nr=X(R(er)),rr=R(nr);f(nr),f(er);var ir=X(er,2);let ar;var or=X(R(ir)),sr=R(or);f(or),f(ir),f(Gn),w(Gn,e=>Ac?.(e));var cr=X(Gn,2);hu(X(R(cr),2),{ariaLabel:`Loom view`,get value(){return wa.view},options:[{value:`weave`,label:`Weave · Text and alternatives`},{value:`map`,label:`Map · All branches`},{value:`path`,label:`Current path`},{value:`options`,label:`Next options`},{value:`saved`,label:`Starred`}],onchange:e=>Et(e)}),f(cr);var lr=X(cr,2),ur=e=>{var n=zk(),r=q(n),i=R(r),o=R(i),c=R(o,!0);f(o);var l=X(o,2);s(l),a(l,e=>A(me,e),()=>B(me)),f(i);var u=X(i,2);hu(u,{get value(){return Aa.mode},options:[{value:`text`,label:`Text`},{value:`advanced`,label:`Advanced`}],ariaLabel:`Search mode`,onchange:Oe});var d=X(u,2),m=e=>{var t=Ik(),n=q(t),r=X(n,2);let i;Be(R(r),{name:`help`}),f(r),U(()=>{i=y(r,1,`icon-btn help-btn svelte-1byp7q8`,null,i,{on:wa.filterHelpOpen}),S(r,`aria-expanded`,wa.filterHelpOpen)}),K(`click`,n,()=>void Na(Aa.expr)),K(`click`,r,()=>wa.filterHelpOpen=!wa.filterHelpOpen),g(e,t)};p(d,e=>{Aa.mode===`advanced`&&e(m)});var h=X(d,2),_=e=>{var t=Lk();Be(R(t),{name:`dismiss`}),f(t),K(`click`,t,()=>{Pa(),B(me)?.focus()}),g(e,t)};p(h,e=>{Aa.expr&&e(_)}),f(r);var v=X(r,2),b=R(v);let x;var C=R(b,!0);f(b);var w=X(b,2),T=e=>{var t=Rk(),n=R(t),r=R(n),i=R(r,!0);f(r);var a=X(r,2),o=R(a,!0),s=X(o),c=R(s,!0);f(s);var l=X(s,1,!0);f(a),f(n);var u=X(n,2);Be(R(u),{name:`up`}),f(u);var d=X(u,2);Be(R(d),{name:`down`}),f(d),f(t),U(e=>{G(i,e),G(o,B(Te).before),G(c,B(Te).match),G(l,B(Te).after),a.dir=a.dir},[()=>kt(B(we))]),K(`click`,n,()=>void ke()),K(`click`,u,()=>void ke(-1)),K(`click`,d,()=>void ke(1)),g(e,t)};p(w,e=>{B(we)&&B(Te)&&e(T)}),f(v),U(()=>{G(c,Aa.mode===`text`?`Search messages`:`Advanced filters`),t(l,Aa.expr),S(l,`placeholder`,Aa.mode===`text`?`Words or a phrase…`:`starred, text:fox`),S(l,`aria-invalid`,Aa.error?!0:void 0),x=y(b,1,`svelte-1byp7q8`,null,x,{err:Aa.error!==null}),G(C,Aa.loading?`Searching…`:Aa.error??(Aa.matchingIds===null?Aa.mode===`advanced`?`Press Enter or Apply to run the filters.`:`Search all branches. Enter moves to the next match; Shift+Enter moves back.`:B(be).length===0?`No messages match. Try different words or clear the search.`:`${B(Se)>=0?`${B(Se)+1} of `:``}${B(be).length} matching ${B(be).length===1?`message`:`messages`}`))}),K(`input`,l,e=>Ee(e.currentTarget.value)),K(`keydown`,l,Ae),g(e,n)};p(lr,e=>{(wa.view===`map`||wa.view===`saved`)&&e(ur)});var dr=X(lr,2),fr=e=>{var t=Bk();h(1,t,()=>ut,lu),h(2,t,()=>ut,uu),g(e,t)};p(dr,e=>{Aa.mode===`advanced`&&wa.filterHelpOpen&&(wa.view===`map`||wa.view===`saved`)&&e(fr)});var pr=X(dr,2),mr=e=>{var t=Vk(),n=R(t),r=R(n);f(n),f(t),U(()=>G(r,`sort:${wa.siblingSort??``}`)),g(e,t)};p(pr,e=>{wa.siblingSort!=="default"&&e(mr)});var hr=X(pr,2),gr=e=>{var t=Hk(),n=R(t),r=R(n);f(n);var i=X(n,2),a=X(i,2);f(t),U(()=>{G(r,`${Ra.ids.length??``} selected`),i.disabled=Ra.ids.length<2}),K(`click`,i,Rn),K(`click`,a,function(...e){Ba?.apply(this,e)}),g(e,t)};p(hr,e=>{Ra.ids.length>0&&e(gr)});var _r=X(hr,2);F(R(_r),()=>Q.root_id,e=>{{let t=c(()=>o()&&wa.view===`weave`);Sk(e,{get active(){return B(t)},oninspect:(e,t)=>void xn(e,t),onwrite:yn})}}),f(_r);var vr=X(_r,2),yr=e=>{var t=Uk(),n=X(R(t),2);f(t),K(`click`,n,Bn),g(e,t)},br=e=>{var t=L(),n=q(t),r=e=>{g(e,Wk())},i=e=>{var t=Yk(),n=q(t),r=R(n),i=X(R(r),2),o=R(i);f(i);var s=X(i,4),l=R(s);f(s);var h=X(s,2),v=e=>{var t=Gk(),n=X(q(t),2),r=R(n);f(n),U(()=>G(r,`${B(ie)??``} ${B(ie)===1?`token`:`tokens`}`)),g(e,t)};p(h,e=>{B(ie)>0&&e(v)}),T(2),f(r);var b=X(r,2),x=R(b);Be(R(x),{name:`subtract`}),f(x);var C=X(x,2),w=R(C);{let e=c(()=>Math.round(B(Ve).zoom*100));Fl(w,{get value(){return B(e)}})}T(),f(C);var E=X(C,2);Be(R(E),{name:`add`}),f(E);var O=X(E,2),k=X(O,2);f(b),f(n);var j=X(n,2);let M;var N=X(R(j),2),F=X(N,2);let L;var ee=R(F),ne=R(ee);m(ne,17,()=>B(z).edges,e=>`${e.parentId}|${e.childId}`,(e,t)=>{var n=Kk(),r=q(n);let i;var a=X(r);let o;U((e,n,s,c)=>{S(r,`d`,B(t).path),i=y(r,0,`edge-depth svelte-1byp7q8`,null,i,e),pe(r,n),S(a,`d`,B(t).path),o=y(a,0,`edge-line svelte-1byp7q8`,null,o,s),pe(a,c),S(a,`data-loom-edge`,`${B(t).parentId}|${B(t).childId}`)},[()=>({"active-edge":oe(B(t)),"quiet-edge":!oe(B(t)),"filtered-edge":H(B(t))}),()=>se(B(t)),()=>({"active-edge":oe(B(t)),"quiet-edge":!oe(B(t)),"filtered-edge":H(B(t))}),()=>se(B(t))]),g(e,n)}),m(X(ne),17,()=>B(ae),e=>e.id,(e,t)=>{var n=qk(),r=q(n);let i;var a=X(r);let o;U((e,n)=>{i=y(r,0,`junction-halo svelte-1byp7q8`,null,i,e),S(r,`cx`,B(t).x),S(r,`cy`,B(t).y),o=y(a,0,`junction-core svelte-1byp7q8`,null,o,n),S(a,`cx`,B(t).x),S(a,`cy`,B(t).y),S(a,`data-loom-junction`,B(t).id)},[()=>({"active-junction":B(te).get(B(t).id)?.isActivePath}),()=>({"active-junction":B(te).get(B(t).id)?.isActivePath})]),g(e,n)}),f(ee),m(X(ee,2),17,()=>B(z).nodes,e=>e.id,(e,t)=>{let n=c(()=>B(te).get(B(t).id)),r=c(()=>B(I).get(B(t).id));var i=Jk();let a;var o=R(i);{let e=c(()=>B(r).shared?B(r).memberIds.length:0),t=c(()=>B(r).shared&&B(u).has(B(n).node.id)),i=c(()=>!B(r).shared&&B(Me)===B(n).node.id),a=c(()=>!B(r).shared&&Q.active_node_id===B(n).node.id),s=c(()=>B(d).has(B(n).node.id)),l=c(()=>B(n).depth+1),f=c(()=>(Q.children_of.get(B(n).node.id)?.length??0)>0),p=c(()=>_.has(B(n).node.id)),m=c(()=>!B(r).shared&&Q.pendingNodeId===B(n).node.id),h=c(()=>B(r).shared?null:ue(B(n).node)),g=c(()=>B(r).shared?null:de(B(n).node)),v=c(()=>B(r).shared?null:fe(B(n).node)),y=c(()=>B(r).shared?null:B(r).start>0?`continuation`:le(B(n).node)),b=c(()=>B(r).shared?void 0:e=>_n(B(n).node,e)),x=c(()=>B(r).shared?void 0:()=>{A(Me,B(n).node.id,!0)}),S=c(()=>B(r).shared?void 0:Cn),C=c(()=>B(r).shared?void 0:e=>Vt(e,B(n).node.id)),w=c(()=>!$.active);ak(o,{onmeasure:e=>{P.get(B(r).id)!==e&&P.set(B(r).id,e)},get node(){return B(n).node},get displayId(){return B(r).id},get tokenStart(){return B(r).start},get tokenEnd(){return B(r).end},get sharedCount(){return B(e)},get sharedUsesActivePath(){return B(t)},get onActivePath(){return B(n).isActivePath},get focused(){return B(i)},get current(){return B(a)},get selected(){return B(s)},get level(){return B(l)},get hasChildren(){return B(f)},get collapsed(){return B(p)},get dead(){return B(n).isDead},get streaming(){return B(m)},get ring(){return B(h)},get weightBadge(){return B(g)},get steerLabel(){return B(v)},get forkLabel(){return B(y)},get onclick(){return B(b)},get onfocus(){return B(x)},get onkeydown(){return B(S)},get oncontextmenu(){return B(C)},onactions:e=>Vt(e,B(n).node.id),ongrow:()=>void vn(B(n).node),onbranch:e=>yn(B(n).node,e.currentTarget),onselecttoken:e=>void xn(B(n).node,e),onbranchsentence:e=>void bn(B(n).node,e),get sentenceBranchAvailable(){return B(w)},ontogglechildren:()=>yt(B(n).node.id)})}f(i),U(e=>{a=y(i,1,`tree-node-wrap svelte-1byp7q8`,null,a,e),S(i,`data-loom-node-id`,B(r).id),S(i,`data-loom-shared`,B(r).shared?B(r).memberIds.length:void 0),S(i,`data-loom-depth`,B(t).depth),pe(i,`left:${B(t).x}px;top:${B(t).y}px;width:${B(t).width}px;height:${B(t).height}px;--branch-depth:${B(t).depth}`)},[()=>({"filtered-out":B(n).filteredOut,"search-match":Aa.matchingIds!==null&&!B(n).filteredOut,"search-current":B(ge)===B(t).id,selected:!B(r).shared&&B(d).has(B(n).node.id),pinned:!B(r).shared&&Fa.nodeId===B(n).node.id,"active-path-node":B(n).isActivePath,"current-node":!B(r).shared&&Q.active_node_id===B(n).node.id,"dead-node":B(n).isDead})]),g(e,i)}),f(F),f(j),a(j,e=>A(Re,e),()=>B(Re)),U((e,t,n)=>{G(o,`${B(D).length??``} ${B(D).length===1?`turn`:`turns`}`),G(l,`${B(re)??``} ${B(re)===1?`fork`:`forks`}`),x.disabled=B(Ve).zoom<=Ok,E.disabled=B(Ve).zoom>=kk,M=y(j,1,`tree-scroll loom-viewport svelte-1byp7q8`,null,M,{dragging:B(Ge),"camera-animating":B(Ue)}),pe(N,B(Ze)),L=y(F,1,`loom-canvas svelte-1byp7q8`,null,L,{"camera-animating":B(Ue)}),pe(F,`width:${B(z).width}px;height:${B(z).height}px;transform:translate3d(${B(Ve).x}px,${B(Ve).y}px,0) scale(${B(Ve).zoom})`),S(F,`data-loom-nodes`,B(z).nodes.length),S(F,`data-loom-edges`,B(z).edges.length),S(F,`data-loom-zoom`,e),S(F,`data-loom-camera-x`,t),S(F,`data-loom-camera-y`,n),S(ee,`width`,B(z).width),S(ee,`height`,B(z).height),S(ee,`viewBox`,`0 0 ${B(z).width} ${B(z).height}`)},[()=>B(Ve).zoom.toFixed(2),()=>B(Ve).x.toFixed(2),()=>B(Ve).y.toFixed(2)]),K(`click`,x,()=>nt(B(Ve).zoom-.12)),K(`click`,E,()=>nt(B(Ve).zoom+.12)),K(`click`,O,et),K(`click`,k,Tt),ye(`wheel`,j,it),K(`pointerdown`,j,mt),K(`pointermove`,j,ht),K(`pointerup`,j,vt),ye(`pointercancel`,j,vt),ye(`lostpointercapture`,j,vt),g(e,t)},o=e=>{var t=iA(),n=R(t),r=X(R(n),2),i=e=>{var t=Xk();K(`click`,t,()=>Et(`options`)),g(e,t)};p(r,e=>{Q.active_node_id&&e(i)}),f(n);var a=X(n,2);m(a,23,()=>B(Fe),e=>e.key,(e,t,n)=>{let r=c(()=>B(t).end>=0?B(t).node.tokens?.[B(t).end]:null),i=c(()=>B(t).sentenceIndex!==null&&!$.active&&B(r)?.raw_index!=null&&B(r)?.token_id!=null);var a=rA();let o;var s=X(R(a),2),l=R(s),u=R(l),d=R(u,!0);f(u);var h=X(u,2),_=e=>{var n=Zk(),r=R(n);f(n),U(()=>G(r,`sentence ${B(t).sentenceIndex+1}`)),g(e,n)};p(h,e=>{B(t).sentenceIndex!==null&&e(_)});var v=X(h,2),b=e=>{g(e,Qk())};p(v,e=>{Q.active_node_id===B(t).node.id&&e(b)});var x=X(v,2);f(l);var C=X(l,2),w=e=>{var n=eA();m(n,23,()=>B(t).node.tokens.slice(B(t).start,B(t).end+1),(e,n)=>`${e.raw_index??B(t).start+n}:${e.token_id??e.text}`,(e,n,r)=>{let i=c(()=>B(t).start+B(r));var a=$k(),o=R(a,!0);f(a),U(e=>{S(a,`data-loom-token-node`,B(t).node.id),S(a,`data-token-index`,B(i)),S(a,`aria-label`,e),G(o,B(n).text||`∅`)},[()=>`Open token ${B(i)+1}: ${B(n).text.trim()||`whitespace`}`]),K(`click`,a,()=>void xn(B(t).node,B(i))),g(e,a)}),f(n),g(e,n)},T=e=>{var n=tA(),r=R(n,!0);f(n),U(e=>G(r,e),[()=>Dt(B(t).node)]),K(`click`,n,()=>void At(B(t).node)),g(e,n)};p(C,e=>{B(t).sentenceIndex!==null&&B(t).node.tokens?e(w):e(T,-1)});var E=X(C,2),D=R(E),O=X(D,2),k=e=>{var n=nA();U(()=>{n.disabled=!B(i),S(n,`title`,B(i)?`Keep everything through this sentence and generate a new continuation`:`Exact sentence replay is unavailable while the model is busy`)}),K(`click`,n,()=>void bn(B(t).node,B(t).end)),g(e,n)};p(O,e=>{B(t).sentenceIndex!==null&&e(k)}),f(E),f(s),f(a),U((e,r)=>{o=y(a,1,`path-snippet svelte-1byp7q8`,null,o,{"current-snippet":Q.active_node_id===B(t).node.id&&B(n)===B(Fe).length-1}),S(a,`data-path-snippet`,B(t).key),G(d,e),S(x,`aria-label`,r)},[()=>kt(B(t).node),()=>`Actions for ${kt(B(t).node)}`]),K(`click`,x,e=>Vt(e,B(t).node.id)),K(`click`,D,()=>void At(B(t).node)),g(e,a)}),f(a),f(t),g(e,t)},s=e=>{var t=fA(),n=R(t),r=R(n),i=X(R(r),2),a=R(i,!0);f(i),f(r);var o=X(r,2),s=e=>{var t=oA(),n=R(t),r=R(n,!0);f(n);var i=X(n,2),a=e=>{var t=aA();K(`click`,t,e=>yn(B(Ne),e.currentTarget)),g(e,t)};p(i,e=>{B(Ne).parent_id&&e(a)}),f(t),U(()=>{n.disabled=$.active,G(r,$.active?`Generating…`:`Generate another`)}),K(`click`,n,()=>void vn(B(Ne))),g(e,t)};p(o,e=>{B(Ne)&&e(s)}),f(n);var c=X(n,2),l=e=>{g(e,sA())},u=e=>{var t=dA();m(t,23,()=>B(Ie),e=>e.id,(e,t,n)=>{var r=uA();let i;var a=R(r),o=R(a),s=R(o);f(o);var c=X(o,2),l=R(c,!0);f(c);var u=X(c,2),d=e=>{g(e,cA())};p(u,e=>{Q.active_node_id===B(t).id&&e(d)});var m=X(u,2),h=e=>{g(e,lA())};p(m,e=>{B(t).starred&&e(h)});var _=X(m,2);f(a);var v=X(a,2),b=R(v,!0);f(v);var x=X(v,2),C=R(x),w=X(C,2),T=R(w,!0);f(w),f(x),f(r),U((e,a)=>{i=y(r,1,`option-card svelte-1byp7q8`,null,i,{"active-option":Q.active_node_id===B(t).id}),S(r,`data-option-node`,B(t).id),G(s,`Option ${B(n)+1}`),G(l,e),S(_,`aria-label`,`Actions for option ${B(n)+1}`),G(b,a),G(T,B(t).starred?`Remove saved`:`Save for later`)},[()=>kt(B(t)),()=>Dt(B(t))]),K(`click`,_,e=>Vt(e,B(t).id)),K(`click`,v,()=>void At(B(t))),K(`click`,C,()=>void At(B(t))),K(`click`,w,()=>void To(B(t).id,!B(t).starred)),g(e,r)}),f(t),g(e,t)};p(c,e=>{B(Ie).length===0?e(l):e(u,-1)}),f(t),U(e=>G(a,e),[()=>B(Ne)?Dt(B(Ne)):`Choose a point in the map to see its alternatives.`]),g(e,t)},l=e=>{var t=_A(),n=X(R(t),2),r=e=>{var t=pA(),n=R(t),r=R(n,!0);f(n);var i=X(n,2),a=R(i,!0);f(i),f(t),U(()=>{G(r,Aa.matchingIds===null?`Nothing saved yet`:`No starred messages match`),G(a,Aa.matchingIds===null?`Use a node’s menu and choose “Save this branch.”`:`Try different words or clear the search.`)}),g(e,t)},i=e=>{var t=gA();m(t,21,()=>B(Le),e=>e.node.id,(e,t)=>{var n=hA(),r=R(n),i=R(r),a=R(i,!0);f(i);var o=X(i,2),s=R(o,!0);f(o);var c=X(o,2),l=e=>{var n=mA(),r=R(n,!0);f(n),U(()=>G(r,B(t).node.notes)),g(e,n)};p(c,e=>{B(t).node.notes&&e(l)}),f(r);var u=X(r,2),d=R(u),m=X(d,2),h=X(m,2);f(u),f(n),U((e,r,i)=>{S(n,`data-saved-node`,B(t).node.id),G(a,e),G(s,r),S(h,`aria-label`,i)},[()=>kt(B(t).node),()=>Dt(B(t).node),()=>`Actions for ${kt(B(t).node)}`]),K(`click`,d,()=>void At(B(t).node)),K(`click`,m,()=>void To(B(t).node.id,!1)),K(`click`,h,e=>Vt(e,B(t).node.id)),g(e,n)}),f(t),g(e,t)};p(n,e=>{B(Le).length===0?e(r):e(i,-1)}),f(t),g(e,t)};p(n,e=>{B(D).length===0?e(r):wa.view===`map`?e(i,1):wa.view===`path`?e(o,2):wa.view===`options`?e(s,3):e(l,-1)}),g(e,t)};p(vr,e=>{Q.error?e(yr):wa.view!==`weave`&&e(br,1)}),f(Hn),a(Hn,e=>A(tn,e),()=>B(tn));var xr=X(Hn,2),Sr=e=>{let t=c(()=>Q.nodes.get(B(Pt).nodeId)),n=c(()=>(B(t)?.text??``).replace(/\s+/g,` `).trim()||`Empty turn`),r=c(()=>B(t)?.role_label?.trim()||B(t)?.role||`turn`),i=c(()=>B(t)?.recipe===null&&B(t)?.role!==`system`?B(Pt).nodeId:B(t)?.recipe===null?null:B(t)?.parent_id??null),o=c(()=>B(i)?(Q.children_of.get(B(i))??[]).filter(e=>Q.nodes.get(e)?.recipe!==null).length:0);var s=bA();let l;var u=R(s),m=R(u),_=R(m,!0);f(m);var v=X(m,2),b=R(v,!0);f(v),f(u);var x=X(u,2),C=R(x),T=X(C,2),E=X(T,2),D=X(E,2),O=X(D,2),k=X(O,2),j=e=>{var t=vA();K(`click`,t,kn),g(e,t)};p(k,e=>{(_i.info?.scene_mode??!1)&&(B(t)?.role===`user`||B(t)?.role===`assistant`)&&e(j)}),f(x);var M=X(x,2),N=R(M),P=R(N,!0);f(N);var F=X(N,2);f(M);var I=X(M,2),L=R(I),ee=e=>{var t=yA(),n=q(t),r=R(n,!0);f(n);var i=X(n,2),a=R(i,!0);f(i),U(e=>{G(r,Fa.nodeId===B(Pt).nodeId?`Remove comparison pin`:`Pin for comparison`),G(a,e)},[()=>B(d).has(B(Pt).nodeId)?`Remove from comparison`:`Add to comparison`]),K(`click`,n,Pn),K(`click`,i,Ln),g(e,t)};p(L,e=>{B(t)?.recipe!==null&&e(ee)});var te=X(L,2),z=X(te,2);f(I);var ne=X(I,2),V=R(ne);f(ne),f(s),a(s,e=>A(Ft,e),()=>B(Ft)),w(s,e=>Bt?.(e)),U((e,i)=>{l=y(s,1,`loom-menu svelte-1byp7q8`,null,l,{positioned:B(Lt)}),pe(s,`left:${B(It).x}px;top:${B(It).y}px`),G(_,B(r)),G(b,B(n)),G(P,B(t)?.starred?`Remove saved marker`:`Save this branch`),te.disabled=B(o)<2,S(te,`title`,B(o)<2?`Create at least two replies first`:``),V.disabled=e,S(V,`title`,i)},[()=>B(Pt).nodeId!==null&&yo(B(Pt).nodeId),()=>B(Pt).nodeId!==null&&yo(B(Pt).nodeId)?vo:``]),K(`keydown`,s,qt),K(`click`,C,An),K(`click`,T,En),K(`click`,E,zn),K(`click`,D,Dn),K(`click`,O,On),K(`click`,N,Mn),K(`click`,F,Nn),K(`click`,te,In),K(`click`,z,Fn),K(`click`,V,jn),h(2,s,()=>ct,tu),g(e,s)};p(xr,e=>{B(Pt).open&&B(Pt).nodeId&&e(Sr)});var Cr=X(xr,2),wr=t=>{var n=kA(),r=q(n),i=X(r,2),o=R(i),l=R(o),u=R(l),d=t=>{g(t,e(`Generate alternatives`))},m=t=>{g(t,e(`Edit turn`))},_=t=>{g(t,e(`Start a branch`))},v=t=>{g(t,e(`Delete branch`))},x=t=>{g(t,e(`Clear loom`))},C=t=>{g(t,e(`Add note`))},w=t=>{g(t,e(`Go to turn`))},E=t=>{g(t,e(`Search conversation`))},D=t=>{g(t,e(`Create guided variations`))},O=t=>{g(t,e(`Generate several replies`))};p(u,e=>{B(Xt).kind===`regenerate`?e(d):B(Xt).kind===`edit`?e(m,1):B(Xt).kind===`branch`?e(_,2):B(Xt).kind===`delete`?e(v,3):B(Xt).kind===`clear`?e(x,4):B(Xt).kind===`note`?e(C,5):B(Xt).kind===`navpicker`?e(w,6):B(Xt).kind===`search`?e(E,7):B(Xt).kind===`fanout`?e(D,8):B(Xt).kind===`regen_mode`&&e(O,9)}),f(l);var k=X(l,2);Be(R(k),{name:`dismiss`}),f(k),f(o);var M=X(o,2),N=R(M),P=e=>{var t=xA(),n=q(t);a($f(X(R(n),2),{get value(){return B(Xt).n},min:1,max:16,step:1,oninput:e=>{e!==null&&(B(Xt).n=e)},onkeydown:e=>{e.key===`Enter`&&(e.preventDefault(),pn())}}),e=>A(Zt,e,!0),()=>B(Zt)),f(n),T(2),g(e,t)},F=e=>{var t=SA(),n=X(q(t),2),r=R(n,!0);f(n),T(2),U(e=>G(r,e),[()=>Q.nodes.get(B(Xt).nodeId??``)?.text.slice(0,240)||`Empty turn`]),g(e,t)},I=e=>{var t=CA();T(2),g(e,t)},L=e=>{var t=wA();s(t),a(t,e=>A(Zt,e),()=>B(Zt)),U(()=>{S(t,`aria-label`,B(Xt).kind===`navpicker`?`Node ID prefix`:`Search node text`),S(t,`placeholder`,B(Xt).kind===`navpicker`?`node id prefix (or 'root')`:`search node text`)}),K(`keydown`,t,e=>{e.key===`Enter`&&(e.preventDefault(),pn())}),j(t,()=>B(Xt).text,e=>B(Xt).text=e),g(e,t)},ee=e=>{var t=TA(),n=q(t),r=X(R(n),2);s(r),a(r,e=>A(Zt,e),()=>B(Zt)),f(n);var i=X(n,2),o=X(R(i),2);s(o),f(i),T(2),K(`keydown`,r,e=>{e.key===`Enter`&&(e.preventDefault(),pn())}),j(r,()=>B(Xt).vector,e=>B(Xt).vector=e),K(`keydown`,o,e=>{e.key===`Enter`&&(e.preventDefault(),pn())}),j(o,()=>B(Xt).text,e=>B(Xt).text=e),g(e,t)},te=e=>{var t=EA(),n=q(t),r=X(R(n),2);{let e=c(()=>B(Xt).mode??`unsteered`);hu(r,{get value(){return B(e)},options:[{value:`unsteered`,label:`unsteered`},{value:`inverted`,label:`inverted`},{value:`reseed`,label:`reseed`},{value:`cool`,label:`cool`},{value:`hot`,label:`hot`}],onchange:e=>{B(Xt).mode=e},ariaLabel:`regen mode`})}f(n);var i=X(n,2);a($f(X(R(i),2),{get value(){return B(Xt).n},min:1,max:16,step:1,oninput:e=>{e!==null&&(B(Xt).n=e)},onkeydown:e=>{e.key===`Enter`&&(e.preventDefault(),pn())}}),e=>A(Zt,e,!0),()=>B(Zt)),f(i),T(2),g(e,t)},z=e=>{var t=DA(),n=q(t);_e(n),a(n,e=>A(Zt,e),()=>B(Zt)),T(2),U(()=>{S(n,`aria-label`,B(Xt).kind===`edit`?`Node text`:B(Xt).kind===`branch`?`Branch text`:`Node note`),S(n,`placeholder`,B(Xt).kind===`branch`?`(empty = branch from blank)`:``)}),K(`keydown`,n,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),pn()),e.key===`b`&&(e.metaKey||e.ctrlKey)&&e.preventDefault()}),j(n,()=>B(Xt).text,e=>B(Xt).text=e),g(e,t)};p(N,e=>{B(Xt).kind===`regenerate`?e(P):B(Xt).kind===`delete`?e(F,1):B(Xt).kind===`clear`?e(I,2):B(Xt).kind===`navpicker`||B(Xt).kind===`search`?e(L,3):B(Xt).kind===`fanout`?e(ee,4):B(Xt).kind===`regen_mode`?e(te,5):e(z,-1)});var ne=X(N,2),V=e=>{var t=OA(),n=R(t,!0);f(t),U(()=>G(n,B(Xt).error)),g(e,t)};p(ne,e=>{B(Xt).error&&e(V)}),f(M);var re=X(M,2),ie=R(re);a(ie,e=>A($t,e),()=>B($t));var ae=X(ie,2),oe=R(ae),H=t=>{g(t,e(`Delete branch`))},se=t=>{g(t,e(`Save and clear loom`))},ce=t=>{g(t,e(`Save`))},le=t=>{g(t,e(`Create branch`))},ue=t=>{g(t,e(`Go`))},de=t=>{g(t,e(`Search`))},fe=t=>{g(t,e(`Generate`))};p(oe,e=>{B(Xt).kind===`delete`?e(H):B(Xt).kind===`clear`?e(se,1):B(Xt).kind===`edit`||B(Xt).kind===`note`?e(ce,2):B(Xt).kind===`branch`?e(le,3):B(Xt).kind===`navpicker`?e(ue,4):B(Xt).kind===`search`?e(de,5):e(fe,-1)}),f(ae),f(re),f(i),a(i,e=>A(Qt,e),()=>B(Qt)),U((e,t)=>{y(ae,1,b(B(Xt).kind===`delete`||B(Xt).kind===`clear`?`danger`:`primary`),`svelte-1byp7q8`),ae.disabled=e,S(ae,`title`,t)},[()=>B(fn)||B(Xt).kind===`clear`&&$.active||B(Xt).kind===`delete`&&B(Xt).nodeId!==null&&yo(B(Xt).nodeId),()=>B(Xt).kind===`delete`&&B(Xt).nodeId!==null&&yo(B(Xt).nodeId)?vo:``]),K(`click`,r,cn),h(1,r,()=>ct,eu),h(2,r,()=>ct,tu),K(`keydown`,i,un),K(`click`,k,cn),K(`click`,ie,cn),K(`click`,ae,()=>void pn()),h(1,i,()=>lt,()=>iu(8)),h(2,i,()=>lt,()=>au(4)),g(t,n)};p(Cr,e=>{B(Xt).kind&&e(wr)}),U(()=>{S(Kn,`aria-current`,wa.view===`weave`?`page`:void 0),qn=y(Kn,1,`svelte-1byp7q8`,null,qn,{active:wa.view===`weave`}),S(Jn,`aria-current`,wa.view===`map`?`page`:void 0),Yn=y(Jn,1,`svelte-1byp7q8`,null,Yn,{active:wa.view===`map`}),S(Xn,`aria-current`,wa.view===`path`?`page`:void 0),Zn=y(Xn,1,`svelte-1byp7q8`,null,Zn,{active:wa.view===`path`}),G($n,`${B(Fe).length??``} ${B(Fe).length===1?`snippet`:`snippets`}`),S(er,`aria-current`,wa.view===`options`?`page`:void 0),tr=y(er,1,`svelte-1byp7q8`,null,tr,{active:wa.view===`options`}),G(rr,`${B(Ie).length??``} available`),S(ir,`aria-current`,wa.view===`saved`?`page`:void 0),ar=y(ir,1,`svelte-1byp7q8`,null,ar,{active:wa.view===`saved`}),G(sr,`${B(Le).length??``} ${B(Le).length===1?`point`:`points`}`),S(_r,`hidden`,wa.view!==`weave`||!!Q.error)}),K(`click`,Kn,()=>Et(`weave`)),K(`click`,Jn,()=>Et(`map`)),K(`click`,Xn,()=>Et(`path`)),K(`click`,er,()=>Et(`options`)),K(`click`,ir,()=>Et(`saved`)),g(r,Vn),W()}H([`click`,`input`,`keydown`,`pointerdown`,`pointermove`,`pointerup`]);var MA=V({open:!1}),NA=null;function PA(){!MA.open&&typeof document<`u`&&document.activeElement instanceof HTMLElement&&(NA=document.activeElement),MA.open=!0}function FA(){let e=NA;NA=null,MA.open=!1,queueMicrotask(()=>{e?.isConnected&&e.focus()})}function IA(){let e=[{label:`Concepts`,group:`Controls`,action:{kind:`tab`,tab:`subspace`},keywords:`pillar flat affine concept vector caa steer probe`},{label:`Moods and scales`,group:`Controls`,action:{kind:`tab`,tab:`manifold`},keywords:`pillar curved emotions months steer probe`},{label:`Model features`,group:`Controls`,action:{kind:`tab`,tab:`sae`},keywords:`pillar features sparse autoencoder`},{label:`Layer predictions`,group:`Controls`,action:{kind:`tab`,tab:`lens`},keywords:`pillar jacobian jlens workspace readout token`}];for(let t of PC)for(let n of t.tools)e.push({label:n.label.replace(/…$/,``),group:t.label.toLowerCase(),action:n.drawer===`local_runtime`||n.drawer===`health`?{kind:`controls`,section:`model`}:{kind:`drawer`,drawer:n.drawer},keywords:n.keywords});return e}var LA=I(`

                                  `),RA=I(``),zA=I(``),BA=I(`
                                  `,1);function VA(e,t){n(t,!0);let r=IA(),i=J(``),o=J(0),l=J(null),u=J(null),d=J(null),_=[`button:not([disabled]):not([tabindex='-1'])`,`[href]`,`input:not([disabled])`,`select:not([disabled])`,`textarea:not([disabled])`,`[tabindex]:not([tabindex="-1"])`].join(`,`),v=c(()=>{let e=B(i).trim().toLowerCase();if(!e)return r;let t=e.split(/\s+/);return r.filter(e=>{let n=`${e.label} ${e.group} ${e.keywords??``}`.toLowerCase();return t.every(e=>n.includes(e))}).sort((t,n)=>{let r=t=>{let n=t.label.toLowerCase();return n===e?0:n.startsWith(e)?1:n.includes(e)?2:(t.keywords??``).toLowerCase().includes(e)?3:4};return r(t)-r(n)})});Ce(()=>{MA.open&&(A(i,``),A(o,0),xe().then(()=>B(l)?.focus()))}),Ce(()=>{B(o)>=B(v).length&&A(o,Math.max(0,B(v).length-1),!0)}),Ce(()=>{B(o),B(u)?.querySelector(`[data-selected="true"]`)?.scrollIntoView({block:`nearest`})});function y(e){switch(FA(),e.action.kind){case`drawer`:{let t=e.action.drawer;queueMicrotask(()=>rt(t))}break;case`tab`:ha(e.action.tab),window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`controls`}));break;case`controls`:window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:{view:`controls`,section:e.action.section}}));break}}function b(e){if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),FA();return}if(e.key===`ArrowDown`){e.preventDefault(),A(o,Math.min(B(v).length-1,B(o)+1),!0);return}if(e.key===`ArrowUp`){e.preventDefault(),A(o,Math.max(0,B(o)-1),!0);return}if(e.key===`Enter`){e.preventDefault();let t=B(v)[B(o)];t&&y(t)}}function x(e){if(e.key!==`Tab`||!B(d))return;let t=[...B(d).querySelectorAll(_)].filter(e=>e.offsetParent!==null);if(t.length===0){e.preventDefault(),B(d).focus();return}let n=t[0],r=t[t.length-1];e.shiftKey&&(document.activeElement===n||document.activeElement===B(d))?(e.preventDefault(),r.focus()):!e.shiftKey&&document.activeElement===r&&(e.preventDefault(),n.focus())}let C={subspace:`var(--pillar-subspace)`,manifold:`var(--pillar-manifold)`,sae:`var(--pillar-sae)`,lens:`var(--pillar-lens)`};function w(e){return e.action.kind===`tab`?C[e.action.tab]:null}var E=L(),D=q(E),O=e=>{var t=BA(),n=q(t),r=X(n,2),_=R(r),C=R(_);Be(C,{name:`search`,class:`glass-icon`});var E=X(C,2);s(E),a(E,e=>A(l,e),()=>B(l)),T(2),f(_);var D=X(_,2),O=R(D),k=e=>{var t=LA(),n=R(t);f(t),U(e=>G(n,`No commands match “${e??``}”. Edit or clear the search.`),[()=>B(i).trim()]),g(e,t)},M=e=>{var t=L();m(q(t),19,()=>B(v),e=>e.group+e.label,(e,t,n)=>{let r=c(()=>w(B(t)));var i=zA(),a=R(i),s=e=>{var t=RA();let n;U(()=>n=pe(t,``,n,{background:B(r)})),g(e,t)};p(a,e=>{B(r)&&e(s)});var l=X(a,2),u=R(l,!0);f(l);var d=X(l,2),m=R(d,!0);f(d),f(i),U(()=>{S(i,`id`,`command-palette-option-${B(n)}`),S(i,`aria-selected`,B(n)===B(o)),S(i,`data-selected`,B(n)===B(o)),G(u,B(t).label),G(m,B(t).group)}),K(`click`,i,()=>y(B(t))),K(`mousemove`,i,()=>A(o,B(n),!0)),g(e,i)}),g(e,t)};p(O,e=>{B(v).length===0?e(k):e(M,-1)}),f(D),a(D,e=>A(u,e),()=>B(u)),f(r),a(r,e=>A(d,e),()=>B(d)),U(()=>S(E,`aria-activedescendant`,B(v).length>0?`command-palette-option-${B(o)}`:void 0)),K(`click`,n,function(...e){FA?.apply(this,e)}),K(`keydown`,n,e=>{(e.key===`Enter`||e.key===` `)&&FA()}),h(1,n,()=>ct,eu),h(2,n,()=>ct,tu),K(`keydown`,r,x),ye(`introstart`,r,e=>{e.currentTarget.inert=!1}),ye(`outrostart`,r,e=>{e.currentTarget.inert=!0}),K(`keydown`,E,b),j(E,()=>B(i),e=>A(i,e)),h(1,r,()=>lt,iu),h(2,r,()=>lt,au),g(e,t)};p(D,e=>{MA.open&&e(O)}),g(e,E),W()}H([`click`,`keydown`,`mousemove`]);var HA=`/assets/eleutherai.png`,UA=`/assets/openai.png`,WA=I(``),GA=I(``),KA=I(``);function qA(e,t){n(t,!0);let r=Y(t,`size`,3,24),i=c(()=>t.modelId.toLowerCase().split(`/`).at(-1)??``),a=c(()=>B(i).startsWith(`qwen`)?`qwen`:B(i).startsWith(`gemma`)?`gemma`:B(i).startsWith(`gpt2`)||B(i).startsWith(`gpt-2`)?`openai`:B(i).startsWith(`pythia`)?`eleutherai`:null);var o=L(),s=q(o),l=e=>{var t=WA();let n;U(()=>n=pe(t,``,n,{"--provider-logo-size":`${r()}px`})),g(e,t)},u=e=>{var t=GA();let n;U(()=>n=pe(t,``,n,{"--provider-logo-size":`${r()}px`})),g(e,t)},d=e=>{var t=KA();let n;var i=R(t);let o;f(t),U(()=>{S(t,`data-provider`,B(a)),n=pe(t,``,n,{"--provider-logo-size":`${r()}px`}),o=pe(i,``,o,{"mask-image":`url("${B(a)===`openai`?UA:HA}")`})}),g(e,t)};p(s,e=>{B(a)===`qwen`?e(l):B(a)===`gemma`?e(u,1):B(a)&&e(d,2)}),g(e,o),W()}var JA=I(` `);function YA(e,t){n(t,!0);let r=c(()=>_i.info?.model_id??``),i=c(()=>B(r).split(`/`).at(-1)??B(r)),a=c(()=>{let e=B(i).match(/^(gemma|qwen)-?(\d+(?:\.\d+)?)-(\d+(?:\.\d+)?b)(?:-|$)/i);return e?`${e[1].toLowerCase()===`gemma`?`Gemma ${e[2]}`:`Qwen${e[2]}`} ${e[3].toUpperCase()}`:B(i)||`No model open`});var o=JA(),s=R(o),l=R(s);qA(l,{get modelId(){return B(i)}});var u=X(l,2),d=R(u,!0),m=X(d),h=e=>{Cm(e,{})};p(m,e=>{_i.info?.is_base_model&&e(h)}),f(u),f(s);var _=X(s,2),v=R(_);f(_),f(o),U(()=>{G(d,B(a)),G(v,`Drowse 0.1`)}),g(e,o),W()}var XA=I(` `),ZA=I(`
                                  `),QA=I(`
                                  `);function $A(e,t){n(t,!0);let r=new Map;function i(e){let t=r.get(e);t&&t.handle!==null&&clearTimeout(t.handle),r.delete(e),Xe(e)}function a(e,t){if(t.remaining<=0){i(e);return}t.startedAt=performance.now(),t.paused=!1,t.handle=setTimeout(()=>i(e),t.remaining)}function o(e){let t=r.get(e);!t||t.paused||t.handle===null||(clearTimeout(t.handle),t.handle=null,t.remaining=Math.max(0,t.remaining-(performance.now()-t.startedAt)),t.paused=!0)}function s(e){let t=r.get(e);!t||!t.paused||a(e,t)}Ce(()=>{for(let e of qe.entries){if(e.ttlMs===null||r.has(e.id))continue;let t={handle:null,remaining:e.ttlMs,startedAt:0,paused:!1};r.set(e.id,t),a(e.id,t)}let e=new Set(qe.entries.map(e=>e.id));for(let[t,n]of r)e.has(t)||(n.handle!==null&&clearTimeout(n.handle),r.delete(t))}),Pe(()=>{for(let e of r.values())e.handle!==null&&clearTimeout(e.handle);r.clear()});var c=L(),l=q(c),u=e=>{var t=QA();m(t,21,()=>qe.entries,e=>e.id,(e,t)=>{var n=ZA();let r;var a=R(n),c=R(a),l=R(c,!0);f(c);var u=X(c,2),d=e=>{var n=XA(),r=R(n,!0);f(n),U(()=>G(r,B(t).detail)),g(e,n)};p(u,e=>{B(t).detail&&e(d)}),f(a);var m=X(a,2);Be(R(m),{name:`dismiss`}),f(m),f(n),U(()=>{r=y(n,1,`toast svelte-3r7513`,null,r,{warning:B(t).kind===`warning`,error:B(t).kind===`error`}),S(n,`role`,B(t).kind===`error`?`alert`:`status`),S(n,`aria-live`,B(t).kind===`error`?`assertive`:`polite`),G(l,B(t).message),S(m,`aria-label`,`Dismiss notification: ${B(t).message}`)}),ye(`pointerenter`,n,()=>o(B(t).id)),ye(`pointerleave`,n,()=>s(B(t).id)),K(`focusin`,n,()=>o(B(t).id)),K(`focusout`,n,e=>{e.currentTarget.contains(e.relatedTarget)||s(B(t).id)}),K(`click`,m,()=>i(B(t).id)),h(1,n,()=>lt,()=>({y:-8,duration:$l(220),easing:Zl})),h(2,n,()=>lt,()=>({y:-4,duration:$l(140),easing:Xl})),g(e,n)}),f(t),g(e,t)};p(l,e=>{qe.entries.length>0&&e(u)}),g(e,c),W()}H([`focusin`,`focusout`,`click`]);var ej=I(`
                                  `),tj=I(`Chats Models Credits Contribute`,1),nj=I(`
                                  `,1),rj=I(`
                                  `);function ij(e,t){let n=Y(t,`siteNavigation`,3,!0),i=Y(t,`homeHref`,3,`/`),a=Y(t,`compact`,3,!1),o=typeof __DROWSE_SOURCE_URL__==`string`?__DROWSE_SOURCE_URL__:`https://github.com/a9lim/polythetic`;function s(e,t){!t||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),t())}var c=rj();let l;var u=R(c),d=R(u);r(d,()=>t.leading??Ie);var m=X(d,2);f(u);var h=X(u,2),_=e=>{var n=ej();r(R(n),()=>t.actions??Ie),f(n),g(e,n)},v=e=>{var r=nj(),i=q(r),a=R(i),c=e=>{var n=tj(),r=q(n),i=X(r,2),a=X(i,2),c=X(a,2);U(()=>{S(r,`aria-current`,t.current===`chats`?`page`:void 0),S(i,`aria-current`,t.current===`models`?`page`:void 0),S(a,`aria-current`,t.current===`credits`?`page`:void 0),S(c,`href`,o)}),K(`click`,r,e=>s(e,t.onChats)),K(`click`,i,e=>s(e,t.onModels)),g(e,n)};p(a,e=>{n()&&e(c)}),f(i);var l=X(i,2);fp(R(l),{}),f(l),g(e,r)};p(h,e=>{t.current===`workbench`?e(_):e(v,-1)}),f(c),U(()=>{l=y(c,1,`page-header svelte-2fr32i`,null,l,{compact:a(),workbench:t.current===`workbench`}),S(m,`href`,i()),S(m,`aria-current`,t.current===`home`?`page`:void 0)}),g(e,c)}H([`click`]);var aj=I(``),oj=I(``),sj=I(``),cj=I(``),lj=I(``),uj=I(` `,1);function dj(e,t){let r=E();n(t,!0);let i=du(),o=typeof __DROWSE_SOURCE_URL__==`string`?__DROWSE_SOURCE_URL__:`https://github.com/a9lim/polythetic`,s=J(!1),c=J(null),l=J(null),u=J(``);function d(){if(!B(c)||!B(l))return;let e=B(c).getBoundingClientRect(),t=window.visualViewport,n=t?.offsetLeft??0,r=t?.offsetTop??0,i=t?.width??innerWidth,a=t?.height??innerHeight,o=Math.min(288,i-32),s=Math.max(n+16,Math.min(e.right-o,n+i-o-16)),d=Math.max(r+16,Math.min(e.bottom+8,r+a-64));A(u,`left:${s}px;top:${d}px;width:${o}px;max-height:${r+a-d-16}px;`)}async function m(){A(s,!0),i.mount(),await xe(),!(!B(s)||!B(l))&&(B(l).showPopover(),d(),await xe(),!(!B(s)||!B(l))&&(i.show(B(l)),B(l).querySelector(`button:not(:disabled), a`)?.focus({preventScroll:!0})))}function h(e=!1){A(s,!1),i.close(B(l)),e&&B(c)?.focus({preventScroll:!0})}function _(e){h(!0),e()}function v(e){e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),h(!0))}function y(e){B(s)&&!B(l)?.contains(e.target)&&!B(c)?.contains(e.target)&&h()}ne(()=>{let e=window.visualViewport;return e?.addEventListener(`resize`,d),e?.addEventListener(`scroll`,d),()=>{e?.removeEventListener(`resize`,d),e?.removeEventListener(`scroll`,d),i.destroy()}});var b=uj();ye(`pointerdown`,ce,y),ye(`resize`,ce,d);var x=q(b);Be(X(R(x)),{name:`down`,size:14}),f(x),a(x,e=>A(c,e),()=>B(c));var C=X(x,2),w=e=>{var n=lj(),i=R(n),d=R(i);Be(R(d),{name:`chats`,size:18}),T(),f(d);var m=X(d,2),y=e=>{var n=aj();Be(R(n),{name:`models`,size:18}),T(),f(n),U(()=>n.disabled=t.busy),K(`click`,n,()=>_(t.onModels)),g(e,n)};p(m,e=>{t.hosted&&e(y)}),f(i);var b=X(i,2),x=R(b),C=e=>{var n=oj(),r=R(n);Be(r,{name:`controls`,size:18});var i=X(r);f(n),U(()=>{S(n,`aria-pressed`,t.toolsVisible),G(i,`${t.toolsVisible?`Hide`:`Show`} ${t.toolsLabel??``}`)}),K(`click`,n,()=>_(t.onToggleTools)),g(e,n)};p(x,e=>{t.toolsLabel&&e(C)});var w=X(x,2),E=e=>{var n=sj();Be(R(n),{name:`download`,size:18}),T(),f(n),U(()=>n.disabled=t.generating),K(`click`,n,()=>_(t.onDownload)),g(e,n)};p(w,e=>{t.hasChat&&e(E)});var D=X(w,2);Be(R(D),{name:`search`,size:18}),T(),f(D);var O=X(D,2);Be(R(O),{name:`appearance`,size:16}),T(),f(O);var k=X(O,2);Be(R(k),{name:`help`,size:18}),T(),f(k),f(b);var j=X(b,2);fp(X(R(j)),{}),f(j);var M=X(j,2),N=e=>{var t=cj(),n=X(R(t));f(t),U(()=>S(n,`href`,o)),g(e,t)};p(M,e=>{t.hosted&&e(N)}),f(n),a(n,e=>A(l,e),()=>B(l)),U(()=>{S(n,`id`,r),pe(n,B(u)),d.disabled=t.busy}),K(`keydown`,n,v),K(`focusout`,n,e=>{B(s)&&e.relatedTarget instanceof Node&&!B(l)?.contains(e.relatedTarget)&&e.relatedTarget!==B(c)&&h()}),K(`click`,d,()=>_(t.onChats)),K(`click`,D,()=>_(t.onAllTools)),K(`click`,O,()=>_(()=>rt(`appearance`))),K(`click`,k,()=>_(t.onHelp)),g(e,n)};p(C,e=>{i.mounted&&e(w)}),U(()=>{S(x,`aria-expanded`,B(s)),S(x,`aria-controls`,r)}),K(`click`,x,()=>B(s)?h():void m()),K(`keydown`,x,v),g(e,b),W()}H([`click`,`keydown`,`focusout`]);var fj=new Set([`checking`,`downloading`,`loading`,`working`,`thinking`,`analyzing`,`loom-working`,`saving`,`training`]),pj=1e3/24;function mj(e,t=0,n=`light`,r=!1,i){let a=i??(n===`dark`?`#c5b3ff`:`#5b3fbf`),o=n===`dark`?`#141822`:`#ffffff`;t=(t%48+48)%48;let s=(.75+.25*Math.cos(t*Math.PI*2/48)).toFixed(3),c=Math.sin(t*Math.PI*2/48)*3,l={checking:``,downloading:``,loading:``,working:``,thinking:``,analyzing:``,"loom-working":``,saving:``,training:``};if(!fj.has(e)){let t=e===`chat-settings`?`settings`:e;Le[t]&&(l[e]=`${Le[t].map(e=>``).join(``)}`)}if(!(e in l))throw Error(`Unknown tab icon: ${e}`);return`${r?``:``}${l[e]}`}var hj=48,gj={home:``,credits:`Credits`,chats:`Your chats`,models:`Choose a model`,checking:`Checking this device`,ready:`Device ready`,unsupported:`Device not supported`,downloading:`Downloading files`,loading:`Loading model`,working:`Generating reply`,loom:`Loom`,analyzing:`Computing insights`,"loom-working":`Loom · Generating reply`,paused:`Download paused`,error:`Action needed`,offline:`Download waiting for connection`,conversation:``,controls:`Response settings`,"chat-settings":`Chat settings`,tokens:`Token details`,comparison:`Compare replies`,thinking:`Thinking`,saving:`Saving chat`,training:`Building model tools`};function _j(e){return gj[e]?`${gj[e]} · Drowse`:`Drowse`}function vj(e){return e.boot===`failed`||e.saveStatus===`error`?`error`:e.boot===`loading`?`loading`:e.runtime?e.runtime:e.active?e.replay?`analyzing`:e.thinking?`thinking`:e.view===`branches`?`loom-working`:`working`:e.drawer===`token_drilldown`||e.drawer===`probe_inspector`?`tokens`:e.drawer===`compare`||e.drawer===`node_compare`||e.drawer===`correlation`?`comparison`:e.drawer===`load_conversation`?`chats`:e.drawer===`save_conversation`?e.saveStatus===`saving`?`saving`:`chat-settings`:e.drawer===`manifold_builder`||e.drawer===`advanced_sampling`||e.drawer===`system_prompt`?`controls`:e.view===`branches`?`loom`:e.view===`controls`?e.section===`model`?`models`:e.section===`chat`?`chat-settings`:`controls`:`conversation`}function yj(e,t=0,n=`light`){return`/icons/tab-${e}-${n}${fj.has(e)?`-${(t%hj+hj)%hj}`:``}.png`}var bj;function xj(){bj?.();let e=!1,t=document.querySelector(`link[rel="icon"]`),n=t??document.createElement(`link`),r={href:n.getAttribute(`href`),type:n.getAttribute(`type`),sizes:n.getAttribute(`sizes`)};n.rel=`icon`,n.type=`image/png`,n.sizes.value=`96x96`,t||document.head.append(n);let i=matchMedia(`(prefers-reduced-motion: reduce)`),a=matchMedia(`(prefers-color-scheme: dark)`),o=()=>{let e=document.documentElement.dataset.theme;return e===`light`||e===`dark`?e:a.matches?`dark`:`light`},s=`home`,c,l=0,u=0,d=new Map,f=(e,t)=>{let n=mj(s,l,t,!1,e),r=d.get(n);if(r)return r;let i=new Promise((e,t)=>{let r=new Image;r.onload=()=>{let n=document.createElement(`canvas`);n.width=n.height=96;let i=n.getContext(`2d`);if(!i){t(Error(`Favicon canvas unavailable`));return}i.drawImage(r,0,0,96,96),e(n.toDataURL(`image/png`))},r.onerror=()=>t(Error(`Favicon artwork unavailable`)),r.src=`data:image/svg+xml,${encodeURIComponent(n)}`});return d.size>=hj*3&&d.delete(d.keys().next().value),d.set(n,i),i},p=()=>{if(e)return;let t=++u,r=o(),a=document.documentElement.dataset.chatAccent,c=Rs(Ls(a)?a:`purple`),d=`${yj(s,l,r)}?v=fluent`;c.id===`purple`&&(!fj.has(s)||i.matches||document.hidden)?n.setAttribute(`href`,d):f(c[r],r).then(r=>{!e&&t===u&&n.setAttribute(`href`,r)}).catch(()=>{!e&&t===u&&n.setAttribute(`href`,d)}),n.dataset.state=s,n.dataset.theme=r,n.dataset.accent=c.id},m=()=>{if(clearInterval(c),c=void 0,l=0,p(),!i.matches&&!document.hidden&&yj(s,1)!==yj(s)){let e=performance.now();c=setInterval(()=>{let t=Math.floor((performance.now()-e)/pj)%hj;t!==l&&(l=t,p())},pj)}};i.addEventListener(`change`,m),document.addEventListener(`visibilitychange`,m),a.addEventListener(`change`,p);let h=new MutationObserver(p);h.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-theme`,`data-chat-accent`]});let g=()=>{if(!e){if(e=!0,clearInterval(c),d.clear(),i.removeEventListener(`change`,m),document.removeEventListener(`visibilitychange`,m),a.removeEventListener(`change`,p),h.disconnect(),delete n.dataset.state,delete n.dataset.theme,delete n.dataset.accent,!t)n.remove();else for(let e of[`href`,`type`,`sizes`])r[e]===null?n.removeAttribute(e):n.setAttribute(e,r[e]);bj===g&&(bj=void 0)}};return bj=g,{update(t){!e&&(t!==s||!n.dataset.state)&&(s=t,m())},dispose:g}}function Sj(e,t){n(t,!0);let r=Y(t,`state`,3,`home`),i=J(null);ne(()=>{let e=xj();return A(i,e,!0),()=>e.dispose()}),Ce(()=>{B(i)?.update(r())}),d(`w8udf3`,e=>{ge(e=>{ue.title=e??``},[()=>t.title??_j(r())])}),W()}var Cj=I(``);function wj(t,r){n(r,!0);let i=null,a=Promise.resolve(),o=!1;async function s(){if(i!==null&&clearTimeout(i),i=null,!Q.loaded||$.active)return a;let e;try{e=n_()}catch(e){throw wc.status=`error`,wc.error=je(e,`The chat could not be autosaved. Keep this page open and download a backup.`),e}let t=wc.activeId,n=_i.info?.is_base_model?`base`:`chat`;wc.status=`saving`;let r=a.catch(()=>void 0).then(async()=>{try{let r=await Cc.autosave(e,t,n);if(o||Q.root_id!==e.tree.root_id||wc.activeId!==t)return;wc.activeId=r?.id??null,wc.avatarSeed=r?.avatarSeed??null,wc.accent=r?.accent??`purple`,wc.status=r?`saved`:`idle`,wc.error=null}catch(e){throw o||(wc.status=`error`,wc.error=je(e,`Autosave failed. Keep this page open and use Save chat to download a backup.`)),e}});return a=r,r}Ce(()=>{Q.rev,Q.loaded,$.active,i!==null&&clearTimeout(i),i=null,!(!Q.loaded||$.active||Ze.open===`load_conversation`)&&(JSON.stringify(xi),JSON.stringify([...nr.entries]),nr.subspaceAlong,nr.customExpression,JSON.stringify(Hr.active.map(e=>Hr.entries.get(e)?.request)),Hr.sortMode,JSON.stringify(fi),De(()=>{wc.status=`pending`}),i=setTimeout(()=>{s().catch(()=>void 0)},600))}),ne(()=>{o=!1;let e=Ec(s),t=()=>{document.hidden&&s().catch(()=>void 0)};return document.addEventListener(`visibilitychange`,t),()=>{s().catch(()=>void 0),o=!0,e(),document.removeEventListener(`visibilitychange`,t)}});var c=L(),l=q(c),u=t=>{var n=Cj(),r=R(n),i=R(r,!0);f(r);var a=X(r,2);Du(a,{onclick:()=>void s().catch(()=>void 0),children:(t,n)=>{T(),g(t,e(`Retry autosave`))},$$slots:{default:!0}}),Du(X(a,2),{variant:`solid`,onclick:()=>rt(`save_conversation`),children:(t,n)=>{T(),g(t,e(`Save chat / backup`))},$$slots:{default:!0}}),f(n),U(()=>G(i,wc.error)),g(t,n)};p(l,e=>{wc.status===`error`&&e(u)}),g(t,c),W()}function Tj(e,t){n(t,!0),Ce(()=>{let e=Rs(wc.accent);if(e.id===`purple`)return;let t=document.documentElement;return t.dataset.chatAccent=e.id,t.style.setProperty(`--chat-accent-dark`,e.dark),t.style.setProperty(`--chat-accent-light`,e.light),()=>{delete t.dataset.chatAccent,t.style.removeProperty(`--chat-accent-dark`),t.style.removeProperty(`--chat-accent-light`)}}),W()}var Ej=`drowse.pending-conversation.v1`;function Dj(e=kj(`sessionStorage`)){if(!e)return null;try{let t=be(e,Ej);if(!t)return null;let n=JSON.parse(t);return n.version!==1||typeof n.id!=`string`||!n.id.trim()||typeof n.modelId!=`string`||!n.modelId.trim()?null:n}catch{return null}}function Oj(e=kj(`sessionStorage`)){try{e&&Ee(e,Ej)}catch{}}function kj(e){if(!(typeof window>`u`))try{return window[e]}catch{return}}var Aj=I(`start drowse serve`,1),jj=I(``),Mj=I(``),Nj=I(``),Pj=I(` `,1),Fj=I(``),Ij=I(`
                                  `,1),Lj=I(`
                                  Opening workbench…
                                  `),Rj=I(`

                                  See every path

                                  `),zj=I(` `,1);function Bj(t,r){n(r,!0);let i=J(!1);async function o(e=`chats`){if(!B(i)){if(!r.onhome){rt(`load_conversation`);return}if(!($.active&&!window.confirm(`Stop the current reply and ${e===`models`?`open Models`:`return to Your chats`}? Your conversation will be saved on this device.`))){A(i,!0);try{await(e===`models`&&r.onmodels?r.onmodels():r.onhome())}catch(t){Z(je(t,`${e===`models`?`Models`:`Your chats`} could not open. Stay here and try again.`),{kind:`error`})}finally{A(i,!1)}}}}let s=J(`loading`);Ce(()=>{if(B(s)===`ready`)return Uo()});let l=J(null),u=J(null);ne(()=>re()?.subscribe(e=>{A(u,e.lifecycle===`failed`||e.generation.phase===`failed`?`error`:e.lifecycle===`loading`?`loading`:e.lifecycle===`checking`?`checking`:e.fitting.phase===`running`?`training`:e.download.phase===`running`?`downloading`:null,!0)}));let d=J(null),m=J(!0),_=c(()=>$e.visible),v=c(()=>Ze.open!==null),b=J(`conversation`),x=J(!1),C=J(!1),E=c(()=>B(b)===`branches`?B(C):B(x));function D(){B(b)===`branches`?A(C,!B(C)):A(x,!B(x))}let O=J(`response`),k=c(()=>Ko.pendingIndex===null?null:Ko.turns[Ko.pendingIndex]),j=c(()=>vj({boot:B(s),runtime:B(u),active:$.active,replay:$.replay!==null&&$.replay!==void 0,thinking:!!(B(k)?.thinkingTokens?.length&&!B(k)?.tokens?.length),view:B(b),section:B(O),drawer:Ze.open,saveStatus:wc.status})),M=null,N=null,P=c(()=>B(b)===`conversation`?`1`:B(b)===`branches`?`2`:`3`);function F(e){let t=e.detail;if(typeof t==`object`){(t.section===`response`||t.section===`model`||t.section===`chat`)&&A(O,t.section,!0),A(b,t.view,!0);return}(t===`conversation`||t===`branches`||t===`controls`)&&A(b,t,!0)}let I=[`button:not([disabled])`,`[href]`,`input:not([disabled])`,`select:not([disabled])`,`textarea:not([disabled])`,`[tabindex]:not([tabindex="-1"])`].join(`,`);function L(e){e?.focus({preventScroll:!0})}Ce(()=>{let e=Ze.open,t=B(v);if(e!==null&&N===null&&(M=document.activeElement instanceof HTMLElement?document.activeElement:null),t)xe().then(()=>{let e=B(d)?.querySelector(I);L(e??B(d))});else if(e===null&&N!==null){let e=M;xe().then(()=>{e?.isConnected&&L(e)}),M=null}N=e});function ee(e){if(e.key!==`Tab`||!B(d))return;let t=[...B(d).querySelectorAll(I)].filter(e=>e.offsetParent!==null);if(t.length===0){e.preventDefault(),L(B(d));return}let n=t[0],r=t[t.length-1];e.shiftKey&&(document.activeElement===n||document.activeElement===B(d))?(e.preventDefault(),L(r)):!e.shiftKey&&(document.activeElement===r||document.activeElement===B(d))&&(e.preventDefault(),L(n))}function te(e){return{advanced_sampling:`Sampling settings`,cast:`Role settings`,compare:`Compare controls by layer`,correlation:`Compare saved readings`,health:`Model health`,appearance:`Appearance`,help:`Help and shortcuts`,load_conversation:`Saved chats`,local_runtime:`Model settings`,manifold_builder:`Create a concept or scale`,surface_geometry:`Surface geometry`,manifold_merge:`Combine response controls`,manifold_pack:`Downloaded response controls`,manifolds:`Add manifold`,node_compare:`Compare conversation branches`,probe_inspector:`Reading details`,save_conversation:`Save chat`,download_chat:`Download chat`,session_admin:`API access`,subspace:`Add subspace`,system_prompt:`System prompt`,template_lab:`Prompt template lab`,token_drilldown:`Generated word details`,transcript:`Conversation transcript`}[e]??e.replaceAll(`_`,` `)}async function z(){A(s,`loading`),A(l,null);try{await gs(),$e.params=null,wc.activeId=null,wc.avatarSeed=null,wc.accent=`purple`,wc.status=`idle`;let e=Dj();if(e){let t=await Cc.get(e.id);if(t.modelId!==e.modelId)throw Error(`The saved chat changed before it could be opened. Return to Chats and try again.`);await r_(t.snapshot),wc.activeId=t.id,wc.avatarSeed=t.avatarSeed,wc.accent=t.accent??`purple`,Oj()}else if(St.mode===`browser`&&_i.info){let e=mo(),t=e&&await Cc.findForTree(_i.info.model_id,e.root_id);t&&(await r_({...t.snapshot,tree:e}),wc.activeId=t.id,wc.avatarSeed=t.avatarSeed,wc.accent=t.accent??`purple`)}try{await Wa()}catch{}A(s,`ready`)}catch(e){A(l,je(e,`Unable to open the workbench. Reopen the model and try again.`),!0),A(s,`failed`)}}ne(()=>(z(),window.addEventListener(`drowse:workspace`,F),()=>window.removeEventListener(`drowse:workspace`,F)));async function V(e){if(e.key===`Escape`){if(MA.open){FA(),e.preventDefault();return}if(wa.modalRequest.kind!==null)return;if(Ze.open!==null){it(),e.preventDefault();return}if($.active){no(),e.preventDefault();return}}if(!(e.ctrlKey||e.metaKey)||e.shiftKey)return;let t=e.key.toLowerCase();if(t===`r`){e.preventDefault();let t=Q.active_node_id;if(!t)return;Q.nodes.get(t)?.recipe?await Oo(1):Va(`regenerate`,{nodeId:t,n:1});return}if(t===`e`){e.preventDefault();let t=Q.active_node_id;if(!t)return;Va(`edit`,{nodeId:t,text:Q.nodes.get(t)?.text??``});return}if(t===`b`){e.preventDefault();let t=Q.active_node_id;if(!t)return;Va(`branch`,{nodeId:t,text:Q.nodes.get(t)?.text??``});return}if(t===`n`){e.preventDefault(),Va(`navpicker`,{nodeId:Q.active_node_id});return}if(t===`d`){e.preventDefault();let t=Q.active_node_id;if(!t)return;Va(`delete`,{nodeId:t});return}}var ie=zj();ye(`keydown`,ce,V);var ae=q(ie),oe=e=>{Tj(e,{})};p(ae,e=>{B(s)===`ready`&&e(oe)});var H=X(ae,2);Sj(H,{get state(){return B(j)}});var se=X(H,2),le=t=>{var n=Mj(),r=R(n),i=R(r,!0);f(r);var a=X(r,2),o=R(a,!0);f(a);var s=X(a,2),c=R(s),u=e=>{var t=Aj();T(),g(e,t)},d=t=>{g(t,e(`retry the local model, or return to device setup`))};p(c,e=>{St.mode===`http`?e(u):e(d,-1)}),f(s);var m=X(s,2),h=X(m,2),_=e=>{var t=jj();K(`click`,t,()=>window.location.assign(`/app`)),g(e,t)};p(h,e=>{St.mode!==`http`&&e(_)}),f(n),U(()=>{G(i,St.mode===`http`?`offline`:`runtime unavailable`),G(o,B(l))}),K(`click`,m,z),g(t,n)},ue=e=>{var t=Rj();let n;var r=X(R(t),2),l=R(r),u=e=>{wj(e,{})};p(l,e=>{B(s)===`ready`&&e(u)}),f(r);var k=X(r,2);let j;var M=R(k);Xf(M,{});var N=X(M,2),F=R(N);{let e=e=>{var t=Nj();He(R(t),{}),f(t),U(()=>{S(t,`aria-expanded`,B(m)),S(t,`aria-label`,B(m)?`Hide left sidebar`:`Show left sidebar`),S(t,`title`,B(m)?`Hide left sidebar`:`Show left sidebar`)}),K(`click`,t,()=>A(m,!B(m))),g(e,t)},t=e=>{var t=Pj(),n=q(t);{let e=c(()=>St.mode!==`http`),t=c(()=>Q.nodes.size>1),r=c(()=>B(b)===`controls`?null:B(b)===`branches`?`Loom tools`:`chat tools`);dj(n,{get hosted(){return B(e)},get busy(){return B(i)},get hasChat(){return B(t)},get generating(){return $.active},get toolsLabel(){return B(r)},get toolsVisible(){return B(E)},onToggleTools:D,onChats:()=>void o(),onModels:()=>void o(`models`),onDownload:()=>rt(`download_chat`),get onAllTools(){return PA},onHelp:()=>rt(`help`)})}var r=X(n,2);He(R(r),{side:`right`}),f(r),U(()=>{S(r,`aria-expanded`,B(_)),S(r,`aria-label`,B(_)?`Hide right sidebar`:`Show right sidebar`),S(r,`title`,B(_)?`Hide right sidebar`:`Show right sidebar`)}),K(`click`,r,()=>B(_)?tt():et()),g(e,t)},n=c(()=>St.mode!==`http`),r=c(()=>St.mode===`http`?`#workspace-main`:`/`);ij(F,{current:`workbench`,compact:!0,get siteNavigation(){return B(n)},get homeHref(){return B(r)},leading:e,actions:t,$$slots:{leading:!0,actions:!0}})}f(N);var I=X(N,2),L=R(I),z=R(L),ne=R(z);let V;var re=R(ne);let ie;var ae=R(re);Be(ae,{name:`conversation`,size:16});var oe=X(ae,2),H=R(oe),se=R(H,!0);f(H),T(2),f(oe);var ce=X(oe,2),le=R(ce,!0);f(ce),f(re);var ue=X(re,2),de=R(ue);let fe;Be(R(de),{name:`controls`,size:16}),T(),f(de),f(ue),f(ne);var pe=X(ne,2);let me;Be(R(pe),{name:`loom`,size:16}),T(),f(pe),f(z),w(z,e=>Ac?.(e));var W=X(z,2),he=X(R(W),2);Be(R(he),{name:`chats`}),T(),f(he);var ge=X(he,2),_e=e=>{var t=Fj();Be(R(t),{name:`models`}),T(),f(t),U(()=>t.disabled=B(i)),K(`click`,t,()=>void o(`models`)),g(e,t)};p(ge,e=>{St.mode!==`http`&&e(_e)});var ve=X(ge,4);Be(R(ve),{name:`search`}),T(),f(ve);var be=X(ve,2);Be(R(be),{name:`appearance`}),T(),f(be);var xe=X(be,2);Be(R(xe),{name:`help`}),T(),f(xe),f(W),f(L);var Se=X(L,2),Ce=R(Se);YA(R(Ce),{}),f(Ce),f(Se),f(I);var we=X(I,2),Te=R(we),Ee=R(Te),De=R(Ee,!0);f(Ee);var Oe=X(Ee,2);AO(R(Oe),{get headersVisible(){return B(x)}}),f(Oe),f(Te);var ke=X(Te,2),Ae=X(R(ke),2),je=R(Ae);{let e=c(()=>B(b)===`branches`);jA(je,{get active(){return B(e)},get headersVisible(){return B(C)}})}f(Ae),f(ke);var Me=X(ke,2),J=R(Me),Y=R(J);f(J);var Ne=X(J,2);qE(R(Ne),{get section(){return B(O)},set section(e){A(O,e,!0)}}),f(Ne),f(Me),f(we);var Pe=X(we,2),Ie=R(Pe),Le=e=>{{let t=c(()=>B(_)&&!B(v));jf(e,{docked:!0,get params(){return $e.params},get active(){return B(t)}})}};p(Ie,e=>{$e.docked&&e(Le)}),f(Pe);var Re=X(Pe,2),ze=e=>{let t=c(()=>MC[Ze.open]);var n=Ij(),r=q(n),i=X(r,2);let o;var s=R(i);{let e=c(()=>NC(Ze.open,Ze.params));Fe(s,()=>B(t).component,(t,n)=>{n(t,{get params(){return B(e)}})})}f(i),a(i,e=>A(d,e),()=>B(d)),U(e=>{o=y(i,1,`drawer svelte-1n46o8q`,null,o,{narrow:B(t).narrow,"token-details":Ze.open===`token_drilldown`,"download-confirm":Ze.open===`download_chat`}),S(i,`aria-label`,e)},[()=>te(Ze.open)]),K(`click`,r,function(...e){it?.apply(this,e)}),h(1,r,()=>ct,eu),h(2,r,()=>ct,tu),K(`keydown`,i,ee),ye(`introstart`,i,e=>{e.currentTarget.inert=!1}),ye(`outrostart`,i,e=>{e.currentTarget.inert=!0}),h(1,i,()=>lt,()=>nu(24)),h(2,i,()=>lt,()=>ru(14)),g(e,n)};p(Re,e=>{Ze.open!==null&&e(ze)}),f(k);var Ve=X(k,2),Ue=e=>{var t=Lj();h(1,t,()=>ct,eu),h(2,t,()=>ct,tu),g(e,t)};p(Ve,e=>{B(s)===`loading`&&e(Ue)});var We=X(Ve,2);$A(We,{}),VA(X(We,2),{}),f(t),U(()=>{n=y(t,1,`shell workspace-material svelte-1n46o8q`,null,n,{loading:B(s)===`loading`,"loom-workspace":B(b)===`branches`}),r.inert=B(v)||MA.open,j=y(k,1,`layout svelte-1n46o8q`,null,j,{"sidebar-collapsed":!B(m),"has-token-sidebar":B(_)}),k.inert=MA.open||B(s)!==`ready`,S(k,`aria-busy`,B(s)===`loading`),N.inert=B(v)||B(i),S(I,`data-open`,B(m)),S(I,`aria-hidden`,!B(m)),I.inert=B(v)||!B(m),V=y(ne,1,`workspace-group svelte-1n46o8q`,null,V,{current:B(b)===`conversation`||B(b)===`controls`}),ie=y(re,1,`workspace-parent svelte-1n46o8q`,null,ie,{active:B(b)===`conversation`}),S(re,`aria-current`,B(b)===`conversation`?`page`:void 0),G(se,_i.info?.is_base_model?`Completion`:`Conversation`),G(le,_i.info?.is_base_model?`Text`:`Chat`),fe=y(de,1,`workspace-child svelte-1n46o8q`,null,fe,{active:B(b)===`controls`}),S(de,`aria-current`,B(b)===`controls`?`page`:void 0),me=y(pe,1,`workspace-parent svelte-1n46o8q`,null,me,{active:B(b)===`branches`}),S(pe,`aria-current`,B(b)===`branches`?`page`:void 0),he.disabled=B(i),S(we,`data-page`,B(P)),S(Te,`aria-hidden`,B(b)!==`conversation`),Te.inert=B(b)!==`conversation`||B(v),G(De,_i.info?.is_base_model?`Continue text with your model`:`Talk with your model`),S(ke,`aria-hidden`,B(b)!==`branches`),ke.inert=B(b)!==`branches`||B(v),S(Me,`aria-hidden`,B(b)!==`controls`),Me.inert=B(b)!==`controls`||B(v),G(Y,`${_i.info?.is_base_model?`Completion`:`Response`}, model, and chat controls`),S(Pe,`data-open`,B(_)),S(Pe,`aria-hidden`,!B(_)),Pe.inert=!B(_)||B(v)}),K(`click`,re,()=>A(b,`conversation`)),K(`click`,de,()=>A(b,`controls`)),K(`click`,pe,()=>A(b,`branches`)),K(`click`,he,()=>void o()),K(`click`,ve,function(...e){PA?.apply(this,e)}),K(`click`,be,()=>rt(`appearance`)),K(`click`,xe,()=>rt(`help`)),K(`click`,Ce,()=>{A(O,`model`),A(b,`controls`)}),g(e,t)};p(se,e=>{B(s)===`failed`?e(le):e(ue,-1)}),g(t,ie),W()}H([`click`,`keydown`]);export{Bj as default}; \ No newline at end of file diff --git a/drowse/web/dist/assets/App-qca6ctlo.js b/drowse/web/dist/assets/App-qca6ctlo.js new file mode 100644 index 00000000..bd074bce --- /dev/null +++ b/drowse/web/dist/assets/App-qca6ctlo.js @@ -0,0 +1,155 @@ +import{$ as e,A as t,At as n,B as r,Bt as i,C as a,Ct as o,D as s,Dt as c,E as l,Et as u,F as d,G as f,Gt as p,H as m,Ht as h,I as g,J as _,K as v,L as y,Lt as b,M as x,Mt as S,N as C,Nt as w,O as T,Ot as E,P as D,Pt as O,Q as k,R as A,Rt as j,S as M,St as N,T as P,Tt as F,U as I,Ut as L,V as R,W as ee,Wt as te,X as z,Z as B,_ as ne,_t as V,a as re,at as ie,b as ae,bt as oe,c as se,ct as H,d as ce,dt as le,et as ue,ft as de,g as fe,gt as U,h as pe,ht as W,i as me,it as G,j as he,jt as K,k as ge,kt as _e,l as ve,lt as ye,mt as be,n as xe,nt as Se,o as Ce,ot as we,p as Te,pt as Ee,q as De,r as Oe,rt as ke,s as Ae,st as je,t as Me,tt as Ne,u as Pe,ut as Fe,v as Ie,vt as Le,w as Re,wt as ze,x as q,xt as J,y as Be,yt as Ve,z as He,zt as Y}from"./theme-CnGipp0S.js";typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var Ue={more:[`M7 12a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm7 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm7 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0Z`],appearance:[`M11.5582 13.6469L11.4746 13.7179L4.54692 20.5186C5.04216 20.8239 5.62551 21 6.25 21H17.75C18.3745 21 18.9578 20.8239 19.4531 20.5186L12.5254 13.7179L12.432 13.6399C12.1705 13.4552 11.8174 13.4576 11.5582 13.6469ZM21 6.25C21 4.45507 19.5449 3 17.75 3H6.25C4.45507 3 3 4.45507 3 6.25V17.75C3 18.3771 3.17758 18.9626 3.4852 19.4592L10.4238 12.6475L10.5592 12.5248C11.3941 11.8273 12.615 11.8293 13.4477 12.5306L13.5762 12.6475L20.5148 19.4592C20.8224 18.9626 21 18.3771 21 17.75V6.25ZM15.25 10.75C14.1454 10.75 13.25 9.85457 13.25 8.75C13.25 7.64543 14.1454 6.75 15.25 6.75C16.3546 6.75 17.25 7.64543 17.25 8.75C17.25 9.85457 16.3546 10.75 15.25 10.75Z`],subtract:[`M3.996 13H20c0.552 0 1-0.448 1-1s-0.448-1-1-1H3.996c-0.552 0-1 0.448-1 1s0.448 1 1 1z`],help:[`M12 2c5.523 0 10 4.478 10 10s-4.477 10-10 10S2 17.522 2 12 6.477 2 12 2zm0 13.5c-0.552 0-1 0.448-1 1s0.448 1 1 1 1-0.448 1-1-0.448-1-1-1zm0-8.75c-1.519 0-2.75 1.231-2.75 2.75 0 0.414 0.336 0.75 0.75 0.75 0.38 0 0.694-0.282 0.743-0.648L10.75 9.5c0-0.69 0.56-1.25 1.25-1.25s1.25 0.56 1.25 1.25c0 0.539-0.135 0.805-0.645 1.332L12.47 10.97c-0.878 0.878-1.22 1.447-1.22 2.53 0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75c0-0.539 0.135-0.805 0.645-1.332l0.135-0.138c0.878-0.878 1.22-1.447 1.22-2.53 0-1.519-1.231-2.75-2.75-2.75z`],shuffle:[`M19.207 4.293c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l0.801 0.802c-3.809 0.161-6.169 2.59-8.226 4.706l-0.085 0.088C8.057 13.593 6.147 15.5 3 15.5c-0.552 0-1 0.448-1 1s0.448 1 1 1c4.05 0 6.503-2.525 8.632-4.715l0.085-0.088c2.124-2.184 3.96-4.02 6.857-4.185l-0.781 0.78c-0.39 0.391-0.39 1.025 0 1.415 0.39 0.39 1.024 0.39 1.414 0l2.5-2.5C21.895 8.02 22 7.765 22 7.5c0-0.265-0.105-0.52-0.293-0.707l-2.5-2.5zM3 6.5c3.229 0 5.443 1.605 7.287 3.367-0.197 0.199-0.388 0.396-0.574 0.587l-0.147 0.152c-0.233 0.24-0.459 0.47-0.68 0.693C7.186 9.68 5.476 8.5 3 8.5c-0.552 0-1-0.447-1-1 0-0.552 0.448-1 1-1zm15.594 10.991c-3.01-0.128-5.115-1.671-6.881-3.357 0.197-0.2 0.388-0.397 0.574-0.589l0.147-0.151c0.233-0.24 0.459-0.47 0.68-0.693 1.601 1.524 3.21 2.66 5.46 2.787l-0.781-0.78c-0.39-0.391-0.39-1.025 0-1.415 0.39-0.39 1.024-0.39 1.414 0l2.5 2.5C21.895 15.98 22 16.235 22 16.5c0 0.265-0.105 0.52-0.293 0.707l-2.5 2.5c-0.39 0.39-1.024 0.39-1.414 0-0.39-0.39-0.39-1.024 0-1.414l0.801-0.802z`],add:[`M11.883 3.007L12 3c0.513 0 0.935 0.386 0.993 0.883L13 4v7h7c0.513 0 0.936 0.386 0.993 0.883L21 12c0 0.513-0.386 0.935-0.883 0.993L20 13h-7v7c0 0.513-0.386 0.936-0.883 0.993L12 21c-0.513 0-0.935-0.386-0.993-0.883L11 20v-7H4c-0.513 0-0.936-0.386-0.993-0.883L3 12c0-0.513 0.386-0.935 0.883-0.993L4 11h7V4c0-0.513 0.386-0.936 0.883-0.993L12 3l-0.117 0.007z`],back:[`M15.707 4.293c0.39 0.39 0.39 1.024 0 1.414L9.414 12l6.293 6.293c0.39 0.39 0.39 1.024 0 1.414-0.39 0.39-1.024 0.39-1.414 0l-7-7c-0.39-0.39-0.39-1.024 0-1.414l7-7c0.39-0.39 1.024-0.39 1.414 0z`],chats:[`M9.5 3C5.358 3 2 6.358 2 10.5c0 1.133 0.252 2.21 0.703 3.175-0.302 1.225-0.563 2.534-0.681 3.142-0.134 0.69 0.465 1.293 1.153 1.17 0.623-0.11 1.978-0.36 3.236-0.65C7.354 17.762 8.401 18 9.5 18c4.142 0 7.5-3.358 7.5-7.5C17 6.358 13.642 3 9.5 3zM9.462 19c1.338 1.241 3.13 2 5.1 2 1.1 0 2.145-0.237 3.088-0.663 1.043 0.244 2.186 0.488 2.913 0.64 0.892 0.186 1.672-0.615 1.467-1.5-0.162-0.703-0.418-1.795-0.671-2.803 0.45-0.964 0.703-2.04 0.703-3.174 0-3.283-2.11-6.073-5.047-7.09 0.35 0.638 0.621 1.324 0.8 2.048 1.653 1.068 2.747 2.928 2.747 5.042 0 0.992-0.24 1.925-0.665 2.747l-0.13 0.253 0.07 0.276c0.228 0.895 0.467 1.9 0.642 2.65-0.774-0.163-1.818-0.39-2.74-0.61l-0.264-0.062-0.243 0.121c-0.804 0.4-1.71 0.625-2.67 0.625-1.06 0-2.055-0.274-2.92-0.756C10.978 18.91 10.28 19 9.563 19h-0.1z`],check:[`M8.5 16.586l-3.793-3.793c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l4.5 4.5c0.39 0.39 1.024 0.39 1.414 0l11-11c0.39-0.39 0.39-1.024 0-1.414-0.39-0.39-1.024-0.39-1.414 0L8.5 16.586z`],comparison:[`M21.25 12.5c0.414 0 0.75-0.336 0.75-0.75S21.664 11 21.25 11H2.75C2.336 11 2 11.336 2 11.75s0.336 0.75 0.75 0.75h18.5zM17.75 2C18.993 2 20 3.007 20 4.25V10H4V4.25C4 3.007 5.007 2 6.25 2h11.5zM4 19.25V13.5h16v5.75c0 1.243-1.007 2.25-2.25 2.25H6.25C5.007 21.5 4 20.493 4 19.25z`],controls:[`M8.75 14.5c1.537 0 2.825 1.067 3.163 2.5h9.337c0.414 0 0.75 0.336 0.75 0.75 0 0.38-0.282 0.694-0.648 0.743L21.25 18.5l-9.337 0.001C11.574 19.934 10.286 21 8.75 21c-1.537 0-2.824-1.066-3.163-2.499L2.75 18.5C2.336 18.5 2 18.164 2 17.75c0-0.38 0.282-0.694 0.648-0.743L2.75 17h2.837c0.339-1.433 1.626-2.5 3.163-2.5zM15.25 3c1.537 0 2.825 1.067 3.163 2.5h2.837C21.664 5.5 22 5.836 22 6.25c0 0.38-0.282 0.694-0.648 0.743L21.25 7l-2.837 0.001C18.074 8.434 16.786 9.5 15.25 9.5c-1.537 0-2.824-1.066-3.163-2.499L2.75 7C2.336 7 2 6.664 2 6.25c0-0.38 0.282-0.694 0.648-0.743L2.75 5.5h9.337C12.425 4.067 13.713 3 15.25 3z`],conversation:[`M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10c-1.64 0-3.225-0.396-4.644-1.142l-4.29 1.117c-0.455 0.119-0.92-0.154-1.037-0.608-0.037-0.14-0.037-0.288 0-0.428l1.116-4.289C2.397 15.23 2 13.643 2 12 2 6.477 6.477 2 12 2zm1.252 11H8.75l-0.102 0.007C8.282 13.057 8 13.37 8 13.75s0.282 0.694 0.648 0.743L8.75 14.5h4.502l0.101-0.007c0.367-0.05 0.649-0.363 0.649-0.743s-0.282-0.694-0.649-0.743L13.252 13zm1.998-3.5h-6.5L8.648 9.507C8.282 9.557 8 9.87 8 10.25s0.282 0.694 0.648 0.743L8.75 11h6.5l0.102-0.007C15.718 10.943 16 10.63 16 10.25s-0.282-0.694-0.648-0.743L15.25 9.5z`],copy:[`M8.5 13.75c0 2.347 1.903 4.25 4.25 4.25h1.74c-0.128 1.678-1.53 3-3.24 3h-5C4.455 21 3 19.545 3 17.75v-7.5C3 8.455 4.455 7 6.25 7H8.5v6.75zM17.75 3C19.545 3 21 4.455 21 6.25v7.5c0 1.795-1.455 3.25-3.25 3.25h-5c-1.795 0-3.25-1.455-3.25-3.25v-7.5C9.5 4.455 10.955 3 12.75 3h5z`],credits:[`M8 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm9 0c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM4.25 14C3.007 14 2 15.007 2 16.25v0.25S2 21 8 21s6-4.5 6-4.5v-0.25c0-1.243-1.007-2.25-2.25-2.25h-7.5zM17 19.5c-1.171 0-2.068-0.181-2.755-0.458 0.342-0.575 0.527-1.128 0.627-1.558 0.06-0.26 0.092-0.481 0.11-0.649 0.008-0.084 0.012-0.155 0.015-0.211L15 16.55v-0.3c0-0.872-0.343-1.664-0.902-2.248L14.2 14h5.6c1.215 0 2.2 0.985 2.2 2.2 0 0 0 3.3-5 3.3z`],dismiss:[`M4.21 4.387l0.083-0.094c0.36-0.36 0.928-0.388 1.32-0.083l0.094 0.083L12 10.585l6.293-6.292c0.39-0.39 1.024-0.39 1.414 0 0.39 0.39 0.39 1.024 0 1.414L13.415 12l6.292 6.293c0.36 0.36 0.388 0.928 0.083 1.32l-0.083 0.094c-0.36 0.36-0.928 0.388-1.32 0.083l-0.094-0.083L12 13.415l-6.293 6.292c-0.39 0.39-1.024 0.39-1.414 0-0.39-0.39-0.39-1.024 0-1.414L10.585 12 4.293 5.707c-0.36-0.36-0.388-0.928-0.083-1.32l0.083-0.094L4.21 4.387z`],down:[`M4.293 8.293c0.39-0.39 1.024-0.39 1.414 0L12 14.586l6.293-6.293c0.39-0.39 1.024-0.39 1.414 0 0.39 0.39 0.39 1.024 0 1.414l-7 7c-0.39 0.39-1.024 0.39-1.414 0l-7-7c-0.39-0.39-0.39-1.024 0-1.414z`],download:[`M13 3c0-0.552-0.448-1-1-1s-1 0.448-1 1v12.086l-3.293-3.293c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l5 5c0.39 0.39 1.024 0.39 1.414 0l5-5c0.39-0.39 0.39-1.024 0-1.414-0.39-0.39-1.024-0.39-1.414 0L13 15.086V3zM5 20c-0.552 0-1 0.448-1 1s0.448 1 1 1h14c0.552 0 1-0.448 1-1s-0.448-1-1-1H5z`],error:[`M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2zm-0.001 12.502c-0.552 0-0.999 0.447-0.999 0.999 0 0.551 0.447 0.999 0.999 0.999 0.551 0 0.998-0.448 0.998-0.999 0-0.551-0.447-0.999-0.998-0.999zM11.994 7c-0.414 0-0.75 0.337-0.749 0.751l0.004 4.501 0.007 0.101c0.05 0.367 0.363 0.65 0.743 0.649 0.414 0 0.75-0.337 0.75-0.751l-0.004-4.502-0.007-0.101C12.688 7.282 12.374 7 11.994 7z`],external:[`M11 3c-0.552 0-1 0.448-1 1s0.448 1 1 1h6.586L3.293 19.293c-0.39 0.39-0.39 1.023 0 1.414 0.39 0.39 1.024 0.39 1.414 0L19 6.414V13c0 0.552 0.448 1 1 1s1-0.448 1-1V4c0-0.552-0.448-1-1-1h-9z`],home:[`M13.45 2.533c-0.837-0.707-2.063-0.707-2.9 0L3.8 8.228C3.291 8.655 3 9.284 3 9.948v9.305c0 0.966 0.784 1.75 1.75 1.75h3c0.966 0 1.75-0.784 1.75-1.75V15.25c0-0.68 0.542-1.232 1.217-1.25h2.566c0.675 0.018 1.217 0.57 1.217 1.25v4.003c0 0.966 0.784 1.75 1.75 1.75h3c0.966 0 1.75-0.784 1.75-1.75V9.947c0-0.662-0.292-1.292-0.8-1.72l-6.75-5.694z`],info:[`M12.002 1.999c5.523 0 10.001 4.478 10.001 10.002 0 5.523-4.478 10.001-10.001 10.001C6.478 22.002 2 17.524 2 12.001 2 6.477 6.478 1.999 12.002 1.999zM12 10.5c-0.414 0-0.75 0.336-0.75 0.75v5c0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75v-5c0-0.414-0.336-0.75-0.75-0.75zM12 9c0.552 0 1-0.448 1-1s-0.448-1-1-1-1 0.448-1 1 0.448 1 1 1z`],loom:[`M4 5.5C4 3.567 5.567 2 7.5 2S11 3.567 11 5.5c0 1.59-1.06 2.932-2.511 3.358 0.688 2.253 2.783 3.892 5.261 3.892h0.33C14.425 11.177 15.825 10 17.5 10c1.933 0 3.5 1.567 3.5 3.5S19.433 17 17.5 17c-1.676 0-3.076-1.177-3.42-2.75h-0.33c-2.231 0-4.218-1.044-5.5-2.67v3.5C9.823 15.425 11 16.825 11 18.5c0 1.933-1.567 3.5-3.5 3.5S4 20.433 4 18.5c0-1.676 1.177-3.076 2.75-3.42V8.92C5.177 8.575 4 7.175 4 5.5z`],models:[`M13.409 2.511c-0.904-0.366-1.914-0.366-2.818 0l-7.498 3.04C2.432 5.819 2 6.461 2 7.173v9.653c0 0.712 0.432 1.354 1.092 1.621l7.5 3.04c0.903 0.367 1.913 0.367 2.817 0l7.498-3.04C21.567 18.18 22 17.538 22 16.826V7.173c0-0.713-0.432-1.354-1.093-1.622l-7.498-3.04zm-7.36 5.472c0.147-0.387 0.58-0.582 0.967-0.435L12 9.438l4.984-1.89c0.387-0.147 0.82 0.048 0.967 0.435 0.147 0.387-0.048 0.82-0.435 0.967l-4.766 1.81v5.49c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75v-5.49L6.484 8.95C6.097 8.803 5.902 8.37 6.049 7.983z`],moon:[`M20.026 17.001c-2.762 4.784-8.879 6.423-13.663 3.661-1.302-0.752-2.399-1.77-3.234-2.982-0.28-0.406-0.099-0.966 0.365-1.132 3.767-1.348 5.785-2.91 6.956-5.146C11.682 9.05 12 6.472 11.139 2.94c-0.12-0.489 0.266-0.954 0.769-0.927 1.556 0.083 3.078 0.53 4.457 1.327 4.784 2.762 6.423 8.879 3.66 13.662z`],next:[`M8.293 4.293c-0.39 0.39-0.39 1.024 0 1.414L14.586 12l-6.293 6.293c-0.39 0.39-0.39 1.024 0 1.414 0.39 0.39 1.024 0.39 1.414 0l7-7c0.39-0.39 0.39-1.024 0-1.414l-7-7c-0.39-0.39-1.024-0.39-1.414 0z`],offline:[`M12.858 14.273l7.434 7.434c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414l-17.999-18c-0.39-0.39-1.024-0.39-1.414 0-0.39 0.39-0.39 1.024 0 1.414l3.096 3.097C4.747 7.233 4.136 7.73 3.57 8.299 3.08 8.788 2.608 9.365 2.179 9.982c-0.314 0.454-0.201 1.077 0.252 1.392 0.454 0.315 1.077 0.202 1.392-0.252 0.363-0.524 0.761-1.01 1.16-1.41 0.571-0.57 1.195-1.057 1.855-1.46L7.99 9.405c-0.608 0.35-1.18 0.784-1.7 1.303-0.615 0.616-1.117 1.31-1.503 2.074-0.25 0.493-0.052 1.094 0.44 1.344 0.494 0.249 1.095 0.051 1.344-0.441 0.291-0.575 0.668-1.098 1.134-1.563 0.527-0.528 1.128-0.94 1.768-1.234l1.408 1.407c-0.933 0.21-1.82 0.679-2.545 1.405-0.46 0.46-0.826 1.009-1.09 1.612-0.222 0.506 0.01 1.096 0.515 1.317 0.506 0.222 1.096-0.009 1.317-0.515 0.167-0.381 0.394-0.722 0.672-1 0.842-0.842 2.034-1.123 3.108-0.841zm-1.332-5.93l2.228 2.229c0.958 0.278 1.861 0.795 2.616 1.55 0.444 0.444 0.837 0.995 1.137 1.582 0.252 0.491 0.854 0.686 1.346 0.435 0.491-0.252 0.686-0.854 0.435-1.346-0.393-0.767-0.907-1.488-1.504-2.085-1.717-1.717-4.011-2.505-6.258-2.364zM8.51 5.328l1.651 1.651c3.108-0.581 6.44 0.33 8.844 2.735 0.42 0.42 0.822 0.906 1.172 1.413 0.314 0.455 0.936 0.569 1.391 0.255 0.454-0.314 0.569-0.936 0.255-1.39-0.417-0.605-0.896-1.184-1.404-1.692-3.223-3.224-7.833-4.214-11.91-2.972zm4.552 11.114c0.586 0.586 0.586 1.537 0 2.123-0.586 0.586-1.537 0.586-2.123 0-0.586-0.586-0.586-1.537 0-2.123 0.586-0.586 1.537-0.586 2.123 0z`],paused:[`M5.746 3c-0.966 0-1.75 0.784-1.75 1.75v14.5c0 0.966 0.784 1.75 1.75 1.75h3.5c0.967 0 1.75-0.784 1.75-1.75V4.75c0-0.966-0.783-1.75-1.75-1.75h-3.5zm9 0c-0.966 0-1.75 0.784-1.75 1.75v14.5c0 0.966 0.784 1.75 1.75 1.75h3.5c0.967 0 1.75-0.784 1.75-1.75V4.75c0-0.966-0.783-1.75-1.75-1.75h-3.5z`],ready:[`M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2zm3.22 6.97l-4.47 4.47-1.97-1.97c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06l2.5 2.5c0.293 0.293 0.767 0.293 1.06 0l5-5c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.767-0.293-1.06 0z`],refresh:[`M5 12c0-3.866 3.134-7 7-7 1.32 0 2.554 0.365 3.608 1H15c-0.552 0-1 0.448-1 1s0.448 1 1 1h3c0.552 0 1-0.448 1-1V4c0-0.552-0.448-1-1-1s-1 0.448-1 1v0.516C15.57 3.559 13.85 3 12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-0.38-0.024-0.755-0.07-1.124-0.068-0.548-0.568-0.937-1.116-0.868-0.548 0.068-0.936 0.568-0.868 1.116C18.98 11.41 19 11.703 19 12c0 3.866-3.134 7-7 7s-7-3.134-7-7z`],return:[`M7 19c0 0.552 0.448 1 1 1h5c2.242 0 4.01-0.778 5.218-2.023C19.414 16.744 20 15.113 20 13.5c0-1.613-0.586-3.244-1.782-4.477C17.01 7.778 15.242 7 13 7H8.414l2.043-2.043c0.39-0.39 0.39-1.024 0-1.414-0.39-0.39-1.024-0.39-1.414 0l-3.75 3.75c-0.39 0.39-0.39 1.024 0 1.414l3.75 3.75c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414L8.414 9H13c1.758 0 2.99 0.597 3.782 1.415C17.586 11.245 18 12.363 18 13.5s-0.414 2.256-1.218 3.085C15.99 17.403 14.758 18 13 18H8c-0.552 0-1 0.448-1 1z`],search:[`M15.843 17.368C14.5 18.392 12.82 19 11 19c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8c0 1.877-0.646 3.603-1.729 4.967l4.427 4.317c0.396 0.386 0.404 1.019 0.018 1.414-0.386 0.396-1.019 0.404-1.414 0.018l-4.459-4.348zM17 11c0-3.314-2.686-6-6-6s-6 2.686-6 6 2.686 6 6 6 6-2.686 6-6z`],send:[`M12.815 12.197l-7.532 1.255c-0.176 0.03-0.323 0.15-0.386 0.318L2.3 20.728c-0.248 0.64 0.421 1.25 1.035 0.942l18-9c0.553-0.276 0.553-1.065 0-1.341l-18-9C2.72 2.022 2.05 2.632 2.299 3.27l2.598 6.958c0.063 0.167 0.21 0.289 0.386 0.318l7.532 1.255c0.109 0.018 0.182 0.122 0.164 0.23-0.014 0.085-0.08 0.15-0.164 0.165z`],settings:[`M12.012 2.25c0.734 0.009 1.465 0.093 2.182 0.253 0.312 0.07 0.546 0.33 0.582 0.649l0.17 1.527c0.077 0.7 0.669 1.232 1.375 1.233 0.19 0 0.377-0.04 0.552-0.117l1.4-0.615c0.292-0.128 0.633-0.059 0.85 0.174 1.012 1.08 1.766 2.377 2.205 3.792 0.094 0.305-0.015 0.636-0.272 0.825l-1.241 0.916c-0.354 0.26-0.563 0.673-0.563 1.112 0 0.44 0.209 0.853 0.564 1.114l1.242 0.915c0.257 0.19 0.366 0.521 0.272 0.826-0.439 1.415-1.192 2.71-2.204 3.792-0.217 0.232-0.557 0.302-0.849 0.175l-1.406-0.617c-0.402-0.176-0.864-0.15-1.244 0.07s-0.634 0.607-0.682 1.044l-0.17 1.526c-0.034 0.315-0.263 0.574-0.571 0.647-1.448 0.345-2.958 0.345-4.406 0-0.308-0.073-0.537-0.332-0.572-0.647L9.057 19.32c-0.05-0.436-0.303-0.822-0.683-1.041-0.38-0.219-0.84-0.245-1.242-0.07l-1.406 0.617c-0.292 0.127-0.632 0.057-0.85-0.175-1.011-1.082-1.765-2.38-2.203-3.796-0.094-0.305 0.015-0.636 0.272-0.826l1.243-0.916c0.354-0.26 0.564-0.673 0.564-1.112 0-0.44-0.21-0.853-0.564-1.114L2.945 9.973C2.688 9.783 2.58 9.452 2.673 9.147c0.44-1.415 1.193-2.711 2.205-3.792 0.218-0.233 0.558-0.302 0.85-0.174l1.4 0.615c0.403 0.177 0.866 0.15 1.248-0.073 0.38-0.22 0.633-0.609 0.682-1.045l0.17-1.526c0.036-0.319 0.27-0.58 0.583-0.65 0.717-0.159 1.449-0.243 2.201-0.252zM12 9c-1.657 0-3 1.343-3 3s1.343 3 3 3c1.656 0 3-1.343 3-3s-1.344-3-3-3z`],star:[`M10.788 3.102c0.495-1.003 1.926-1.003 2.421 0l2.358 4.778 5.273 0.766c1.107 0.16 1.549 1.522 0.748 2.303l-3.816 3.719 0.901 5.25c0.19 1.104-0.968 1.945-1.959 1.424l-4.716-2.48-4.715 2.48c-0.99 0.52-2.148-0.32-1.96-1.423l0.901-5.251-3.815-3.72c-0.801-0.78-0.359-2.141 0.748-2.302L8.43 7.88l2.358-4.778z`],stop:[`M4.75 3C3.784 3 3 3.784 3 4.75v14.5C3 20.216 3.784 21 4.75 21h14.5c0.966 0 1.75-0.784 1.75-1.75V4.75C21 3.784 20.216 3 19.25 3H4.75z`],sun:[`M12 2c0.414 0 0.75 0.336 0.75 0.75v1.5C12.75 4.664 12.414 5 12 5s-0.75-0.336-0.75-0.75v-1.5C11.25 2.336 11.586 2 12 2zm5 10c0 2.761-2.239 5-5 5s-5-2.239-5-5 2.239-5 5-5 5 2.239 5 5zm4.25 0.75c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-1.5C19.336 11.25 19 11.586 19 12s0.336 0.75 0.75 0.75h1.5zM12 19c0.414 0 0.75 0.336 0.75 0.75v1.5c0 0.414-0.336 0.75-0.75 0.75s-0.75-0.336-0.75-0.75v-1.5c0-0.414 0.336-0.75 0.75-0.75zm-7.75-6.25C4.664 12.75 5 12.414 5 12s-0.336-0.75-0.75-0.75h-1.5C2.336 11.25 2 11.586 2 12s0.336 0.75 0.75 0.75h1.5zM4.22 4.22c0.293-0.293 0.767-0.293 1.06 0l1.5 1.5c0.293 0.293 0.293 0.768 0 1.06-0.293 0.294-0.767 0.294-1.06 0l-1.5-1.5c-0.293-0.292-0.293-0.767 0-1.06zm1.06 15.56c-0.293 0.294-0.767 0.294-1.06 0-0.293-0.292-0.293-0.767 0-1.06l1.5-1.5c0.293-0.293 0.767-0.293 1.06 0 0.293 0.293 0.293 0.768 0 1.06l-1.5 1.5zm14.5-15.56c-0.293-0.293-0.767-0.293-1.06 0l-1.5 1.5c-0.293 0.293-0.293 0.768 0 1.06 0.293 0.294 0.767 0.294 1.06 0l1.5-1.5c0.293-0.292 0.293-0.767 0-1.06zm-1.06 15.56c0.293 0.294 0.767 0.294 1.06 0 0.293-0.292 0.293-0.767 0-1.06l-1.5-1.5c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.768 0 1.06l1.5 1.5z`],swap:[`M15.207 2.29l4 3.996c0.361 0.36 0.39 0.928 0.084 1.32l-0.083 0.095-4 4.005c-0.39 0.39-1.023 0.39-1.414 0-0.36-0.36-0.389-0.927-0.084-1.32l0.083-0.094L16.083 8H5.5C4.987 8 4.564 7.613 4.507 7.116L4.5 6.999c0-0.513 0.386-0.935 0.883-0.993L5.5 5.999h10.59l-2.296-2.293c-0.36-0.36-0.389-0.928-0.084-1.32l0.083-0.095c0.36-0.36 0.928-0.388 1.32-0.084l0.094 0.084 4 3.995-4-3.995zm4.284 14.592L19.497 17c0 0.513-0.386 0.936-0.883 0.993L18.497 18H7.914l2.293 2.293c0.361 0.36 0.39 0.927 0.084 1.32l-0.083 0.094c-0.36 0.36-0.927 0.389-1.32 0.084l-0.094-0.084-4-3.996c-0.36-0.36-0.389-0.927-0.084-1.32l0.083-0.094 4-4.004c0.39-0.39 1.024-0.39 1.415 0 0.36 0.36 0.388 0.927 0.083 1.32l-0.083 0.094L7.918 16h10.58c0.512 0 0.935 0.386 0.993 0.883L19.497 17l-0.006-0.117z`],tokens:[`M2 6.75C2 4.679 3.679 3 5.75 3h12.5C20.321 3 22 4.679 22 6.75v10.5c0 2.071-1.679 3.75-3.75 3.75H5.75C3.679 21 2 19.321 2 17.25V6.75zM12.75 7.5h2.75v0.75C15.5 8.664 15.836 9 16.25 9S17 8.664 17 8.25v-1.5C17 6.336 16.664 6 16.25 6h-8.5C7.336 6 7 6.336 7 6.75v1.5C7 8.664 7.336 9 7.75 9S8.5 8.664 8.5 8.25V7.5h2.75v9h-0.5c-0.414 0-0.75 0.336-0.75 0.75S10.336 18 10.75 18h2.5c0.414 0 0.75-0.336 0.75-0.75s-0.336-0.75-0.75-0.75h-0.5v-9z`],unsupported:[`M16.906 5.68C13.768 3.237 9.228 3.458 6.343 6.343 3.458 9.228 3.237 13.768 5.68 16.906L16.906 5.68zm1.414 1.414L7.094 18.32c3.138 2.443 7.678 2.222 10.563-0.663 2.885-2.885 3.106-7.425 0.663-10.563zM4.93 4.929c3.905-3.905 10.237-3.905 14.142 0 3.905 3.905 3.905 10.237 0 14.142-3.905 3.905-10.237 3.905-14.142 0-3.905-3.905-3.905-10.237 0-14.142z`],up:[`M4.293 15.707c0.39 0.39 1.024 0.39 1.414 0L12 9.414l6.293 6.293c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414l-7-7c-0.39-0.39-1.024-0.39-1.414 0l-7 7c-0.39 0.39-0.39 1.024 0 1.414z`],upload:[`M5.5 2c-0.552 0-1 0.448-1 1s0.448 1 1 1h13c0.552 0 1-0.448 1-1s-0.448-1-1-1h-13zm7.207 3.793c-0.39-0.39-1.024-0.39-1.414 0l-5 5c-0.39 0.39-0.39 1.024 0 1.414 0.39 0.39 1.024 0.39 1.414 0L11 8.914V21c0 0.552 0.448 1 1 1s1-0.448 1-1V8.914l3.293 3.293c0.39 0.39 1.024 0.39 1.414 0 0.39-0.39 0.39-1.024 0-1.414l-5-5z`],warning:[`M9.138 3.707c1.228-2.276 4.493-2.276 5.721 0l6.743 12.502c1.168 2.165-0.4 4.793-2.86 4.793H5.255c-2.46 0-4.028-2.628-2.86-4.793L9.137 3.707zM12.001 15c-0.552 0-1 0.448-1 1s0.448 1 1 1 1-0.448 1-1-0.448-1-1-1zm0-7.5c-0.414 0-0.75 0.336-0.75 0.75v4.5c0 0.414 0.336 0.75 0.75 0.75s0.75-0.336 0.75-0.75v-4.5c0-0.414-0.336-0.75-0.75-0.75z`]},We=ue(``),Ge=ue(``);function Ke(e,n){O(n,!0);let r=q(n,`class`,3,``),a=q(n,`size`,3,16),o=q(n,`spin`,3,!1);var s=Ge();let c;f(s,21,()=>Ue[n.name],v,(e,n)=>{var r=We();W(()=>t(r,`d`,H(n))),B(e,r)}),i(s),W(()=>{c=D(s,0,`fluent-icon ${r()}`,`svelte-1xukml3`,c,{spinning:o()}),t(s,`width`,a()),t(s,`height`,a()),t(s,`data-icon`,n.name)}),B(e,s),w()}var qe=ue(``);function Je(e,n){let r=q(n,`side`,3,`left`);var a=qe(),s=o(J(a));i(a),W(()=>t(s,`d`,r()===`left`?`M9 4v16`:`M15 4v16`)),B(e,a)}var Ye={subspace:[],manifolds:[],manifold_builder:[`fitting`,`manifold_artifacts`],surface_geometry:[],manifold_merge:[`manifold_artifacts`],manifold_pack:[`manifold_artifacts`],save_conversation:[],download_chat:[],load_conversation:[],compare:[],system_prompt:[],token_drilldown:[],correlation:[],probe_inspector:[],advanced_sampling:[],health:[],appearance:[],session_admin:[`session_admin`],local_runtime:[],help:[],feedback:[],node_compare:[],transcript:[],template_lab:[`manifold_artifacts`,`fitting`],cast:[]};function Xe(e){return Ze(e,ve())}function Ze(e,t){if(!t)return{available:!0,reason:null};let n=t.operations[e];return{available:n.available,reason:n.available?null:n.reasons[0]?Ie(n.reasons[0],`This action is unavailable in the current browser or model session.`):`This action is unavailable in the current browser or model session.`}}function Qe(e,t=ve()){for(let n of Ye[e]){let e=Ze(n,t);if(!e.available)return e}return{available:!0,reason:null}}var $e=ze({entries:[]}),et=0;function X(e,t={}){let n=++et,r=t.kind??`info`;return $e.entries=[...$e.entries,{id:n,kind:r,message:e,detail:t.detail??null,ttlMs:t.ttlMs===void 0?r===`error`?null:6e3:t.ttlMs}],n}function tt(e,t){$e.entries=$e.entries.map(n=>n.id===e?{...n,...t}:n)}function nt(e){$e.entries=$e.entries.filter(t=>t.id!==e)}var rt=ze({open:null,params:null}),it=null,at=ze({docked:!1,visible:!1,params:null});function ot(e){rt.open===`token_drilldown`&&(at.params=e??rt.params,ut()),at.docked=!0,at.visible=!0}function st(){at.visible=!1,document.getElementById(`workspace-token-sidebar`)?.contains(document.activeElement)&&document.querySelector(`[aria-controls="workspace-token-sidebar"]`)?.focus({preventScroll:!0})}function ct(e){st(),at.docked=!1,lt(`token_drilldown`,e)}function lt(e,t=null){let n=Qe(e);if(!n.available){X(n.reason??`This tool is unavailable.`,{kind:`warning`});return}if(e===`token_drilldown`&&at.docked){at.params=t,at.visible=!0;return}rt.open===null&&typeof document<`u`&&document.activeElement instanceof HTMLElement&&(it=document.activeElement),rt.open=e,rt.params=t}function ut(){let e=it;it=null,rt.open=null,rt.params=null,queueMicrotask(()=>{e?.isConnected&&e.focus()})}var dt={locale:`en`,duration:400,ease:`cubic-bezier(0.19, 1, 0.22, 1)`,disabled:!1,respectReducedMotion:!0};function ft(e,t,n){if(n<1){let r=t*Math.sqrt(1-n*n);return 1-Math.exp(-n*t*e)*(Math.cos(r*e)+n*t/r*Math.sin(r*e))}let r=Math.sqrt(n*n-1),i=-t*(n+r),a=-t*(n-r),o=-i/(a-i);return 1-(1-o)*Math.exp(i*e)-o*Math.exp(a*e)}function pt(e,t,n){let r=0;for(let i=0;i<10;i+=.001)if(Math.abs(ft(i,e,t)-1)>n)r=0;else if(r+=.001,r>.1)return Math.ceil((i-r+.001)*1e3);return 1e4}function mt(e,t){if(typeof e==`object`){let t=gt(e);return{ease:t.easing,duration:t.duration}}return{ease:e,duration:t}}var ht=new Map;function gt(e){let{stiffness:t=100,damping:n=10,mass:r=1,precision:i=.001}=e??{},a=`${t}:${n}:${r}:${i}`,o=ht.get(a);if(o)return o;let s=Math.sqrt(t/r),c=n/(2*Math.sqrt(t*r)),l=pt(s,c,i),u=Math.min(100,Math.max(32,Math.round(l/15))),d=[];for(let e=0;e2&&d[d.length-2]===`1`;)d.splice(d.length-2,1);let f={easing:`linear(${d.join(`, `)})`,duration:l};return ht.set(a,f),f}function _t(e,t){let n=e.length,r=t.length,i=Array.from({length:n+1},()=>Array(r+1).fill(0));for(let a=n-1;a>=0;a--)for(let n=r-1;n>=0;n--)i[a][n]=e[a]===t[n]?i[a+1][n+1]+1:Math.max(i[a+1][n],i[a][n+1]);let a=[],o=[],s=0,c=0;for(;s=i[s][c+1]?s++:c++;return[a,o]}var vt=`\0n`,yt=0;function bt(){return`${vt}${yt++}`}function xt(e){return e>=`0`&&e<=`9`}function St(e){for(let t of e)if(xt(t))return!0;return!1}function Ct(e){let t=``;for(let n of e)!xt(n)&&!wt.includes(n)&&(t+=n);return t}var wt=`.,'\xA0   `,Tt=`+-−(#`,Et=`%.,!?:;)"'”’`,Dt=/\p{Sc}/u;function Ot(e,t){return t.includes(e)||Dt.test(e)}function kt(e){let t=0,n=e.length;for(;tt&&Ot(e[n-1],Et);)n--;if(t>=n||!xt(e[t])||!xt(e[n-1]))return!1;for(let r=t;re.type===`decimal`)?.value??`.`}catch{}return jt.set(t,r),r}function Nt(e,t,n,r=`.`){let i=e.split(``);if(!t||t.length===0)return Pt(i);let a=t.map(e=>e.string===`\xA0`?` `:e.string),o=n==null?zt(a,i,r):Ft(a,i,n,r),s=new Set;for(let[,e]of o)s.add(t[e].id);let c=[];for(let e=0;e({id:bt(),string:e===` `?`\xA0`:e,kind:At(e)}))}function Ft(e,t,n,r){let i=new Map,a=Lt(e,r),o=Lt(t,r),s=(e,t)=>i.set(o[e],a[t]),c=0;for(;c0){let e=c-l;for(let t=0;t=0&&t=0&&ti&&o>i&&e[a-1]===t[o-1]&&!xt(e[a-1]);)r.set(o-1,a-1),a--,o--;let s=Ut(e,i,a,n),c=Ut(t,i,o,n),l=Ht(e,i,s),u=Ht(t,i,c);if(l>0&&u>0&&Math.abs(l-u)>=Vt)return r;if(!f(i,s,i,c,!0))for(let e=1;s-e>=i&&c-e>=i;e++)d(s-e,c-e);if(se[t]).reverse(),l.map(e=>t[e]).reverse());for(let e=0;e0}return r}function Bt(e,t,n){let r=[];for(let i=t;i=t;i--)if(e[i]===r)return i;return n}function Wt(){let e=new Set;return{reserve(t){e.add(t)},has(t){return e.has(t)},take(t){if(!e.has(t))return e.add(t),t;let n=1;for(;e.has(`${t}~${n}`);)n++;let r=`${t}~${n}`;return e.add(r),r}}}function Gt(e){let t=[],n=[],r=()=>{n.length!==0&&(t.push({word:n.map(e=>e.string).join(``),segments:n}),n=[])};for(let t of e)t.string===`\xA0`||t.string===` +`?r():n.push(t);return r(),t}function Kt(e){let t=[],n=[],r=()=>{if(n.length===0)return;let e=n.map(e=>e.string).join(``);kt(e)?t.push(...Nt(e)):t.push(...n),n=[]};for(let i of e)i.string===`\xA0`||i.string===` +`?(r(),t.push(i)):n.push(i);return r(),t}function qt(e,t,n=!0){let r=e.includes(` +`),i=e.includes(` `)||r,a=Wt();if(r){let r=e.split(` +`),i=[],o=0;return r.forEach((e,n)=>{n>0&&(i.push({id:a.take(`newline-${o}`),string:` +`}),o+=1),e.length>0&&i.push(...Jt(e,t,!0,o,a)),o+=e.length}),n?Kt(i):i}let o=Jt(e,t,i,0,a);return n?Kt(o):o}function Jt(e,t,n,r,i){return typeof Intl.Segmenter<`u`?Yt(new Intl.Segmenter(t,{granularity:n?`word`:`grapheme`}).segment(e)[Symbol.iterator](),r,i):Zt(e,n,r,i)}function Yt(e,t,n){let r=[];for(let i of Array.from(e)){let e=t+i.index;i.segment===` `?r.push({id:n.take(`space-${e}`),string:`\xA0`}):r.push({id:Xt(i.segment,e,n),string:i.segment})}return r}function Xt(e,t,n){return n.has(e)?n.take(`${e}-${t}`):n.take(e)}function Zt(e,t,n,r){let i=t?e.split(` `):e.split(``),a=[],o=n;return i.forEach((e,n)=>{t&&n>0&&(a.push({id:r.take(`space-${o}`),string:`\xA0`}),o+=1),a.push({id:Xt(e,o,r),string:e}),o+=e.length}),a}var Qt=`torph-root`,$t=`torph-item`,en=`torph-id`,tn=`torph-kind`,nn=`torph-slot`,rn=`torph-exiting`,an=`torph-sr`,on=`torph-debug`,sn=`empty`,cn={linear:[0,0,1,1],ease:[.25,.1,.25,1],"ease-in":[.42,0,1,1],"ease-out":[0,0,.58,1],"ease-in-out":[.42,0,.58,1]},ln=(e,t,n)=>{let r=1-n;return 3*r*r*n*e+3*r*n*n*t+n*n*n};function un(e,t,n,r){return i=>{if(i<=0)return 0;if(i>=1)return 1;let a=0,o=1;for(let t=0;t<24;t+=1){let t=(a+o)/2;ln(e,n,t)t===0?e:Math.max(e,n[t-1]))}function fn(e){let t=[],n=[];for(let r of e.split(`,`)){let e=r.trim().split(/\s+/).filter(Boolean),i=Number(e[0]);if(!Number.isFinite(i))return null;let a=e.slice(1);if(a.length>2)return null;if(a.length===0){t.push(i),n.push(null);continue}for(let e of a){if(!e.endsWith(`%`))return null;let r=Number(e.slice(0,-1));if(!Number.isFinite(r))return null;t.push(i),n.push(r/100)}}if(t.length<2)return null;let r=dn(n);return e=>{if(e<=r[0])return t[0];let n=r.length-1;if(e>=r[n])return t[n];let i=0;for(;iNumber(e.trim()));return e.length!==4||e.some(e=>!Number.isFinite(e))?null:un(e[0],e[1],e[2],e[3])}let i=/^linear\(([^)]*)\)$/.exec(t);return i?fn(i[1]):null}var mn=1e-4;function hn(e,t){let n=Math.min(Math.max(t,0),1-mn);return(e(n+mn)-e(n))/mn}function gn(e,t){return e*t}function _n(e){let t=getComputedStyle(e).transform;if(!t||t===`none`)return{tx:0,ty:0};let n=t.match(/matrix\(([^)]+)\)/);if(!n)return{tx:0,ty:0};let r=n[1].split(`,`).map(Number);return{tx:r[4]||0,ty:r[5]||0}}function vn(e){let t=getComputedStyle(e),n=parseFloat(t.width),r=parseFloat(t.height);if(Number.isNaN(n)||Number.isNaN(r)){let t=e.getBoundingClientRect();return{width:t.width,height:t.height}}return{width:n,height:r}}function yn(e){let{tx:t,ty:n}=_n(e),r=Number(getComputedStyle(e).opacity)||1;return e.getAnimations().forEach(e=>e.cancel()),{tx:t,ty:n,opacity:r}}var bn=8,xn=.1,Sn=.5,Cn=.5,wn=()=>performance.now();function Tn(e,t){let n=Math.max(0,Math.min(bn,t)-hn(e,0));if(!(n>0))return{curve:e,k:0};let r=Math.max(3,Math.ceil(n/(Math.E*xn))-1);return{curve:t=>t>=1?1:e(t)+n*t*(1-t)**r,k:n}}function En(e,t){let n=Math.min(120,Math.max(32,Math.round(t/8))),r=[];for(let t=0;t{let c=e.animate([{[t]:`${n}px`},{[t]:`${r}px`}],{duration:a,easing:i,fill:`both`});return s!==void 0&&(c.currentTime=s),{anim:c,from:n,to:r,easing:i,curve:o,startedAt:wn()-(s??0)}};if(i&&i.elapsed!==null&&Math.abs(i.to-r)Sn){let e=Tn(s,(i?.velocity??0)*a/l);e.k>0&&(d=e.curve,u=En(e.curve,a))}return c(n,r,u,d)}function On(e,t){let n=e.anim.currentTime===null,r=wn()-e.startedAt,i=n||!Number.isFinite(r)||r>=t||r<0?null:r;return{from:e.from,to:e.to,easing:e.easing,curve:e.curve,elapsed:i,velocity:i===null||!e.curve?0:(e.to-e.from)*hn(e.curve,i/t)/t}}var kn=new WeakMap;function An(e){return kn.get(e)?.snapshot()}function jn(e){e.style.width=``,e.style.height=``,e.style.transitionProperty=``}function Mn(e){let t=kn.get(e);t&&(kn.delete(e),t.stop(),t.onCancel?.())}function Nn(e){let t=kn.get(e);t&&(kn.delete(e),t.stop()),jn(e)}function Pn(e,t,n,r,i,a,o){let s=An(e);if(Mn(e),t===0||n===0){jn(e),o?.();return}e.style.transitionProperty=`none`,e.style.width=``,e.style.height=``,e.offsetWidth;let{width:c,height:l}=vn(e),u=pn(i),d=Dn(e,`width`,t,c,s?.width,r,i,u),f=Dn(e,`height`,n,l,s?.height,r,i,u),p=()=>{d.anim.cancel(),f.anim.cancel()};d.anim.onfinish=()=>{kn.delete(e),p(),jn(e),a?.()},kn.set(e,{stop:p,onCancel:o,snapshot:()=>({width:On(d,r),height:On(f,r)})})}function Fn(e,t,n,r,i,a){Mn(e),e.style.transitionProperty=`none`,e.style.width=`${t}px`,e.style.height=`${n}px`;let o=setTimeout(()=>{kn.delete(e),jn(e),i?.()},r),s=e=>({from:e,to:e,easing:`linear`,curve:null,elapsed:null,velocity:0});kn.set(e,{stop:()=>clearTimeout(o),onCancel:a,snapshot:()=>({width:s(t),height:s(n)})})}function In(e){let t=Array.from(e.children),n={},r=e.getBoundingClientRect();return t.forEach((e,t)=>{if(e.hasAttribute(rn)||e.hasAttribute(an)||e.tagName===`BR`)return;let i=e.getAttribute(en)||`child-${t}`,a=e.getBoundingClientRect(),{tx:o,ty:s}=_n(e);n[i]={x:a.left-r.left-o,y:a.top-r.top-s}}),n}function Ln(e,t,n){let r=e[n],i=t[n];return!r||!i?{dx:0,dy:0}:{dx:r.x-i.x,dy:r.y-i.y}}function Rn(e,t,n,r=`backward-first`){let[i,a]=r===`backward-first`?[`backward`,`forward`]:[`forward`,`backward`],o=r=>{if(r===`backward`){for(let r=e-1;r>=0;r--)if(n.has(t[r]))return t[r]}else for(let r=e+1;rr.has(n)&&!t.has(e[i]))),a=new Map;for(let r=0;re.remove()}function Vn(e,t){let{deltaX:n,deltaY:r,isNew:i,duration:a,ease:o}=t,s=yn(e),c=n+s.tx,l=r+s.ty,u=i&&s.opacity>=1?0:s.opacity;e.animate([{transform:`translate(${c}px, ${l}px) scale(${i?.95:1})`},{transform:`none`}],{duration:a,easing:o,fill:`both`}),u<1&&e.animate([{opacity:u},{opacity:1}],{duration:gn(a,i?.5:.25),delay:i?gn(a,.25):0,easing:`linear`,fill:`both`})}function Hn(e,t){let n=0,r=0;for(let i=e;i&&i!==t;i=i.offsetParent)n+=i.offsetLeft,r+=i.offsetTop;return{x:n,y:r}}function Un(e,t){let n=document.createElement(e);return n.setAttribute($t,``),n.setAttribute(en,t),n.setAttribute(`aria-hidden`,`true`),n}function Wn(e,t){let n=new Map;for(let r of t){if(r.tagName===`BR`)continue;let{x:t,y:i}=Hn(r,e),{tx:a,ty:o}=_n(r),{width:s,height:c}=vn(r),l=Number(getComputedStyle(r).opacity)||1;r.getAnimations().forEach(e=>e.cancel()),n.set(r,{left:t+a,top:i+o,width:s,height:c,opacity:l})}for(let e=t.length-1;e>=0;e--)t[e].tagName===`BR`&&(t[e].remove(),t.splice(e,1));t.forEach(e=>{let t=n.get(e);e.setAttribute(rn,``),e.style.position=`absolute`,e.style.pointerEvents=`none`,e.style.left=`${t.left}px`,e.style.top=`${t.top}px`,e.style.width=`${t.width}px`,e.style.height=`${t.height}px`,e.style.opacity=String(t.opacity)})}function Gn(e,t){if(t.size===0)return;let n=Array.from(e.children),r=new Set;for(let e of n){if(e.hasAttribute(rn))continue;let n=e.getAttribute(en);if(!n||r.has(n))continue;let i=t.get(n);if(i){r.add(n);for(let t of i){let n=Un(`span`,t.id);Kn(n,t),e.before(n)}e.remove()}}}function Kn(e,t){if(!t.kind){e.removeAttribute(tn),e.removeAttribute(nn),e.textContent=t.string;return}e.setAttribute(tn,t.kind),e.setAttribute(nn,``);let n=e.firstElementChild;n||(e.textContent=``,n=document.createElement(`span`),e.appendChild(n)),n.textContent=t.string}function qn(e){return e.hasAttribute(nn)?e.firstElementChild??e:e}function Jn(e,t,n,r){let i=new Map;t.forEach(e=>{let t=e.getAttribute(en);n.has(t)&&!e.hasAttribute(rn)&&(i.set(t,e),e.remove())}),Array.from(e.childNodes).forEach(e=>{e.nodeType===Node.TEXT_NODE&&e.remove()}),r.forEach(t=>{let n=i.get(t.id);if(n&&i.delete(t.id),t.string===` +`){n&&n.tagName===`BR`?e.appendChild(n):e.appendChild(Un(`br`,t.id));return}if(n&&n.tagName!==`BR`)n.style.transformOrigin=``,Kn(n,t),e.appendChild(n);else{let n=Un(`span`,t.id);Kn(n,t),e.appendChild(n)}})}var Yn=.45,Xn=.25;function Zn(e,t){let{dx:n,dy:r,slideDistance:i,duration:a,ease:o}=t,s=qn(e);e.animate({transform:`translate(${n}px, ${r}px)`,offset:1},{duration:a,easing:o,fill:`both`}),s.animate({transform:`translate(0px, ${i}px)`,offset:1},{duration:a,easing:o,fill:`both`});let c=s.animate({opacity:0,offset:1},{duration:a*Yn,easing:`linear`,fill:`both`});c.onfinish=()=>e.remove()}function Qn(e,t){let{deltaX:n,deltaY:r,slideDistance:i,kind:a,duration:o,ease:s}=t;$n(e,{deltaX:n,deltaY:r,duration:o,ease:s});let c=qn(e),l=yn(c),u=a===`digit`?-i:i;c.animate({transform:`translate(0px, ${l.ty+u}px)`,offset:0},{duration:o,easing:s,fill:`both`});let d=l.opacity>=1?0:l.opacity;d<1&&c.animate([{opacity:d},{opacity:1}],{duration:o*Xn,easing:`linear`,fill:`both`})}function $n(e,t){let{deltaX:n,deltaY:r,duration:i,ease:a}=t,{tx:o,ty:s}=_n(e);e.getAnimations().forEach(e=>e.cancel());let c=n+o,l=r+s;c===0&&l===0||e.animate({transform:`translate(${c}px, ${l}px)`,offset:0},{duration:i,easing:a,fill:`both`})}var er=6,tr=.8,nr=.45,rr=.35;function ir(e){let t=e.map(e=>e.getBoundingClientRect()),n=Math.min(...t.map(e=>e.left)),r=Math.max(...t.map(e=>e.right)),i=Math.min(...t.map(e=>e.top)),a=Math.max(...t.map(e=>e.bottom)),o=(n+r)/2,s=(i+a)/2;return t.map(e=>`${o-e.left}px ${s-e.top}px`)}function ar(e,t){let{duration:n,ease:r}=t,i=ir(e);e.forEach((e,t)=>{e.getAnimations().forEach(e=>e.cancel()),e.style.transformOrigin=i[t],e.animate({transform:`scale(${tr})`,offset:1},{duration:n,easing:r,fill:`both`});let a=e.animate({opacity:0,offset:1},{duration:n*nr,easing:`linear`,fill:`both`});a.onfinish=()=>e.remove()})}function or(e,t){let{duration:n,ease:r}=t,i=ir(e);e.forEach((e,t)=>{let a=yn(e);e.style.transformOrigin=i[t],e.animate({transform:`scale(${tr})`,offset:0},{duration:n,easing:r,fill:`both`});let o=a.opacity>=1?0:a.opacity;e.animate([{opacity:o},{opacity:1}],{duration:n*rr,easing:`linear`,fill:`both`})})}function sr(e,t){let n=[],r=[],i=()=>{r.length>=er&&n.push(r),r=[]};for(let n of e)t.has(n)?r.push(n):i();return i(),n}var cr=`\0#`;function lr(e,t){if(e.segments.length!==1||e.word.length<=1)return e.segments;let n=e.segments[0],r=e.word.split(``).map((e,t)=>({id:`${n.id}:${t}`,string:e}));return t.set(n.id,r),r}function ur(e){return e.map(e=>({...e,kind:e.kind??At(e.string)}))}function dr(e,t){if(e.length===0||t.length===0)return 0;let[n]=_t(e.split(``),t.split(``));return n.length/Math.max(e.length,t.length)}function fr(e,t){let n=[],r=0;for(let i=0;is&&kt(e),l=e=>c(e)?cr:e,u=s&&(St(t)||o.some(e=>St(e.word)));if(o.length<=1&&!i&&!a&&!u)return{segments:qt(t,n,s),splits:new Map};let d=[],f=[],p=t.split(/( |\n)/),m=[];for(let e of p)e===` `||e===` +`?m.push(e):e.length>0&&(f.push(m),d.push(e),m=[]);let h=m,g=o.map(e=>e.word);if(g.length*d.length>gr)return{segments:qt(t,n,s),splits:new Map};let[_,v]=_t(g.map(l),d.map(l)),y=new Set(_),b=new Set(v),x=new Map;for(let e=0;et).filter(e=>!y.has(e)),C=d.map((e,t)=>t).filter(e=>!b.has(e)),w=new Set;for(let e of C)for(let t of S)if(!w.has(t)&&l(d[e])===l(g[t])){x.set(e,t),w.add(t);break}w.size>0&&(S=S.filter(e=>!w.has(e)),C=C.filter(e=>!x.has(e)));let T=new Map,E=new Set,D=fr(g.length,y),O=fr(d.length,b);if(S.length*C.length<=hr)for(let e of C){let t=-1,n=pr;for(let r of S){if(E.has(r)||D[r]!==O[e])continue;let i=mr(g[r],d[e]);i>n&&(n=i,t=r)}t>=0&&(T.set(e,t),E.add(t))}let k=d.map((e,t)=>{let n=x.get(t),r=n??T.get(t);return r===void 0?{mode:`fresh`}:c(e)?{mode:`number`,oi:r}:n===void 0?{mode:`morph`,oi:r}:{mode:`reuse`,oi:r}}),A=k.filter(e=>e.mode===`number`).length===1?r.cursorIndex:void 0,j=Mt(n),M=Wt();for(let e of k){if(e.mode===`fresh`)continue;let t=o[e.oi];if(e.mode!==`reuse`&&t.segments.length===1){let e=t.segments[0];for(let n=0;n0?[` `]:[]));let t=k[e],n=d[e];if(t.mode===`reuse`)for(let e of o[t.oi].segments)N.push(e);else if(t.mode===`number`){let e=o[t.oi];N.push(...Nt(n,ur(lr(e,P)),A===void 0?void 0:A-F,j))}else if(t.mode===`morph`){let e=o[t.oi],r=e.word,i=lr(e,P),a=r.split(``),s=n.split(``),[c,l]=_t(a,s),u=new Map;for(let e=0;e span { + display: inline-block; + will-change: opacity, transform; +} + +/* + * Softens the clip above into a gradient, positionally rather than on a timer, so + * it stays in step with the slide at any duration. The band (--torph-fade, 0 for a + * hard edge) must eat into the box: the clip trims at the border box, so a ramp + * reaching past it sits in territory already removed and is never seen. no-clip + * plus repeat-x is what carries the profile across glyph overhang. + */ +@supports (mask-clip: no-clip) or (-webkit-mask-clip: no-clip) { + [${nn}] { + --torph-mask: linear-gradient( + to bottom, + transparent, + #000 var(--torph-fade, 0.15em), + #000 calc(100% - var(--torph-fade, 0.15em)), + transparent + ); + -webkit-mask-image: var(--torph-mask); + mask-image: var(--torph-mask); + -webkit-mask-repeat: repeat-x; + mask-repeat: repeat-x; + -webkit-mask-clip: no-clip; + mask-clip: no-clip; + } +} + +[${Qt}][${on}] { + outline: 2px solid magenta; + [${$t}] { + outline: 2px solid cyan; + outline-offset: -4px; + } +}`,yr=null,br=0;function xr(){br++,!yr&&(yr=document.createElement(`style`),yr.dataset.torph=`true`,yr.textContent=vr,document.head.appendChild(yr))}function Sr(){br--,!(br>0||!yr)&&(yr.remove(),yr=null)}function Cr(){if(typeof window>`u`)return{prefersReducedMotion:!1,destroy:()=>{}};let e=window.matchMedia(`(prefers-reduced-motion: reduce)`),t={prefersReducedMotion:e.matches,destroy:r};function n(e){t.prefersReducedMotion=e.matches}function r(){e.removeEventListener(`change`,n)}return e.addEventListener(`change`,n),t}var wr={...dt,debug:!1,scale:!0,numbers:!0},Tr=class{element;options={};data;currentMeasures={};prevMeasures={};previousSegments=[];isInitialRender=!0;reducedMotion=null;srNode=null;hasSetup=!1;constructor(e){let t=Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0)),{ease:n,...r}={...wr,...t},{ease:i,duration:a}=mt(n,r.duration);this.options={...r,ease:i,duration:a},this.element=e.element,this.options.respectReducedMotion&&(this.reducedMotion=Cr()),this.data=``,this.isDisabled()||this.setup()}setup(){this.hasSetup||(this.hasSetup=!0,this.element.setAttribute(Qt,``),this.options.debug&&this.element.setAttribute(on,``),xr())}destroy(){this.reducedMotion?.destroy(),Nn(this.element),this.element.getAnimations().forEach(e=>e.cancel()),this.srNode?.remove(),this.srNode=null,this.element.removeAttribute(Qt),this.element.removeAttribute(on),this.hasSetup&&(this.hasSetup=!1,Sr())}isDisabled(){return!!(this.options.disabled||this.reducedMotion?.prefersReducedMotion)}update(e,t){let n=typeof e==`number`?e.toLocaleString(this.options.locale,{minimumFractionDigits:this.options.decimals,maximumFractionDigits:this.options.decimals}):e;if(n!==this.data){if(this.data=n,this.isDisabled()){typeof n==`string`&&(this.srNode=null,this.element.textContent=n,this.previousSegments=[],this.isInitialRender=!0);return}if(this.setup(),this.data instanceof HTMLElement)throw Error(`HTMLElement not yet supported`);this.options.onAnimationStart&&!this.isInitialRender&&this.options.onAnimationStart(),this.createTextGroup(this.data,this.element,t)}}createTextGroup(e,t,n){let{width:r,height:i}=vn(t),a=this.options.numbers!==!1;this.syncAccessibleText(e);let o,s;if(this.previousSegments.length>0){let t=_r(this.previousSegments,e,this.options.locale,{numbers:a,cursorIndex:n});o=t.segments,s=t.splits}else o=qt(e,this.options.locale,a),s=new Map;let c=o.length===0;c&&(o=[{id:sn,string:`​`}]),Gn(t,s),this.prevMeasures=In(this.element);let l=Array.from(t.children).filter(e=>!e.hasAttribute(an)),u=new Set(o.map(e=>e.id)),d=l.filter(e=>!u.has(e.getAttribute(en))&&!e.hasAttribute(rn)),f=zn(l,new Set(d),l.map(e=>e.getAttribute(en)),u);Wn(t,d),Jn(t,l,u,o),this.currentMeasures=In(this.element);let p=o.reduce((e,t)=>t.string===` +`?e+1:e,1),m=(t.offsetHeight||20*p)/p;t.style.width=`${r}px`,t.offsetWidth;let h=In(this.element);t.style.width=``,this.updateStyles(o,h,m);let g=this.isInitialRender?[]:sr(l,new Set(d)),_=new Set(g.flat());for(let e of g)ar(e,{duration:this.options.duration,ease:this.options.ease});if(d.forEach(e=>{if(this.isInitialRender||e.getAttribute(en)===sn){e.remove();return}if(_.has(e))return;let t=f.get(e),{dx:n,dy:r}=t?Ln(this.currentMeasures,this.prevMeasures,t):{dx:0,dy:0};e.hasAttribute(tn)?Zn(e,{dx:n,dy:r,slideDistance:m,duration:this.options.duration,ease:this.options.ease}):Bn(e,{dx:n,dy:r,duration:this.options.duration,ease:this.options.ease,scale:this.options.scale})}),this.previousSegments=o,this.isInitialRender){this.isInitialRender=!1,t.style.width=``,t.style.height=``;return}c?Fn(t,r,i,this.options.duration,this.options.onAnimationComplete,this.options.onAnimationCancel):Pn(t,r,i,this.options.duration,this.options.ease,this.options.onAnimationComplete,this.options.onAnimationCancel)}updateStyles(e,t,n){if(this.isInitialRender)return;let r=Array.from(this.element.children).filter(e=>!e.hasAttribute(an)),i=e.map(e=>e.id),a=new Map(e.map(e=>[e.id,e.kind])),o=r.filter(e=>!e.hasAttribute(rn)&&e.tagName!==`BR`&&e.getAttribute(en)!==sn),s=new Set(o.filter(e=>!this.prevMeasures[e.getAttribute(en)])),c=new Set;for(let e of sr(o,s))e.forEach(e=>c.add(e)),or(e,{duration:this.options.duration,ease:this.options.ease});let l=new Set(i.filter(e=>this.prevMeasures[e]));r.forEach((r,o)=>{if(r.hasAttribute(rn)||r.tagName===`BR`||c.has(r))return;let s=r.getAttribute(en)||`child-${o}`;if(s===sn)return;let u=!this.prevMeasures[s],d=u?Rn(e.findIndex(e=>e.id===s),i,l):s,{dx:f,dy:p}=d?Ln(this.prevMeasures,t,d):{dx:0,dy:0},m=a.get(s);m&&u?Qn(r,{deltaX:f,deltaY:p,slideDistance:n,kind:m,duration:this.options.duration,ease:this.options.ease}):m?$n(r,{deltaX:f,deltaY:p,duration:this.options.duration,ease:this.options.ease}):Vn(r,{deltaX:f,deltaY:p,isNew:u,duration:this.options.duration,ease:this.options.ease})})}syncAccessibleText(e){if(!this.srNode||this.srNode.parentNode!==this.element){let e=document.createElement(`span`);e.setAttribute(an,``),this.element.prepend(e),this.srNode=e}this.srNode.textContent=e}},Er=new Map,Dr=0;function Or(e,t){Er.set(e,t),!Dr&&(Dr=requestAnimationFrame(()=>{Dr=0;let e=[...Er.values()];Er.clear();for(let t of e)t()}))}var kr=new Map,Ar=null,jr=null,Mr=null;function Nr(){for(let{update:e}of kr.values())e()}function Pr(e,t){return Ar||(Mr=matchMedia(`(prefers-reduced-motion: reduce)`),Mr.addEventListener(`change`,Nr),document.addEventListener(`visibilitychange`,Nr),document.addEventListener(`selectionchange`,Nr),Ar=new IntersectionObserver(e=>{for(let t of e){let e=kr.get(t.target);e&&(e.visible=t.isIntersecting,e.update())}}),jr=new ResizeObserver(e=>{for(let t of e)kr.get(t.target)?.update()})),kr.set(e,{visible:!1,update:t}),Ar.observe(e),jr.observe(e),()=>{Er.delete(e),kr.delete(e),Ar.unobserve(e),jr.unobserve(e),!kr.size&&(Ar.disconnect(),jr.disconnect(),Ar=null,jr=null,Mr.removeEventListener(`change`,Nr),Mr=null,document.removeEventListener(`visibilitychange`,Nr),document.removeEventListener(`selectionchange`,Nr),Dr&&cancelAnimationFrame(Dr),Dr=0)}}function Fr(e,t){let n=e.parentElement,r=n.querySelector(`.morph-source`),i=t,a=null,o=``,s=!1;function c(){a?.destroy(),a=null,e.replaceChildren(),e.removeAttribute(`style`),n.removeAttribute(`data-morph-active`)}function l(){if(s)return;let t=document.getSelection();if(!(!i.disabled&&!Mr?.matches&&!document.hidden&&kr.get(n)?.visible&&!n.closest(`[inert]`)&&(!t||t.isCollapsed)&&i.text.length<=100&&!i.text.includes(` +`))){c();return}let l=getComputedStyle(r),u=Number.parseFloat(l.lineHeight)||Number.parseFloat(l.fontSize)*1.4;if(r.getBoundingClientRect().height>u*1.5){c();return}let d=i.numbers&&!/[eE][+-]?\d/.test(i.text),f=JSON.stringify([i.duration,d,i.identity,n.closest(`[data-morph-snapshot]`)?.getAttribute(`data-morph-snapshot`)]);(!a||o!==f)&&(c(),o=f,a=new Tr({element:e,numbers:d,duration:i.duration,ease:`cubic-bezier(0.2, 0, 0, 1)`,scale:!1,respectReducedMotion:!1,onAnimationComplete:()=>requestAnimationFrame(()=>{if(!s)for(let t of e.getAnimations({subtree:!0}))t.playState===`finished`&&t.cancel()})})),a.update(i.text),n.setAttribute(`data-morph-active`,``)}let u=()=>Or(n,l),d=Pr(n,u);return document.fonts.ready.then(()=>{s||u()}),{update(e){i=e,n.removeAttribute(`data-morph-active`),u()},destroy(){s=!0,d(),c()}}}var Ir=e(` `);function Z(e,n){let r=q(n,`numbers`,3,!0),a=q(n,`duration`,3,180),s=q(n,`disabled`,3,!1),c=q(n,`class`,3,``);var l=Ir(),u=J(l),d=J(u,!0);i(u),g(o(u),(e,t)=>Fr?.(e,t),()=>({text:String(n.text),numbers:r(),duration:a(),disabled:s(),identity:n.identity})),i(l),W(e=>{D(l,1,`morph-text ${c()??``}`,`svelte-1d3hxj`),t(l,`data-text`,e),z(d,n.text)},[()=>String(n.text)]),B(e,l)}j();var Lr=ue(``);function Rr(e){B(e,Lr())}var zr=e=>e;function Br(e){let t=e-1;return t*t*t+1}function Vr(e){let t=typeof e==`string`&&e.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);return t?[parseFloat(t[1]),t[2]||`px`]:[e,`px`]}function Hr(e,{delay:t=0,duration:n=400,easing:r=zr}={}){let i=+getComputedStyle(e).opacity;return{delay:t,duration:n,easing:r,css:e=>`opacity: ${e*i}`}}function Ur(e,{delay:t=0,duration:n=400,easing:r=Br,x:i=0,y:a=0,opacity:o=0}={}){let s=getComputedStyle(e),c=+s.opacity,l=s.transform===`none`?``:s.transform,u=c*(1-o),[d,f]=Vr(i),[p,m]=Vr(a);return{delay:t,duration:n,easing:r,css:(e,t)=>` + transform: ${l} translate(${(1-e)*d}${f}, ${(1-e)*p}${m}); + opacity: ${c-u*t}`}}function Wr(e,{delay:t=0,duration:n=400,easing:r=Br,axis:i=`y`}={}){let a=getComputedStyle(e),o=+a.opacity,s=i===`y`?`height`:`width`,c=parseFloat(a[s]),l=i===`y`?[`top`,`bottom`]:[`left`,`right`],u=l.map(e=>`${e[0].toUpperCase()}${e.slice(1)}`),d=parseFloat(a[`padding${u[0]}`]),f=parseFloat(a[`padding${u[1]}`]),p=parseFloat(a[`margin${u[0]}`]),m=parseFloat(a[`margin${u[1]}`]),h=parseFloat(a[`border${u[0]}Width`]),g=parseFloat(a[`border${u[1]}Width`]);return{delay:t,duration:n,easing:r,css:e=>`overflow: hidden;opacity: ${Math.min(e*20,1)*o};${s}: ${e*c}px;padding-${l[0]}: ${e*d}px;padding-${l[1]}: ${e*f}px;margin-${l[0]}: ${e*p}px;margin-${l[1]}: ${e*m}px;border-${l[0]}-width: ${e*h}px;border-${l[1]}-width: ${e*g}px;min-${s}: 0`}}var Gr=e(``);function Kr(e,n){let r=q(n,`label`,3,`Close drawer`);var a=Gr();Ke(J(a),{name:`dismiss`}),i(a),W(()=>t(a,`aria-label`,r())),G(`click`,a,function(...e){n.onclick?.apply(this,e)}),B(e,a)}ke([`click`]);var qr=[`forEach`,`isDisjointFrom`,`isSubsetOf`,`isSupersetOf`],Jr=[`difference`,`intersection`,`symmetricDifference`,`union`],Yr=!1,Xr=class e extends Set{#e=new Map;#t=E(0);#n=E(0);#r=le||-1;constructor(e){if(super(),e){for(var t of e)super.add(t);this.#n.v=super.size}Yr||this.#a()}#i(e){return le===this.#r?E(e):c(e)}#a(){Yr=!0;var t=e.prototype,n=Set.prototype;for(let e of qr)t[e]=function(...t){return H(this.#t),n[e].apply(this,t)};for(let r of Jr)t[r]=function(...t){return H(this.#t),new e(n[r].apply(this,t))}}has(e){var t=super.has(e),n=this.#e,r=n.get(e);if(r===void 0){if(!t)return H(this.#t),!1;r=this.#i(!0),n.set(e,r)}return H(r),t}add(e){return super.has(e)||(super.add(e),u(this.#n,super.size),F(this.#t)),this}delete(e){var t=super.delete(e),n=this.#e,r=n.get(e);return r!==void 0&&(n.delete(e),u(r,!1)),t&&(u(this.#n,super.size),F(this.#t)),t}clear(){if(super.size!==0){super.clear();var e=this.#e;for(var t of e.values())u(t,!1);e.clear(),u(this.#n,0),F(this.#t)}}keys(){return this.values()}values(){return H(this.#t),super.values()}entries(){return H(this.#t),super.entries()}[Symbol.iterator](){return this.keys()}get size(){return H(this.#n)}},Zr=class extends Map{#e=new Map;#t=E(0);#n=E(0);#r=le||-1;constructor(e){if(super(),e){for(var[t,n]of e)super.set(t,n);this.#n.v=super.size}}#i(e){return le===this.#r?E(e):c(e)}has(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else return H(this.#t),!1;return H(n),!0}forEach(e,t){this.#a(),super.forEach(e,t)}get(e){var t=this.#e,n=t.get(e);if(n===void 0)if(super.has(e))n=this.#i(0),t.set(e,n);else{H(this.#t);return}return H(n),super.get(e)}set(e,t){var n=this.#e,r=n.get(e),i=super.get(e),a=super.set(e,t),o=this.#t;if(r===void 0)r=this.#i(0),n.set(e,r),u(this.#n,super.size),F(o);else if(i!==t){F(r);var s=o.reactions===null?null:new Set(o.reactions);(s===null||!r.reactions?.every(e=>s.has(e)))&&F(o)}return a}delete(e){var t=this.#e,n=t.get(e),r=super.delete(e);return n!==void 0&&(t.delete(e),u(n,-1)),r&&(u(this.#n,super.size),F(this.#t)),r}clear(){if(super.size!==0){super.clear();var e=this.#e;u(this.#n,0);for(var t of e.values())u(t,-1);F(this.#t),e.clear()}}#a(){H(this.#t);var e=this.#e;if(this.#n.v!==e.size){for(var t of super.keys())if(!e.has(t)){var n=this.#i(0);e.set(t,n)}}for([,n]of this.#e)H(n)}keys(){return H(this.#t),super.keys()}values(){return this.#a(),super.values()}entries(){return this.#a(),super.entries()}[Symbol.iterator](){return this.entries()}get size(){return H(this.#n),super.size}},Qr=class{#e;#t;constructor(e,t){this.#e=e,this.#t=S(t)}get current(){return this.#t(),this.#e()}},$r=/\(.+\)/,ei=new Set([`all`,`print`,`screen`,`and`,`or`,`not`,`only`]),ti=class extends Qr{constructor(e,t){let n=$r.test(e)||e.split(/[\s,]+/).some(e=>ei.has(e.trim()))?e:`(${e})`,r=window.matchMedia(n);super(()=>r.matches,e=>we(r,`change`,e))}},ni=Pe(),ri=ni.sessions,ii=ni.profiles,ai=ni.probes,oi=ni.manifolds,si=ni.templates,ci=ni.tree,li=ni.instruments;function ui(e,t,n,r){return ni.manifolds.fit(e,t,n,r)}function di(e,t){return ni.manifolds.install(e,t)}function fi(e,t){return ni.manifolds.generate(e,t)}var pi=96,mi=96,hi=new Map,gi=[],_i={geometry:0,lens:0,sae:0},vi=null;function yi(e,t,n,r,i,a=`interactive`){let o=Oi(e,t,n,r),s=hi.get(o);if(s)ki(o,s),s.state===`queued`&&a===`interactive`&&Ci(s);else{if(gi.length>=mi)return Promise.reject(Error(`The token reading queue is full. Wait for a reading to finish, then select this token again.`));let i,c,l=new Promise((e,t)=>{i=e,c=t});s={key:o,family:e,nodeId:t,rawIndex:n,options:{...r},priority:a,promise:l,resolve:i,reject:c,progress:null,listeners:new Set,state:`queued`,invalidated:!1},hi.set(o,s),Si(s)}if(i&&(s.listeners.add(i),s.progress&&i(s.progress)),wi(),Ei(),!i)return s.promise;let c=s;return s.promise.finally(()=>c.listeners.delete(i))}function bi(e){return _i[e]}function xi(e){let t=e?[e]:[`geometry`,`lens`,`sae`];for(let e of t)_i[e]+=1;for(let[e,n]of hi)t.includes(n.family)&&(hi.delete(e),n.invalidated=!0,n.state!==`settled`&&(n.reject(Error(`The conversation or reading source changed. Select the token again to get a current reading.`)),n.listeners.clear()));for(let e=gi.length-1;e>=0;--e)gi[e].invalidated&&gi.splice(e,1);Ei()}function Si(e){e.priority===`interactive`?gi.unshift(e):gi.push(e)}function Ci(e){e.priority=`interactive`;let t=gi.indexOf(e);t<=0||(gi.splice(t,1),gi.unshift(e))}function wi(){if(vi||gi.length===0)return;let e=gi.shift();vi=e,e.state=`active`,Ti(e)}async function Ti(e){try{let t=await li.tokenReadout(e.family,e.nodeId,e.rawIndex,e.options,void 0,t=>Di(e,t));if(e.invalidated)return;let n=t.measurements.instruments[e.family];if(!n||e.family!==`geometry`&&(!(`readout`in n)||!n.readout))throw Error(`No reading was returned for this token. Check the active reading source and try again.`);e.state=`settled`,hi.get(e.key)===e&&ki(e.key,e),e.resolve(t)}catch(t){hi.get(e.key)===e&&hi.delete(e.key),e.reject(t)}finally{e.listeners.clear(),vi===e&&(vi=null),Ai(),wi(),Ei()}}function Ei(){let e=vi===null?0:1;for(let t=0;tsetTimeout(e,r))}}catch(e){o.error=Ni(e)}finally{o.polling=!1}}}return{state:o,async start(r={}){if(!(o.running||o.polling)){try{s(await li.startPreparation(e,{operation:t,...r}))}catch(e){o.running=!1,o.error=Ni(e),X(`${n}: ${o.error}`,{kind:`error`});return}l()}},async cancel(){if(!(!o.running||o.cancelling)){o.cancelling=!0;try{s(await li.cancelPreparation(e)),X(`${n} cancelling…`,{kind:`info`})}catch(e){o.cancelling=!1,X(`${n} cancel: ${Ni(e)}`,{kind:`error`})}}},async check(){if(!o.polling)try{let n=await li.preparationStatus(e);if(n.operation!==t)return;s(n),n.state===`running`&&l()}catch{}}}}var Fi=2**53-1;function Ii(e,t){return t??Fi}function Li(e,t){return Ii(e?.runtimeClass,t)}function Ri(e,t){return Math.min(e,t)}var zi=34028234663852886e22,Bi=2**53-1,Vi=2**53-1,Hi=2**53-1;function Ui(e){return e===`http`?Bi:e===`browser`?Vi:0}function Wi(e){return e===`http`?8:e===`browser`?5:0}function Gi(e,t){return Math.max(0,Math.min(Ui(t),Math.floor(e)))}var Ki=.5,qi=`__surprise__`,Ji=`__entropy__`;function Yi(e){let t=/^(.+)\[(\d+)\]$/.exec(e);return t?{base:t[1],axis:Number(t[2])}:{base:e,axis:0}}function Xi(e,t){let{base:n,axis:r}=Yi(t),i=e.coordsByProbe?.[n];if(i&&r1e-6?t:Ki)));if(r===0)return`transparent`;let i=(Math.abs(r)*ia*100).toFixed(1);return`color-mix(in srgb, ${n===`surprise`?na:n===`sae`?ra:r>0?ea:ta} ${i}%, transparent)`}function oa(e){return e===`__surprise__`||e===`__probability__`||e===`__entropy__`||e?.startsWith(`jlens/`)?`surprise`:e?.startsWith(`sae/`)?`sae`:`signed`}function sa(e,t=0){if(!e||e.length===0)return 1;let n=0;for(let r of e){let e=r?.[t];if(typeof e==`number`&&Number.isFinite(e)){let t=Math.abs(e);t>n&&(n=t)}}return n>1e-6?n:1}function ca(e,t,n=Ki,r=Ki,i=`signed`,a=`signed`){let o=aa(e,n,i),s=aa(t,r,a);return{backgroundImage:`linear-gradient(to bottom, ${o} 0%, ${o} 50%, ${s} 50%, ${s} 100%)`}}function la(e,t,n=Ki,r=Ki,i=`signed`,a=`signed`){return{backgroundImage:`linear-gradient(to bottom, ${aa(e,n,i)}, ${aa(t,r,a)})`}}function ua(e,t=null,n=!1,r=Ki,i=Ki,a=`signed`,o=`signed`){if(t==null){let t=aa(e,r,a);return t===`transparent`?{}:{backgroundColor:t}}return n?la(e,t,r,i,a,o):ca(e,t,r,i,a,o)}var da={BOTH:null,BEFORE:`before`,AFTER:`after`,THINKING:`thinking`,RESPONSE:`response`,PROMPT:`before`,GENERATED:`response`};function fa(e,t=1){let n=[];for(let[r,i]of e)i.enabled&&i.mode===`subspace`&&n.push(pa(r,i,t));for(let[t,r]of e)r.enabled&&r.mode===`jlens`&&n.push(_a(t,r));for(let[t,r]of e)r.enabled&&r.mode===`sae`&&n.push(va(t,r));for(let[t,r]of e)r.enabled&&r.mode===`manifold`&&n.push(ya(t,r));if(n.length===0)return``;let r=n[0];for(let e=1;eha(e)).join(`,`),i=`${ma(e,t.variant)}%${r}`;return`${ha(n)} ${i}${ga(t.trigger)}`}function ma(e,t){return t===`raw`?e:`${e}:${t}`}function ha(e){return Number.isNaN(e)||!Number.isFinite(e)?`0`:String(e)}function ga(e){let t=da[e];return t?`@${t}`:``}function _a(e,t){return`${ha(t.alpha)} ${t.ablate?`!`:``}${e}${ga(t.trigger)}`}function va(e,t){return`${ha(t.alpha)} ${t.ablate?`!`:``}${e}${ga(t.trigger)}`}function ya(e,t){let n=t.label?t.label:t.coords.map(e=>ha(e)).join(`,`),r=`${ma(e,t.variant)}%${n}`;return`${(t.onto??0)>0?`${ha(t.blend)},${ha(t.onto)}`:ha(t.blend)} ${r}${ga(t.trigger)}`}var ba=ze({entries:[],index:null,stash:``,pulledSlot:null}),xa=ze({rev:0,text:``});function Sa(e){xa.text=e,xa.rev+=1}function Ca(e){let t=e.trim();if(!t)return;let n=ba.entries;if((n.length>0?n[n.length-1]:null)!==t){let e=[...n,t];ba.entries=e.length>200?e.slice(e.length-200):e}ba.index=null,ba.stash=``,ba.pulledSlot=null}function wa(e,t){let n=ba.entries,r=ka.queue,i=r.filter(e=>e.rebuild!==null),a=i.length,o=n.length;if(a===0&&o===0)return null;let s=Ta(i),c;if(s<0){if(e>0)return null;ba.stash=t,c=0}else if(c=s+(e<0?1:-1),c>=a+o)c=a+o-1;else if(c<0){ba.pulledSlot=null,ba.index=null;let e=ba.stash;return ba.stash=``,e}if(c=0?t:null,ba.index=null,e.text}return ba.pulledSlot=null,ba.index=o-1-(c-a),n[ba.index]}function Ta(e){let t=e.length;if(ba.pulledSlot!==null){let n=ka.queue[ba.pulledSlot];if(n!==void 0){let r=e.indexOf(n);if(r>=0)return t-1-r}}if(ba.index!==null){let e=ba.entries.length;if(ba.index>=0&&ba.index=0&&rt.id!==e)}var Fa=`rack`;function Ia(e,t){if(!($.active||ka.queue.length>0)){t();return}let n=ka.queue,r=n[n.length-1];if(r&&r.coalesceKey===Fa){let i=r.apply;n[n.length-1]={...r,label:e,apply:async()=>{await i(),await t()}};return}Ma({label:e,text:null,apply:t,awaitsGen:!1,rebuild:null,coalesceKey:Fa})}function La(){return $.active||ka.queue.length>0}var Ra=ze({entries:new Zr,customExpression:null,subspaceAlong:.5,profiles:new Zr,correlation:null,catalog:[],loading:!1,error:null}),za=ze({names:[]}),Ba=0;function Va(){Ba+=1,Ra.correlation=null}async function Ha(){let e=await ii.list();za.names=e.profiles.map(e=>e.name),Ra.profiles.clear();for(let t of e.profiles)Ra.profiles.set(t.name,t)}async function Ua(e){let t=Ba;try{let n=await ii.correlation(e);t===Ba&&(Ra.correlation=n)}catch{t===Ba&&(Ra.correlation=null)}}function Wa(e=[],t=null,n=`raw`){return{mode:`subspace`,ablate:!1,coords:e,label:t,variant:n,trigger:`BOTH`,enabled:!0}}function Ga(e,t){let n=Ra.entries.get(e);n&&n.mode===`subspace`&&Ra.entries.set(e,t(n))}function Ka(e){Ia(`subspace along ${e.toFixed(3)}`,()=>{Ra.subspaceAlong=e})}function qa(e,t){Ia(`subspace coords ${e}`,()=>{Ga(e,e=>({...e,coords:[...t],label:null}))})}function Ja(e,t){Ia(`subspace label ${e} ${t??``}`,()=>{if(t===null){Ga(e,e=>({...e,label:null}));return}let n=no(e);Ga(e,e=>{if(!n)return{...e,label:t};let r=n.node_labels.indexOf(t),i=r>=0&&n.node_coords[r]?[...n.node_coords[r]]:e.coords;return{...e,label:t,coords:i}})})}function Ya(e,t){Ia(`subspace trigger ${e} ${t}`,()=>{Ga(e,e=>({...e,trigger:t}))})}function Xa(e,t){Ia(`${t?`enable`:`disable`} ${e}`,()=>{Ga(e,e=>({...e,enabled:t}))})}function Za(e,t){Ia(`${t?`ablate`:`push`} ${e}`,()=>{Ga(e,e=>({...e,ablate:t}))})}function Qa(e,t=`raw`){if(Ra.entries.has(e))return;Ra.customExpression=null;let n=no(e),r=[],i=null;n&&n.node_count===2&&n.node_labels.length>0?(i=n.node_labels[0],r=n.node_coords?.[0]?[...n.node_coords[0]]:[]):n?r=ro(n):i=(e.includes(`/`)?e.slice(e.indexOf(`/`)+1):e).split(`.`)[0],Ra.entries.set(e,Wa(r,i,t))}function $a(e){Ra.entries.delete(e)}function eo(){return Ra.customExpression??fa(Ra.entries,Ra.subspaceAlong)}async function to(){Ra.loading=!0;try{Ra.catalog=(await oi.list()).manifolds,Ra.error=null}catch(e){Ra.catalog=[],Ra.error=Ie(e,`Saved directions could not be refreshed.`)}finally{Ra.loading=!1}}function no(e){for(let t of Ra.catalog)if(`${t.namespace}/${t.name}`===e||t.name===e)return t;return null}function ro(e){return e.domain.type===`box`?e.domain.axes.map(e=>(e.lo+e.hi)/2):Array(e.intrinsic_dim).fill(0)}function io(e,t){let n=Ra.entries.get(e);n&&n.mode===`manifold`&&Ra.entries.set(e,t(n))}function ao(e,t=`raw`){if(Ra.entries.has(e))return;Ra.customExpression=null;let n=no(e),r=n?ro(n):[];Ra.entries.set(e,{mode:`manifold`,blend:.5,onto:0,coords:r,label:null,variant:t,trigger:`BOTH`,enabled:!0})}function oo(e){Ra.entries.delete(e)}var so=.3,co={jlens:`jlens/`,sae:`sae/`};function lo(e,t){let n=(t,n)=>{let r=Ra.entries.get(t);r&&r.mode===e&&Ra.entries.set(t,n(r))};return{remove(e){Ra.entries.delete(e)},setAlpha(e,r){Ia(`${t} alpha ${e} ${r.toFixed(3)}`,()=>{n(e,e=>({...e,alpha:r}))})},setAblate(e,t){Ia(`${t?`ablate`:`push`} ${e}`,()=>{n(e,e=>({...e,ablate:t}))})},setEnabled(e,t){Ia(`${t?`enable`:`disable`} ${e}`,()=>{n(e,e=>({...e,enabled:t}))})},setTrigger(e,r){Ia(`${t} trigger ${e} ${r}`,()=>{n(e,e=>({...e,trigger:r}))})}}}var uo={jlens:lo(`jlens`,`jlens`),sae:lo(`sae`,`SAE`)};function fo(e){return uo[e]}function po(e,t){let n=`${co[e]}${t}`;Ra.entries.has(n)||(Ra.customExpression=null,Ra.entries.set(n,{mode:e,ablate:!1,alpha:so,trigger:`BOTH`,enabled:!0}))}function mo(e){let t=e.trim().replace(/^jlens\//,``);t&&po(`jlens`,t)}function ho(e){po(`sae`,String(e))}function go(e,t){Ia(`manifold blend ${e} ${t.toFixed(3)}`,()=>{io(e,e=>({...e,blend:t}))})}function _o(e,t){Ia(`manifold onto ${e} ${t.toFixed(3)}`,()=>{io(e,e=>({...e,onto:t}))})}function vo(e,t){Ia(`manifold coords ${e}`,()=>{io(e,e=>({...e,coords:[...t],label:null}))})}function yo(e,t){Ia(`manifold label ${e} ${t??``}`,()=>{if(t===null){io(e,e=>({...e,label:null}));return}let n=no(e);io(e,e=>{if(!n)return{...e,label:t};let r=n.node_labels.indexOf(t),i=r>=0&&n.node_coords[r]?[...n.node_coords[r]]:e.coords;return{...e,label:t,coords:i}})})}function bo(e,t){Ia(`manifold trigger ${e} ${t}`,()=>{io(e,e=>({...e,trigger:t}))})}function xo(e,t){Ia(`manifold ${t?`enable`:`disable`} ${e}`,()=>{io(e,e=>({...e,enabled:t}))})}function So(e,t){let n=e=>{let n=t[e];return typeof n==`number`&&Number.isFinite(n)?n:null},r=[],i=e.family===`geometry`?n(`${e.name}:fraction`):null;if(e.family===`geometry`)for(let t=0;t0?t.coords[0]:0}function Do(e,t){if(ji(t))return t.per_layer??{};if(e.family===`geometry`&&!e.is_affine)return t.fraction_per_layer??{};let n={};for(let[e,r]of Object.entries(t.coords_per_layer??{}))n[e]=Array.isArray(r)&&r.length>0?r[0]:0;return n}function Oo(e){let t=To.entries.get(e);if(!t||!Ts.active)return t;let n=Ts.probeReadings?.[e]??null;if(!n){let r=Ts.probes?.[e],i=null,a=Ts.coordsByProbe?.[e];r===void 0&&a?.[0]!==void 0&&(r=a[0]);let o={};for(let[t,n]of Object.entries(Ts.perLayerScores??{})){let r=n[e];typeof r==`number`&&Number.isFinite(r)&&(o[t]=r)}if(r===void 0&&t.info.family===`lens`){let e=t.info.word,n=Ts.lensAggregate?.find(([t])=>t===e);if(n){r=n[1];for(let[t,n]of Object.entries(Ts.lensReadout??{})){let r=n.find(([t])=>t===e);r&&(o[t]=r[1])}}}if(r===void 0&&t.info.family===`sae`){let e=Ts.saeReadout?.find(e=>e.id===t.info.feature_id);if(e){let n=e.max_act;r=n!=null&&n>0?e.activation/n:e.activation,i=n!=null&&n>0?`activation_over_max`:`raw_activation`;let a=t.info.layers[0];a!==void 0&&(o[String(a)]=r)}}if(r!==void 0){let e=r;if(t.info.family!==`geometry`)return{...t,current:e,sparkline:[e],perLayer:o,reading:{value:e,unit:i??(t.info.family===`lens`?`mean_token_probability`:t.info.max_act==null?`raw_activation`:`activation_over_max`),per_layer:o,depth:null},aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null};let s=t.info.is_affine,c=s?a??[e]:[],l=Object.fromEntries(Object.entries(o).map(([e,t])=>[e,[t]]));n={fraction:s?0:e,nearest:[],coords:c,residual:0,fraction_per_layer:s?{}:o,coords_per_layer:s?l:{},residual_per_layer:{}}}}if(!n)return{...t,current:0,previous:0,sparkline:[],perLayer:{},reading:null,aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:[],trajectory:[]};let r=Eo(t.info,n);return{...t,current:r,previous:r,sparkline:[r],perLayer:Do(t.info,n),reading:n,aggregate:n,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:ko(n),trajectory:[]}}function ko(e){return ji(e)?[]:e.nearest}function Ao(e){return e.family!==`geometry`||e.intrinsic_dim!==2?!1:e.domain?.type===`box`&&!!e.node_coords&&e.node_coords.length>0}function jo(e,t){let n=e.node_coords;if(!n)return null;let r=e.node_labels.indexOf(t);if(r<0||r>=n.length)return null;let i=n[r];return Array.isArray(i)?[...i]:null}function Mo(e){return e.family===`geometry`?{selector:e.manifold,name:e.name,top_n:e.top_n}:e.family===`lens`?{selector:`jlens/${e.word}`,name:e.name}:{selector:`sae/${e.feature_id}`,name:e.name}}function No(e,t=Mo(e)){return{request:t,info:e,sparkline:[],current:0,previous:0,perLayer:{},reading:null,aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:[],trajectory:[],subspaceTrail:[]}}function Po(e,t=0){let n=To.entries.get(e)?.info;return!n||n.family!==`geometry`?1:sa(n.node_coords,t)}function Fo(){let e=0;for(let t of To.active){let n=Oo(t);if(!n||n.info.family!==`sae`)continue;let r=n.aggregate??n.reading;r&&ji(r)&&r.unit===`activation_over_max`||(e=Math.max(e,n.current??0))}for(let t of Rs()){let n=Ts.active?void 0:ws.meta.get(t.id);t.max_act??n?.max_act??(e=Math.max(e,t.activation))}return Math.max(e,1)}function Io(e){if(!e||e===`__surprise__`||e===`__probability__`||e===`__entropy__`)return Ki;let{base:t,axis:n}=Yi(e),r=Oo(t);if(r?.info.family===`lens`||e.startsWith(`jlens/`))return 1;if(r?.info.family===`sae`){let e=r.aggregate??r.reading;return e&&ji(e)&&e.unit===`activation_over_max`?1:Fo()}return Po(t,n)}function Lo(){let e=[...To.active];return To.sortMode===`name`?e.sort():To.sortMode===`value`?e.sort((e,t)=>{let n=To.entries.get(e)?.current??0;return(To.entries.get(t)?.current??0)-n}):To.sortMode===`change`&&e.sort((e,t)=>{let n=To.entries.get(e),r=To.entries.get(t),i=Math.abs((n?.current??0)-(n?.previous??0));return Math.abs((r?.current??0)-(r?.previous??0))-i}),e}var Ro=0,zo=0;async function Bo(){let e=++Ro,t=zo;To.loading=!0;try{let n=await ai.list();if(e!==Ro||t!==zo)return;let r=new Set,i=new Set;for(let e of n.probes){r.add(e.name);let t=To.entries.get(e.name);JSON.stringify(t?.info)!==JSON.stringify(e)&&(i.add(e.family),t&&i.add(t.info.family)),t?To.entries.set(e.name,{...t,info:e}):To.entries.set(e.name,No(e))}for(let e of[...To.entries.keys()])r.has(e)||(i.add(To.entries.get(e).info.family),To.entries.delete(e));To.active=n.probes.map(e=>e.name);for(let e of i)xi(e);i.size>0&&(Va(),Jo()),To.error=null}catch(n){if(e!==Ro||t!==zo)return;To.error=Ie(n,`Live readings could not be refreshed.`)}finally{e===Ro&&(To.loading=!1)}}async function Vo(e,t={}){let n={selector:e,name:t.name,top_n:t.top_n},r=await ai.attach(n);zo+=1,To.error=null;let i={selector:e,name:r.name,...r.family===`geometry`?{top_n:t.top_n??r.top_n}:{}},a=To.entries.get(r.name);return a?To.entries.set(r.name,{...a,request:i,info:r}):To.entries.set(r.name,No(r,i)),To.active.includes(r.name)||(To.active=[...To.active,r.name]),xi(r.family),a&&a.info.family!==r.family&&xi(a.info.family),Va(),Yo.target===null&&(Yo.target=r.name),r}async function Ho(e){let t=To.entries.get(e)?.info.family;await ai.detach(e),zo+=1,To.error=null,To.entries.delete(e),To.active=To.active.filter(t=>t!==e),Va(),Yo.target===e&&(Yo.target=null),Yo.compareTarget===e&&(Yo.compareTarget=null),t&&xi(t)}function Uo(e){To.sortMode=e}function Wo(){for(let[e,t]of To.entries)To.entries.set(e,{...t,nearest:[],aggregate:null,savedAggregate:null,savedCoordinates:[],savedFraction:null,trajectory:[],subspaceTrail:[]})}function Go(e){if(e)for(let[t,n]of Object.entries(e)){let e=To.entries.get(t);if(!e)continue;let r=Eo(e.info,n),i=e.sparkline.slice();i.push(r),i.length>60&&i.splice(0,i.length-60);let a=e.trajectory,o=ko(n);if(Ao(e.info)&&o.length>0){let t=jo(e.info,o[0][0]);t&&(a=e.trajectory.slice(),a.push(t),a.length>Co&&a.splice(0,a.length-Co))}let s=e.subspaceTrail,c=ji(n)?void 0:n.subspace_coords_per_layer;c&&Object.keys(c).length>0&&(s=e.subspaceTrail.slice(),s.push({perLayer:c}),s.length>wo&&s.splice(0,s.length-wo)),To.entries.set(t,{...e,sparkline:i,current:r,previous:e.current,perLayer:Do(e.info,n),reading:n,savedAggregate:null,savedCoordinates:[],savedFraction:null,nearest:o,trajectory:a,subspaceTrail:s})}}function Ko(e){if(e)for(let[t,n]of Object.entries(e)){let e=To.entries.get(t);e&&To.entries.set(t,{...e,aggregate:n,savedAggregate:null,savedCoordinates:[],savedFraction:null,current:Eo(e.info,n),perLayer:Do(e.info,n),nearest:ko(n)})}}function qo(){for(let[e,t]of To.entries)To.entries.set(e,{...t,previous:t.current})}function Jo(){if(!Q.loaded||$.active)return;let e=(Q.active_node_id?Q.nodes.get(Q.active_node_id):void 0)?.aggregate_readings??{};for(let[t,n]of To.entries){let{value:r,coordinates:i,fraction:a}=So(n.info,e);To.entries.set(t,{...n,current:r??0,previous:n.current,perLayer:{},reading:null,aggregate:null,savedAggregate:r,savedCoordinates:i,savedFraction:a,nearest:[],trajectory:[],subspaceTrail:[]})}}var Yo=ze({target:qi,compareTarget:null,compareTwo:!1,smoothBlend:!1});function Xo(e){Yo.target=e}function Zo(e){Yo.compareTarget=e}function Qo(){Yo.compareTwo=!Yo.compareTwo}function $o(e){Yo.compareTwo=e}var es=ze({info:null,lastRefresh:null,error:null});function ts(e){return es.info?.instruments?.find(t=>t.family===e)}function ns(){return ts(`sae`)?.source!=null}async function rs(){try{es.info=await ri.get(),es.lastRefresh=Date.now(),es.error=null,ls(),rc()}catch(e){es.error=Ie(e,`The model details could not be refreshed.`)}}var is=ze({temperature:null,top_p:null,top_k:null,max_tokens:256,seed:null,system_prompt:``,stop_sequences:``,logit_bias_text:``,presence_penalty:0,frequency_penalty:0,user_role:`user`,assistant_role:`assistant`,thinking:!1,return_top_k:8});function as(e,t){if(e===`max_tokens`){is.max_tokens=Ri(t,cs());return}is[e]=t}var os=null,ss=ze({info:null});function cs(){return Li(ve()?.signals,se()?.snapshot.contextTokens??void 0)}function ls(){let e=es.info,t=se()?.snapshot.modelDefaults;e&&t?.model_id===e.model_id?ss.info=structuredClone(b(t)):e&&ss.info?.model_id!==e.model_id&&(ss.info=structuredClone(b(e)));let n=e?`${e.model_id}\0${e.default_user_role??``}\0${e.default_assistant_role??``}`:null;e&&os!==n&&(os=n,is.user_role=e.default_user_role??`user`,is.assistant_role=e.default_assistant_role??`assistant`);let r=e?.config;r&&(typeof r.max_tokens==`number`&&Number.isFinite(r.max_tokens)&&(is.max_tokens=Ri(r.max_tokens,cs())),typeof r.temperature==`number`&&(is.temperature=r.temperature),typeof r.top_p==`number`&&(is.top_p=r.top_p),is.top_k=r.top_k,typeof r.system_prompt==`string`&&(is.system_prompt=r.system_prompt),typeof r.thinking==`boolean`&&(is.thinking=r.thinking),is.return_top_k=Gi(is.return_top_k,Pe().mode))}var us={},ds=null;function fs(e){let t=e.max_tokens===void 0?e:{...e,max_tokens:Ri(e.max_tokens,cs())};return Object.assign(is,t),Object.assign(us,t),ds||=ps().finally(()=>{ds=null}),ds}async function ps(){for(;Object.keys(us).length>0;){let e=us;us={},es.info=await ri.patch(e),es.lastRefresh=Date.now(),Object.keys(us).length===0&&ls()}}function ms(){let e=is.stop_sequences.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);return e.length>0?e:null}function hs(){let e=is.logit_bias_text.trim();if(!e)return null;try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e={};for(let[n,r]of Object.entries(t)){let t=Number(r);Number.isFinite(t)&&(e[String(Number(n))]=t)}return Object.keys(e).length>0?e:null}}catch{}let t={};for(let n of e.split(/\r?\n/)){let e=n.match(/^\s*(-?\d+)\s*[:=,\s]\s*(-?\d+(?:\.\d+)?)\s*$/);e&&(t[String(Number(e[1]))]=Number(e[2]))}return Object.keys(t).length>0?t:null}function gs(){let e=ms(),t=hs(),n=Gi(is.return_top_k,Pe().mode);return{...e?{stop:e}:{},...t?{logit_bias:t}:{},...is.presence_penalty===0?{}:{presence_penalty:is.presence_penalty},...is.frequency_penalty===0?{}:{frequency_penalty:is.frequency_penalty},...n>0?{return_top_k:n}:{},..._s(is.user_role,es.info?.default_user_role,`user`,`user_role`),..._s(is.assistant_role,es.info?.default_assistant_role,`assistant`,`assistant_role`)}}function _s(e,t,n,r){let i=e.trim(),a=t?.trim()||n;return!i||i===a?{}:{[r]:i}}function vs(){let e={temperature:is.temperature,top_p:is.top_p,top_k:is.top_k,max_tokens:Ri(is.max_tokens,cs()),persist_per_layer_scores:!0,...To.active.length>0&&Xe(`probe_subspace_trails`).available?{persist_subspace_coords:!0}:{},...gs(),...is.seed===null?{}:{seed:is.seed}};return Object.keys(e).length>0?e:null}var ys=ze({layers:null,readout:null,aggregate:null,aggHistory:[],workspaceSortMode:`strength`,busy:!1}),bs=ze({sources:[],loading:!1,busy:!1,error:null});async function xs(){if(!bs.loading){bs.loading=!0;try{bs.sources=(await li.sources(`lens`)).sources,bs.error=null}catch(e){bs.error=Ie(e,`Word-likelihood sources could not be refreshed.`)}finally{bs.loading=!1}}}async function Ss(e){if(!(bs.busy||!e)){bs.busy=!0,bs.error=null;try{if(ts(`lens`)?.capabilities.source_switch===!0)ys.layers=(await li.setLensSource(e)).live_layers;else{let t=await li.activateInstalledPack(`lens`,{source:e});ys.layers=t.live.enabled&&`layers`in t.live?t.live.layers??[]:null}xi(`lens`),await rs(),await xs(),X(`J-lens · ${e}`,{kind:`info`})}catch(e){bs.error=Ie(e,`Word insights could not start. Close and reopen the model after changing its tools.`),X(`J-lens source: ${bs.error}`,{kind:`error`})}finally{bs.busy=!1}}}function Cs(e){ys.workspaceSortMode=e}var ws=ze({live:!1,readout:[],history:new Zr,meta:new Zr,release:null,layer:null,sortMode:`strength`,busy:!1}),Ts=ze({active:!1,key:null,tokenText:``,probeReadings:null,probes:null,coordsByProbe:null,perLayerScores:null,lensReadout:null,lensAggregate:null,saeReadout:null,lensLoading:!1,saeLoading:!1,lensError:null,saeError:null}),Es=140,Ds=null,Os=null;function ks(e,t,n){return`${es.info?.model_id??`unknown-model`}:${e}:${t}:${+!!n}`}function As(e){return e?{readout:Object.fromEntries(e.layers.map(e=>[String(e.layer),e.tokens.map(e=>[e.token,Math.exp(e.logprob)])])),aggregate:e.aggregate.map(e=>[e.token,e.strength,e.com,e.spread])}:null}function js(e){if(!e)return;let t=e.instruments.geometry?.readings,n=e.instruments.lens?.readings,r=e.instruments.sae?.readings;if(!(!t&&!n&&!r))return{...t??{},...n??{},...r??{}}}function Ms(e,t,n){return yi(`lens`,e,t,{topK:Mi(is.return_top_k),steered:!0,raw:n,layers:`all`},void 0,`background`).then(e=>As(e.measurements.instruments.lens?.readout))}function Ns(e,t,n){return yi(`sae`,e,t,{topK:Mi(is.return_top_k),steered:!0,raw:n},void 0,`background`).then(e=>e.measurements.instruments.sae?.readout?.features??[])}function Ps(e,t){Os!==null&&clearTimeout(Os),Ds!==null&&clearTimeout(Ds),Os=null,Ds=null;let n=Ll(),r=e.rawIndex??null,i=es.info?.model_id??`unknown-model`,a=t&&r!==null?ks(t,r,n):`live:${i}:${t??`none`}:${r??`none`}:${e.tokenId??`none`}`,o=e.measurements,s=o?.instruments.lens?.readout,c=o?.instruments.sae?.readout;Ts.active=!0,Ts.key=a,Ts.tokenText=e.text,Ts.probeReadings=js(o)??null,Ts.probes=o?.scores??e.probes??null,Ts.coordsByProbe=e.coordsByProbe??null,Ts.perLayerScores=o?.per_layer_scores??e.perLayerScores??null,Ts.lensReadout=null,Ts.lensAggregate=null,Ts.saeReadout=c?.features??null,Ts.lensLoading=!1,Ts.saeLoading=!1,Ts.lensError=null,Ts.saeError=null;let l=As(s);if(l&&(Ts.lensReadout=l.readout,Ts.lensAggregate=l.aggregate),!t||r===null)return;let u=s===void 0&&es.info?.jlens_fitted===!0&&ts(`lens`)?.capabilities.token_readout===!0,d=c===void 0&&ns()&&ts(`sae`)?.capabilities.token_readout===!0;Ts.lensLoading=u,Ts.saeLoading=d,!(!u&&!d)&&(Ds=setTimeout(()=>{Ds=null,u&&Ms(t,r,n).then(e=>{!Ts.active||Ts.key!==a||e&&(Ts.lensReadout=e.readout,Ts.lensAggregate=e.aggregate)}).catch(e=>{!Ts.active||Ts.key!==a||(Ts.lensError=Ie(e,`This token's word-likelihood reading could not be rebuilt. Try again, or close and reopen the model.`))}).finally(()=>{Ts.active&&Ts.key===a&&(Ts.lensLoading=!1)}),d&&Ns(t,r,n).then(e=>{!Ts.active||Ts.key!==a||(Ts.saeReadout=e)}).catch(e=>{!Ts.active||Ts.key!==a||(Ts.saeError=Ie(e,`This token's feature reading could not be rebuilt. Try again, or close and reopen the model.`))}).finally(()=>{Ts.active&&Ts.key===a&&(Ts.saeLoading=!1)})},Es))}function Fs(){Ds!==null&&clearTimeout(Ds),Os!==null&&clearTimeout(Os),Ds=null,Os=setTimeout(()=>{Ts.active=!1,Ts.key=null,Ts.tokenText=``,Ts.lensLoading=!1,Ts.saeLoading=!1,Ts.lensError=null,Ts.saeError=null,Os=null},45)}function Is(){return Ts.active?Ts.lensReadout:ys.readout}function Ls(){return Ts.active?Ts.lensAggregate:ys.aggregate}function Rs(){return Ts.active?Ts.saeReadout??[]:ws.readout}var zs=ze({sources:[],loading:!1,busy:!1,error:null});async function Bs(){if(!zs.loading){zs.loading=!0;try{zs.sources=(await li.sources(`sae`)).sources,zs.error=null}catch(e){zs.error=Ie(e,`Learned-feature sources could not be refreshed.`)}finally{zs.loading=!1}}}function Vs(e){ws.sortMode=e}var Hs=new Set,Us=0;function Ws(e){ws.readout=e;for(let t of e){let e=[...ws.history.get(t.id)??[],t.activation].slice(-60);ws.history.delete(t.id),ws.history.set(t.id,e),(t.max_act!=null||t.label!=null)&&ws.meta.set(t.id,{label:t.label??ws.meta.get(t.id)?.label??null,max_act:t.max_act??ws.meta.get(t.id)?.max_act??null})}for(;ws.history.size>512;){let e=ws.history.keys().next().value;if(e===void 0)break;ws.history.delete(e),ws.meta.delete(e),Hs.delete(e)}}async function Gs(){if(!ns())return;let e=[];for(let t of ws.history.keys())if(!(ws.meta.get(t)?.max_act!=null&&ws.meta.get(t)?.label?.trim())&&!Hs.has(t)&&(e.push(t),e.length>=64))break;if(e.length===0)return;for(let t of e)Hs.add(t);let t=Us;try{let n=await li.saeFeaturesMetadata(e);if(t!==Us)return;for(let t of e)Object.hasOwn(n.features,String(t))||Hs.delete(t);for(let[e,t]of Object.entries(n.features)){let n=ws.meta.get(Number(e));ws.meta.set(Number(e),{label:t.label??n?.label??null,max_act:t.max_act??n?.max_act??null})}}catch{if(t!==Us)return;for(let t of e)Hs.delete(t)}}async function Ks(e){if(!ws.busy){ws.busy=!0;try{let t=await li.setLive(`sae`,{enabled:e});ws.live=t.enabled,t.enabled||(Us++,ws.readout=[],ws.history.clear(),ws.meta.clear(),Hs.clear())}catch(e){X(`SAE live: `+Ie(e,`That learned-feature reading is not available.`),{kind:`error`})}finally{ws.busy=!1}}}var qs=Pi(`sae`,`fetch`,{label:`SAE fetch`,intervalMs:1e3,successMessage:`SAE loaded`,onSettled:async()=>{await rs(),await Bs(),await Bo()}});async function Js(e,t=null){let n=e.trim();if(n){if(ts(`sae`)?.capabilities.preparations.includes(`fetch`)===!0){await qs.start({release:n,layer:t});return}if(!zs.busy){zs.busy=!0,zs.error=null;try{await li.activateInstalledPack(`sae`,{source:n,layer:t}),xi(`sae`),await rs(),await Bs(),await Bo(),X(`SAE · ${n}`,{kind:`info`})}catch(e){zs.error=Ie(e,`Model features could not start. Close and reopen the model after changing its tools.`),X(`SAE source: ${zs.error}`,{kind:`error`})}finally{zs.busy=!1}}}}var Ys=ze({enabled:!0,busy:!1});async function Xs(e){if(!Ys.busy){Ys.busy=!0;try{Ys.enabled=(await li.setLive(`geometry`,{enabled:e})).enabled}catch(e){X(`probe live: `+Ie(e,`That concept reading is not available.`),{kind:`error`})}finally{Ys.busy=!1}}}var Zs=ze({tab:`subspace`});function Qs(e){Zs.tab=e}async function $s(e){if(!ys.busy){ys.busy=!0;try{let t=await li.setLive(`lens`,{enabled:e});ys.layers=t.enabled&&`layers`in t?t.layers??[]:null,t.enabled||(ys.readout=null,ys.aggregate=null,ys.aggHistory=[])}catch(e){X(`lens live: `+Ie(e,`Word-likelihood details could not be loaded.`),{kind:`error`})}finally{ys.busy=!1}}}var ec=Pi(`lens`,`fetch`,{label:`J-lens fetch`,intervalMs:1e3,successMessage:`J-lens active · live`,onSettled:async()=>{await rs(),await xs()}}),tc=null,nc=null;function rc(){let e=ts(`lens`),t=ts(`sae`),n=ts(`geometry`),r=e?.source??null,i=t===void 0?null:`${t.source??``}:${`layer`in t.live?t.live.layer??``:``}`;r!==tc&&xi(`lens`),i!==nc&&xi(`sae`),tc=r,nc=i,ys.layers=e?.live.enabled&&`layers`in e.live?e.live.layers:null,ws.live=t?.live.enabled===!0;let a=t?.source??null,o=t&&`layer`in t.live?t.live.layer:null;(a!==ws.release||o!==ws.layer)&&(Us++,ws.release=a,ws.layer=o,ws.readout=[],ws.history.clear(),ws.meta.clear(),Hs.clear()),Ys.enabled=n?.live.enabled!==!1}function ic(e){return e.replace(/\s+/g,` `).trim().toLowerCase()}function ac(e,t){let n=ic(t);return n.length>0&&ic(e).includes(n)}function oc(e,t){let n=e.replace(/\s+/g,` `).trim(),r=ic(t),i=r?n.toLowerCase().indexOf(r):-1;if(i<0)return{before:n.slice(0,150),match:``,after:n.length>150?`…`:``};let a=Math.max(0,i-45),o=Math.min(n.length,i+r.length+90);return{before:(a>0?`…`:``)+n.slice(a,i),match:n.slice(i,i+r.length),after:n.slice(i+r.length,o)+(o{lc.get(n)===r&&cc.set(n,e.label)}).catch(()=>{}).finally(()=>{lc.get(n)===r&&lc.delete(n)})}function fc(e){if(e===void 0){cc.clear(),lc.clear();return}for(let t of e)cc.delete(t),lc.delete(t)}var pc=ze({mode:`text`,expr:``,matchingIds:null,error:null,loading:!1}),mc=0;function hc(e){let t=/(?:^|,)\s*sort:(surprise|confidence)\s*(?=,|$)/gi,n=`default`,r=e.replace(t,(e,t)=>(n=t.toLowerCase(),``));return sc.siblingSort=n,r.replace(/,,+/g,`,`).replace(/^\s*,|,\s*$/g,``).trim()}async function gc(e,t=pc.mode){let n=++mc,r=Q.root_id,i=()=>n===mc&&r===Q.root_id;pc.expr=e,pc.mode=t;let a=e.trim();if(!a){pc.matchingIds=null,pc.error=null,pc.loading=!1,sc.siblingSort=`default`;return}let o=[...Q.nodes.values()];if(t===`text`){sc.siblingSort=`default`,pc.matchingIds=new Set(o.filter(e=>ac(e.text??``,a)).map(e=>e.id)),pc.error=null,pc.loading=!1;return}let s=hc(a);if(!s){pc.matchingIds=null,pc.error=null,pc.loading=!1;return}let c=s.split(`,`).map(e=>e.trim()).filter(Boolean),l=c.filter(e=>/^text:/i.test(e)).map(e=>e.slice(5).trim()),u=c.some(e=>e.toLowerCase()===`starred`),d=c.filter(e=>!/^text:/i.test(e)&&e.toLowerCase()!==`starred`).join(`,`),f=new Set(o.filter(e=>(!u||e.starred)&&l.every(t=>ac(e.text??``,t))).map(e=>e.id));pc.loading=!0,pc.error=null,pc.matchingIds=null;try{if(l.some(e=>!e))throw Error(`Enter words after text:.`);let e=d?(await ci.filter(d)).matching_node_ids:[...f];if(!i())return;pc.matchingIds=new Set(e.filter(e=>f.has(e)))}catch(e){if(!i())return;e instanceof fe?pc.error=Ie(e.body&&typeof e.body==`object`&&`detail`in e.body?String(e.body.detail):e.message,`The conversation could not be searched.`):pc.error=Ie(e,`The conversation could not be searched.`),pc.matchingIds=null}finally{i()&&(pc.loading=!1)}}function _c(){mc+=1,pc.expr=``,pc.matchingIds=null,pc.error=null,pc.loading=!1,sc.siblingSort=`default`}var vc=ze({nodeId:null});function yc(e){vc.nodeId=e}function bc(){vc.nodeId=null}var xc=ze({ids:[]});function Sc(e){xc.ids.indexOf(e)===-1?xc.ids=[...xc.ids,e]:xc.ids=xc.ids.filter(t=>t!==e)}function Cc(){xc.ids=[]}function wc(e,t={}){sc.modalRequest={seq:sc.modalRequest.seq+1,kind:e,nodeId:t.nodeId??Q.active_node_id,text:t.text??``,n:t.n??1}}function Tc(e,t,n){let r=[],i=null,a=()=>{i!==null&&n(i),i=null;let t=r;r=[];for(let n of t)e(n)};return{flush:a,push(e){r.push(e),r.length>=256?a():i===null&&(i=t(a))}}}var Ec={channel:null,unsubscribe:null,unsubscribeState:null,listeners:new Xr,opening:!1,recoveringGap:!1,treeRecovery:null,ready:null,flushTokens:null},Dc=null;function Oc(){if(Ec.opening&&Ec.channel&&Ec.ready)return Ec.ready.then(()=>Ec.channel);if(Ec.channel?.isOpen)return Ec.treeRecovery?Ec.treeRecovery.then(()=>Ec.channel):Promise.resolve(Ec.channel);Ec.flushTokens?.(),Ec.unsubscribe?.(),Ec.unsubscribeState?.();let e=ni.events;Ec.channel=e,Ec.opening=!0;let t=!0,n=null,r=[],i=[],a=!1,o=0,s=0,c=e=>{for(let t of Ec.listeners)try{t(e)}catch{}},l=Tc(({message:e,receivedAt:t})=>{Mc(e,t),c(e)},e=>requestAnimationFrame(e),e=>cancelAnimationFrame(e));Ec.flushTokens=l.flush;let u=e=>{if(a){i.push(e),e.type===`tree_mutated`&&(o=Math.max(o,e.rev));return}if(e.type===`token`&&typeof requestAnimationFrame==`function`&&(typeof document>`u`||document.visibilityState===`visible`)){l.push({message:e,receivedAt:performance.now()});return}if(l.flush(),Mc(e)===`tree_resync`&&e.type===`tree_mutated`){f(e.rev);return}c(e)},d=()=>{Ec.channel===e&&(l.flush(),Ec.flushTokens=null,s+=1,a=!1,o=0,i.length=0,Ec.unsubscribe?.(),Ec.unsubscribeState?.(),Ec.unsubscribe=null,Ec.unsubscribeState=null,Ec.channel=null,Ec.opening=!1,Ec.recoveringGap=!1,Ec.treeRecovery=null,Ec.ready=null)},f=t=>{if(o=Math.max(o,t),a||Ec.channel!==e)return;a=!0;let n=++s,r=(async()=>{try{let t=null;for(let r=0;r<3;r+=1){if(t=await ci.get(),Ec.channel!==e||n!==s)return;if(t.rev>=o)break}if(!t||t.rev{Ec.channel===e&&Ec.treeRecovery===r&&(Ec.treeRecovery=null)})},p=t=>{l.flush(),!(Ec.channel!==e||Ec.recoveringGap)&&(Ec.recoveringGap=!0,(async()=>{try{await e.stop();let n=await ci.get();if(Ec.channel!==e)return;Xc(n,{preserveLiveTokens:!1}),e.acknowledgeSnapshot(),u({type:`error`,code:t.code,message:`The event stream lost synchronization. Generation was stopped and the authoritative conversation was restored.`})}catch(t){if(Ec.channel!==e)return;let n=Ie(t,`The conversation could not be restored.`);e.close(),d(),u({type:`error`,code:`TREE_RESYNC_FAILED`,message:`The event stream could not be recovered: ${n}`})}finally{Ec.channel===e&&(Ec.recoveringGap=!1)}})())};Ec.unsubscribe=e.subscribe(e=>{t?r.push(e):e.type===`error`&&e.code===`EVENT_SEQUENCE_GAP`?p(e):u(e)}),Ec.unsubscribeState=e.subscribeState(r=>{if(r.state!==`closed`||r.expected||Ec.channel!==e)return;let i=r.reason??`The Drowse runtime connection closed unexpectedly`,a=Ie({code:`RUNTIME_CHANNEL_CLOSED`,message:i},`The local model connection closed. Reopen the model and try again.`);if(t){n=i;return}d(),Q.error=a,$.active||kl.pendingIndex!==null||Q.pendingNodeId!==null||Hl.processingAb||La()?u({type:`error`,code:`RUNTIME_CHANNEL_CLOSED`,message:i}):X(a,{kind:`error`,ttlMs:null})});let m=(async()=>{try{await e.open();let i=await ci.get();if(n||!e.isOpen)throw Error(n??`The Drowse runtime connection closed during setup`);Xc(i,{preserveLiveTokens:!1,allowRevisionRegression:!0}),t=!1;for(let e of r)e.type===`tree_mutated`&&e.rev<=i.rev||(e.type===`error`&&e.code===`EVENT_SEQUENCE_GAP`?p(e):u(e));if(r.length=0,Ec.treeRecovery&&await Ec.treeRecovery,Ec.channel!==e||!e.isOpen)throw Error(`The Drowse runtime connection closed during tree recovery`);await Promise.allSettled([rs(),Ha(),Bo(),Ua(),to()])}catch(n){throw t=!1,Q.error=Ie(n,`The conversation could not reconnect.`),X(`reconnect: ${Q.error}`,{kind:`error`}),e.close(),Ec.channel===e&&d(),n}finally{Ec.channel===e&&(Ec.opening=!1)}})();return Ec.ready=m,m.then(()=>e)}function kc(){Ec.flushTokens?.(),Ec.flushTokens=null,Ec.unsubscribe?.(),Ec.unsubscribeState?.(),Ec.channel?.close(),Ec.channel=null,Ec.unsubscribe=null,Ec.unsubscribeState=null,Ec.opening=!1,Ec.recoveringGap=!1,Ec.treeRecovery=null,Ec.ready=null}typeof window<`u`&&window.addEventListener(`beforeunload`,kc);function Ac(){return Hl.processingAb&&Hl.pendingTurnIdx!==null?kl.turns[Hl.pendingTurnIdx]?.abPair??null:kl.pendingIndex===null?null:kl.turns[kl.pendingIndex]??null}function jc(e){if(!e||Hl.processingAb||!Q.loaded||Q.pendingNodeId===e&&Q.active_node_id===e&&kl.pendingIndex!==null&&kl.turns[kl.pendingIndex]?.nodeId===e)return;if(Q.pendingNodeId=e,!Q.nodes.has(e)){Q.error=`The conversation lost sync while the reply was arriving. Reload it and try again.`,X(Q.error,{kind:`error`});return}Q.active_node_id=e,Hc(),qc();let t=kl.pendingIndex;if(t!==null){let n=kl.turns[t];n&&(n.nodeId=e,n.tokens=n.tokens??[],n.thinkingTokens=n.thinkingTokens??[])}}function Mc(e,t=performance.now()){switch(e.type){case`tree_mutated`:return e.cast&&(Vc.roster=e.cast),e.op===`restore`||!Qc(e)?`tree_resync`:void 0;case`started`:if($.active=!0,$.replay=null,$.tokensSoFar=0,$.startedAt=performance.now(),Dc=null,$.finishedAt=null,$.tokPerSec=0,$.ppl={logSum:0,count:0,mean:null},$.finishReason=null,Pl.responseTokens=[],Pl.thinkingTokens=[],Hl.processingAb||Wo(),e.node_id&&(Q.pendingNodeId=e.node_id,qc()),Hl.processingAb&&Hl.pendingTurnIdx!==null){let e=kl.turns[Hl.pendingTurnIdx];e&&(e.abPair={role:Hl.pendingRole??e.role,roleLabel:Hl.pendingRoleLabel??e.roleLabel,text:``,generated:!0,tokens:[],thinkingTokens:[]}),kl.pendingIndex=Hl.pendingTurnIdx}else if(Q.loaded&&e.node_id){qc();let e=kl.pendingIndex;if(e!==null){let t=kl.turns[e];t&&(t.tokens=t.tokens??[],t.thinkingTokens=t.thinkingTokens??[])}}else Q.loaded?(kl.pendingIndex=null,qc()):(Q.error=`The conversation was not ready when generation started. Reload it and try again.`,X(Q.error,{kind:`error`}));return;case`generation_progress`:jc(e.node_id),$.replay={completed:e.completed,total:e.total};return;case`token`:{jc(e.node_id);let n=Ac(),r=e.thinking?n?.thinkingTokens:n?.tokens;if(e.raw_index!=null&&e.raw_index<=(r?.findLast(e=>e.rawIndex!=null)?.rawIndex??-1))return;let i=e.raw_index==null||e.raw_index>=($.replay?.total??0);if(i&&($.tokensSoFar+=1),typeof e.perplexity==`number`&&Number.isFinite(e.perplexity)&&e.perplexity>0&&($.ppl.logSum+=Math.log(e.perplexity),$.ppl.count+=1,$.ppl.mean=Math.exp($.ppl.logSum/$.ppl.count)),i){let e=t;if(Dc===null)Dc=e;else{let t=(e-Dc)/1e3;t>0&&($.tokPerSec=($.tokensSoFar-1)/t)}}let a=e.measurements,o=js(a),s=a?.scores,c=As(a?.instruments.lens?.readout),l=c?.readout,u=c?.aggregate,d=a?.instruments.sae?.readout?.features,f={text:e.text,thinking:e.thinking,tokenId:e.token_id,perLayerScores:a?.per_layer_scores,probes:s,logprob:e.logprob??null,samplerEntropy:e.sampler_entropy??null,perplexity:e.perplexity??null,topAlts:e.top_alts??null,rawIndex:e.raw_index??null,measurements:a};if(s&&Yo.target){let e=s[Yo.target];typeof e==`number`&&(f.score=e)}if(o){let e={};for(let[t,n]of Object.entries(o)){let r=n.coords;Array.isArray(r)&&r.length>1&&(e[t]=r)}Object.keys(e).length>0&&(f.coordsByProbe=e)}let p=n;if(p&&(e.thinking?(p.thinking=!0,(p.thinkingTokens??=[]).push(f),Hl.processingAb||Pl.thinkingTokens.push(f)):(p.text=(p.text??``)+e.text,(p.tokens??=[]).push(f),Hl.processingAb||Pl.responseTokens.push(f))),!Hl.processingAb){if(Go(o),l&&(ys.readout=l),u){ys.aggregate=u;let e=u.map(([e,t])=>[e,t]);ys.aggHistory.push(e),ys.aggHistory.length>60&&ys.aggHistory.shift()}d&&Ws(d)}return}case`done`:{jc(e.node_id),$.active=!1,$.finishedAt=performance.now(),$.finishReason=e.result?.finish_reason??`stop`,Hl.processingAb||Ko(js(e.result?.measurements));let t=Ac();if(t){t.finishReason=e.result?.finish_reason??`stop`,t.tokensSoFar=e.result?.tokens??$.tokensSoFar,t.meanLogprob=e.result?.mean_logprob??null;let n=Fl($);n!==null&&(t.perplexity=n)}typeof e.result?.tokens==`number`&&Number.isFinite(e.result.tokens)&&($.tokensSoFar=Math.max(0,e.result.tokens-($.replay?.total??0)));let n=Hl.processingAb,r=kl.pendingIndex;if(kl.pendingIndex=null,Q.pendingNodeId&&(Q.pendingNodeId=null,Q.loaded&&qc()),n){Hl.processingAb=!1,Hl.pendingTurnIdx=null,Hl.pendingRole=null,Hl.pendingRoleLabel=null,Na();return}qo(),Ua(),Gs(),ql.enabled&&r!==null&&kl.turns[r]?.generated===!0&&Kl(r)||Na();return}case`error`:{$.active=!1,$.finishedAt=performance.now(),jc(e.node_id);let t=Hl.processingAb,n=Ie(e,`Generation stopped before the answer was complete. Try again or reopen the model.`);if(t&&Hl.pendingTurnIdx!==null){let e=kl.turns[Hl.pendingTurnIdx];e&&(e.abPair={role:`system`,text:`Alternative generation stopped: ${n}`})}else kl.turns=[...kl.turns,{role:`system`,text:`Drowse stopped: ${n}`}];kl.pendingIndex=null,Q.pendingNodeId&&(Q.pendingNodeId=null,Q.loaded&&qc()),X(`Generation: ${n}`,{kind:`error`,ttlMs:null}),Hl.processingAb=!1,Hl.pendingTurnIdx=null,Hl.pendingRole=null,Hl.pendingRoleLabel=null,Na();return}}}function Nc(e,t){return t===null?`append`:e===null?`generate`:`send`}function Pc(e,t,n,r){return{id:ja(),label:Nc(e,n),text:e,apply:()=>Ic(e,t,n,r),awaitsGen:!0,rebuild:e===null?null:e=>Pc(e,t,n,r),createdAt:Date.now(),endsOnUserNode:(n??t)===`user`?!0:(n??t)===`assistant`?!1:null}}async function Fc(e,t,n,r={}){if(!(e!==null&&e===``)){if(e!==null&&t===null)throw Error(`A text submission requires an authored role`);if(!(e===null&&n===null)){if(La()){let{replaceSlot:i,...a}=r,o=Pc(e,t,n,a);Ma({label:o.label,text:o.text,apply:o.apply,awaitsGen:o.awaitsGen,rebuild:o.rebuild,endsOnUserNode:o.endsOnUserNode},{replaceSlot:i??null});return}return Ic(e,t,n,r)}}}async function Ic(e,t,n,r={}){if(!Q.loaded&&(await $c(),!Q.loaded))throw Error(`Conversation tree is not ready; retry after it loads`);let i=await Oc(),a=r.steering===void 0?eo():r.steering,o=vs();$.maxTokens=o?.max_tokens??is.max_tokens;let s=r.parent_node_id,c=s===`active@drain`?Q.active_node_id:s,l={type:`submit`,text:e,authored_role:t,generated_role:n,steering:a||null,sampling:o,thinking:is.thinking??!1,raw:r.raw??!1,...r.authored_thinking?{authored_thinking:r.authored_thinking}:{},...c===void 0?{}:{parent_node_id:c},...r.n===void 0?{}:{n:r.n},...r.recipe_override===void 0?{}:{recipe_override:r.recipe_override}};i.send(l)}async function Lc(e={}){if(!Q.loaded&&(await $c(),!Q.loaded))throw Error(`Conversation tree is not ready; retry after it loads`);let t=await Oc(),n=e.steering===void 0?eo():e.steering,r=e.steering===void 0?n||null:n,i=vs();$.maxTokens=i?.max_tokens??is.max_tokens;let a={type:`generate`,...e.append_same_role===void 0?{}:{append_same_role:e.append_same_role},input:null,steering:r,sampling:i,thinking:is.thinking??!1,stateless:e.stateless??!1,raw:e.raw??!1,...e.parent_node_id===void 0?{}:{parent_node_id:e.parent_node_id},...e.n===void 0?{}:{n:e.n},...e.recipe_override===void 0?{}:{recipe_override:e.recipe_override},...e.generate_seat!==void 0&&e.generate_seat!==`assistant`?{generate_seat:e.generate_seat}:{}};t.send(a)}async function Rc(e,t,n,r=!1){let i=await Oc(),a={type:`generate`,fork_node_id:e,fork_raw_index:t,fork_alt_token_id:n,...r?{fork_seed:crypto.getRandomValues(new Uint32Array(1))[0]&2147483647}:{}};i.send(a)}async function zc(e,t,n){let r=await Oc(),i={type:`generate`,fork_node_id:e,fork_raw_index:t,fork_replacement_text:n};r.send(i)}function Bc(){Ec.flushTokens?.();let e=Ec.channel;e&&e.stop().catch(e=>{Ec.flushTokens?.(),Mc({type:`error`,code:`RUNTIME_STOP_FAILED`,message:Ie(e,`The model could not be stopped cleanly.`)})})}var Q=ze({loaded:!1,tree_format:null,drowse_version:null,session_id:null,name:null,root_id:null,active_node_id:null,nodes:new Zr,children_of:new Zr,rev:0,pendingNodeId:null,activePath:[],modelId:null,error:null}),Vc=ze({roster:{}});function Hc(){let e=Q.active_node_id;if(!e){Q.activePath=[];return}let t=[],n=e,r=new Set;for(;n&&!r.has(n);)r.add(n),t.push(n),n=Q.nodes.get(n)?.parent_id??null;Q.activePath=t.reverse()}function Uc(e){let t=e.measurements,n={text:e.text,thinking:!1};e.token_id!==void 0&&(n.tokenId=e.token_id),e.logprob!==void 0&&(n.logprob=e.logprob),e.sampler_entropy!==void 0&&(n.samplerEntropy=e.sampler_entropy),e.perplexity!==void 0&&(n.perplexity=e.perplexity),e.top_alts&&(n.topAlts=e.top_alts),e.raw_index!==void 0&&(n.rawIndex=e.raw_index);let r=t?.scores??e.probes;r&&(n.probes=r);let i=t?.per_layer_scores??e.per_layer_scores;i&&(n.perLayerScores=i),t&&(n.measurements=t);let a=js(t);if(a){let e={};for(let[t,n]of Object.entries(a))!ji(n)&&n.coords.length>1&&(e[t]=n.coords);Object.keys(e).length>0&&(n.coordsByProbe=e)}return n}function Wc(e){let t={role:e.role,text:e.text,roleLabel:e.role_label,nodeId:e.id,generated:e.recipe!==null,appliedSteering:e.applied_steering??null,aggregateReadings:e.aggregate_readings??void 0,finishReason:e.finish_reason??void 0};e.tokens&&e.tokens.length>0&&(t.tokens=e.tokens.map(e=>{let t=Uc(e);return t.thinking=!1,t}));let n=[...e.thinking_tokens??[],...e.tokens??[]].map(e=>e.perplexity).filter(e=>typeof e==`number`&&Number.isFinite(e)&&e>0);return n.length>0&&(t.perplexity=Math.exp(n.reduce((e,t)=>e+Math.log(t),0)/n.length)),e.thinking_tokens&&e.thinking_tokens.length>0?(t.thinkingTokens=e.thinking_tokens.map(e=>{let t=Uc(e);return t.thinking=!0,t}),t.thinking=!0):e.thinking_text&&(t.thinkingTokens=[{text:e.thinking_text,thinking:!0}],t.thinking=!0),t}function Gc(e,t){if(e===null)return;let n=Q.children_of.get(e)??[];n.includes(t)||Q.children_of.set(e,[...n,t])}function Kc(e){let{children:t,...n}=e;return Q.nodes.set(n.id,n),Q.children_of.has(n.id)||Q.children_of.set(n.id,[...t??[]]),n.parent_id===null?Q.root_id=n.id:Gc(n.parent_id,n.id),n}function qc(e=!0){if(!Q.loaded)return;let t=Q.activePath;if(t.length===0){kl.turns=[],kl.pendingIndex=null;return}let n=[],r=new Map(kl.turns.map(e=>[e.nodeId,e])),i=null;for(let a of t){let t=Q.nodes.get(a);if(!t||t.parent_id===null&&t.role===`system`&&!t.text)continue;let o=r.get(a),s;if(e&&o&&o.role===t.role&&o.nodeId===a){if(o.nodeId=a,(Q.pendingNodeId!==a||!$.active||t.finish_reason!==null)&&(o.text=t.text),o.generated=t.recipe!==null,o.appliedSteering=t.applied_steering??o.appliedSteering??null,o.aggregateReadings=t.aggregate_readings??o.aggregateReadings,o.finishReason=t.finish_reason??o.finishReason,t.finish_reason!==null||(o.tokens?.length??0)===0){let e=Wc(t);(e.tokens||e.thinkingTokens)&&(o.tokens=e.tokens,o.thinkingTokens=e.thinkingTokens)}s=o}else s=Wc(t);Q.pendingNodeId===a&&(i=n.length),n.push(s)}kl.turns=n,kl.pendingIndex=i}function Jc(e,t){let n=new Set,r=e=>{e.parent_id&&n.add(`${e.parent_id}|${e.id}`);for(let t of Q.children_of.get(e.id)??[])n.add(`${e.id}|${t}`)};for(let t of e){let e=Q.nodes.get(t.id);(!e||e.parent_id!==t.parent_id||(e.applied_steering??e.recipe?.steering??null)!==(t.applied_steering??t.recipe?.steering??null))&&(e&&r(e),r(t))}for(let e of t){let t=Q.nodes.get(e);t&&r(t)}fc(n)}function Yc(e,t){return t.length>0||e.some(e=>{let t=Q.nodes.get(e.id);return t?t.parent_id!==e.parent_id||t.role!==e.role||t.role_label!==e.role_label||t.text!==e.text||t.thinking_text!==e.thinking_text||t.applied_steering!==e.applied_steering||JSON.stringify(t.recipe)!==JSON.stringify(e.recipe)||t.raw_token_ids?.length!==e.raw_token_ids?.length||(t.raw_token_ids??[]).some((t,n)=>t!==e.raw_token_ids?.[n]):!1})}function Xc(e,t={}){if(Q.loaded&&!t.allowRevisionRegression&&e.model_id===Q.modelId&&e.root_id===Q.root_id&&e.session_id===Q.session_id&&e.reve.id)),n=[...Q.nodes.keys()].filter(e=>!t.has(e));Jc(e.nodes,n),Yc(e.nodes,n)&&xi()}else fc(),xi();Q.loaded=!0,Q.tree_format=e.tree_format,Q.drowse_version=e.drowse_version,Q.session_id=e.session_id,Q.name=e.name,Q.root_id=e.root_id,Q.active_node_id=e.active_node_id,Q.rev=e.rev,Q.modelId=e.model_id,Q.error=null,Q.nodes.clear();for(let t of e.nodes)Q.nodes.set(t.id,t);Q.children_of.clear();for(let[t,n]of Object.entries(e.children_of))Q.children_of.set(t,[...n]);return Vc.roster=e.cast,Hc(),qc(t.preserveLiveTokens??!0),Jo(),!0}function Zc(){if(!Q.loaded||!Q.root_id||!Q.active_node_id||Q.tree_format===null||Q.drowse_version===null)return null;let e=[];for(let[,t]of Q.nodes)e.push(t);let t={};for(let n of e)t[n.id]=[...Q.children_of.get(n.id)??[]];return{tree_format:Q.tree_format,drowse_version:Q.drowse_version,root_id:Q.root_id,active_node_id:Q.active_node_id,rev:Q.rev,nodes:e,children_of:t,model_id:Q.modelId??es.info?.model_id??null,session_id:Q.session_id,name:Q.name,cast:{...Vc.roster}}}function Qc(e){if(Q.loaded&&e.rev>Q.rev+1)return!1;Jc([...e.added??[],...e.updated??[]],e.removed??[]),Yc(e.updated??[],e.removed??[])&&xi();for(let t of e.added??[])Kc(t);for(let t of e.removed??[]){let e=Q.nodes.get(t);if(Q.nodes.delete(t),Q.children_of.delete(t),e?.parent_id){let n=Q.children_of.get(e.parent_id);n&&Q.children_of.set(e.parent_id,n.filter(e=>e!==t))}}for(let t of e.updated??[])Kc(t);if(e.active_node_id!==void 0&&e.active_node_id!==null&&(Q.active_node_id=e.active_node_id),Q.root_id!==null&&!Q.nodes.has(Q.root_id)){let t=(e.added??[]).find(e=>e.parent_id==null)??[...Q.nodes.values()].find(e=>e.parent_id==null);t&&(Q.root_id=t.id)}return Q.rev=e.rev,Hc(),qc(),Jo(),!0}async function $c(){if(!($.active&&Q.loaded))try{Xc(await ci.get(),{reconcileEdgeLabels:!0})}catch(e){let t=Ie(e,`The conversation map could not be refreshed.`);Q.loaded||(Q.error=t),X(`tree: ${t}`,{kind:`error`})}}function el(e,t){X(`${e}: ${Ie(t,`That conversation change could not be saved.`)}`,{kind:`error`})}var tl=`Finish or stop the current reply before deleting this branch.`;function nl(e){if(!$.active)return!1;let t=Q.pendingNodeId;if(!t||!Q.nodes.has(t)||e===t)return!0;let n=(e,t)=>{let n=Q.nodes.get(t)??null;for(;n?.parent_id;){if(n.parent_id===e)return!0;n=Q.nodes.get(n.parent_id)??null}return!1};return n(e,t)||n(t,e)}async function rl(e){try{await ci.navigate(e),await $c()}catch(e){el(`navigate`,e)}}async function il(e,t){try{await ci.edit(e,t),await $c()}catch(e){el(`edit`,e)}}async function al(e,t,n){try{let r=await ci.branch(e,t,void 0,n);return await $c(),r.node_id}catch(e){return el(`branch`,e),null}}async function ol(e){let t=Q.nodes.get(e);if(!t||t.role!==`user`&&t.role!==`assistant`)return null;let n=t.role===`user`?`assistant`:`user`;return al(e,t.text,n)}async function sl(e){if(nl(e))return X(tl,{kind:`warning`}),!1;try{let t=Q.nodes.get(e)?.parent_id;return t?(Q.activePath.includes(e)&&await ci.navigate(t),await ci.delete(e),await $c(),!0):!1}catch(e){return el(`delete`,e),!1}}async function cl(e,t){try{await ci.star(e,t),await $c()}catch(e){el(`star`,e)}}async function ll(e,t){try{await ci.note(e,t),await $c()}catch(e){el(`note`,e)}}async function ul(e,t=1,n={}){if(!Q.loaded)return;let r=Q.nodes.get(e);if(!r||r.role===`system`)return;let i=r.parent_id;if(i)try{await Lc({parent_node_id:i,append_same_role:!1,n:t,recipe_override:n.recipe_override??void 0,generate_seat:r.role})}catch(e){el(`regenerate`,e)}}async function dl(e=1,t={}){let n=Q.active_node_id;if(n)return ul(n,e,t)}async function fl(e,t={}){if(!Q.loaded)return;let n=Q.nodes.get(e);if(!(!n||n.role===`system`||n.recipe!==null))try{await Lc({parent_node_id:n.id,n:t.n??1,recipe_override:t.recipe_override??void 0,generate_seat:n.role===`user`?`assistant`:`user`})}catch(e){el(`regenerate`,e)}}var pl=new Set;function ml(e){return pl.add(e),()=>pl.delete(e)}var hl=4,gl=`drowse.chat.v4.`,_l=`drowse.chat.v3.`;function vl(){let e=es.info?.model_id;return e?gl+e:null}function yl(e){if(!e||typeof e!=`object`)return!1;let t=e;if(t.version!==hl||typeof t.model_id!=`string`||typeof t.saved_at!=`number`||!t.highlight||typeof t.highlight!=`object`)return!1;let n=t.highlight;return!(!(typeof n.target==`string`||n.target===null)||!(typeof n.compareTarget==`string`||n.compareTarget===null)||typeof n.compareTwo!=`boolean`)}function bl(e){try{return globalThis.localStorage?Ce(globalThis.localStorage,e):null}catch{return null}}function xl(e,t){try{globalThis.localStorage?.setItem(e,t)}catch{}}function Sl(e){try{globalThis.localStorage&&Ae(globalThis.localStorage,e)}catch{}}function Cl(){let e=vl();if(!e)return;let t=es.info?.model_id;t&&Sl(_l+t);let n=bl(e);if(n)try{let t=JSON.parse(n);if(!yl(t)){Sl(e);return}if(t.model_id!==es.info?.model_id)return;Q.pendingNodeId=null;let r=t.highlight.target===`__probability__`?qi:t.highlight.target,i=t.highlight.compareTarget===`__probability__`?qi:t.highlight.compareTarget;Yo.target=r,Yo.compareTarget=i===r?null:i,Yo.compareTwo=t.highlight.compareTwo&&Yo.compareTarget!==null}catch{Sl(e)}}var wl=null;function Tl(){wl||=setTimeout(()=>{wl=null;let e=vl();if(!e)return;let t={version:4,model_id:es.info.model_id,saved_at:Date.now(),highlight:{target:Yo.target,compareTarget:Yo.compareTarget,compareTwo:Yo.compareTwo}};xl(e,JSON.stringify(t))},250)}function El(){Ol?.();let e=Ee(()=>{U(()=>{if(Yo.target,Yo.compareTarget,Yo.compareTwo,!Dl){Dl=!0;return}Tl()})}),t=()=>{Ol===t&&(Ol=null,e(),wl!==null&&clearTimeout(wl),wl=null,Dl=!1)};return Ol=t,t}var Dl=!1,Ol=null;ml(()=>{wl!==null&&clearTimeout(wl),wl=null,Dl=!1});var kl=ze({turns:[],pendingIndex:null});function Al(e,t){return t||(e===`user`?es.info?.default_user_role??`user`:e===`assistant`?es.info?.default_assistant_role??`assistant`:e)}function jl(e,t){return(Al(e,t).charAt(0)||e.charAt(0)||`?`).toUpperCase()}async function Ml(){let e=Q.root_id;if(e!==null){await rl(e);return}throw Error(`Cannot clear chat before the tree root is loaded`)}function Nl(){$.active||ka.queue.length>0?Ma({label:`/clear`,text:null,apply:Ml,awaitsGen:!1,rebuild:null,endsOnUserNode:!1}):Ml()}var Pl=ze({responseTokens:[],thinkingTokens:[]}),$=ze({active:!1,tokensSoFar:0,maxTokens:0,startedAt:null,finishedAt:null,tokPerSec:0,ppl:{logSum:0,count:0,mean:null},finishReason:null});function Fl(e){return e.ppl.count<=0?null:Math.exp(e.ppl.logSum/e.ppl.count)}var Il=ze({mode:`chat`});function Ll(){return es.info?.is_base_model===!0||Il.mode===`raw`}var Rl=`drowse.genui.v1.`;function zl(){let e=es.info?.model_id;return e?Rl+e:null}function Bl(){let e=zl(),t=e?bl(e):null;es.info?.is_base_model===!0?Il.mode=`raw`:t===`chat`||t===`raw`?Il.mode=t:Il.mode=`chat`}function Vl(e){Il.mode=es.info?.is_base_model===!0?`raw`:e;let t=zl();t&&xl(t,Il.mode)}var Hl=ze({pendingTurnIdx:null,processingAb:!1,pendingRole:null,pendingRoleLabel:null});function Ul(e){let t=[];for(let n=0;n{Gl=null,!(!ql.enabled||$.active||Hl.processingAb)&&Wl(e,t)},0),!0)}var ql=ze({enabled:!1,mode:`unsteered`,custom:``});function Jl(){let e=!ql.enabled;if(ql.enabled=!ql.enabled,!e){Gl!==null&&(clearTimeout(Gl),Gl=null);return}if(!$.active)for(let e=kl.turns.length-1;e>=0;e--){let t=kl.turns[e];if(t&&!(!t.generated||t.role===`system`)){if(t.abPair)break;Kl(e);break}}}function Yl(){ql.enabled=!1,Gl!==null&&(clearTimeout(Gl),Gl=null)}function Xl(e){if(ql.mode=e,!(!ql.enabled||$.active||Hl.processingAb))for(let e=kl.turns.length-1;e>=0;e--){let t=kl.turns[e];if(t?.generated&&t.role!==`system`){Kl(e);return}}}function Zl(e){ql.custom=e}function Ql(){return ql.enabled?ql.mode===`custom`?ql.custom.trim()||null:ql.mode:null}async function $l(){await rs(),Cl(),Bl(),await Promise.allSettled([Ha(),Bo(),Ua(),to(),$c()])}var eu=[`temperature`,`top_p`,`top_k`,`max_tokens`,`seed`,`system_prompt`,`stop_sequences`,`logit_bias_text`,`presence_penalty`,`frequency_penalty`,`thinking`,`return_top_k`,`user_role`,`assistant_role`],tu=new Set([`BOTH`,`BEFORE`,`AFTER`,`THINKING`,`RESPONSE`,`PROMPT`,`GENERATED`]),nu=/^(?:raw|sae(?:-.+)?|role(?:-.+)?|from(?:-.+)?)$/u;function ru(e,t){let n=ou(e,`conversation snapshot`);pu(n,[`customSteeringExpression`,`highlightState`,`model_id`,`probeRack`,`samplingState`,`savedAt`,`session_id`,`steerRack`,`subspaceAlong`,`tree`,`version`],`conversation snapshot`),n.version!==7&&_u(`snapshot version`),mu(n.savedAt,`saved timestamp`),mu(n.model_id,`model id`),mu(n.session_id,`session id`);let r=ou(n.tree,`conversation tree`);uu(r.tree_format,`tree format`),mu(r.drowse_version,`tree Drowse version`),mu(r.root_id,`tree root id`),mu(r.active_node_id,`tree active node id`),uu(r.rev,`tree revision`),(r.model_id!==n.model_id||r.session_id!==null&&r.session_id!==n.session_id)&&_u(`tree identity`),Array.isArray(r.nodes)||_u(`tree nodes`),ou(r.children_of,`tree children map`),ou(r.cast,`tree cast`),lu(n.subspaceAlong,`subspace strength`),typeof n.customSteeringExpression!=`string`&&n.customSteeringExpression!==null&&_u(`custom steering expression`);let i=su(n.steerRack,`steering rack`),a=new Set;for(let e of i){let t=ou(e,`steering row`),n=mu(t.name,`steering row name`);if(a.has(n)&&_u(`duplicate steering row ${n}`),a.add(n),(!tu.has(t.trigger)||typeof t.enabled!=`boolean`)&&_u(`steering row ${n}`),t.mode===`jlens`||t.mode===`sae`){lu(t.alpha,`steering row ${n} alpha`),t.ablate!==void 0&&typeof t.ablate!=`boolean`&&_u(`steering row ${n} ablation`),t.mode===`jlens`&&!n.startsWith(`jlens/`)&&_u(`J-lens row ${n}`),t.mode===`sae`&&!/^sae\/(?:0|[1-9]\d*)$/u.test(n)&&_u(`SAE row ${n}`);continue}t.mode!==`subspace`&&t.mode!==`manifold`&&_u(`steering row ${n} mode`),t.mode===`subspace`&&t.ablate!==void 0&&typeof t.ablate!=`boolean`&&_u(`steering row ${n} ablation`),fu(t.coords,`steering row ${n} coordinates`),gu(t.label,`steering row ${n} label`),(typeof t.variant!=`string`||!nu.test(t.variant))&&_u(`steering row ${n} variant`),t.mode===`manifold`&&(lu(t.blend,`steering row ${n} blend`),lu(t.onto,`steering row ${n} onto`))}let o=ou(n.probeRack,`probe rack`);o.sortMode!==`name`&&o.sortMode!==`value`&&o.sortMode!==`change`&&_u(`probe sort mode`);let s=cu(o.active,`active probes`);new Set(s).size!==s.length&&_u(`duplicate active probe`);let c=new Set;for(let e of su(o.entries,`probe entries`)){let t=ou(e,`probe row`),n=mu(t.name,`probe row name`);c.has(n)&&_u(`duplicate probe row ${n}`),c.add(n);let r=ou(t.request,`probe ${n} request`);mu(r.selector,`probe ${n} selector`),r.name!==n&&_u(`probe ${n} alias`),r.top_n!==void 0&&(uu(r.top_n,`probe ${n} nearest count`),r.top_n<1&&_u(`probe ${n} nearest count`)),fu(t.sparkline,`probe ${n} sparkline`),lu(t.current,`probe ${n} current value`),lu(t.previous,`probe ${n} previous value`)}(s.some(e=>!c.has(e))||c.size!==s.length)&&_u(`probe roster`);let l=ou(n.highlightState,`highlight state`);gu(l.target,`highlight target`),gu(l.compareTarget,`highlight compare target`),(typeof l.compareTwo!=`boolean`||typeof l.smoothBlend!=`boolean`)&&_u(`highlight state`);let u=ou(n.samplingState,`sampling state`);Object.keys(u).sort().join(`\0`)!==[...t].sort().join(`\0`)&&_u(`sampling fields`),du(u.temperature,`sampling temperature`),du(u.top_p,`sampling top-p`),du(u.top_k,`sampling top-k`),lu(u.max_tokens,`sampling max tokens`),du(u.seed,`sampling seed`),hu(u.system_prompt,`sampling system prompt`),hu(u.stop_sequences,`sampling stop sequences`),hu(u.logit_bias_text,`sampling logit bias`),lu(u.presence_penalty,`sampling presence penalty`),lu(u.frequency_penalty,`sampling frequency penalty`),u.thinking!==null&&typeof u.thinking!=`boolean`&&_u(`sampling thinking`),lu(u.return_top_k,`sampling alternatives`),hu(u.user_role,`sampling user role`),hu(u.assistant_role,`sampling assistant role`)}function iu(e){let t=new Map;for(let{name:n,...r}of e.steerRack){let e=structuredClone(r);(e.mode===`subspace`||e.mode===`jlens`||e.mode===`sae`)&&(e.ablate=e.ablate===!0),t.set(n,e)}let n=new Map(e.probeRack.entries.map(e=>[e.name,structuredClone(e)]));return{snapshot:e,steerEntries:t,steeringExpression:e.customSteeringExpression??fa(t,e.subspaceAlong),probeRequests:e.probeRack.active.map(e=>structuredClone(n.get(e).request)),probeRows:n}}async function au(e){let t=await e.capture();await e.preflight();try{await e.apply()}catch(n){try{await e.rollback(t)}catch(e){throw AggregateError([n,e],`Conversation restore failed and the previous workspace could not be fully restored`)}throw n}}function ou(e,t){return(!e||typeof e!=`object`||Array.isArray(e))&&_u(t),e}function su(e,t){return Array.isArray(e)||_u(t),e}function cu(e,t){let n=su(e,t);return n.every(e=>typeof e==`string`&&e.length>0)||_u(t),n}function lu(e,t){return(typeof e!=`number`||!Number.isFinite(e))&&_u(t),e}function uu(e,t){let n=lu(e,t);return Number.isSafeInteger(n)||_u(t),n}function du(e,t){e!==null&&lu(e,t)}function fu(e,t){let n=su(e,t);return n.every(e=>typeof e==`number`&&Number.isFinite(e))||_u(t),n}function pu(e,t,n){Object.keys(e).sort().join(`\0`)!==[...t].sort().join(`\0`)&&_u(n)}function mu(e,t){return(typeof e!=`string`||e.trim().length===0)&&_u(t),e}function hu(e,t){typeof e!=`string`&&_u(t)}function gu(e,t){e!==null&&typeof e!=`string`&&_u(t)}function _u(e){throw TypeError(`Invalid ${e}`)}var vu=[{id:`purple`,name:`Lavender`,dark:`#c5b3ff`,light:`#5b3fbf`},{id:`blue`,name:`Sky`,dark:`#a9d5ff`,light:`#245c91`},{id:`mint`,name:`Mint`,dark:`#a4dfc6`,light:`#23664f`},{id:`rose`,name:`Rose`,dark:`#f2b8d4`,light:`#923e68`},{id:`peach`,name:`Peach`,dark:`#f3c6a5`,light:`#88502c`},{id:`periwinkle`,name:`Iris`,dark:`#bfc5ff`,light:`#4b50a1`}],yu=`purple`;function bu(e){return vu.some(t=>t.id===e)}function xu(e=yu){return vu.find(t=>t.id===e)??vu[0]}function Su(e){let t=xu(e);return`--chat-accent-dark: ${t.dark}; --chat-accent-light: ${t.light};`}var Cu=`drowse-saved-conversations`,wu=1,Tu=`conversations`,Eu=`drowse-saved-conversations-v1`,Du=64*1024*1024,Ou=120,ku=256,Au=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`ConversationLibraryError`}},ju=Promise.resolve(),Mu=async e=>{let t=ju,n;ju=new Promise(e=>{n=e}),await t;try{return await e()}finally{n()}},Nu=e=>typeof navigator<`u`&&navigator.locks?navigator.locks.request(Eu,{mode:`exclusive`},e):Mu(e),Pu=class{samplingKeys;store;now;randomId;runExclusive;initialization=null;constructor(e){this.samplingKeys=[...e.samplingKeys],this.store=e.store??new Fu,this.now=e.now??Date.now,this.randomId=e.randomId??Yu,this.runExclusive=e.runExclusive??Nu}initialize(){return this.initialization??=this.store.initialize().catch(e=>{throw this.initialization=null,e}),this.initialization}list(){return this.readList(e=>structuredClone(e))}listSummaries(){return this.readList(Iu)}async findForTree(e,t){let{conversations:n}=await this.readList(e=>({id:e.id,name:e.name,updatedAt:e.updatedAt,modelId:e.modelId,rootId:e.snapshot.tree.root_id})),r=n.find(n=>n.modelId===e&&n.rootId===t);return r?this.get(r.id):null}async hasAny(){return await this.initialize(),this.store.hasAny?this.store.hasAny():(await this.store.list()).length>0}async readList(e){await this.initialize();let t=t=>{try{if(Lu(t.value,this.samplingKeys),t.value.id!==t.key)throw qu(`Saved conversation key does not match its id`);return{conversation:e(t.value)}}catch(e){let n=Ku(t.value)?t.value:null;return{issue:{id:t.key,name:typeof n?.name==`string`?n.name:null,reason:Ju(e).message}}}},n=this.store.map?await this.store.map(t):(await this.store.list()).map(t),r=[],i=[];for(let e of n)`conversation`in e?r.push(e.conversation):i.push(e.issue);return r.sort((e,t)=>t.updatedAt-e.updatedAt||e.id.localeCompare(t.id)),{conversations:r,issues:i}}async get(e){Uu(e,`saved conversation id`),await this.initialize();let t=await this.store.read(e);if(t===void 0)throw new Au(`NOT_FOUND`,`This saved conversation no longer exists`);if(Lu(t,this.samplingKeys),t.id!==e)throw qu(`Saved conversation key does not match its id`);return structuredClone(t)}async create(e){let t=Vu(e.name);ru(e.snapshot,this.samplingKeys);let n=e.avatarSeed===void 0?null:Hu(e.avatarSeed);return await this.initialize(),this.runExclusive(async()=>{let r=this.randomId();for(let e=0;e<4&&await this.store.read(r)!==void 0;e+=1)r=this.randomId();if(await this.store.read(r)!==void 0)throw qu(`Unable to allocate a unique saved conversation id`);let i=this.now(),a={schemaVersion:1,id:r,name:t,avatarSeed:n??Hu(this.randomId()),...e.accent===void 0?{}:{accent:e.accent},modelId:e.snapshot.model_id,...e.modelType===void 0?{}:{modelType:e.modelType},createdAt:e.createdAt??i,updatedAt:e.updatedAt??i,snapshot:structuredClone(e.snapshot)};return Lu(a,this.samplingKeys),await this.store.write(a),structuredClone(a)})}async update(e,t){return Uu(e,`saved conversation id`),await this.initialize(),this.runExclusive(async()=>{let n=await this.store.read(e);if(n===void 0)throw new Au(`NOT_FOUND`,`This saved conversation no longer exists`);Lu(n,this.samplingKeys);let r=structuredClone(t.snapshot??n.snapshot),i={...n,...t.accent===void 0?{}:{accent:t.accent},name:t.name===void 0?n.name:Vu(t.name),avatarSeed:t.avatarSeed===void 0?n.avatarSeed:Hu(t.avatarSeed),modelId:r.model_id,updatedAt:t.snapshot===void 0?n.updatedAt:this.now(),snapshot:r};return Lu(i,this.samplingKeys),await this.store.write(i),structuredClone(i)})}async duplicate(e){let t=await this.get(e),n=t.snapshot,r=this.randomId(),i=new Map(n.tree.nodes.map((e,t)=>[e.id,`${r}-${t}`])),a=e=>{let t=i.get(e);if(t===void 0)throw qu(`The conversation has a missing tree node`);return t};return n.tree.root_id=a(n.tree.root_id),n.tree.active_node_id=a(n.tree.active_node_id),n.tree.nodes=n.tree.nodes.map(e=>({...e,id:a(e.id),parent_id:e.parent_id===null?null:a(e.parent_id)})),n.tree.children_of=Object.fromEntries(Object.entries(n.tree.children_of).map(([e,t])=>[a(e),t.map(a)])),this.create({name:`${t.name.slice(0,Ou-7).trimEnd()} (copy)`,avatarSeed:t.avatarSeed,accent:t.accent,modelType:t.modelType,snapshot:n})}async autosave(e,t,n){return ru(e,this.samplingKeys),await this.initialize(),this.runExclusive(async()=>{let r;if(t){let n=await this.store.read(t);if(n===void 0)throw new Au(`NOT_FOUND`,`This chat was deleted. Save as new to keep your current work.`);Lu(n,this.samplingKeys),n.modelId===e.model_id&&n.snapshot.tree.root_id===e.tree.root_id&&(r=n)}if(!r){let t=t=>{try{return Lu(t.value,this.samplingKeys),t.value.modelId===e.model_id&&t.value.snapshot.tree.root_id===e.tree.root_id?t.value:null}catch{return null}};r=(this.store.map?await this.store.map(t):(await this.store.list()).map(t)).filter(e=>e!==null).sort((e,t)=>t.updatedAt-e.updatedAt)[0]}if(!r&&!e.tree.nodes.some(e=>e.parent_id!==null))return null;if(r&&r.snapshot.tree.rev>e.tree.rev)throw new Au(`INVALID_RECORD`,`A newer version of this chat is already saved. Open it from Your chats, or save this version as new.`);if(r&&(n===void 0||r.modelType===n)&&JSON.stringify({...r.snapshot,savedAt:``})===JSON.stringify({...e,savedAt:``}))return structuredClone(r);let i=this.now(),a=r?.id??this.randomId();if(!r&&await this.store.read(a)!==void 0)throw qu(`Unable to allocate a unique saved conversation id`);let o={schemaVersion:1,id:a,name:r?.name??Ru(i),avatarSeed:r?.avatarSeed??Hu(this.randomId()),...r?.accent===void 0?{}:{accent:r.accent},modelId:e.model_id,...(n??r?.modelType)===void 0?{}:{modelType:n??r?.modelType},createdAt:r?.createdAt??i,updatedAt:i,snapshot:structuredClone(e)};return Lu(o,this.samplingKeys),await this.store.write(o),structuredClone(o)})}async delete(e){return Uu(e,`saved conversation id`),await this.initialize(),this.runExclusive(()=>this.store.delete(e))}close(){this.store.close?.(),this.initialization=null}},Fu=class{database=null;initialization=null;initialize(){return this.initialization??=this.initializeOnce().catch(e=>{throw this.initialization=null,e}),this.initialization}async list(){return this.withDatabase(async e=>{let t=e.transaction(Tu,`readonly`),n=Qu(t),r=t.objectStore(Tu),[i,a]=await Promise.all([Zu(r.getAllKeys()),Zu(r.getAll())]);return await n,a.map((e,t)=>({key:String(i[t]),value:e}))})}async map(e){return this.withDatabase(async t=>{let n=t.transaction(Tu,`readonly`),r=Qu(n),i=[],a=new Promise((t,r)=>{let a=n.objectStore(Tu).openCursor();a.onerror=()=>r(a.error),a.onsuccess=()=>{let o=a.result;if(o===null){t();return}try{i.push(e({key:String(o.key),value:o.value})),o.continue()}catch(e){n.abort(),r(e)}},n.addEventListener(`abort`,()=>r(n.error),{once:!0})});return await Promise.all([a,r]),i})}async hasAny(){return this.withDatabase(async e=>{let t=e.transaction(Tu,`readonly`),n=Qu(t),[r]=await Promise.all([Zu(t.objectStore(Tu).count()),n]);return r>0})}async read(e){return this.withDatabase(async t=>{let n=t.transaction(Tu,`readonly`),r=Qu(n),i=await Zu(n.objectStore(Tu).get(e));return await r,i})}async write(e){await this.withDatabase(async t=>{let n=t.transaction(Tu,`readwrite`),r=Qu(n);n.objectStore(Tu).put(e),await r})}async delete(e){return await this.read(e)===void 0?!1:(await this.withDatabase(async t=>{let n=t.transaction(Tu,`readwrite`),r=Qu(n);n.objectStore(Tu).delete(e),await r}),!0)}close(){this.invalidate(this.database)}async initializeOnce(){if(typeof indexedDB>`u`)throw new Au(`INDEXEDDB_UNAVAILABLE`,`Browser storage is unavailable`);let e=await Xu();this.database=e,e.onversionchange=()=>this.invalidate(e),e.onclose=()=>this.invalidate(e,!1)}async withDatabase(e){for(let t=0;t<2;t+=1){await this.initialize();let n=this.database;if(n===null){this.initialization=null;continue}try{return await e(n)}catch(e){if(t===0&&$u(e)){this.invalidate(n);continue}throw e}}throw new Au(`INDEXEDDB_UNAVAILABLE`,`Browser storage closed while accessing saved conversations`)}invalidate(e,t=!0){e!==null&&(t&&e.close(),this.database===e&&(this.database=null,this.initialization=null))}};function Iu(e){let{nodes:t,children_of:n,root_id:r}=e.snapshot.tree;return{schemaVersion:e.schemaVersion,id:e.id,name:e.name,avatarSeed:e.avatarSeed,...e.accent===void 0?{}:{accent:e.accent},modelId:e.modelId,...e.modelType===void 0?{}:{modelType:e.modelType},createdAt:e.createdAt,updatedAt:e.updatedAt,messageCount:t.filter(e=>(e.role===`user`||e.role===`assistant`)&&(e.text.length>0||(e.raw_token_ids?.length??0)>0)).length,threadCount:t.filter(e=>e.id!==r&&(n[e.id]?.length??0)===0).length}}function Lu(e,t){if(!Ku(e))throw qu(`Saved conversation is not an object`);if(Gu(e,[...`modelType`in e?[`modelType`]:[],...`accent`in e?[`accent`]:[],`avatarSeed`,`createdAt`,`id`,`modelId`,`name`,`schemaVersion`,`snapshot`,`updatedAt`]),e.schemaVersion!==1)throw qu(`Saved conversation version is unsupported`);if(Uu(e.id,`saved conversation id`),Vu(e.name),Hu(e.avatarSeed),`accent`in e&&!bu(e.accent))throw qu(`Chat accent color is invalid`);if(Uu(e.modelId,`model id`,512),`modelType`in e&&e.modelType!==`base`&&e.modelType!==`chat`)throw qu(`Model type is invalid`);if(Wu(e.createdAt,`creation time`),Wu(e.updatedAt,`update time`),e.updatedAtDu)throw new Au(`STORAGE_LIMIT`,`This conversation is larger than the 64 MiB save limit`)}function Ru(e=Date.now()){let t=Object.fromEntries(new Intl.DateTimeFormat(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,hourCycle:`h23`,timeZoneName:`short`}).formatToParts(e).map(({type:e,value:t})=>[e,t]));return`New Chat - ${t.month} ${t.day} - ${Number(t.hour)}:${t.minute} ${t.timeZoneName}`}function zu(e){return(e.split(`/`).at(-1)??e).replace(/[-_]+/gu,` `).replace(/\b(qwen|gemma|llama|mistral)(\d)/giu,(e,t,n)=>`${t.charAt(0).toUpperCase()}${t.slice(1).toLowerCase()}${n}`).replace(/\b(qwen|gemma|llama|mistral)\b/giu,e=>`${e.charAt(0).toUpperCase()}${e.slice(1).toLowerCase()}`).replace(/\b(\d+(?:\.\d+)?)b\b/giu,`$1B`).replace(/\s+/gu,` `).trim()}function Bu(){return Yu()}function Vu(e){if(typeof e!=`string`)throw qu(`Conversation name is invalid`);let t=e.replace(/\s+/gu,` `).trim();if(!t)throw qu(`Give this conversation a name`);if(t.length>Ou)throw qu(`Conversation names must be ${Ou} characters or fewer`);return t}function Hu(e){if(typeof e!=`string`)throw qu(`Avatar seed is invalid`);let t=e.trim();if(!t||t.length>ku)throw qu(`Avatar seed is invalid`);return t}function Uu(e,t,n=256){if(typeof e!=`string`||!e.trim()||e.length>n)throw qu(`${t} is invalid`)}function Wu(e,t){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw qu(`${t} is invalid`)}function Gu(e,t){let n=Object.keys(e).sort(),r=[...t].sort();if(n.length!==r.length||n.some((e,t)=>e!==r[t]))throw qu(`Saved conversation fields are invalid`)}function Ku(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function qu(e){return new Au(`INVALID_RECORD`,e)}function Ju(e){return e instanceof Error?e:Error(String(e))}function Yu(){let e=globalThis.crypto;if(!e?.getRandomValues)throw qu(`Secure random identifiers are unavailable`);if(typeof e.randomUUID==`function`)return e.randomUUID();let t=e.getRandomValues(new Uint8Array(16));t[6]=t[6]&15|64,t[8]=t[8]&63|128;let n=Array.from(t,e=>e.toString(16).padStart(2,`0`));return`${n.slice(0,4).join(``)}-${n.slice(4,6).join(``)}-${n.slice(6,8).join(``)}-${n.slice(8,10).join(``)}-${n.slice(10).join(``)}`}async function Xu(){let e=await new Promise((e,t)=>{let n=!1,r=indexedDB.open(Cu,wu);r.onupgradeneeded=()=>{let e=r.result;e.objectStoreNames.contains(Tu)||e.createObjectStore(Tu,{keyPath:`id`})},r.onsuccess=()=>{if(n){r.result.close();return}n=!0,e(r.result)},r.onerror=()=>{n||(n=!0,t(r.error??new Au(`INDEXEDDB_UNAVAILABLE`,`Saved conversation storage could not be opened`)))},r.onblocked=()=>{n||(n=!0,t(new Au(`INDEXEDDB_BLOCKED`,`Close other Drowse tabs, then try again`)))}});return await me(e,[Tu]),e}function Zu(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error??Error(`Browser storage request failed`))})}function Qu(e){return new Promise((t,n)=>{e.oncomplete=()=>t(),e.onerror=()=>n(e.error??Error(`Browser storage transaction failed`)),e.onabort=()=>n(e.error??Error(`Browser storage transaction was aborted`))})}function $u(e){return e instanceof DOMException&&e.name===`InvalidStateError`}var ed=5e3;async function td(e=navigator.storage,t=ed,n){if(!e)return!1;let r=[];if(e.persist&&r.push(nd(()=>e.persist())),e.persisted&&r.push(nd(()=>e.persisted())),r.length===0)return!1;let i=rd(r),a=!1;i.then(e=>{a&&e&&n?.()});try{return await id(i,ad(t))}catch{return a=!0,!1}}function nd(e){try{return Promise.resolve(e()).then(e=>e===!0,()=>!1)}catch{return Promise.resolve(!1)}}function rd(e){return new Promise(t=>{let n=e.length,r=!1;for(let i of e)i.then(e=>{if(!r){if(e){r=!0,t(!0);return}--n,n===0&&(r=!0,t(!1))}})})}function id(e,t){return new Promise((n,r)=>{let i=setTimeout(()=>r(Error(`The persistent-storage request timed out`)),t);e.then(e=>{clearTimeout(i),n(e)},e=>{clearTimeout(i),r(e)})})}function ad(e){if(!Number.isFinite(e)||e<=0)throw RangeError(`Storage persistence timeouts must be positive numbers`);return e}var od=new Pu({samplingKeys:eu}),sd=ze({activeId:null,avatarSeed:null,accent:`purple`,status:`idle`,error:null}),cd=null;function ld(e){return cd=e,()=>{cd===e&&(cd=null)}}async function ud(){await cd?.()}async function dd(){return navigator.storage?.persist?td(navigator.storage):null}var fd=0;function pd(e){let t=e.classList.contains(`theme-toggle`);e.classList.add(`sliding-selection`);let n=document.createElement(`span`);if(n.className=`selection-indicator`,n.setAttribute(`aria-hidden`,`true`),t){let t=++fd;n.style.viewTransitionName=`theme-selection-${t}`,e.querySelectorAll(`button`).forEach((e,n)=>{e.style.viewTransitionName=`theme-option-${t}-${n}`})}e.prepend(n);let r=0,i=0,a=null;function o(){r=0;let n=e.querySelector(`button[aria-pressed="true"], button[aria-selected="true"], button[aria-current="page"]`);if(!n||!n.getClientRects().length){e.removeAttribute(`data-selection-visible`);return}t&&a&&a!==n&&(e.dataset.selectionReady=``),a=n;let o=0,s=0,c=n;for(;c&&c!==e;)o+=c.offsetLeft,s+=c.offsetTop,c=c.offsetParent;e.style.setProperty(`--selection-x`,`${o}px`),e.style.setProperty(`--selection-y`,`${s}px`),e.style.setProperty(`--selection-width`,`${n.offsetWidth}px`),e.style.setProperty(`--selection-height`,`${n.offsetHeight}px`),e.dataset.selectionVisible=``,!t&&!e.hasAttribute(`data-selection-ready`)&&!i&&(i=requestAnimationFrame(()=>{e.dataset.selectionReady=``,i=0}))}function s(){r||=requestAnimationFrame(o)}let c=new ResizeObserver(s);function l(){c.disconnect(),c.observe(e),e.querySelectorAll(`button`).forEach(e=>c.observe(e))}let u=new MutationObserver(e=>{e.some(e=>e.type===`childList`)&&l(),o()});return u.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:[`aria-pressed`,`aria-selected`,`aria-current`,`class`]}),l(),o(),{destroy(){u.disconnect(),c.disconnect(),cancelAnimationFrame(r),cancelAnimationFrame(i),n.remove()}}}var md=e(``),hd=e(` `),gd=e(``),_d=e(`
                                  `);function vd(e,n){O(n,!0);let r=q(n,`value`,15),a=q(n,`fill`,3,!1),c=q(n,`ariaLabel`,3,`View`);function u(e){e!==r()&&(r(e),n.onchange?.(e))}var d=_d();let p;f(d,21,()=>n.items,e=>e.value,(e,t)=>{var n=gd(),a=()=>u(H(t).value);T(n,()=>({class:`tab`,"aria-label":H(t).label,"aria-pressed":H(t).value===r(),"aria-description":H(t).title,disabled:H(t).disabled,onclick:a,[l]:{on:H(t).value===r()},[s]:{"--tab-c":H(t).color}}),void 0,void 0,void 0,`svelte-190ojsy`);var c=J(n),d=e=>{B(e,md())};_(c,e=>{H(t).color&&e(d)});var f=o(c,2),p=J(f,!0);i(f);var m=o(f,2),h=e=>{var n=hd(),r=J(n,!0);i(n),W(()=>z(r,H(t).meta)),B(e,n)};_(m,e=>{H(t).meta&&e(h)}),i(n),W(()=>z(p,H(t).label)),B(e,n)}),i(d),g(d,e=>pd?.(e)),W(()=>{p=D(d,1,`sk-tabs svelte-190ojsy`,null,p,{fill:a()}),t(d,`aria-label`,c())}),B(e,d),w()}function yd(e,t){return e?(t===`thinking`?e.thinkingTokens:e.tokens)??[]:[]}function bd(e){let t=[];return e.forEach((e,n)=>{let r=e.thinkingTokens?.length??0;r>0&&t.push({turnIdx:n,seg:`thinking`,length:r});let i=e.tokens?.length??0;i>0&&t.push({turnIdx:n,seg:`response`,length:i})}),t}function xd(e,t){return e.findIndex(e=>e.turnIdx===t.turnIdx&&e.seg===t.seg)}function Sd(e,t,n){let r=xd(e,t);if(r<0)return null;let i=t.tokenIdx+n;if(i>=0&&i=e.length)return null;let o=e[a];return{turnIdx:o.turnIdx,seg:o.seg,tokenIdx:n>0?0:o.length-1}}function Cd(e,t,n){let r=n>0?e.find(e=>e.turnIdx>t.turnIdx):[...e].reverse().find(e=>e.turnIdxe.turnIdx===r.turnIdx);return{turnIdx:i.turnIdx,seg:i.seg,tokenIdx:0}}function wd(e,t){if(e.length===0)return null;let n=xd(e,t);if(n>=0)return t.tokenIdxe.turnIdx===t.turnIdx);if(r)return{turnIdx:r.turnIdx,seg:r.seg,tokenIdx:Math.min(t.tokenIdx,r.length-1)};let i=e.find(e=>e.turnIdx>t.turnIdx)??e[e.length-1];return{turnIdx:i.turnIdx,seg:i.seg,tokenIdx:0}}var Td=48,Ed=class{#e=E(null);get data(){return H(this.#e)}set data(e){u(this.#e,e,!0)}#t=E(!1);get loading(){return H(this.#t)}set loading(e){u(this.#t,e,!0)}#n=E(null);get error(){return H(this.#n)}set error(e){u(this.#n,e,!0)}#r=E(null);get origin(){return H(this.#r)}set origin(e){u(this.#r,e,!0)}#i=E(null);get source(){return H(this.#i)}set source(e){u(this.#i,e,!0)}#a=E(null);get progress(){return H(this.#a)}set progress(e){u(this.#a,e,!0)}#o=null;#s=new Map;#c=!1;adopt(e,t){this.#o=null,this.data=e,this.origin=`captured`,this.source=t,this.loading=!1,this.error=null,this.progress=null}clear(){this.#o=null,this.data=null,this.origin=null,this.source=null,this.loading=!1,this.error=null,this.progress=null}dispose(){this.#c=!0,this.clear(),this.#s.clear()}replay(e,t,n,r,i){let a=Dd(e,t,n,r);this.#o=a;let o=this.#s.get(a);if(o&&o.state!==`failed`){this.#s.delete(a),this.#s.set(a,o),this.#l(a,o);return}let s={state:`loading`,data:null,source:null,error:null,progress:{phase:`queued`,completed:0,total:n+1,progress:0,message:`Waiting for the current model task to finish`}};this.#s.set(a,s),this.#l(a,s),yi(e,t,n,r,e=>{let t=Od(e);t!==null&&(s.progress=t,this.#o===a&&this.#l(a,s))}).then(e=>{let{data:t,source:n}=i(e.measurements);s.state=`ready`,s.data=t,s.source=n,s.error=null,s.progress=null}).catch(e=>{s.state=`failed`,s.error=ne(e),s.progress=null}).finally(()=>{this.#u(),this.#o===a&&this.#l(a,s)})}#l(e,t){this.#c||this.#o!==e||(this.loading=t.state===`loading`,this.data=t.data,this.error=t.error,this.origin=t.state===`ready`?`replayed`:null,this.source=t.source,this.progress=t.progress)}#u(){if(!(this.#s.size<=Td))for(let[e,t]of this.#s){if(this.#s.size<=Td)break;t.state===`loading`||e===this.#o||this.#s.delete(e)}}};function Dd(e,t,n,r){return JSON.stringify([e,bi(e),t,n,r.topK??null,r.steered??!0,r.raw??!1,r.layers??null])}function Od(e){if(e.event!==`progress`||e.data===null||typeof e.data!=`object`)return null;let t=e.data;return t.kind!==`token_readout`||![`queued`,`context`,`readout`,`complete`].includes(String(t.phase))||!Number.isInteger(t.completed)||!Number.isInteger(t.total)||typeof t.progress!=`number`||!Number.isFinite(t.progress)||typeof t.message!=`string`?null:{phase:t.phase,completed:Math.max(0,Number(t.completed)),total:Math.max(0,Number(t.total)),progress:Math.max(0,Math.min(1,t.progress)),message:t.message}}var kd=ze({tab:`lens`});function Ad(e,t){return e===`logits`||t[e]?e:t.lens?`lens`:t.sae?`sae`:t.geometry?`geometry`:`logits`}var jd=e(` `,1);function Md(e,t){O(t,!0);let n=q(t,`value`,15),r=q(t,`min`,3,0),s=q(t,`max`,3,1),c=q(t,`step`,3,.01),l=q(t,`disabled`,3,!1);function d(e){let r=parseFloat(e.currentTarget.value);Number.isFinite(r)&&(u(m,!0),n(r),t.oninput?.(r))}let f,p,m=E(!1),h=K(()=>t.displayValue??n().toFixed(Math.min(6,(String(c()).split(`.`)[1]??``).length)));function g(){if(!H(m)||!f||!p)return;let e=f.getBoundingClientRect(),t=s()===r()?0:Math.max(0,Math.min(1,(n()-r())/(s()-r()))),i=e.left+10+(getComputedStyle(f).direction===`rtl`?1-t:t)*(e.width-20),a=p.getBoundingClientRect().width/2,o=window.visualViewport,c=o?.offsetLeft??0,l=o?.offsetTop??0,u=o?.width??innerWidth,d=o?.height??innerHeight;if(e.bottom<=l||e.top>=l+d){p.hidePopover();return}p.matches(`:popover-open`)||p.showPopover(),p.style.left=`${Math.max(c+a+8,Math.min(c+u-a-8,i))}px`,p.style.top=`${Math.max(l+8,Math.min(l+d-p.offsetHeight-8,e.top-p.offsetHeight+2))}px`}ae(()=>(window.addEventListener(`resize`,g),document.addEventListener(`scroll`,g,!0),window.visualViewport?.addEventListener(`resize`,g),window.visualViewport?.addEventListener(`scroll`,g),()=>{window.removeEventListener(`resize`,g),document.removeEventListener(`scroll`,g,!0),window.visualViewport?.removeEventListener(`resize`,g),window.visualViewport?.removeEventListener(`scroll`,g)})),U(()=>{n(),H(h),H(m)&&!l()?ye().then(()=>{!H(m)||l()||!p?.isConnected||(p.showPopover(),g())}):p?.hidePopover()});let _=null;function v(e){if(!_||e.pointerId!==_.id||l())return;let i=e.currentTarget,a=i.getBoundingClientRect(),o=Math.max(1,a.width-20),u=getComputedStyle(i).direction===`rtl`,d=Math.max(0,Math.min(1,(e.clientX-a.left-10-_.offset)/o)),f=r()+(u?1-d:d)*(s()-r());i.value=String(Math.max(r(),Math.min(s(),r()+Math.round((f-r())/c())*c()))),n(i.valueAsNumber),t.oninput?.(n())}function y(e){if(l()||e.button!==0||!e.isPrimary)return;e.preventDefault();let t=e.currentTarget,i=t.getBoundingClientRect(),a=s()===r()?0:(n()-r())/(s()-r()),o=i.left+10+(getComputedStyle(t).direction===`rtl`?1-a:a)*(i.width-20),c=e.clientX-o;u(m,!0),_={id:e.pointerId,offset:Math.abs(c)<=12?c:0},t.focus({preventScroll:!0}),t.setPointerCapture(e.pointerId),v(e)}function b(e){if(_?.id!==e.pointerId)return;_=null,u(m,!1);let t=e.currentTarget;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId)}var x=jd(),S=N(x),C=()=>u(m,!0),D=()=>u(m,!1);T(S,()=>({onfocus:C,onblur:D,class:`sk-slider`,type:`range`,min:r(),max:s(),step:c(),value:n(),disabled:l(),"aria-description":t.title,"aria-label":t.ariaLabel,"aria-valuetext":H(h),oninput:d,onpointerdown:y,onpointermove:v,onpointerup:b,onpointercancel:b,onlostpointercapture:b}),void 0,void 0,void 0,`svelte-1ia2ohq`,!0),a(S,e=>f=e,()=>f);var k=o(S,2);Z(J(k),{get text(){return H(h)},duration:120}),i(k),a(k,e=>p=e,()=>p),B(e,x),w()}function Nd(e,t){if(t)return t===`__surprise__`?Zi(e.logprob):t===`__probability__`?Qi(e.logprob):t===`__entropy__`?$i(e.samplerEntropy):Xi(e,t)}function Pd(e){let t=Yo.target;if(!t)return{};let n=Yo.compareTwo&&Yo.compareTarget?Yo.compareTarget:null;return ua(Nd(e,t),n===null?null:Nd(e,n),Yo.smoothBlend,Io(t),n===null?void 0:Io(n),Fd(t),n===null?void 0:Fd(n))}function Fd(e){let t=To.entries.get(Yi(e).base)?.info;return t?.family===`lens`?`surprise`:t?.family===`sae`?`sae`:oa(e)}function Id(e){let t=Pd(e),n=[];return t.backgroundColor&&n.push(`background-color: ${t.backgroundColor}`),t.backgroundImage&&n.push(`background-image: ${t.backgroundImage}`),n.join(`;`)}var Ld=e(`
                                  `),Rd=e(``),zd=e(``),Bd=e(``),Vd=e(`
                                  sequence context
                                  `);function Hd(e,t){O(t,!0);let n=K(()=>Math.max(0,t.index-60)),r=K(()=>Math.min(t.tokens.length,t.index+60+1)),s=K(()=>t.tokens.slice(H(n),H(r)).map((e,t)=>({tok:e,i:H(n)+t})));function c(e){return e.replace(/\n/g,`⏎`)}let d=E(null);U(()=>{t.index,H(s);let e=H(d)?.querySelector(`.current`);if(H(d)&&e){let t=e.getBoundingClientRect(),n=H(d).getBoundingClientRect();H(d).scrollLeft+=t.left+t.width/2-n.left-H(d).clientWidth/2}});var p=Vd(),m=J(p),h=o(J(m),2),g=J(h);{let e=K(()=>`token ${t.index+1} / ${t.tokens.length}`);Z(g,{get text(){return H(e)}})}i(h),i(m);var v=o(m,2),y=e=>{var n=Ld(),r=J(n);{let e=K(()=>t.tokens.length-1),n=K(()=>`Token ${t.index+1}`);Md(r,{get value(){return t.index},min:0,get max(){return H(e)},step:1,get displayValue(){return H(n)},ariaLabel:`Sequence token position`,get oninput(){return t.onjump}})}i(n),B(e,n)};_(v,e=>{t.tokens.length>1&&e(y)});var b=o(v,2),x=J(b),S=e=>{var t=Rd(),r=J(t);i(t),W(()=>z(r,`…${H(n)??``}`)),B(e,t)};_(x,e=>{H(n)>0&&e(S)});var C=o(x,2);f(C,17,()=>H(s),({tok:e,i:t})=>t,(e,n)=>{let r=()=>H(n).tok,a=()=>H(n).i;var o=zd(),s=()=>t.onjump(a());T(o,e=>({type:`button`,class:`rtok`,style:e,tabindex:`-1`,"aria-current":a()===t.index,"aria-description":`token ${a()+1} / ${t.tokens.length}`,onclick:s,[l]:{current:a()===t.index}}),[()=>Id(r())],void 0,void 0,`svelte-cca58d`);var u=J(o,!0);i(o),W(e=>z(u,e),[()=>c(r().text)]),B(e,o)});var D=o(C,2),k=e=>{var n=Bd(),a=J(n);i(n),W(()=>z(a,`${t.tokens.length-H(r)}…`)),B(e,n)};_(D,e=>{H(r)u(d,e),()=>H(d)),i(p),B(e,p),w()}var Ud=e(``);function Wd(e,n){O(n,!0);let r=q(n,`digits`,3,0),a=q(n,`signed`,3,!1),o=K(()=>n.format??{useGrouping:!1,minimumFractionDigits:r(),maximumFractionDigits:r(),signDisplay:a()?`always`:`auto`}),s=K(()=>Number.isFinite(n.value)?new Intl.NumberFormat(`en-US`,H(o)).format(n.value):`-`);var c=Ud();Z(J(c),{get text(){return H(s)}}),i(c),W(()=>t(c,`data-value`,n.value)),B(e,c),w()}function Gd(e,t=!1){return Number.isFinite(e)?e!==0&&Math.abs(e)<1e-4?t?e<0?`−<0.01%`:`<0.01%`:e.toExponential(2):t?`${(e*100).toLocaleString(`en-US`,{maximumFractionDigits:2})}%`:e.toLocaleString(`en-US`,{maximumFractionDigits:4}):`Not available`}function Kd(e,t,n=!1){return Number.isFinite(e)?n?Gd(e,!0):!Number.isFinite(t)||t<=0?`${Gd(e)} · scale unavailable`:`${Gd(e)} · ${Gd(Math.abs(e)/t,!0)} of scale (${Gd(t)})`:`Not available`}function qd(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&t>0?Math.min(1,Math.abs(e)/t):0}var Jd=e(``),Yd=e(` `);function Xd(e,n){O(n,!0);let r=q(n,`width`,3,144),a=q(n,`height`,3,8),s=q(n,`showBaseline`,3,!1),c=q(n,`bipolar`,3,!1),l=q(n,`percentage`,3,!1),u=K(()=>qd(n.value,n.max)*(c()?50:100)),d=K(()=>c()?n.value<0?50-H(u):50:0),f=K(()=>n.color??(n.value>0?`var(--accent-green)`:n.value<0?`var(--accent-red)`:`var(--fg-muted)`)),p=K(()=>n.title??Kd(n.value,n.max,l()));var m=Yd();let h,g;var v=J(m);let y;var b=o(v,2),x=e=>{B(e,Jd())};_(b,e=>{c()&&e(x)}),i(m),W(()=>{h=D(m,1,`bar svelte-irr9qk`,null,h,{baseline:s()}),t(m,`aria-label`,H(p)),g=C(m,``,g,{"--bar-width":`${r()}px`,height:`${a()}px`}),y=C(v,``,y,{left:`${H(d)}%`,width:`${H(u)}%`,"--fill":H(f)})}),B(e,m),w()}var Zd=e(` `),Qd=e(`
                                  `);function $d(e,n){O(n,!0);let r=q(n,`scale`,3,Ki),a=q(n,`size`,3,14),o=q(n,`positiveColor`,3,`var(--layer-cell-positive)`),s=q(n,`negativeColor`,3,`var(--layer-cell-negative)`),c=q(n,`active`,3,!1),l=q(n,`showValue`,3,!1),u=K(()=>n.value===null||n.value===void 0||!Number.isFinite(n.value)),d=K(()=>{if(H(u))return 0;let e=Number.isFinite(r())&&r()>1e-6?r():Ki;return Math.max(-1,Math.min(1,n.value/e))}),f=K(()=>{if(H(u))return`var(--layer-cell-empty)`;let e=H(d);if(Math.abs(e)<1e-9)return`var(--layer-cell-neutral)`;let t=e>0?o():s(),n=15+Math.abs(e)*85;return`color-mix(in srgb, var(--layer-cell-neutral) ${100-n}%, ${t} ${n}%)`}),p=K(()=>!H(u)&&Math.abs(H(d))>=.55?`var(--text-on-accent)`:`var(--fg)`),m=K(()=>n.title??(H(u)?`-`:n.value.toFixed(3))),h=K(()=>l()&&!H(u)?n.value.toFixed(2):``);var g=Qd();let v;var y=J(g),b=e=>{var t=Zd(),n=J(t,!0);i(t),W(()=>z(n,H(h))),B(e,t)};_(y,e=>{H(h)&&e(b)}),i(g),W(()=>{v=D(g,1,`cell svelte-w2uko1`,null,v,{active:c()}),C(g,`width: ${a()??``}px; height: ${a()??``}px; background: ${H(f)??``}; color: ${H(p)??``};`),t(g,`aria-label`,H(m))}),B(e,g),w()}var ef=e(`
                                  `),tf=e(`
                                  `,1),nf=e(`
                                  `),rf=e(`
                                  `);function af(e,n){O(n,!0);let r=q(n,`emptyMessage`,3,`no data yet, generate a token first`),a=E(0),s=E(!1);U(()=>{H(a)>=n.cells.length&&u(a,Math.max(0,n.cells.length-1),!0)});function c(e){if(n.cells.length!==0){if(e.key===`ArrowRight`)u(a,Math.min(n.cells.length-1,H(a)+1),!0);else if(e.key===`ArrowLeft`)u(a,Math.max(0,H(a)-1),!0);else if(e.key===`Home`)u(a,0);else if(e.key===`End`)u(a,n.cells.length-1);else return;e.preventDefault()}}var d=rf(),p=J(d),m=J(p),h=e=>{var t=ef(),n=J(t,!0);i(t),W(()=>z(n,r())),B(e,t)},g=e=>{var t=tf(),r=N(t),c=J(r);i(r);var l=o(r,2);f(l,23,()=>n.cells,e=>e.layer,(e,t,r)=>{{let i=K(()=>H(s)&&H(r)===H(a));$d(e,{get value(){return H(t).value},get scale(){return n.scale},size:13,get title(){return H(t).title},get positiveColor(){return n.positiveColor},get negativeColor(){return n.negativeColor},get active(){return H(i)}})}}),i(l);var u=o(l,2),d=J(u);i(u),W(()=>{z(c,`L${n.cells[0].layer??``}`),z(d,`L${n.cells[n.cells.length-1].layer??``}`)}),B(e,t)};_(m,e=>{n.cells.length===0?e(h):e(g,-1)}),i(p);var v=o(p,2),y=e=>{var t=nf();T(t,()=>({class:`keyboard-readout`,"aria-hidden":!H(s),"aria-description":n.cells[H(a)].title,[l]:{visible:H(s)}}),void 0,void 0,void 0,`svelte-2plfw6`),Z(J(t),{get text(){return n.cells[H(a)].title}}),i(t),B(e,t)};_(v,e=>{n.cells[H(a)]&&e(y)}),i(d),W(e=>{t(p,`aria-label`,n.ariaLabel),t(p,`aria-valuemax`,e),t(p,`aria-valuenow`,H(a)),t(p,`aria-valuetext`,n.cells[H(a)]?.title??r()),t(p,`tabindex`,n.cells.length>0?0:void 0)},[()=>Math.max(0,n.cells.length-1)]),ie(`focus`,p,()=>u(s,!0)),ie(`blur`,p,()=>u(s,!1)),G(`keydown`,p,c),G(`pointermove`,p,e=>{if(e.pointerType===`touch`&&e.buttons===0)return;let t=[...e.currentTarget.querySelectorAll(`.cell`)].findIndex(t=>{let n=t.getBoundingClientRect();return e.clientX>=n.left&&e.clientX<=n.right});t>=0&&(u(a,t,!0),u(s,!0))}),G(`pointerdown`,p,e=>{e.currentTarget.focus(),u(s,!0)}),B(e,d),w()}ke([`keydown`,`pointermove`,`pointerdown`]);function of(e){return e*e*e}function sf(e){let t=e-1;return t*t*t+1}var cf=()=>typeof window<`u`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches;function lf(e){return cf()?0:e}function uf(){return{duration:lf(160),easing:sf}}function df(){return{duration:lf(110),easing:of}}function ff(e=18,t=0){return{x:e,y:t,duration:lf(220),easing:sf}}function pf(e=10,t=0){return{x:e,y:t,duration:lf(150),easing:of}}function mf(e=-8){return{y:e,duration:lf(200),easing:sf}}function hf(e=-4){return{y:e,duration:lf(130),easing:of}}function gf(e=4){return{y:e,duration:lf(170),easing:sf}}function _f(e=-2){return{y:e,duration:lf(100),easing:of}}function vf(e){let t=getComputedStyle(e);return{duration:lf(Number.parseFloat(t.getPropertyValue(`--selection-dur`))*1e3),easing:sf,css:e=>`opacity: ${e}; transform: translateY(${(1-e)*4}px);`}}function yf(){return{duration:lf(200),easing:sf}}function bf(){return{duration:lf(130),easing:of}}function xf(){let e=E(!1),t;function n(){clearTimeout(t),t=void 0}return{get mounted(){return H(e)},mount(){n(),u(e,!0)},show(e){n(),e.inert=!1,e.offsetHeight,e.classList.remove(`is-closing`),e.classList.add(`is-open`)},close(r){if(n(),!r){u(e,!1);return}r.inert=!0,r.classList.remove(`is-open`),r.classList.add(`is-closing`);let i=getComputedStyle(r).getPropertyValue(`--dropdown-close-dur`).trim(),a=parseFloat(i)*(i.endsWith(`ms`)?1:1e3),o=()=>{r.classList.remove(`is-closing`),u(e,!1)},s=lf(a);s===0?o():t=setTimeout(o,s)},destroy(){n()}}}var Sf=e(`
                                • `),Cf=e(`
                                    `),wf=e(`
                                    `);function Tf(e,n){let r=Ne();O(n,!0);let s=q(n,`value`,15),c=q(n,`placeholder`,3,``),l=q(n,`disabled`,3,!1),d=q(n,`invalid`,3,!1),p=E(!1),m=xf(),h=E(-1),g=E(null),y=E(null),b=E(``),x=E(``),S=null;U(()=>{l()&&H(p)&&N(!1)});let k=K(()=>n.options.findIndex(e=>e.value===s())),A=K(()=>H(k)>=0?n.options[H(k)].label:``);async function j(e){let t=n.options[e];!t||t.disabled||(s(t.value),n.onchange?.(t.value),N(!0),await ye())}async function M(){if(!l()&&(u(p,!0),m.mount(),u(h,H(k)>=0?H(k):F(0,1),!0),await ye(),H(p))){try{H(y)?.showPopover()}catch{}ne(),await ye(),!(!H(p)||!H(y))&&(m.show(H(y)),H(y)?.focus())}}function N(e){H(p)&&(u(p,!1),m.close(H(y)),u(x,``),e&&queueMicrotask(()=>H(g)?.focus()))}function P(){H(p)?N(!1):M()}function F(e,t){if(n.options.length===0)return-1;let r=e;for(let e=0;e=0&&r=n.options.length&&(r=0)}return-1}function I(e){if(n.options.length===0)return;let t=H(h);for(let r=0;r=n.options.length&&(t=0),!n.options[t].disabled){u(h,t,!0),L();return}}function L(){if(!H(y)||H(h)<0)return;let e=H(y).children[H(h)];if(!e)return;let t=e.offsetTop,n=t+e.offsetHeight;tH(y).scrollTop+H(y).clientHeight&&(H(y).scrollTop=n-H(y).clientHeight)}function R(e){if(e.length!==1)return;let t=e.toLowerCase();if(!/[a-z0-9]/.test(t))return;u(x,H(x)+t),S&&clearTimeout(S),S=setTimeout(()=>{u(x,``),S=null},600);let r=H(x),i=H(h)>=0?(H(h)+1)%n.options.length:0;for(let e=0;e=0&&j(H(h));break;case`Escape`:e.preventDefault(),e.stopPropagation(),N(!0);break;case`Tab`:setTimeout(()=>N(!1),0);break;default:R(e.key)}}function ne(){if(!H(g)||!H(y))return;let e=H(g).parentElement.getBoundingClientRect(),t=window.visualViewport,n=t?.offsetLeft??0,r=t?.offsetTop??0,i=t?.width??window.innerWidth,a=r+(t?.height??window.innerHeight),o=Math.max(0,a-e.bottom-8-2),s=Math.max(0,e.top-r-8-2),c=Math.min(320,Math.max(40,H(y).scrollHeight)),l=oo,d=Math.max(40,Math.min(320,l?s:o)),f=Math.min(c,d),p=Math.min(e.width,i-16);u(b,`left:${Math.max(n+8,Math.min(e.left,n+i-p-8))}px;top:${l?Math.max(r+8,e.top-f-2):Math.min(a-f-8,e.bottom+2)}px;width:${p}px;max-height:${d}px`),H(y).dataset.origin=l?`bottom-left`:`top-left`}function V(e){if(!H(p))return;let t=e.target;H(g)?.contains(t)||H(y)?.contains(t)||N(!1)}function re(){H(p)&&ne()}ae(()=>(document.addEventListener(`mousedown`,V,!0),window.addEventListener(`resize`,re),window.addEventListener(`scroll`,re,!0),window.visualViewport?.addEventListener(`resize`,re),window.visualViewport?.addEventListener(`scroll`,re),()=>{document.removeEventListener(`mousedown`,V,!0),window.removeEventListener(`resize`,re),window.removeEventListener(`scroll`,re,!0),window.visualViewport?.removeEventListener(`resize`,re),window.visualViewport?.removeEventListener(`scroll`,re),S&&clearTimeout(S),m.destroy()}));var oe=wf();let se;var ce=J(oe);T(ce,()=>({type:`button`,class:`sk-select-trigger field-focus`,disabled:l(),"aria-description":n.title,"aria-haspopup":`listbox`,"aria-expanded":H(p),"aria-controls":H(p)?`${r}-listbox`:void 0,"aria-label":n.ariaLabel,"data-invalid":d()||void 0,"aria-describedby":n.ariaDescribedby,onclick:P,onkeydown:ee}),void 0,void 0,void 0,`svelte-1v3k3t3`);var le=J(ce);let ue;var de=J(le);{let e=K(()=>H(A)||c());Z(de,{get text(){return H(e)},numbers:!1})}i(le);var fe=o(le,2);Ke(J(fe),{name:`down`}),i(fe),i(ce),a(ce,e=>u(g,e),()=>H(g));var pe=o(ce,2),me=e=>{var o=Cf();f(o,21,()=>n.options,v,(e,n,a)=>{var o=Sf();let s;var c=J(o,!0);i(o),W(()=>{t(o,`id`,`${r}-opt-${a}`),s=D(o,1,`sk-select-opt svelte-1v3k3t3`,null,s,{"is-highlight":a===H(h),"is-active":a===H(k),"is-disabled":!!H(n).disabled}),t(o,`aria-selected`,a===H(k)),t(o,`aria-disabled`,!!H(n).disabled),z(c,H(n).label)}),ie(`mouseenter`,o,()=>H(n).disabled?null:u(h,a,!0)),G(`click`,o,e=>{e.preventDefault(),e.stopPropagation(),j(a)}),G(`keydown`,o,te),B(e,o)}),i(o),a(o,e=>u(y,e),()=>H(y)),W(()=>{t(o,`id`,`${r}-listbox`),C(o,H(b)),t(o,`aria-invalid`,d()),t(o,`aria-label`,n.ariaLabel),t(o,`aria-activedescendant`,H(h)>=0?`${r}-opt-${H(h)}`:void 0)}),G(`keydown`,o,te),B(e,o)};_(pe,e=>{m.mounted&&e(me)}),i(oe),W(()=>{se=D(oe,1,`sk-select svelte-1v3k3t3`,null,se,{"is-open":H(p),"is-disabled":l()}),ue=D(le,1,`sk-select-label svelte-1v3k3t3`,null,ue,{"is-placeholder":H(k)<0})}),B(e,oe),w()}ke([`keydown`,`click`]);var Ef=e(`
                                    `),Df=e(`

                                    Subspace fraction

                                    `),Of=e(`
                                    Layer readings
                                    `);function kf(e,n){O(n,!0);let r=E(``),a=K(()=>Object.keys(n.reading.coords_per_layer??{}).filter(e=>Number.isSafeInteger(Number(e))&&Number(e)>=0&&n.reading.coords_per_layer[e]?.length>0).sort((e,t)=>Number(e)-Number(t))),s=K(()=>H(a).includes(H(r))?H(r):H(a)[0]),c=K(()=>n.reading.coords_per_layer?.[H(s)]??[]),l=K(()=>n.reading.fraction_per_layer?.[H(s)]);var d=k(),p=N(d),m=e=>{var d=Of(),p=J(d),m=o(J(p),2);{let e=K(()=>H(a).map(e=>({value:e,label:`Layer ${e}`}))),t=K(()=>`${n.name} layer`);Tf(m,{get value(){return H(s)},get options(){return H(e)},onchange:e=>{u(r,e,!0)},get ariaLabel(){return H(t)}})}i(p);var h=o(p,2),g=J(h);f(g,17,()=>H(c),v,(e,r,a)=>{var c=Ef(),l=J(c),u=J(l,!0);i(l);var d=o(l,2);{let e=K(()=>Po(n.name,a));Xd(d,{get value(){return H(r)},get max(){return H(e)},bipolar:!0})}var f=o(d,2),p=J(f,!0);i(f),i(c),W(e=>{t(c,`aria-label`,`${n.name} layer ${H(s)} axis ${a}`),z(u,n.axisLabels[a]??`c${a}`),z(p,e)},[()=>H(r).toFixed(3)]),B(e,c)});var y=o(g,2),b=e=>{var t=Df(),n=o(J(t)),r=J(n,!0);i(n),i(t),W(e=>z(r,e),[()=>H(l).toFixed(3)]),B(e,t)};_(y,e=>{H(l)!=null&&e(b)}),i(h),i(d),W(()=>t(d,`aria-label`,`${n.name} layer readings`)),B(e,d)};_(p,e=>{H(a).length>0&&e(m)}),B(e,d),w()}var Af=e(`
                                    `);function jf(e,n){var r=Af(),a=J(r);I(J(a),()=>n.left),i(a);var s=o(a,2);I(J(s),()=>n.bar),i(s);var c=o(s,2);I(J(c),()=>n.middle),i(c);var l=o(c,2);I(J(l),()=>n.right),i(l),i(r),W(()=>t(r,`aria-label`,n.ariaLabel)),B(e,r)}var Mf=e(`
                                    `);function Nf(e,t){let n=q(t,`accent`,3,`--accent`),r=q(t,`disabled`,3,!1),a=q(t,`active`,3,!1);var s=Mf();let c,l;var u=J(s);I(J(u),()=>t.statline),i(u);var d=o(u,2);I(J(d),()=>t.body),i(d),i(s),W(()=>{c=D(s,1,`card svelte-17l5p3y`,null,c,{disabled:r(),active:a()}),l=C(s,``,l,{"--card-accent":`var(${n()??``})`})}),B(e,s)}var Pf=e(``);function Ff(e,t){let n=q(t,`filled`,3,!1),r=K(()=>t.shape===`circle`?n()?`●`:`○`:t.shape===`diamond`?n()?`◆`:`◇`:t.shape===`triangle`?n()?`▲`:`△`:n()?`■`:`□`);var a=Pf(),o=J(a,!0);i(a),W(()=>{D(a,1,`marker ${t.shape??``}`,`svelte-1a5iijm`),z(o,H(r))}),B(e,a)}var If=e(``);function Lf(e,t){let n=q(t,`variant`,3,`ghost`),r=q(t,`size`,3,`md`),a=q(t,`disabled`,3,!1),o=q(t,`busy`,3,!1),c=q(t,`static`,3,!1),u=q(t,`type`,3,`button`);var d=If();T(d,()=>({class:`sk-btn ${n()??``} ${r()??``}`,disabled:a(),"aria-description":t.title,"aria-label":t.ariaLabel,"aria-busy":o()||void 0,type:u(),onclick:t.onclick,[l]:{accented:t.accent!==void 0,"loading-pulse":o(),static:c()},[s]:{"--btn-accent":t.accent,"--btn-solid-fill":t.accent??`var(--action-bg)`,"--btn-solid-ink":t.accent?`var(--text-on-accent)`:`var(--action-ink)`}}),void 0,void 0,void 0,`svelte-g9c1iq`),I(J(d),()=>t.children),i(d),B(e,d)}var Rf=e(`

                                    `),zf=e(`
                                    `),Bf=e(`

                                    `);function Vf(e,t){let n=q(t,`detail`,3,null);var r=Bf(),a=J(r),s=J(a,!0);i(a);var c=o(a,2),l=e=>{var t=Rf(),r=J(t,!0);i(t),W(()=>z(r,n())),B(e,t)};_(c,e=>{n()&&e(l)});var u=o(c,2),d=e=>{var n=zf();I(J(n),()=>t.children),i(n),B(e,n)};_(u,e=>{t.children&&e(d)}),i(r),W(()=>z(s,t.title)),B(e,r)}var Hf=e(` `);function Uf(e,n){let r=Ne();O(n,!0);let s=q(n,`label`,3,`About this setting`),c=E(!1),l,d,f=E(``),p=!1,m=!1,h=!1,g,_,v=xf();function y(e){e.pointerType!==`touch`&&(clearTimeout(_),m=!0,clearTimeout(g),g=setTimeout(()=>{u(c,!0)},300))}function b(e){e.pointerType!==`touch`&&(m=!1,clearTimeout(g),clearTimeout(_),_=setTimeout(()=>{(document.activeElement!==l||!l.matches(`:focus-visible`))&&u(c,!1)},150))}function x(){if(!H(c)||!l||!d)return;let e=window.visualViewport,t=e?.offsetLeft??0,n=e?.offsetTop??0,r=e?.width??window.innerWidth,i=e?.height??window.innerHeight;d.style.maxWidth=`min(18rem, ${r-16}px)`,d.style.maxHeight=`${i-16}px`;let a=l.getBoundingClientRect(),o=d.getBoundingClientRect(),s=Math.max(t+8,Math.min(a.left,t+r-o.width-8)),p=a.bottom+6;u(f,`left:${s}px;top:${p+o.height<=n+i-8?p:Math.max(n+8,a.top-o.height-6)}px;max-width:min(18rem, ${r-16}px);max-height:${i-16}px`)}U(()=>{H(c)?(v.mount(),ye().then(()=>{!H(c)||p||(d.showPopover(),x(),v.show(d))})):d?.matches(`:popover-open`)&&v.close(d)}),U(()=>{v.mounted||d?.hidePopover()}),ae(()=>{let e=e=>{e.target instanceof Node&&!l.contains(e.target)&&!d.contains(e.target)&&(clearTimeout(g),u(c,!1))};return document.addEventListener(`pointerdown`,e,!0),document.addEventListener(`keydown`,S,!0),window.addEventListener(`resize`,x),window.addEventListener(`scroll`,x,!0),window.visualViewport?.addEventListener(`resize`,x),window.visualViewport?.addEventListener(`scroll`,x),()=>{p=!0,clearTimeout(g),clearTimeout(_),v.destroy(),document.removeEventListener(`pointerdown`,e,!0),document.removeEventListener(`keydown`,S,!0),window.removeEventListener(`resize`,x),window.removeEventListener(`scroll`,x,!0),window.visualViewport?.removeEventListener(`resize`,x),window.visualViewport?.removeEventListener(`scroll`,x)}});function S(e){e.key===`Escape`&&(clearTimeout(g),H(c)&&(u(c,!1),e.preventDefault(),e.stopPropagation()))}var T=Hf();let k;var A=J(T);Ke(J(A),{name:`help`,size:20}),i(A),a(A,e=>l=e,()=>l);var j=o(A,2),M=J(j,!0);i(j),a(j,e=>d=e,()=>d),i(T),W(()=>{k=D(T,1,`info-tip svelte-46n1f7`,null,k,{open:H(c)}),t(A,`aria-label`,s()),t(A,`aria-describedby`,r),t(A,`aria-expanded`,H(c)),t(j,`id`,r),C(j,H(f)),z(M,n.text)}),ie(`pointerenter`,T,y),ie(`pointerleave`,T,b),G(`focusout`,T,e=>{!m&&!e.currentTarget.contains(e.relatedTarget)&&u(c,!1)}),ie(`focus`,A,()=>{l.matches(`:focus-visible`)&&(clearTimeout(g),u(c,!0))}),G(`pointerdown`,A,e=>{h=e.pointerType===`touch`}),G(`click`,A,e=>{clearTimeout(g),clearTimeout(_),u(c,e.detail>0&&h?!H(c):!0,!0)}),B(e,T),w()}ke([`focusout`,`pointerdown`,`click`]);var Wf=e(` `),Gf=e(` `,1),Kf=e(` `),qf=e(` `),Jf=e(`steered: `),Yf=e(`unsteered`),Xf=e(``),Zf=e(`
                                    readout
                                    `);function Qf(e,t){O(t,!0);let n=q(t,`source`,3,null),r=q(t,`layer`,3,null),a=q(t,`steered`,15),s=q(t,`accent`,3,`var(--accent)`);var c=Zf();let u;var d=o(J(c),2),f=e=>{var n=Gf(),r=N(n);De(r,()=>t.origin,e=>{var n=Wf();T(n,()=>({class:`kv origin`,"aria-description":t.origin===`captured`?`Recorded when this token was generated. No new model run was needed.`:`Computed by running the recorded context through the model again.`}),void 0,void 0,void 0,`svelte-1drc9te`);var r=J(n,!0);i(n),W(()=>z(r,t.origin)),He(1,n,()=>Hr,()=>({duration:lf(140)})),B(e,n)});var a=o(r,2);{let e=K(()=>t.origin===`captured`?`Recorded when this token was generated. No new model run was needed.`:`Computed by running the recorded context through the model again.`);Uf(a,{label:`About readout provenance`,get text(){return H(e)}})}B(e,n)};_(d,e=>{t.origin&&e(f)});var p=o(d,2),m=e=>{var t=Kf(),r=J(t,!0);i(t),W(()=>z(r,n())),B(e,t)};_(p,e=>{n()&&e(m)});var h=o(p,2),g=e=>{var t=qf();T(t,()=>({class:`kv`,"aria-description":`The model layer where this SAE measures feature activations.`}),void 0,void 0,void 0,`svelte-1drc9te`);var n=J(t);i(t),W(()=>z(n,`L${r()??``}`)),B(e,t)};_(h,e=>{r()!=null&&r()>=0&&e(g)});var v=o(h,2),y=e=>{var n=Jf();T(n,()=>({class:`kv steer-chip`,"aria-description":`These steering settings were applied when computing this readout.`}),void 0,void 0,void 0,`svelte-1drc9te`);var r=o(J(n)),a=J(r,!0);i(r),i(n),W(()=>z(a,t.steering)),B(e,n)},b=e=>{var t=Yf();T(t,()=>({class:`kv`,"aria-description":`Computed without steering so you can compare it with the steered readout.`}),void 0,void 0,void 0,`svelte-1drc9te`),B(e,t)};_(v,e=>{t.steering===null?a()||e(b,1):e(y)});var x=o(v,2),S=e=>{var t=Xf(),n=()=>{a(!a())};T(t,()=>({type:`button`,class:`steer-toggle`,"aria-pressed":a(),"aria-description":a()?`Recompute without the original steering to compare its effect.`:`Recompute using the steering saved with this generation.`,onclick:n,[l]:{on:a()}}),void 0,void 0,void 0,`svelte-1drc9te`);var r=J(t);i(t),W(()=>z(r,`Steering ${a()?`on`:`off`}`)),B(e,t)};_(x,e=>{t.showToggle&&e(S)}),i(c),W(()=>u=C(c,``,u,{"--inst-accent":s()})),B(e,c),w()}var $f=e(``),ep=e(`

                                    `);function tp(e,t){let n=q(t,`count`,3,null),r=q(t,`accent`,3,`var(--accent)`);var a=ep();let s;var c=J(a),l=J(c),u=J(l),d=J(u,!0);i(u);var f=o(u,2),p=e=>{var t=$f();Z(J(t),{get text(){return n()}}),i(t),B(e,t)};_(f,e=>{n()&&e(p)}),i(l),i(c);var m=o(c,2);I(J(m),()=>t.children),i(m),i(a),W(()=>{s=C(a,``,s,{"--section-accent":r()}),z(d,t.title)}),B(e,a)}var np=e(` `),rp=e(``),ip=e(` `),ap=e(` `),op=e(`
                                    `);function sp(e,t){let n=q(t,`secondary`,3,null),r=q(t,`secondaryAccent`,3,!1),a=q(t,`meta`,3,null),s=q(t,`badge`,3,null),c=q(t,`tail`,3,null),u=q(t,`tailAccent`,3,!1);var d=op(),f=J(d);I(J(f),()=>t.lead),i(f);var p=o(f,2);T(p,()=>({class:`primary`,"aria-description":t.primaryTitle}),void 0,void 0,void 0,`svelte-19muw5c`);var m=J(p,!0);i(p);var h=o(p,2),g=e=>{var a=np();T(a,()=>({class:`secondary`,"aria-description":t.secondaryTitle,[l]:{accent:r()}}),void 0,void 0,void 0,`svelte-19muw5c`);var o=J(a,!0);i(a),W(()=>z(o,n())),B(e,a)};_(h,e=>{n()&&e(g)});var v=o(h,2),y=e=>{var n=rp();T(n,()=>({class:`meta`,"aria-description":t.metaTitle}),void 0,void 0,void 0,`svelte-19muw5c`),Z(J(n),{get text(){return a()},get identity(){return t.primary}}),i(n),B(e,n)};_(v,e=>{a()&&e(y)});var b=o(v,2),x=e=>{var n=ip();T(n,()=>({class:`badge`,"aria-description":t.badgeTitle}),void 0,void 0,void 0,`svelte-19muw5c`);var r=J(n,!0);i(n),W(()=>z(r,s())),B(e,n)};_(b,e=>{s()&&e(x)});var S=o(b,4),C=e=>{var n=ap();T(n,()=>({class:`tail`,"aria-description":t.tailTitle,[l]:{accent:u()}}),void 0,void 0,void 0,`svelte-19muw5c`);var r=J(n,!0);i(n),W(()=>z(r,c())),B(e,n)};_(S,e=>{c()&&e(C)}),i(d),W(()=>z(m,t.primary)),B(e,d)}var cp=e(``),lp=e(` `),up=e(`
                                    `);function dp(e,n){O(n,!0);let r=q(n,`ariaLabel`,3,`Supporting evidence`);var a=k(),s=N(a),c=e=>{var a=up();f(a,21,()=>n.items,v,(e,t)=>{var n=lp();T(n,()=>({class:`chip`,"aria-description":H(t).title,role:`listitem`,[l]:{soft:H(t).soft}}),void 0,void 0,void 0,`svelte-1u6vkiq`);var r=J(n),a=o(r),s=e=>{var n=cp();Z(J(n),{get text(){return H(t).value},get identity(){return H(t).label}}),i(n),B(e,n)};_(a,e=>{H(t).value&&e(s)}),i(n),W(()=>z(r,`${H(t).label??``} `)),B(e,n)}),i(a),W(()=>t(a,`aria-label`,r())),B(e,a)};_(s,e=>{n.items.length>0&&e(c)}),B(e,a),w()}var fp=e(`%`,1),pp=e(`

                                    You can inspect another token while this finishes. This result will be kept.

                                    `),mp=e(`subspace`),hp=e(` `),gp=e(``),_p=e(` `),vp=e(`@`),yp=e(``),bp=e(`

                                    Across fitted layers

                                    `,1),xp=e(`
                                    How to read geometry
                                    Coordinates
                                    Position in the fitted domain. On a two-pole axis, 0 is neutral and +1 is the named pole. Values can extend beyond a pole.
                                    Subspace
                                    Share of the centered activation in this subspace, from 0 to 1. Larger subspaces can capture more; this is not confidence.
                                    Distance · d
                                    Distance to a node in typical label spacings. Smaller is closer; 1 means one typical spacing away.
                                    Assignment · ~
                                    Relative geometric fit among nodes, not the probability that a trait is true.
                                    Membership
                                    Fit inside a curved manifold’s learned tube. Flat fits always return 1, so that value is hidden.
                                    `,1),Sp=e(` `,1),Cp=e(`

                                    Concept training isn’t available in this session. You can still add a fitted concept as a probe.

                                    `),wp=e(`
                                    `,1);function Tp(e,n){O(n,!0);let r=q(n,`steered`,15),a=K(()=>Object.entries(n.readout.data?.readings??{}).sort(([e],[t])=>e.localeCompare(t,void 0,{sensitivity:`base`}))),s=Qe(`manifold_builder`);function c(e=!1){lt(e?`manifold_builder`:`subspace`,{returnToToken:n.returnToToken,...e?{mode:`discover`}:{}})}let l=K(()=>n.replayAvailable&&((n.readout.data?.steering??null)!==null||!r())),u=K(()=>n.readout.progress!==null&&n.readout.progress.progress>0),d=K(()=>Math.round((n.readout.progress?.progress??0)*100)),m=K(()=>n.readout.progress?.phase===`readout`?`Reading geometry`:n.readout.progress?.phase===`queued`?`Waiting for the model`:`Preparing this token`);function h(e){let t=To.entries.get(e)?.info;return t?.family===`geometry`?t.is_affine:null}function g(e,t,n){let r=To.entries.get(e)?.info,i=r?.family===`geometry`?r.node_labels:void 0;return n===1&&t===0&&i&&i.length===2?i[0]:`c${t}`}function y(e,t){let n=h(e)===!1,r={};if(n)Object.assign(r,t.fraction_per_layer??{});else for(let[e,n]of Object.entries(t.coords_per_layer??{}))r[e]=n[0]??null;return Object.keys(r).sort((e,t)=>Number(e)-Number(t)).map(e=>{let t=r[e],n=t!==null&&t>=0?`+`:``;return{layer:Number(e),value:t,title:t===null?`L${e} · unavailable`:`L${e} · ${n}${t.toFixed(3)}`}})}function b(e,t){return h(e)===!1?1:Po(e,0)}function x(e,t){return[...(e.nearest??[]).map(([e,t])=>({label:e,value:`d=${t.toFixed(2)}`,title:`${t.toFixed(3)} typical label spacings away · smaller is closer`})),...(e.assignment??[]).map(([e,t])=>({label:`~${e}`,value:`${(t*100).toFixed(0)}%`,title:`geometric assignment · ${(t*100).toFixed(1)}% · relative fit among nodes, not semantic confidence`,soft:!0})),...t===!1||e.residual!==0?[{label:`residual`,value:e.residual.toFixed(3),title:`off-surface distance divided by the in-subspace activation norm · smaller is closer to the surface`}]:[],...t!==!0&&e.membership!=null?[{label:`membership`,value:e.membership.toFixed(3),title:`fit inside the learned tube · 0 to 1 · not semantic confidence; without a learned tube this defaults to 1`}]:[]]}var S=k(),E=N(S),A=e=>{var r=pp(),a=J(r),s=J(a);Z(J(s),{get text(){return H(m)},numbers:!1}),i(s);var c=o(s,2),l=J(c),f=e=>{var t=fp();Wd(N(t),{get value(){return H(d)}}),Y(),B(e,t)},p=e=>{B(e,Se(`starting`))};_(l,e=>{H(u)?e(f):e(p,-1)}),i(c),i(a);var h=o(a,2);let g;var v=J(h);i(h);var y=o(h,2),b=J(y,!0);i(y),Y(2),i(r),W(()=>{g=D(h,1,`progress-track svelte-1z0f2vr`,null,g,{indeterminate:!H(u)}),t(h,`aria-valuenow`,H(u)?H(d):void 0),t(h,`aria-valuetext`,H(u)?`${H(d)}%`:`Starting`),C(v,H(u)?`width: ${H(d)}%`:void 0),z(b,n.readout.progress?.message??`Waiting for the model`)}),B(e,r)},j=e=>{{let t=K(()=>`readout: ${n.readout.error}`);Vf(e,{get title(){return H(t)}})}},M=e=>{var t=Sp(),s=N(t);Qf(s,{get origin(){return n.readout.origin},get source(){return n.readout.source},get steering(){return n.readout.data.steering},get showToggle(){return H(l)},accent:`var(--pillar-subspace)`,get steered(){return r()},set steered(e){r(e)}});var c=o(s,2);{let e=K(()=>`${H(a).length} attached`);tp(c,{title:`PROBE READINGS`,get count(){return H(e)},children:(e,t)=>{var n=xp(),r=o(N(n),2);f(r,21,()=>H(a),([e,t])=>e,(e,t)=>{var n=K(()=>p(H(t),2));let r=()=>H(n)[0],a=()=>H(n)[1],s=K(()=>a().coords.length),c=K(()=>y(r(),a())),l=K(()=>h(r())),u=K(()=>H(l)===!1?`--pillar-manifold`:`--pillar-subspace`),d=K(()=>x(a(),H(l)));Nf(e,{get accent(){return H(u)},disabled:!1,statline:e=>{{let t=e=>{{let t=K(()=>H(l)===!1?`diamond`:`circle`);Ff(e,{get shape(){return H(t)},filled:!0})}},n=K(()=>H(l)===null?`geometry`:H(l)?`subspace`:`manifold`),i=K(()=>a().depth_com?.[0]==null?null:`@${a().depth_com[0].toFixed(2)} ±${(a().depth_spread?.[0]??0).toFixed(2)}`);sp(e,{get primary(){return r()},get primaryTitle(){return r()},get secondary(){return H(n)},secondaryAccent:!0,get meta(){return H(i)},metaTitle:`Where this probe’s signal is concentrated across layers: 0 is the first layer, 1 is the last. The ± value shows how widely it is spread.`,lead:t,$$slots:{lead:!0}})}},body:e=>{var t=bp(),n=o(N(t),2);{let e=e=>{var t=mp();T(t,()=>({class:`geo-axis-label`,"aria-description":`Share of the centered activation in this subspace · 0 to 1 · not confidence`}),void 0,void 0,void 0,`svelte-1z0f2vr`),B(e,t)},t=e=>{Xd(e,{percentage:!0,get value(){return a().fraction},max:1,color:`var(--fg)`})},r=e=>{var t=k(),n=N(t),r=e=>{var t=hp(),n=J(t,!0);i(t),W(()=>z(n,a().nearest[0][0])),B(e,t)};_(n,e=>{(a().nearest??[]).length>0&&e(r)}),B(e,t)},o=e=>{var t=gp(),n=J(t);{let e=K(()=>a().fraction.toFixed(3));Z(n,{get text(){return H(e)}})}i(t),B(e,t)},s=K(()=>`Subspace fraction ${a().fraction.toFixed(3)}`);jf(n,{get ariaLabel(){return H(s)},left:e,bar:t,middle:r,right:o,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var u=o(n,2);f(u,17,()=>a().coords,v,(e,t,n)=>{{let c=e=>{var t=_p();T(t,()=>({class:`geo-axis-label`,"aria-description":`coordinate axis ${n}`}),void 0,void 0,void 0,`svelte-1z0f2vr`);var a=J(t,!0);i(t),W(e=>z(a,e),[()=>g(r(),n,H(s))]),B(e,t)},l=e=>{{let i=K(()=>Po(r(),n));Xd(e,{get value(){return H(t)},get max(){return H(i)},bipolar:!0})}},u=e=>{var t=k(),r=N(t),s=e=>{var t=vp();T(t,e=>({class:`geo-depth`,...e}),[()=>({"aria-description":`depth center ±${(a().depth_spread?.[n]??0).toFixed(2)} · 0 first, 1 last`})],void 0,void 0,`svelte-1z0f2vr`);var r=o(J(t));{let e=K(()=>a().depth_com[n].toFixed(2));Z(r,{get text(){return H(e)}})}i(t),B(e,t)};_(r,e=>{a().depth_com&&a().depth_com[n]!=null&&e(s)}),B(e,t)},d=e=>{var n=yp(),r=J(n);{let e=K(()=>H(t).toFixed(3));Z(r,{get text(){return H(e)}})}i(n),B(e,n)},f=K(()=>`${r()} axis ${n}`);jf(e,{get ariaLabel(){return H(f)},left:c,bar:l,middle:u,right:d,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}});var p=o(u,2),m=e=>{{let t=K(()=>b(r(),a())),n=K(()=>H(l)===!1?`var(--pillar-manifold)`:void 0),i=K(()=>`${r()} per-layer readings`);af(e,{get cells(){return H(c)},get scale(){return H(t)},get positiveColor(){return H(n)},get ariaLabel(){return H(i)}})}};_(p,e=>{H(c).length>0&&e(m)});var h=o(p,2);{let e=K(()=>`Geometry evidence for ${r()}`);dp(h,{get items(){return H(d)},get ariaLabel(){return H(e)}})}var y=o(h,2),x=e=>{{let t=K(()=>a().coords.map((e,t)=>g(r(),t,H(s))));kf(e,{get name(){return r()},get reading(){return a()},get axisLabels(){return H(t)}})}};_(y,e=>{H(l)&&e(x)}),B(e,t)},$$slots:{statline:!0,body:!0}})}),i(r),B(e,n)},$$slots:{default:!0}})}B(e,t)},P=e=>{Vf(e,{title:`Add a probe to see concept readings`,detail:`Choose a fitted concept, or create and train one for this model. Add it as a probe to inspect its readings here.`,children:(e,t)=>{var n=wp(),r=N(n),a=J(r);Lf(a,{variant:`solid`,onclick:()=>c(),children:(e,t)=>{Y(),B(e,Se(`Add a probe`))},$$slots:{default:!0}});var l=o(a,2),u=e=>{Lf(e,{onclick:()=>c(!0),children:(e,t)=>{Y(),B(e,Se(`Create a concept`))},$$slots:{default:!0}})};_(l,e=>{s.available&&e(u)}),i(r);var d=o(r,2),f=e=>{B(e,Cp())};_(d,e=>{s.available||e(f)}),B(e,n)},$$slots:{default:!0}})},F=e=>{Vf(e,{title:`no raw decode record`,detail:`replay needs a loom node generated with raw-decode capture in this session`})},I=e=>{Vf(e,{title:`no readings`})};_(E,e=>{n.readout.loading?e(A):n.readout.error?e(j,1):n.readout.data&&H(a).length>0?e(M,2):n.hasGeometryProbes?n.hasReplayContext?e(I,-1):e(F,4):e(P,3)}),B(e,S),w()}var Ep=e(`

                                    This token has almost all of the probability after sampling settings. + That is not a measure of factual accuracy.

                                    `),Dp=e(` `),Op=e(`probability`),kp=e(`logp `),Ap=e(``),jp=e(`
                                    Δ top token id
                                    `,1),Mp=e(`

                                    `),Np=e(`
                                    `,1),Pp=e(` `,1);function Fp(e,t){O(t,!0);let n=Pe().mode,r=Wi(n),a=Ui(n)>0,s=K(()=>n===`http`||n===`browser`&&ts(`geometry`)?.capabilities.token_readout===!0),c=K(()=>{let e=t.token.topAlts;if(!e||e.length===0)return[];let n=e[0]?.logprob??0;return e.map((e,r)=>({rank:r+1,id:e.id,text:e.text,logprob:e.logprob,p:Math.exp(e.logprob),delta:e.logprob-n,chosen:t.token.tokenId!=null&&e.id===t.token.tokenId}))}),l=K(()=>H(c).length===1&&H(c)[0].chosen&&H(c)[0].p>=.9995),d=E(null),p=E(null);function m(e){return e==null||!Number.isFinite(e)?`-`:e.toFixed(3)}function h(e){return Number.isFinite(e)?e>=.001?e.toFixed(4):e.toExponential(2):`-`}function g(e,t){return t===1||!Number.isFinite(e)?`-`:e.toFixed(3)}function v(){a&&(is.return_top_k??0)===0&&(is.return_top_k=r)}async function y(e){if(u(p,null),!t.nodeId){u(p,`no generated loom node is available for this token`);return}if(t.token.rawIndex==null){u(p,`this token has no raw-decode index; forking needs a node generated with raw-decode capture in this session`);return}u(d,e.rank,!0);try{await Rc(t.nodeId,t.token.rawIndex,e.id),ut(),sc.view=`map`,window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`branches`}))}catch(e){u(p,Ie(e,`Unable to create a branch from this word choice. Try another alternative.`),!0)}finally{u(d,null)}}var b=Pp(),x=N(b);Qf(x,{origin:`captured`,source:`sampler`,steering:null,steered:!0,showToggle:!1,accent:`var(--pillar-lens)`});var S=o(x,2);{let e=K(()=>H(c).length>0?`${H(c).length} retained`:`capture unavailable`);tp(S,{title:`RANKED ALTERNATIVES`,get count(){return H(e)},accent:`var(--pillar-lens)`,children:(e,n)=>{var r=k(),u=N(r),b=e=>{var t=Np(),n=N(t),r=e=>{B(e,Ep())};_(n,e=>{H(l)&&e(r)});var a=o(n,2);f(a,21,()=>H(c),e=>e.id,(e,t)=>{Nf(e,{accent:`--pillar-lens`,disabled:!1,get active(){return H(t).chosen},statline:e=>{{let n=e=>{var n=Dp(),r=J(n);i(n),W(()=>z(r,`#${H(t).rank??``}`)),B(e,n)},r=K(()=>JSON.stringify(H(t).text)),a=K(()=>`id ${H(t).id}`),o=K(()=>H(t).chosen?`generated`:null);sp(e,{get primary(){return H(r)},get secondary(){return H(a)},get badge(){return H(o)},lead:n,$$slots:{lead:!0}})}},body:e=>{var n=jp(),r=N(n);{let e=e=>{B(e,Op())},n=e=>{Xd(e,{percentage:!0,get value(){return H(t).p},max:1,color:`var(--pillar-lens)`})},a=e=>{var n=kp(),r=o(J(n));{let e=K(()=>m(H(t).logprob));Z(r,{get text(){return H(e)}})}i(n),B(e,n)},s=e=>{var n=Ap(),r=J(n);{let e=K(()=>h(H(t).p));Z(r,{get text(){return H(e)}})}i(n),B(e,n)},c=K(()=>`Probability ${h(H(t).p)}`);jf(r,{get ariaLabel(){return H(c)},left:e,bar:n,middle:a,right:s,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var a=o(r,2),c=J(a),l=o(J(c)),u=J(l);{let e=K(()=>g(H(t).delta,H(t).rank));Z(u,{get text(){return H(e)}})}i(l),i(c);var f=o(c,2),p=o(J(f)),_=J(p,!0);i(p),i(f);var v=o(f,4);{let e=K(()=>!H(s)||H(t).chosen||H(d)!==null),n=K(()=>H(s)?void 0:`Token branching is not available in the browser runtime yet`);Lf(v,{size:`sm`,get disabled(){return H(e)},onclick:()=>y(H(t)),get title(){return H(n)},children:(e,n)=>{{let n=K(()=>H(d)===H(t).rank?`Starting…`:H(t).chosen?`Used`:H(s)?`Start branch`:`View only`);Z(e,{get text(){return H(n)},numbers:!1})}},$$slots:{default:!0}})}i(a),W(()=>z(_,H(t).id)),B(e,n)},$$slots:{statline:!0,body:!0}})}),i(a);var u=o(a,2),v=e=>{var t=Mp(),n=J(t,!0);i(t),W(()=>z(n,H(p))),B(e,t)};_(u,e=>{H(p)&&e(v)}),B(e,t)},x=e=>{{let n=K(()=>`logprob ${m(t.token.logprob)} · no alternatives captured`);Vf(e,{get title(){return H(n)},children:(e,t)=>{{let t=K(()=>!a||is.return_top_k>0);Lf(e,{onclick:v,get disabled(){return H(t)},children:(e,t)=>{Y();var n=Se();W(()=>z(n,a?is.return_top_k>0?`alts on next run`:`enable alts`:`alts unavailable`)),B(e,n)},$$slots:{default:!0}})}},$$slots:{default:!0}})}},S=e=>{Vf(e,{title:`no logprob data`,children:(e,t)=>{{let t=K(()=>!a||is.return_top_k>0);Lf(e,{onclick:v,get disabled(){return H(t)},children:(e,t)=>{Y();var n=Se();W(()=>z(n,a?is.return_top_k>0?`alts on next run`:`enable alts`:`alts unavailable`)),B(e,n)},$$slots:{default:!0}})}},$$slots:{default:!0}})};_(u,e=>{H(c).length>0?e(b):t.token.logprob==null?e(S,-1):e(x,1)}),B(e,r)},$$slots:{default:!0}})}B(e,b),w()}var Ip=`/assets/gemma-3-1b-it.json`,Lp=`/assets/gemma-3-270m-it.json`,Rp=`/assets/gemma-3-4b-it.json`;function zp(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var Bp=[{size:`270m`,layer:12,sha256:`f99efac8449faa1e5b715e0298f27d5cf3f5646fce5a5ece14ded90a09efeb65`},{size:`1b`,layer:13,sha256:`6be6fbfed9850588adb1826bcc9fc89551d9eaf573311e95b21307fd4a281cd5`},{size:`4b`,layer:17,sha256:`f67e2305cfd1703d8a685d99fb25b6f25a2feaaa4eb45ef08a467f400b696d71`}];function Vp(e,t,n){let r=e;if(!zp(r)||r.modelId!==t.model||r.layer!==t.source||String(r.index)!==String(n)||!zp(r.source)||r.source.hfRepoId!==t.repository||t.folder!==void 0&&r.source.hfFolderId!==t.folder||t.saeId!==void 0&&r.source.saelensSaeId!==t.saeId||!t.folder&&!t.saeId||!Array.isArray(r.explanations))throw Error(`The description belongs to a different SAE dictionary.`);let i=r.explanations.find(e=>zp(e)&&typeof e.description==`string`&&!!e.description.trim());return{label:i?.description.trim()??null,explanationModel:typeof i?.explanationModelName==`string`?i.explanationModelName:null,url:`https://www.neuronpedia.org/${encodeURIComponent(t.model)}/${encodeURIComponent(t.source)}/${n}`}}var Hp=new Map,Up=new Map;function Wp(e){return Bp.find(t=>e.model===`gemma-3-${t.size}-it`&&e.source===`${t.layer}-gemmascope-2-res-16k`&&e.repository===`google/gemma-scope-2-${t.size}-it`&&!!(e.folder||e.saeId)&&(e.folder===void 0||e.folder===`resid_post/layer_${t.layer}_width_16k_l0_medium`)&&(e.saeId===void 0||e.saeId===`layer_${t.layer}_width_16k_l0_medium`))}async function Gp(e,t){let n=Wp(e);if(!n)return null;let r=Up.get(n.size);r||(r=(async()=>{let t=new URL(Object.assign({"./data/sae-descriptions/gemma-3-1b-it.json":Ip,"./data/sae-descriptions/gemma-3-270m-it.json":Lp,"./data/sae-descriptions/gemma-3-4b-it.json":Rp})[`./data/sae-descriptions/gemma-3-${n.size}-it.json`],import.meta.url),r=await fetch(t.href,{signal:AbortSignal.timeout(5e3),credentials:`omit`,referrerPolicy:`no-referrer`});if(!r.ok)throw Error(`Bundled SAE descriptions are unavailable.`);let i=await r.json();if(!zp(i)||i.format_version!==1||i.provider_sha256!==n.sha256||i.feature_count!==16384||!zp(i.source)||i.source.model!==e.model||i.source.source!==e.source||i.source.repository!==e.repository||i.source.folder!==`resid_post/layer_${n.layer}_width_16k_l0_medium`||!zp(i.explanations))throw Error(`Bundled descriptions do not match this SAE.`);for(let[e,t]of Object.entries(i.explanations))if(!/^(0|[1-9]\d*)$/.test(e)||Number(e)>=16384||!Array.isArray(t)||t.length!==2||typeof t[0]!=`string`||!t[0].trim()||t[1]!==null&&typeof t[1]!=`string`)throw Error(`Bundled SAE descriptions are invalid.`);return i.explanations})(),Up.set(n.size,r));let i;try{i=await r}catch{return Up.get(n.size)===r&&Up.delete(n.size),null}let a=i[String(t)];return a?{label:a[0],explanationModel:a[1],url:`https://www.neuronpedia.org/${encodeURIComponent(e.model)}/${encodeURIComponent(e.source)}/${t}`}:null}async function Kp(e,t,n){if(!Number.isSafeInteger(t)||t<0)throw Error(`Invalid SAE feature ID.`);n.throwIfAborted();let r=JSON.stringify([e,t]),i=Hp.get(r);if(i)return i;let a=await Gp(e,t);if(n.throwIfAborted(),!a){let r=await fetch(`https://www.neuronpedia.org/api/feature/${encodeURIComponent(e.model)}/${encodeURIComponent(e.source)}/${t}`,{signal:n,credentials:`omit`,referrerPolicy:`no-referrer`});if(!r.ok)throw Error(`Descriptions could not be loaded. Try again when you are online.`);a=Vp(await r.json(),e,t)}return Hp.set(r,a),Hp.size>512&&Hp.delete(Hp.keys().next().value),a}var qp=e(` `),Jp=e(``),Yp=e(` `),Xp=e(` `,1),Zp=e(`
                                    `);function Qp(e,t){O(t,!0);let n=K(()=>`var(${t.accent})`),r=K(()=>Math.max(1,...Object.values(t.readings).filter(e=>e.unit===`raw_activation`).map(e=>e.value))),a=K(()=>Object.entries(t.readings).sort(([e],[t])=>e.localeCompare(t,void 0,{sensitivity:`base`})));function s(e){let t=e.per_layer??{};return Object.keys(t).sort((e,t)=>Number(e)-Number(t)).map(n=>({layer:Number(n),value:t[n],title:`L${n} · ${Gd(t[n],e.unit===`mean_token_probability`)} · ${c[e.unit]}`}))}let c={mean_token_probability:`mean fitted-layer probability`,activation_over_max:`activation / corpus max`,raw_activation:`raw activation (no corpus max cached)`};function l(e){return Math.max(...e.map(e=>e.value??0),1e-12)}var u=k(),d=N(u),m=e=>{{let u=K(()=>`${H(a).length} captured`);tp(e,{title:`PINNED PROBES`,get count(){return H(u)},get accent(){return H(n)},children:(e,u)=>{var d=Zp();f(d,21,()=>H(a),([e,t])=>e,(e,a)=>{var u=K(()=>p(H(a),2));let d=()=>H(u)[0],f=()=>H(u)[1],m=K(()=>s(f()));Nf(e,{get accent(){return t.accent},disabled:!1,statline:e=>{{let n=e=>{Ff(e,{get shape(){return t.shape},filled:!0})},r=K(()=>`probe ${d()}`),i=K(()=>f().depth?.center?.[0]==null?null:`@${f().depth.center[0].toFixed(2)} ±${(f().depth.spread?.[0]??0).toFixed(2)}`);sp(e,{get primary(){return d()},get primaryTitle(){return H(r)},get meta(){return H(i)},metaTitle:`Where this probe’s signal is concentrated across layers: 0 is the first layer, 1 is the last. The ± value shows how widely it is spread.`,lead:n,$$slots:{lead:!0}})}},body:e=>{var t=Xp(),a=N(t);{let e=e=>{var t=qp();T(t,()=>({class:`row-label`,"aria-description":c[f().unit]}),void 0,void 0,void 0,`svelte-1df69yl`);var n=J(t,!0);i(t),W(()=>z(n,f().unit===`raw_activation`?`activation`:`strength`)),B(e,t)},t=e=>{{let t=K(()=>f().unit===`mean_token_probability`),i=K(()=>Math.max(f().value,0)),a=K(()=>f().unit===`raw_activation`?H(r):1);Xd(e,{get percentage(){return H(t)},get value(){return H(i)},get max(){return H(a)},get color(){return H(n)}})}},o=e=>{B(e,Jp())},s=e=>{var t=Yp(),n=J(t,!0);i(t),W(e=>z(n,e),[()=>f().value.toFixed(3)]),B(e,t)},l=K(()=>`Pinned probe ${d()}`);jf(a,{get ariaLabel(){return H(l)},left:e,bar:t,middle:o,right:s,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var s=o(a,2),u=e=>{{let t=K(()=>l(H(m))),r=K(()=>`${d()} per-layer strength`);af(e,{get cells(){return H(m)},get scale(){return H(t)},get positiveColor(){return H(n)},get ariaLabel(){return H(r)}})}};_(s,e=>{H(m).length>1&&e(u)}),B(e,t)},$$slots:{statline:!0,body:!0}})}),i(d),B(e,d)},$$slots:{default:!0}})}};_(d,e=>{H(a).length>0&&e(m)}),B(e,u),w()}var $p=e(`%`,1),em=e(`

                                    You can inspect another token while this finishes. This result will be kept.

                                    `),tm=e(` `,1),nm=e(`

                                    Checking the SAE description source…

                                    `),rm=e(` `,1),im=e(``),am=e(`

                                    Checking the published feature records…

                                    `),om=e(``),sm=e(` `),cm=e(`

                                    `),lm=e(`

                                    `),um=e(` `),dm=e(`
                                    `,1),fm=e(`
                                    `),pm=e(`

                                    `),mm=e(`
                                    `,1),hm=e(`
                                    `,1),gm=e(`

                                    Feature descriptions are published interpretations, not definitive meanings. Activations are not probabilities.

                                    `,1);function _m(e,n){O(n,!0);let r=q(n,`steered`,15);ae(()=>{Bs()});let a=K(()=>zs.sources.find(e=>e.source===n.readout.source&&e.layer===n.readout.data?.layer)),s=K(()=>H(a)?.description_source),c=K(()=>JSON.stringify(H(s)??null)),l=K(()=>`${n.readout.data?.node_id}/${n.readout.data?.raw_index}/${n.readout.source}/${n.readout.data?.layer}/${n.readout.data?.features.map(e=>e.id).join(`,`)}`),d=E(``),p=E(`activation`),m=E(ze({})),h=E(!1),g=E(``),v=null,y=K(()=>(n.readout.data?.features??[]).some(e=>!e.label?.trim()&&!H(m)[e.id])),b=K(()=>new Map([...n.readout.data?.features??[]].sort((e,t)=>t.activation-e.activation).map((e,t)=>[e.id,t+1])));U(()=>(H(l),H(c),u(m,{},!0),u(g,``),u(h,!1),u(d,``),Fe(()=>{S()}),()=>{v?.abort(),v=null}));let x=K(()=>{let e=H(d).trim().toLowerCase();return[...n.readout.data?.features??[]].filter(t=>!e||`sae/${t.id} ${t.label?.trim()||H(m)[t.id]?.label||``}`.toLowerCase().includes(e)).sort((e,t)=>H(p)===`id`?e.id-t.id:t.activation-e.activation)});async function S(){let e=H(s);if(!e||!n.readout.data||H(h))return;let t=new AbortController;v=t,u(h,!0),u(g,``);let r=setTimeout(()=>t.abort(),2e4),i=n.readout.data.features.filter(e=>!e.label?.trim()&&!H(m)[e.id]);try{for(let n=0;n[n.id,await Kp(e,n.id,t.signal)]));if(v!==t)return;for(let e of r)e.status===`fulfilled`?u(m,{...H(m),[e.value[0]]:e.value[1]},!0):u(g,`Some descriptions could not be loaded. Check your connection and try again.`);if(t.signal.aborted)break}}catch{v===t&&u(g,`Some descriptions could not be loaded. Check your connection and try again.`)}finally{clearTimeout(r),v===t&&u(h,!1)}}let T=K(()=>n.replayAvailable&&((n.readout.data?.steering??null)!==null||!r())),A=K(()=>n.readout.progress!==null&&n.readout.progress.progress>0),j=K(()=>Math.round((n.readout.progress?.progress??0)*100)),M=K(()=>n.readout.progress?.phase===`readout`?`Reading model features`:n.readout.progress?.phase===`queued`?`Waiting for the model`:`Preparing this token`),F=K(()=>Math.max(...(n.readout.data?.features??[]).filter(e=>!(e.max_act!=null&&e.max_act>0)).map(e=>e.activation),1));function I(e){return e.max_act!=null&&e.max_act>0?e.activation/e.max_act:null}function L(e){return e.max_act!=null&&e.max_act>0?[{label:`activation`,value:e.activation.toFixed(3),title:`raw activation · ${e.activation.toFixed(3)}`},{label:`reference maximum`,value:e.max_act.toFixed(3),title:`Reference maximum supplied with this feature: ${e.max_act.toFixed(3)}`}]:[]}var R=k(),ee=N(R),te=e=>{var r=em(),a=J(r),s=J(a);Z(J(s),{get text(){return H(M)},numbers:!1}),i(s);var c=o(s,2),l=J(c),u=e=>{var t=$p();Wd(N(t),{get value(){return H(j)}}),Y(),B(e,t)},d=e=>{B(e,Se(`starting`))};_(l,e=>{H(A)?e(u):e(d,-1)}),i(c),i(a);var f=o(a,2);let p;var m=J(f);i(f);var h=o(f,2),g=J(h,!0);i(h),Y(2),i(r),W(()=>{p=D(f,1,`progress-track svelte-w3bzpw`,null,p,{indeterminate:!H(A)}),t(f,`aria-valuenow`,H(A)?H(j):void 0),t(f,`aria-valuetext`,H(A)?`${H(j)}%`:`Starting`),C(m,H(A)?`width: ${H(j)}%`:void 0),z(g,n.readout.progress?.message??`Waiting for the model`)}),B(e,r)},ne=e=>{{let t=K(()=>`readout: ${n.readout.error}`);Vf(e,{get title(){return H(t)}})}},V=e=>{var a=gm(),c=N(a);Qf(c,{get origin(){return n.readout.origin},get source(){return n.readout.source},get layer(){return n.readout.data.layer},get steering(){return n.readout.data.steering},get showToggle(){return H(T)},accent:`var(--pillar-sae)`,get steered(){return r()},set steered(e){r(e)}});var l=o(c,2),v=o(J(l),2),C=e=>{var n=tm(),r=N(n),a=J(r);{let e=K(()=>H(h)?`Loading descriptions…`:H(g)?`Retry descriptions`:H(y)?`Load published descriptions`:`Descriptions checked`);Z(a,{get text(){return H(e)}})}i(r),Y(2),W(()=>{r.disabled=H(h)||!H(y),t(r,`aria-busy`,H(h))}),G(`click`,r,S),B(e,n)},w=e=>{B(e,nm())},E=e=>{var t=rm(),n=N(t),r=J(n,!0);i(n);var a=o(n,2);W(()=>z(r,zs.error)),G(`click`,a,()=>void Bs()),B(e,t)},D=e=>{B(e,im())};_(v,e=>{H(s)?e(C):zs.loading?e(w,1):zs.error?e(E,2):e(D,-1)});var O=o(v,2),A=e=>{B(e,am())};_(O,e=>{H(h)&&e(A)});var j=o(O,2),M=e=>{var t=om(),n=J(t,!0);i(t),W(()=>z(n,H(g))),B(e,t)};_(j,e=>{H(g)&&e(M)}),i(l);var R=o(l,2),ee=e=>{Qp(e,{get readings(){return n.pinned},accent:`--pillar-sae`,shape:`triangle`})},te=K(()=>n.readout.origin===`captured`&&n.pinned&&Object.keys(n.pinned).length>0);_(R,e=>{H(te)&&e(ee)});var ne=o(R,2),V=e=>{Vf(e,{title:`no features fired at this position`})},re=e=>{var r=hm(),a=N(r),c=J(a),l=o(J(c));ge(l),i(c);var g=o(c,2);Tf(o(J(g)),{ariaLabel:`Sort by`,options:[{value:`activation`,label:`Activation`},{value:`id`,label:`Feature ID`}],get value(){return H(p)},set value(e){u(p,e,!0)}}),i(g),i(a);var v=o(a,2);{let e=K(()=>`${H(x).length} of ${n.readout.data.features.length} recorded`);tp(v,{title:`SAE activations`,get count(){return H(e)},accent:`var(--pillar-sae)`,children:(e,r)=>{var a=mm(),c=N(a);f(c,21,()=>H(x),e=>e.id,(e,r)=>{let a=K(()=>I(H(r))),c=K(()=>L(H(r))),l=K(()=>H(m)[H(r).id]),u=K(()=>H(r).label?.trim()||H(l)?.label);var d=fm();Nf(J(d),{accent:`--pillar-sae`,disabled:!1,statline:e=>{{let t=e=>{var t=sm(),n=J(t);i(t),W(e=>z(n,`#${e??``}`),[()=>H(b).get(H(r).id)]),B(e,t)},a=K(()=>`sae/${H(r).id}`),o=K(()=>`Layer ${n.readout.data?.layer??`-`}`);sp(e,{get primary(){return H(a)},get tail(){return H(o)},tailTitle:`SAE layer`,lead:t,$$slots:{lead:!0}})}},body:e=>{var n=dm(),d=N(n),f=e=>{var t=k();De(N(t),()=>H(u),e=>{var t=cm(),n=J(t,!0);i(t),W(()=>z(n,H(u))),He(1,t,()=>Hr,()=>({duration:lf(160)})),B(e,t)}),B(e,t)},p=e=>{var t=lm(),n=J(t);{let e=K(()=>H(l)?`No description published for this feature`:H(s)?H(h)?`Loading description…`:`Description could not be loaded`:zs.loading?`Loading description source…`:zs.error?`Description source could not be loaded`:`No description included in this pack`);Z(n,{get text(){return H(e)},numbers:!1})}i(t),B(e,t)};_(d,e=>{H(u)?e(f):e(p,-1)});var m=o(d,2),g=e=>{var n=um(),r=J(n);i(n),W(()=>{t(n,`href`,H(l).url),z(r,`Neuronpedia${H(l).explanationModel?` · ${H(l).explanationModel}`:` · feature record`}`)}),B(e,n)};_(m,e=>{H(l)&&e(g)});var v=o(m,2),y=J(v),b=J(y,!0);i(y);var x=o(y,2),S=J(x);{let e=K(()=>H(a)==null?H(r).activation.toFixed(2):H(a).toFixed(3)),t=K(()=>H(a)==null?`raw`:`relative`);Z(S,{get text(){return H(e)},get identity(){return H(t)}})}i(x);var C=o(x,2),w=J(C),T=e=>{{let t=K(()=>Math.max(H(a),0));Xd(e,{get value(){return H(t)},max:1,color:`var(--pillar-sae)`})}},E=e=>{{let t=K(()=>Math.max(H(r).activation,0));Xd(e,{get value(){return H(t)},get max(){return H(F)},color:`color-mix(in srgb, var(--pillar-sae) 55%, transparent)`})}};_(w,e=>{H(a)==null?e(E,-1):e(T)}),i(C),i(v);var D=o(v,2);{let e=K(()=>`Metadata for feature sae/${H(r).id}`);dp(D,{get items(){return H(c)},get ariaLabel(){return H(e)}})}W(()=>{t(v,`aria-label`,`Activation for sae/${H(r).id}`),z(b,H(a)==null?`Raw activation`:`Relative activation`)}),B(e,n)},$$slots:{statline:!0,body:!0}}),i(d),W(()=>t(d,`aria-label`,`SAE feature ${H(r).id}, layer ${n.readout.data.layer}`)),B(e,d)}),i(c);var l=o(c,2),p=e=>{var t=pm(),n=J(t),r=o(n);i(t),W(()=>z(n,`No recorded features match “${H(d)??``}”. `)),G(`click`,r,()=>{u(d,``)}),B(e,t)};_(l,e=>{H(x).length===0&&e(p)}),B(e,a)},$$slots:{default:!0}})}P(l,()=>H(d),e=>u(d,e)),B(e,r)};_(ne,e=>{n.readout.data.features.length===0?e(V):e(re,-1)}),B(e,a)},re=e=>{var t=k(),r=N(t),i=e=>{Vf(e,{title:`No SAE is available for this model`})},a=e=>{Vf(e,{title:`No SAE is available for this conversation length`})},o=e=>{Vf(e,{title:`No SAE is installed`,detail:`Add the available SAE in Model settings, then reopen the model.`})},s=e=>{Vf(e,{title:`No SAE is loaded`,detail:`Check Model settings for a compatible SAE.`})};_(r,e=>{n.availability===`unavailable`?e(i):n.availability===`context-unavailable`?e(a,1):n.availability===`available`?e(o,2):e(s,-1)}),B(e,t)},ie=e=>{Vf(e,{title:`no raw decode record`,detail:`replay needs a loom node generated with raw-decode capture in this session`})},oe=e=>{Vf(e,{title:`no readout`})};_(ee,e=>{n.readout.loading?e(te):n.readout.error?e(ne,1):n.readout.data?e(V,2):n.saeLoaded?n.hasReplayContext?e(oe,-1):e(ie,4):e(re,3)}),B(e,R),w()}ke([`click`]);var vm=e(` `);function ym(e,t){Vf(e,{title:`no J-LENS fit`,children:(e,n)=>{var r=vm(),a=J(r);i(r),W(()=>z(a,`drowse lens fit ${t.modelId??``??``}`)),B(e,r)},$$slots:{default:!0}})}var bm=e(`%`,1),xm=e(`

                                    You can inspect another token while this finishes. This result will be kept.

                                    `),Sm=e(``),Cm=e(`strength`),wm=e(` `),Tm=e(``),Em=e(` `,1),Dm=e(`
                                    `),Om=e(`
                                    `),km=e(``),Am=e(` `),jm=e(` `),Mm=e(`

                                    L \\ rank
                                    `,1),Nm=e(` `,1);function Pm(e,n){O(n,!0);let r=q(n,`steered`,15),a=K(()=>n.replayAvailable&&((n.readout.data?.steering??null)!==null||!r())),s=K(()=>Math.max(0,...n.readout.data?.layers.map(e=>e.tokens.length)??[])),c=K(()=>n.readout.data?.layers.length??0),d=K(()=>n.readout.progress!==null&&n.readout.progress.progress>0),p=K(()=>Math.round((n.readout.progress?.progress??0)*100)),m=K(()=>n.readout.progress?.phase===`readout`?`Reading the J-lens`:n.readout.progress?.phase===`queued`?`Waiting for the model`:`Preparing this token`);function h(e){return`background: color-mix(in srgb, var(--pillar-lens) ${Math.round(Math.min(1,Math.exp(e))*30)}%, var(--bg));`}function g(e,t){let n=Math.exp(t.logprob),r=n>=.001?n.toFixed(4):n.toExponential(2);return`L${e} · ${JSON.stringify(t.token)} · ${Gd(n,!0)} · p=${r} · logprob=${t.logprob.toFixed(3)}`}function y(e){let t=e.token.trim();return t.length>0?t:JSON.stringify(e.token)}function b(e){return e.trim()||JSON.stringify(e)}function x(e){return(n.readout.data?.layers??[]).map(t=>{let n=t.tokens.find(t=>t.token===e.token),r=n?Math.exp(n.logprob):null;return{layer:t.layer,value:r,title:r==null?`L${t.layer} · below top-${H(s)}`:`L${t.layer} · ${Gd(r,!0)} · p ${r.toPrecision(3)}`}})}let S=E(`Select a vocabulary cell to inspect it`),A=E(0);U(()=>{n.readout.data,u(A,0),u(S,`Select a vocabulary cell to inspect it`)});function j(e){let t=[...e.currentTarget.querySelectorAll(`.lens-cell`)];if(t.length){if(e.key===`ArrowRight`)u(A,Math.min(t.length-1,H(A)+1),!0);else if(e.key===`ArrowLeft`)u(A,Math.max(0,H(A)-1),!0);else if(e.key===`ArrowDown`)u(A,Math.min(t.length-1,H(A)+H(s)),!0);else if(e.key===`ArrowUp`)u(A,Math.max(0,H(A)-H(s)),!0);else if(e.key===`Home`)u(A,0);else if(e.key===`End`)u(A,t.length-1);else return;e.preventDefault(),u(S,t[H(A)].getAttribute(`aria-description`)??``,!0),t[H(A)].scrollIntoView({block:`nearest`,inline:`nearest`})}}function M(e){return Math.max(...e.map(e=>e.value??0),1e-12)}function P(e){let t=Math.exp(e);return t>=.001?t.toFixed(3):t.toExponential(1)}function F(e){if(e.ctrlKey||Math.abs(e.deltaY)<=Math.abs(e.deltaX))return;let t=e.currentTarget.closest(`[data-token-details-scroll]`);if(!t)return;let n=e.deltaMode===WheelEvent.DOM_DELTA_LINE?16:e.deltaMode===WheelEvent.DOM_DELTA_PAGE?t.clientHeight:1,r=t.scrollTop;t.scrollTop+=e.deltaY*n,t.scrollTop!==r&&e.preventDefault()}var I=k(),L=N(I),R=e=>{var r=xm(),a=J(r),s=J(a);Z(J(s),{get text(){return H(m)},numbers:!1}),i(s);var c=o(s,2),l=J(c),u=e=>{var t=bm();Wd(N(t),{get value(){return H(p)}}),Y(),B(e,t)},f=e=>{B(e,Se(`starting`))};_(l,e=>{H(d)?e(u):e(f,-1)}),i(c),i(a);var h=o(a,2);let g;var v=J(h);i(h);var y=o(h,2),b=J(y,!0);i(y),Y(2),i(r),W(()=>{g=D(h,1,`progress-track svelte-9hulvj`,null,g,{indeterminate:!H(d)}),t(h,`aria-valuenow`,H(d)?H(p):void 0),t(h,`aria-valuetext`,H(d)?`${H(p)}%`:`Starting`),C(v,H(d)?`width: ${H(p)}%`:void 0),z(b,n.readout.progress?.message??`Waiting for the model`)}),B(e,r)},ee=e=>{{let t=K(()=>`readout: ${n.readout.error}`);Vf(e,{get title(){return H(t)}})}},te=e=>{var d=Nm(),p=N(d);Qf(p,{get origin(){return n.readout.origin},get source(){return n.readout.source},get steering(){return n.readout.data.steering},get showToggle(){return H(a)},accent:`var(--pillar-lens)`,get steered(){return r()},set steered(e){r(e)}});var m=o(p,2),C=e=>{Qp(e,{get readings(){return n.pinned},accent:`--pillar-lens`,shape:`square`})},w=K(()=>n.readout.origin===`captured`&&n.pinned&&Object.keys(n.pinned).length>0);_(m,e=>{H(w)&&e(C)});var E=o(m,2),D=e=>{{let t=K(()=>`${n.readout.data.aggregate?.length??0} tokens`);tp(e,{title:`AGGREGATE WORKSPACE`,get count(){return H(t)},accent:`var(--pillar-lens)`,children:(e,t)=>{var r=Om();f(r,21,()=>n.readout.data.aggregate??[],v,(e,t,r)=>{let a=K(()=>x(H(t))),s=K(()=>H(a).filter(e=>e.value!=null).length);var l=Dm(),u=J(l);{let e=e=>{{let i=e=>{var t=Sm();t.textContent=`#${r+1}`,B(e,t)},a=K(()=>b(H(t).token)),o=K(()=>`@${H(t).com.toFixed(2)} ±${H(t).spread.toFixed(2)}`),s=K(()=>H(t).token===n.readout.data?.token_text?`generated`:null);sp(e,{get primary(){return H(a)},get meta(){return H(o)},metaTitle:`Where this word’s probability is concentrated across layers: 0 is the first layer, 1 is the last. The ± value shows how widely it is spread.`,get badge(){return H(s)},lead:i,$$slots:{lead:!0}})}},l=e=>{var n=Em(),r=N(n);{let e=e=>{B(e,Cm())},n=e=>{Xd(e,{percentage:!0,get value(){return H(t).strength},max:1,color:`var(--pillar-lens)`})},a=e=>{var t=wm(),n=J(t);i(t),W(()=>z(n,`${H(s)??``}/${H(c)??``} layers`)),B(e,t)},o=e=>{var n=Tm(),r=J(n);{let e=K(()=>H(t).strength.toFixed(3));Z(r,{get text(){return H(e)}})}i(n),B(e,n)},l=K(()=>`Strength ${H(t).strength.toFixed(3)}`);jf(r,{get ariaLabel(){return H(l)},left:e,bar:n,middle:a,right:o,$$slots:{left:!0,bar:!0,middle:!0,right:!0}})}var l=o(r,2);{let e=K(()=>M(H(a))),n=K(()=>`Per-layer strength for ${b(H(t).token)}`);af(l,{get cells(){return H(a)},get scale(){return H(e)},positiveColor:`var(--layer-cell-lens)`,get ariaLabel(){return H(n)}})}B(e,n)},d=K(()=>H(t).token===n.readout.data.token_text);Nf(u,{accent:`--pillar-lens`,disabled:!1,get active(){return H(d)},statline:e,body:l,$$slots:{statline:!0,body:!0}})}i(l),B(e,l)}),i(r),B(e,r)},$$slots:{default:!0}})}};_(E,e=>{(n.readout.data.aggregate??[]).length>0&&e(D)});var O=o(E,2);{let e=K(()=>`${n.readout.data.layers.length} layers × ${H(s)} ranks`);tp(O,{title:`LAYER × VOCABULARY`,get count(){return H(e)},accent:`var(--pillar-lens)`,children:(e,r)=>{var a=Mm(),c=N(a);Z(J(c),{get text(){return H(S)},numbers:!1}),i(c);var d=o(c,2);t(d,`aria-valuemin`,0);var p=J(d),m=J(p),_=J(m);f(o(J(_)),17,()=>({length:H(s)}),v,(e,t,n)=>{var r=km();r.textContent=n+1,B(e,r)}),i(_),i(m);var b=o(m);f(b,21,()=>n.readout.data.layers,e=>e.layer,(e,t)=>{var r=jm(),a=J(r),s=J(a);i(a),f(o(a),17,()=>H(t).tokens,e=>e.id,(e,r)=>{var a=Am();T(a,(e,t)=>({class:`lens-cell`,style:e,...t,[l]:{hit:H(r).id===n.readout.data.token_id}}),[()=>h(H(r).logprob),()=>({"aria-description":g(H(t).layer,H(r))})],void 0,void 0,`svelte-9hulvj`);var s=J(a),c=J(s,!0);i(s);var u=o(s,2),d=J(u);i(u),i(a),W((e,t)=>{z(c,e),z(d,`p ${t??``}`)},[()=>y(H(r)),()=>P(H(r).logprob)]),B(e,a)}),i(r),W(()=>z(s,`L${H(t).layer??``}`)),B(e,r)}),i(b),i(p),i(d),W(e=>{t(d,`aria-valuemax`,e),t(d,`aria-valuenow`,H(A)),t(d,`aria-valuetext`,H(S))},[()=>Math.max(0,n.readout.data.layers.reduce((e,t)=>e+t.tokens.length,0)-1)]),G(`keydown`,d,j),ie(`wheel`,d,F),G(`pointermove`,d,e=>{let t=e.target.closest(`.lens-cell`);t&&(u(S,t.getAttribute(`aria-description`)??``,!0),u(A,[...e.currentTarget.querySelectorAll(`.lens-cell`)].indexOf(t),!0))}),G(`pointerdown`,d,e=>{let t=e.target.closest(`.lens-cell`);t&&u(S,t.getAttribute(`aria-description`)??``,!0)}),B(e,a)},$$slots:{default:!0}})}B(e,d)},ne=e=>{ym(e,{get modelId(){return n.modelId}})},V=e=>{Vf(e,{title:`no raw decode record`,detail:`replay needs a loom node generated with raw-decode capture in this session`})},re=e=>{Vf(e,{title:`no readout`})};_(L,e=>{n.readout.loading?e(R):n.readout.error?e(ee,1):n.readout.data?e(te,2):n.jlensFitted?n.hasReplayContext?e(re,-1):e(V,4):e(ne,3)}),B(e,I),w()}ke([`keydown`,`pointermove`,`pointerdown`]);function Fm(e,t,n,r){let i=e.models.flatMap(e=>e.variants).find(e=>e.id===t);if(!i)return`unknown`;let a=i.packs.filter(e=>e.kind===r);if(a.length===0)return`unavailable`;if(n===null)return`available`;let o=i.contextProfiles.find(e=>e.contextTokens===n);return o&&a.some(e=>e.compatibleContextBindingSha256.includes(o.bindingSha256))?`available`:`context-unavailable`}async function Im(e){let t=se();if(!t)return`unknown`;let{modelVariantId:n,contextTokens:r}=t.snapshot;if(!n)return`unknown`;try{return Fm((await t.catalog({preferCached:!0,offline:typeof navigator<`u`&&navigator.onLine===!1})).document,n,r,e)}catch{return`unknown`}}var Lm=e(``),Rm=e(` `),zm=e(` `),Bm=e(`no replay`),Vm=e(`p · logp `),Hm=e(``),Um=e(` `),Wm=e(`
                                    generation recipe
                                    `,1),Gm=e(`
                                    `),Km=e(`
                                    Edit this token or replace it with a longer phrase. Spacing is preserved.
                                    `),qm=e(``),Jm=e(`
                                    Branch from this token
                                    `,1),Ym=e(`

                                    `),Xm=e(`

                                    `),Zm=e(`

                                    `),Qm=e(`
                                    `),$m=e(`
                                    `),eh=e(``);function th(e,n){O(n,!0);let r=q(n,`docked`,3,!1),s=q(n,`active`,3,!0),c=q(n,`mobile`,3,!1),l=E(null),d=K(()=>n.params);function p(){n.onclose?n.onclose():r()?st():ut()}function m(){let e=H(S)?{turnIdx:H(S).turnIdx,tokenIdx:H(S).tokenIdx,isThinking:H(S).seg===`thinking`}:H(d);r()?ct(e):ot(e)}let h=K(()=>H(d)?{turnIdx:H(d).turnIdx,seg:H(d).isThinking?`thinking`:`response`,tokenIdx:H(d).tokenIdx}:null),g=E(null),v=E(`primary`),y=[{value:`primary`,label:`steered`,title:`primary turn`},{value:`shadow`,label:`unsteered`,title:`A/B shadow turn`}];U(()=>{let e=H(h);u(g,e?{...e}:null,!0),u(v,`primary`)});let b=K(()=>kl.turns.map((e,t)=>t===(H(g)?.turnIdx??-1)&&H(v)===`shadow`&&e.abPair?e.abPair:e)),x=K(()=>bd(H(b))),S=K(()=>H(g)?wd(H(x),H(g)):null),C=-1;U(()=>{let e=H(S)?.turnIdx??-1;e!==C&&(C=e,H(v)!==`primary`&&u(v,`primary`))});let k=K(()=>H(S)!=null&&H(S).turnIdx>=0&&H(S).turnIdxH(S)?H(b)[H(S).turnIdx]??null:null),j=K(()=>H(S)?yd(H(A),H(S).seg):[]),M=K(()=>H(S)!=null&&H(S).tokenIdx>=0&&H(S).tokenIdxH(S)?H(v)===`shadow`?H(A)?.nodeId??null:H(k)?.nodeId?H(k).nodeId:H(S).turnIdx<0||Q.activePath.length===0?null:Q.activePath.map(e=>Q.nodes.get(e)).filter(Boolean).filter(e=>!(e.parent_id===null&&e.role===`system`&&!e.text))[H(S).turnIdx]?.id??null:null),I=K(()=>H(F)!=null&&H(M)?.rawIndex!=null),L=K(()=>H(v)===`primary`&&H(F)!=null&&H(M)?.rawIndex!=null&&H(M)?.tokenId!=null&&!$.active),R=K(()=>H(v)===`primary`&&H(F)!=null&&H(M)?.rawIndex!=null&&!$.active),ee=E(!1),te=E(null),ne=E(!1),V=E(``),re=E(!1),se=E(null);U(()=>{H(F),H(M)?.rawIndex,u(te,null),u(ne,!1),u(V,``)});async function ce(){if(!H(R)||!H(M))return;u(V,H(M).text,!0),u(ne,!0),u(te,null),await ye(),H(se)?.focus();let e=H(V).search(/\S/),t=H(V).trimEnd().length;H(se)?.setSelectionRange(e>=0?e:0,t>0?t:H(V).length)}async function le(){if(!(!H(R)||!H(F)||H(M)?.rawIndex==null)){if(H(V).length===0){u(te,`Enter replacement text.`),H(se)?.focus();return}u(te,null),u(re,!0);try{await zc(H(F),H(M).rawIndex,H(V)),(!r()||c())&&p(),sc.view=`map`,window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`branches`}))}catch(e){u(te,Ie(e,`Unable to replace this token and start a new branch.`),!0)}finally{u(re,!1)}}}async function ue(){if(!(!H(L)||!H(F)||H(M)?.rawIndex==null||H(M).tokenId==null)){u(te,null),u(ee,!0);try{await Rc(H(F),H(M).rawIndex,H(M).tokenId,!0),(!r()||c())&&p(),sc.view=`map`,window.dispatchEvent(new CustomEvent(`drowse:workspace`,{detail:`branches`}))}catch(e){u(te,Ie(e,`Unable to continue this branch from the selected token.`),!0)}finally{u(ee,!1)}}}let de=K(()=>H(F)?Q.nodes.get(H(F))??null:null),fe=K(()=>H(de)?.recipe?.sampling??null),pe=K(()=>H(de)?.recipe?.steering??H(A)?.appliedSteering??null);function me(e){return e==null||!Number.isFinite(e)?`-`:Number.isInteger(e)?String(e):e.toFixed(2)}let he=K(()=>{let e=H(fe),t=H(de)?.recipe;if(!e&&!t)return[];let n=[`Temperature ${me(e?.temperature)}`,`Top P ${me(e?.top_p)}`,`Top K ${me(e?.top_k)}`,`Max tokens ${me(e?.max_tokens)}`],r=t?.seed??e?.seed;return r!=null&&n.push(`Seed ${r}`),e?.presence_penalty&&n.push(`Presence penalty ${me(e.presence_penalty)}`),e?.frequency_penalty&&n.push(`Frequency penalty ${me(e.frequency_penalty)}`),e?.return_top_k!=null&&n.push(`Return top K ${e.return_top_k}`),t?.thinking!=null&&n.push(t.thinking?`Thinking on`:`Thinking off`),(t?.probes.length??0)>0&&n.push(`${t.probes.length} recipe probes`),n});function _e(e){e&&u(g,e,!0)}let ve=K(()=>H(S)!=null&&Sd(H(x),H(S),-1)!==null),be=K(()=>H(S)!=null&&Sd(H(x),H(S),1)!==null),xe=K(()=>H(S)!=null&&Cd(H(x),H(S),-1)!==null),Ce=K(()=>H(S)!=null&&Cd(H(x),H(S),1)!==null);function we(e){H(S)&&_e(Sd(H(x),H(S),e))}function Te(e){H(S)&&_e(Cd(H(x),H(S),e))}function Ee(e){H(S)&&u(g,{...H(S),tokenIdx:e===`home`?0:Math.max(0,H(j).length-1)},!0)}let Oe=K(()=>H(S)!=null&&H(h)!=null&&H(S).turnIdx===H(h).turnIdx&&H(S).seg===H(h).seg&&H(S).tokenIdx===H(h).tokenIdx);function ke(){H(h)&&u(g,{...H(h)},!0)}let Ae=K(()=>{if(!H(S))return null;let e=H(S).seg===`thinking`?`response`:`thinking`;return H(x).some(t=>t.turnIdx===H(S).turnIdx&&t.seg===e)?e:null});function je(){!H(S)||!H(Ae)||u(g,{turnIdx:H(S).turnIdx,seg:H(Ae),tokenIdx:0},!0)}function Me(e){if(e.defaultPrevented||!s()||c()&&!H(l)?.contains(e.target)||r()&&!H(l)?.contains(e.target))return;if(e.key===`Escape`){e.preventDefault(),(!r()||c())&&p();return}let t=e.target;if(!(t&&(t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`||t.isContentEditable||t.closest(`[role="slider"], [role="listbox"]`)))){switch(e.key){case`ArrowLeft`:we(-1);break;case`ArrowRight`:we(1);break;case`ArrowUp`:Te(-1);break;case`ArrowDown`:Te(1);break;case`Home`:Ee(`home`);break;case`End`:Ee(`end`);break;default:return}e.preventDefault()}}let Ne=K(()=>H(A)?H(A).roleLabel??H(A).role:``),Pe=K(()=>{let e=H(M)?.topAlts;if(!e||e.length===0||H(M)?.tokenId==null)return null;let t=e.findIndex(e=>e.id===H(M).tokenId);return t>=0?t+1:null});function Le(e){return Number.isFinite(e)?e>=.001?e.toFixed(3):e.toExponential(1):`-`}let Re=K(()=>[{value:`geometry`,label:`geometry`,meta:String(Object.keys(H(M)?.measurements?.instruments.geometry?.readings??{}).length),color:`var(--fg-dim)`,title:`activation geometry`},{value:`logits`,label:`logits`,meta:String(H(M)?.topAlts?.length??0),title:`sampling alternatives`},{value:`sae`,label:`sae`,meta:String(H(M)?.measurements?.instruments.sae?.readout?.features.length??0),color:`var(--pillar-sae)`,title:`sparse features`},{value:`lens`,label:`j-lens`,meta:String(H(M)?.measurements?.instruments.lens?.readout?.layers.length??0),color:`var(--pillar-lens)`,title:`workspace readout`}]),ze=K(()=>H(k)?.abPair!=null),Ve=K(()=>es.info?.jlens_fitted===!0),Ue=K(ns),We=E(`unknown`);ae(()=>{let e=!0;return Im(`sae`).then(t=>{e&&u(We,t,!0)}),()=>{e=!1}});let Ge=K(()=>ts(`lens`)?.capabilities.token_readout===!0),qe=K(()=>ts(`sae`)?.capabilities.token_readout===!0),Ye=K(()=>ts(`geometry`)?.capabilities.token_readout===!0),Xe=K(()=>Mi(is.return_top_k)),Ze=new Ed,Qe=new Ed,$e=new Ed,et=K(()=>{let e=kd.tab;if(!H(M)||!H(S))return`${e}:missing`;if(e===`logits`)return`${e}:ready`;let t=e===`geometry`?$e:e===`sae`?Qe:Ze;return`${e}:${t.loading?`loading`:t.error?`error`:t.data?`ready`:`empty`}`});Be(()=>{Ze.dispose(),Qe.dispose(),$e.dispose()});let X=E(!0),tt=E(!0),nt=E(!0),rt=K(()=>To.active.some(e=>To.entries.get(e)?.info.family===`geometry`)),it=K(()=>H(M)?.measurements?.instruments.lens?.readings??null),at=K(()=>H(M)?.measurements?.instruments.sae?.readings??null),lt=K(()=>{let e=H(M)?.measurements?.instruments.lens;return!e?.readout||!H(M)?null:{node_id:H(F)??``,raw_index:H(M).rawIndex??-1,token_id:H(M).tokenId??-1,token_text:H(M).text,steering:e.binding.steering,aggregate:e.readout.aggregate,layers:e.readout.layers}}),dt=K(()=>{let e=H(M)?.measurements?.instruments.sae;return!e?.readout||!H(M)?null:{node_id:H(F)??``,raw_index:H(M).rawIndex??-1,token_id:H(M).tokenId??-1,token_text:H(M).text,steering:e.binding.steering,layer:e.binding.layer??-1,features:e.readout.features}}),ft=K(()=>{let e=H(M)?.measurements?.instruments.geometry;return!e||Object.keys(e.readings??{}).length===0?null:{steering:e.binding?.steering??null,readings:e.readings}}),pt=E(null);U(()=>{!s()||!H(d)||!H(M)||!es.info||H(pt)===H(d)||(kd.tab=Ad(H(d).initialTab??Fe(()=>kd.tab),{lens:H(lt)!==null||H(I)&&H(Ve)&&H(Ge),sae:H(dt)!==null||H(I)&&H(Ue)&&H(qe),geometry:H(ft)!==null||H(I)&&H(rt)&&H(Ye)}),u(pt,H(d),!0))}),U(()=>{if(!s()||kd.tab!==`lens`)return;let e=H(lt);if(!H(Ge)&&!H(X)&&u(X,!0),(H(X)||!H(Ge))&&e){Ze.adopt(e,H(M)?.measurements?.instruments.lens?.binding.source??null);return}if(Ze.clear(),!H(Ge)||!H(Ve))return;let t=H(F),n=H(M)?.rawIndex;if(!t||n==null)return;let r=H(M)?.tokenId??-1,i=H(M)?.text??``,a=bs.sources.find(e=>e.active)?.source??null;Ze.replay(`lens`,t,n,{topK:H(Xe),steered:H(X),raw:Ll(),layers:`all`},e=>{let o=e.instruments.lens;if(!o?.readout)throw Error(`No J-lens reading was returned. Check the active lens source and try again.`);return{data:{node_id:t,raw_index:n,token_id:r,token_text:i,steering:o?.binding.steering??null,aggregate:o.readout.aggregate,layers:o.readout.layers},source:o?.binding.source??a??null}})}),U(()=>{if(!s()||kd.tab!==`sae`)return;let e=H(dt);if(!H(qe)&&!H(tt)&&u(tt,!0),(H(tt)||!H(qe))&&e){Qe.adopt(e,H(M)?.measurements?.instruments.sae?.binding.source??null);return}if(Qe.clear(),!H(qe)||!H(Ue))return;let t=H(F),n=H(M)?.rawIndex;if(!t||n==null)return;let r=H(M)?.tokenId??-1,i=H(M)?.text??``,a=zs.sources.find(e=>e.active)?.source??ts(`sae`)?.source??null;Qe.replay(`sae`,t,n,{topK:H(Xe),steered:H(tt),raw:Ll()},e=>{let o=e.instruments.sae;if(!o?.readout)throw Error(`No SAE reading was returned. Check the active feature source and try again.`);return{data:{node_id:t,raw_index:n,token_id:r,token_text:i,steering:o?.binding.steering??null,layer:o?.binding.layer??-1,features:o.readout.features},source:o?.binding.source??a??null}})}),U(()=>{if(!s()||kd.tab!==`geometry`)return;let e=H(ft);if(!H(Ye)&&!H(nt)&&u(nt,!0),(H(nt)||!H(Ye))&&e){$e.adopt(e,null);return}if($e.clear(),!H(Ye)||!H(rt))return;let t=H(F),n=H(M)?.rawIndex;!t||n==null||$e.replay(`geometry`,t,n,{steered:H(nt),raw:Ll()},e=>{let t=e.instruments.geometry;if(!t)throw Error(`No probe readings were returned. Check that the probes are attached and try again.`);return{data:{steering:t?.binding?.steering??null,readings:t?.readings??{}},source:null}})});var mt=eh();ie(`keydown`,oe,Me);let ht;var gt=J(mt),_t=J(gt),vt=J(_t),yt=e=>{var t=Lm();T(t,()=>({type:`button`,class:`dock-toggle`,"aria-pressed":r(),"aria-label":r()?`Undock token details`:`Dock token details`,"aria-description":r()?`Show token details in a window`:`Keep token details in a sidebar`,onclick:m}),void 0,void 0,void 0,`svelte-b6e72b`);var n=J(t),a=e=>{Rr(e,{})},o=e=>{Je(e,{side:`right`})};_(n,e=>{r()?e(a):e(o,-1)}),i(t),B(e,t)};_(vt,e=>{c()||e(yt)}),Kr(o(vt,4),{onclick:p}),i(_t);var bt=o(_t,2),xt=J(bt),St=e=>{var t=Wm(),n=N(t),r=J(n),a=J(r);{let e=K(()=>JSON.stringify(H(M).text)),t=K(()=>`${H(S).turnIdx}:${H(S).seg}:${H(S).tokenIdx}`);Z(a,{get text(){return H(e)},numbers:!1,get identity(){return H(t)}})}i(r);var s=o(r,2);T(s,()=>({type:`button`,class:`kv-chip seg-chip`,disabled:!H(Ae),onclick:je,"aria-description":H(Ae)?`Show the ${H(Ae)} tokens from this same turn.`:void 0}),void 0,void 0,void 0,`svelte-b6e72b`);var c=J(s),l=e=>{var t=Se();W(()=>z(t,`Completion ${H(S).turnIdx??``}`)),B(e,t)},u=e=>{var t=Se();W(()=>z(t,`turn ${H(S).turnIdx??``} · ${H(Ne)??``} · ${H(S).seg??``}`)),B(e,t)};_(c,e=>{es.info?.is_base_model?e(l):e(u,-1)}),i(s);var d=o(s,2),p=e=>{var t=Rm();T(t,()=>({class:`kv-chip`,"aria-description":`This token’s ID in the model’s vocabulary.`}),void 0,void 0,void 0,`svelte-b6e72b`);var n=J(t);i(t),W(()=>z(n,`id ${H(M).tokenId??``}`)),B(e,t)};_(d,e=>{H(M).tokenId!=null&&e(p)});var m=o(d,2),h=e=>{var t=zm();T(t,()=>({class:`kv-chip`,"aria-description":`Position in the recorded generation, used to replay or branch from this token.`}),void 0,void 0,void 0,`svelte-b6e72b`);var n=J(t);i(t),W(()=>z(n,`raw ${H(M).rawIndex??``}`)),B(e,t)},g=e=>{var t=Bm();T(t,()=>({class:`kv-chip warn`,"aria-description":`The generation record is missing, so this token cannot be replayed or branched.`}),void 0,void 0,void 0,`svelte-b6e72b`),B(e,t)};_(m,e=>{H(M).rawIndex==null?e(g,-1):e(h)});var v=o(m,2),y=e=>{var t=Vm();T(t,()=>({class:`kv-chip`,"aria-description":`Probability after temperature and Top K / Top P filtering, not the model’s unmodified probability.`}),void 0,void 0,void 0,`svelte-b6e72b`);var n=o(J(t));{let e=K(()=>Le(Math.exp(H(M).logprob))),t=K(()=>`${H(S).turnIdx}:${H(S).seg}:${H(S).tokenIdx}`);Z(n,{get text(){return H(e)},get identity(){return H(t)}})}var r=o(n,2);{let e=K(()=>H(M).logprob.toFixed(3)),t=K(()=>`${H(S).turnIdx}:${H(S).seg}:${H(S).tokenIdx}`);Z(r,{get text(){return H(e)},get identity(){return H(t)}})}var a=o(r,1,!0);i(t),W(()=>z(a,H(Pe)===null?``:` · rank ${H(Pe)}/${H(M).topAlts?.length??0}`)),B(e,t)};_(v,e=>{H(M).logprob!=null&&e(y)}),i(n);var b=o(n,2),x=J(b),C=J(x),w=()=>we(-1);T(C,()=>({type:`button`,class:`scrub-btn`,disabled:!H(ve),onclick:w,"aria-label":`Previous token`,"aria-description":`Inspect the previous token`}),void 0,void 0,void 0,`svelte-b6e72b`),Ke(J(C),{name:`back`}),i(C);var E=o(C,2),D=J(E);{let e=K(()=>`${H(S).tokenIdx+1} / ${H(j).length}`);Z(D,{get text(){return H(e)}})}i(E);var O=o(E,2),k=()=>we(1);T(O,()=>({type:`button`,class:`scrub-btn`,disabled:!H(be),onclick:k,"aria-label":`Next token`,"aria-description":`Inspect the next token`}),void 0,void 0,void 0,`svelte-b6e72b`),Ke(J(O),{name:`next`}),i(O),i(x);var A=o(x,2),P=J(A),F=()=>Te(-1);T(P,()=>({type:`button`,class:`scrub-btn`,disabled:!H(xe),onclick:F,"aria-label":`Previous turn`,"aria-description":`Inspect the previous turn`}),void 0,void 0,void 0,`svelte-b6e72b`),Ke(J(P),{name:`up`}),i(P);var I=o(P,2),L=J(I);{let e=K(()=>`turn ${H(S).turnIdx}`);Z(L,{get text(){return H(e)}})}i(I);var R=o(I,2),ee=()=>Te(1);T(R,()=>({type:`button`,class:`scrub-btn`,disabled:!H(Ce),onclick:ee,"aria-label":`Next turn`,"aria-description":`Inspect the next turn`}),void 0,void 0,void 0,`svelte-b6e72b`),Ke(J(R),{name:`down`}),i(R),i(A);var te=o(A,2),ne=e=>{var t=Hm();Ke(J(t),{name:`return`}),i(t),G(`click`,t,ke),B(e,t)};_(te,e=>{H(Oe)||e(ne)}),i(b);var V=o(b,2),re=J(V),ie=o(J(re),2);T(ie,()=>({class:`recipe-steering`,"aria-description":H(pe)??`no steering`}),void 0,void 0,void 0,`svelte-b6e72b`);var ae=J(ie,!0);i(ie),f(o(ie,2),16,()=>H(he),e=>e,(e,t)=>{var n=Um(),r=J(n,!0);i(n),W(()=>z(r,t)),B(e,n)}),i(re),i(V),W(()=>z(ae,H(pe)??`unsteered`)),B(e,t)},Ct=e=>{var t=Gm(),n=J(t),r=J(n,!0);i(n),i(t),W(()=>z(r,H(d)?`Selected token unavailable`:`No token selected`)),B(e,t)};_(xt,e=>{H(M)&&H(S)?e(St):e(Ct,-1)}),i(bt),i(gt);var wt=o(gt,2),Tt=e=>{var t=Jm(),n=N(t);Hd(n,{get tokens(){return H(j)},get index(){return H(S).tokenIdx},onjump:e=>{H(S)&&u(g,{...H(S),tokenIdx:e},!0)}});var r=o(n,2),s=J(r),c=o(J(s),2),l=J(c);i(c),i(s);var d=o(s,2),f=J(d),p=()=>{H(ne)?(u(ne,!1),u(te,null)):ce()};T(f,()=>({type:`button`,class:`secondary-action`,disabled:!H(R)||H(re),"aria-description":H(R)?void 0:$.active?`Finish or stop the current generation first`:`This saved token does not have an exact replay boundary`,onclick:p}),void 0,void 0,void 0,`svelte-b6e72b`);var m=J(f,!0);i(f);var h=o(f,2),v=()=>void ue();T(h,()=>({type:`button`,class:`primary-action`,disabled:!H(L)||H(ee),"aria-description":H(L)?void 0:$.active?`Finish or stop the current generation first`:`This saved token does not have an exact replay boundary`,onclick:v}),void 0,void 0,void 0,`svelte-b6e72b`);var y=J(h);{let e=K(()=>H(ee)?`Starting…`:`Continue from here`);Z(y,{get text(){return H(e)},numbers:!1})}i(h),i(d);var b=o(d,2),x=e=>{var t=Km(),n=o(J(t),2),r=J(n);ge(r),a(r,e=>u(se,e),()=>H(se));var s=o(r,2),c=J(s);{let e=K(()=>H(re)?`Starting…`:`Start branch`);Z(c,{get text(){return H(e)},numbers:!1})}i(s),i(n),Y(2),i(t),W(()=>s.disabled=!H(R)||H(re)||H(V).length===0),ie(`submit`,t,e=>{e.preventDefault(),le()}),P(r,()=>H(V),e=>u(V,e)),B(e,t)};_(b,e=>{H(ne)&&e(x)});var C=o(b,2),w=e=>{var t=qm(),n=J(t,!0);i(t),W(()=>z(n,H(te))),B(e,t)};_(C,e=>{H(te)&&e(w)}),i(r),W(()=>{z(l,`Keep the text up to here and write a new ending. Your original ${es.info?.is_base_model?`completion`:`response`} stays saved.`),z(m,H(ne)?`Cancel replacement`:`Replace token…`)}),B(e,t)};_(wt,e=>{H(M)&&H(S)&&e(Tt)});var Et=o(wt,2),Dt=J(Et);vd(Dt,{get items(){return H(Re)},ariaLabel:`Token detail view`,get value(){return kd.tab},set value(e){kd.tab=e}});var Ot=o(Dt,2),kt=e=>{vd(e,{get items(){return y},ariaLabel:`Token branch`,get value(){return H(v)},set value(e){u(v,e,!0)}})};_(Ot,e=>{H(ze)&&e(kt)}),i(Et);var At=o(Et,2);De(J(At),()=>H(et),e=>{var t=$m(),n=J(t),r=e=>{var t=Ym();t.textContent=`Geometry token replay is unavailable in this runtime. Geometry captured during generation can still be inspected.`,B(e,t)},a=e=>{var t=Xm();t.textContent=`J-lens token replay is unavailable in this runtime. J-lens data captured during generation can still be inspected.`,B(e,t)},s=e=>{var t=Zm();t.textContent=`SAE token replay is unavailable in this runtime. Sparse-feature data captured during generation can still be inspected.`,B(e,t)};_(n,e=>{H(M)&&H(S)&&kd.tab===`geometry`&&!H(Ye)&&(H(rt)||H(ft))?e(r):H(M)&&H(S)&&kd.tab===`lens`&&!H(Ge)&&(H(Ve)||H(lt))?e(a,1):H(M)&&H(S)&&kd.tab===`sae`&&!H(qe)&&(H(Ue)||H(dt))&&e(s,2)});var c=o(n,2),l=e=>{var t=Qm(),n=J(t,!0);i(t),W(()=>z(n,H(d)?`This token is no longer available. Select another token to inspect it.`:`Select a token in your conversation or Loom to see its full details here.`)),B(e,t)},f=e=>{{let t=K(()=>({turnIdx:H(S).turnIdx,tokenIdx:H(S).tokenIdx,isThinking:H(S).seg===`thinking`}));Tp(e,{get readout(){return $e},get returnToToken(){return H(t)},get hasGeometryProbes(){return H(rt)},get hasReplayContext(){return H(I)},get replayAvailable(){return H(Ye)},get steered(){return H(nt)},set steered(e){u(nt,e,!0)}})}},p=e=>{Fp(e,{get token(){return H(M)},get nodeId(){return H(F)}})},m=e=>{_m(e,{get readout(){return Qe},get saeLoaded(){return H(Ue)},get availability(){return H(We)},get hasReplayContext(){return H(I)},get pinned(){return H(at)},get replayAvailable(){return H(qe)},get steered(){return H(tt)},set steered(e){u(tt,e,!0)}})},h=e=>{{let t=K(()=>es.info?.model_id??null);Pm(e,{get readout(){return Ze},get jlensFitted(){return H(Ve)},get hasReplayContext(){return H(I)},get pinned(){return H(it)},get modelId(){return H(t)},get replayAvailable(){return H(Ge)},get steered(){return H(X)},set steered(e){u(X,e,!0)}})}};_(c,e=>{!H(M)||!H(S)?e(l):kd.tab===`geometry`?e(f,1):kd.tab===`logits`?e(p,2):kd.tab===`sae`?e(m,3):e(h,-1)}),i(t),He(1,t,()=>vf),B(e,t)}),i(At),i(mt),a(mt,e=>u(l,e),()=>H(l)),W(()=>{t(mt,`data-morph-snapshot`,H(S)?`${H(S).turnIdx}:${H(S).seg}:${H(S).tokenIdx}`:`none`),ht=D(mt,1,`drawer svelte-b6e72b`,null,ht,{docked:r()||c(),mobile:c()})}),B(e,mt),w()}ke([`click`]);var nh=`(max-width: 760px), (pointer: coarse) and (max-width: 1024px) and (max-height: 600px)`,rh=[`full`,`half`,`peek`];function ih(e,t=0){let n=Math.max(12,t),r=Math.max(n,e-Math.min(220,e*.42));return{full:n,half:Math.max(n,Math.min(e*.45,r-48)),peek:r}}function ah(e,t){return rh.reduce((n,r)=>Math.abs(t[r]-e)55*Math.log1p(e/55);return et.peek?t.peek+n(e-t.peek):e}function sh(e,t,n){for(e.push({y:t,time:n});e.length>1&&e[0].time8&&e.shift();let r=e[0];return(t-r.y)/Math.max(16,n-r.time)*1e3}function ch(e,t,n,r,i,a){let o=rh.indexOf(e),s=Math.min(80,Math.max(50,a*.08));if(e===`peek`&&n>20&&t+Math.max(0,r)*.2>i.peek+s)return`dismiss`;let c=Math.sign(Math.abs(r)>150?r:n);if(Math.abs(n)>20&&Math.abs(r)>600)return c>0?`peek`:`full`;if(Math.abs(n)>20&&(Math.abs(r)>150||Math.abs(n)>80))return rh[Math.max(0,Math.min(2,o+c))];let l=rh.indexOf(ah(t,i));return rh[Math.max(o-1,Math.min(o+1,l))]}function lh(e,t,n,r){let i=e-t;return t+(i+(n+30*i)*r)*Math.exp(-30*r)}function uh(e,t,n,r){return(n-30*(n+30*(e-t))*r)*Math.exp(-30*r)}function dh(e,t,n){for(let r=e;r&&t.contains(r);r=r.parentElement){let e=getComputedStyle(r);if(/(auto|scroll)/.test(e.overflowY)&&r.scrollHeight>r.clientHeight+1&&(n>0&&r.scrollTop>1||n<0&&r.scrollTop+r.clientHeight