Guard against NaN/div-by-zero in damage calculations
Add runtime guards and tests to prevent NaN or infinite values when damage pools or weights are zero or non-finite. Changes include:
- Add tests: defense-nan-guards.spec.ts and changeDamageTypeValue.test.ts to cover edge cases where incomingDamage or saved damage triples are zero or NaN.
- Strengthen applyItemBuildDamageShift to skip shifting when transferable pool or total is non-positive/NaN (use !(x > 0) checks) and normalize to thirds when needed.
- Make enemyChampionProfile robust: use a 1/3 default base when raw totals are non-positive/NaN, fall back to equal share for damageReceived when sum is non-positive, and avoid dividing by zero by using a weightDivisor fallback for averaged stats.
- Update game slice changeDamageTypeValue reducer to avoid 0/0 by checking denom > 0 and defaulting to 0.5 when both other slots are zero.
- Add extra unit tests for item-build damage shifting behavior and edge cases.
- Change IncomingDamageCell input min from 0 to 1 to prevent zero incoming damage being set via the UI.
These changes prevent runtime NaNs/infinities and ensure normalization remains stable in edge-case inputs.
- Enhance enemy damage type representation and clarify tooltips.
- Improved comments in getItemOffensiveProfile.ts to reflect the heuristic nature of damage type calculations.
- Adjusted EnemyTable and TeamDamageComposition components to provide clearer descriptions of damage types and their estimation methods.
Update build card, item limits, and build keys
Remove syncId from the BuildCard chart to prevent unintended chart synchronization. Add ItemLimit.fatality to arenaPerplexity limits. In AlternativeBuilds, stop slicing the builds list and generate a stable unique key using the index plus joined item ids to avoid React key collisions and allow all sorted builds to render.
Refactor imports, dynamic tabs, add benchmarks
- Replace lodash namespace imports with path-specific imports (e.g. lodash/range, lodash/isEqual) to enable better bundling and tree-shaking.
- Split champion static props into its own module and simplify pages/itemop/[championName].tsx to re-export getStaticPaths/getStaticProps; reduces bundle size for the page.
- Add dynamic tab chunking (src/features/itemop/settings-routes.tsx) with prefetchTabChunk and useTransition integration in menu and champion components to warm and load tab chunks without blocking UI.
- Replace the old static settings-routes with a dynamic version that lazy-loads tab components and provides a lightweight loading skeleton.
- Add scripts/benchmark-pages.ts to measure static export page sizes (HTML + referenced JS/CSS) and a package.json script to run it; bump pnpm version and adjust start scripts for webpack/turbopack usage.
- Add public/_headers for long-lived caching of versioned static assets for static hosts (Cloudflare Pages / Netlify-style).
- Preload key fonts in pages/_document.tsx and update font stylesheets to use font-display: swap and reorganize face declarations for better loading behavior.
- Improve robustness: handle KeyboardJS dynamic import failures, guard chunk preloads, and minor accessibility/structure updates in various UI components (RecentSummoners, AlternativeBuilds, CompareBar, Export Settings tree uses deepdash/standalone and lodash helpers).
Other smaller changes: various UI tweaks, selector typings (RootState), small bugfixes and optimizations across components and scrapers.
Update configuration files and improve tooltip formatting
- Updated `biome.json` and `knip.json` to exclude `src/data/jsonAutoUpdated` from linter and file includes.
- Refactored tooltip formatting in various components to handle non-numeric values gracefully, ensuring proper display of percentages in charts.
- Enhanced `ItemImage` and `ClickableItem` components to support an optional `displayItemId` for better item representation.
- Introduced a new `SkillOrderScaled` component to improve the layout of skill orders in the UI, ensuring better responsiveness and usability.
- Added local champion and skin tracking in the plugin state for improved integration with live game data.
Use itemQuantities map and add footwear flag
Remove per-item mutable `quantity` field from item definitions and instead track counts in a new `itemQuantities` map on ItemProfile. Add a `magicalFootwearApplied` flag and include both fields in checkpoint save/restore and reset logic. Update purchase flow to increment `itemQuantities[itemId]` and pass that count to uniques handling. Clean up obsolete quantity initialization and related mutations to avoid altering shared item data.
