feat: NTE gear optimizer web app

Client-side optimizer for Neverness to Everness console builds. Imports a
gear export from nte-history-exporter, keeps it in IndexedDB, and solves for
the best module placement per character or across a team.

- domain/: pure ports of the Python research scripts (shapes, cartridges,
  board tiling, stats, scoring, set bonuses, Arc effects, sheet prediction).
  No DOM, no storage imports, so they stay worker-safe and Node-testable.
- solver/: single-character solve with branch and bound, plus a three-phase
  team solve (portfolio, leximin, column generation) over disjoint item sets.
  Runs in a Worker when one can be constructed, inline otherwise.
- db/: three storage tiers selected by use rather than feature detection,
  fail-closed import validation, and undo that restores both sides of a steal.
- ui/: React 19 views for items, characters and teams; the board is drawn as
  the deliverable rather than a score.
- Two build targets: a hosted bundle and a single self-contained nte.html
  with no external requests.

Values the model cannot measure are reported as unavailable rather than
guessed: cartridge set bonuses, the level 80 base-stat multiplier, and the
distinction between "optimal for this packing" and globally optimal.

145 tests, tsc clean, both build targets clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
goober 2026-08-21 11:38:17 +03:00
commit 91952b1745
157 changed files with 92600 additions and 0 deletions

13
data-src/guides.json Normal file
View file

@ -0,0 +1,13 @@
{
"format": "nte-guides",
"format_version": 1,
"_source": "Prydwen build guides, entered by hand and reviewed before committing.",
"_why_not_scraped": "Prydwen's character pages are client-rendered, so a plain fetch returns only navigation chrome, and their Gatsby /page-data/ endpoint answers 410 Gone. Their robots.txt does allow content pages with a 10 second crawl-delay, so a headless render would be permitted - it is just not something the build can do unattended. Entries below are typed in from the published guide.",
"_shape": {
"key": "the GA_<key>_* ability key, so it joins to a capture directly",
"variants": "one per published priority set (Main DPS, SubDPS, Break, DoT)",
"targets": "recommended endgame stats, raw stat ids, percentages as fractions",
"priority": "substat ranking, best first; weights are derived from position"
},
"characters": []
}