alpha-visualizer 1.2.1__tar.gz → 1.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alpha_visualizer-1.2.1/.hypothesis/constants/6114e271dda4d8b8 → alpha_visualizer-1.2.2/.hypothesis/constants/5e5c346a22eb22e1 +1 -1
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/CHANGELOG.md +30 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/PKG-INFO +1 -1
- alpha_visualizer-1.2.2/frontend/src/components/browser/__tests__/StrategySlidePanel.test.tsx +84 -0
- alpha_visualizer-1.2.2/frontend/src/hooks/__tests__/useSparklineCache.test.tsx +93 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useSparklineCache.ts +11 -11
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/pyproject.toml +2 -2
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/__init__.py +1 -1
- alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/BrowsePage-CRD1NFN6.js +2 -0
- alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/BrowsePage-CRD1NFN6.js.map +1 -0
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/ChartDataTable-BJ5w8ojJ.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/ChartDataTable-CpbeS-vH.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/ChartDataTable-BJ5w8ojJ.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/ChartDataTable-CpbeS-vH.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/ComparePage-BQWVgWH4.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/ComparePage-CLFz7URF.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/ComparePage-BQWVgWH4.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/ComparePage-CLFz7URF.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/DetailPage-CXVkMosD.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/DetailPage-CQtYJc2N.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/DetailPage-CXVkMosD.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/DetailPage-CQtYJc2N.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/IdeasPage-DOm3fHuz.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/IdeasPage-r2nUwzs8.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/IdeasPage-DOm3fHuz.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/IdeasPage-r2nUwzs8.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/LivePage-BKXWD5s_.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/LivePage-DxqC9viK.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/LivePage-BKXWD5s_.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/LivePage-DxqC9viK.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/LiveTab-BI1uTwbD.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/LiveTab-Bo0cnOzh.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/LiveTab-BI1uTwbD.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/LiveTab-Bo0cnOzh.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/MaintenancePage-B2nz-JsD.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/MaintenancePage-DPuIkcax.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/MaintenancePage-B2nz-JsD.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/MaintenancePage-DPuIkcax.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/ReturnDistributionChart-dFTJCaO7.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/ReturnDistributionChart-DhMITrWS.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/ReturnDistributionChart-dFTJCaO7.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/ReturnDistributionChart-DhMITrWS.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/RunLogDetails-DxKjhiQM.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/RunLogDetails-DWwJcvMo.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/RunLogDetails-DxKjhiQM.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/RunLogDetails-DWwJcvMo.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/SettingsToggles-CH2UYPvW.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/SettingsToggles-DfZwmoRM.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/SettingsToggles-CH2UYPvW.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/SettingsToggles-DfZwmoRM.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/errorMessage-DKeqg0eT.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/errorMessage-sAm1T6PK.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/errorMessage-DKeqg0eT.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/errorMessage-sAm1T6PK.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/index-BLCdAVgG.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/index-C4Iqvc3f.js +3 -3
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/index-BLCdAVgG.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/index-C4Iqvc3f.js.map +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/useBacktestData-XnSfmng5.js → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/useBacktestData-ewTBXVEg.js +2 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/useBacktestData-XnSfmng5.js.map → alpha_visualizer-1.2.2/src/alpha_visualizer/static/assets/useBacktestData-ewTBXVEg.js.map +1 -1
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/index.html +1 -1
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/uv.lock +1 -1
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/BrowsePage-y_9xKk4F.js +0 -2
- alpha_visualizer-1.2.1/src/alpha_visualizer/static/assets/BrowsePage-y_9xKk4F.js.map +0 -1
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.agents/skills/source-command-audit-licenses/SKILL.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.agents/skills/source-command-pre-release/SKILL.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.claude/commands/audit-licenses.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.claude/commands/pre-release.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.codex/hooks.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/ISSUE_TEMPLATE/bug_report_ja.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/ISSUE_TEMPLATE/feature_request_ja.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/codeql/README.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/codeql/codeql-config.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/dependabot.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/workflows/ci.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/workflows/codeql.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/workflows/lighthouse.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.github/workflows/release.yml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.gitignore +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/.gitignore +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/004709bbf59880d3 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/060c20f3c4ff96cb +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/0bf3463e8f4751b8 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/10d56fd11d90e91d +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/1632901e1b51683b +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/1e3ce406f3635331 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/1fedef6b4cc376fe +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/296b8092179c9f55 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/312a7aaf12a1fd47 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/316886ef98081ce9 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/331e194303817b32 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/43f703bafb1e4b04 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/4577b97f57a8a832 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/4726660442f99a00 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/4a1c4d1532cab28e +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/4b255f25d1067b71 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/4c29ef3d0bedcdd8 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/4e26bccf25a8c1bb +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/508b282112ab038e +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/5c80be020ed7a646 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/5c9eb073058f11a0 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/757b1f8305546439 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/7f90c9d611001617 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/812d29a19e56a27b +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/8add761403393fca +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/8bd584eda4b3b534 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/8f23e54ec81ce772 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/96ca93165140d446 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/a27ca3dcb982038c +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/a636a4647020033d +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/a7474b0c3a5a5850 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/ab4df659c6b192db +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/af039261f357a5c1 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/afe5949501fc5b8f +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/b0487cda9820c053 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/b5541576e1e9aea7 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/b9ff5bcd3a53e3a7 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/bc34da97bbdf0eb3 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/c5349cb90ddc7968 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/cd7fdfbe3f66457b +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/d34317036474de6e +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/da39a3ee5e6b4b0d +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/e44a457d795e56c2 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/e4be0e30e6ada148 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/ea2d606acbfff989 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/eed5e66c16ae84b8 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/f2f91c7f9b44111d +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/f7c4a04c97c0daf8 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/fa443af6269a6e02 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/fc009534004030e1 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/fe325b4404aa1121 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/.hypothesis/constants/ff4517cbfe51fea1 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/AGENTS.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/CLAUDE.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/CODE_OF_CONDUCT.en.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/CODE_OF_CONDUCT.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/CONTRIBUTING.en.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/CONTRIBUTING.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/LICENSE +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/NOTICE +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/README.en.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/README.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/SECURITY.en.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/SECURITY.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/THIRDPARTY_LICENSES.txt +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/cliff.toml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/adr/0001-pages-vs-screens.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/adr/0002-charts-visx-vs-components.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/adr/0003-openapi-typescript-codegen.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/adr/0004-condition-node-discriminated-union.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/lighthouse-ci.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/backtest-tv.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/browse.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/compare-heatmap.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/compare.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/detail.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/ideas.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/live.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/optimize.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/strategy-signal-tv.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/en/strategy.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/backtest-tv.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/browse.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/compare-heatmap.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/compare.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/detail.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/ideas.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/live.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/optimize.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/strategy-signal-tv.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/screenshots/ja/strategy.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/plans/2026-07-25-live-equity-rich.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/plans/2026-07-26-browse-recipe-rollup.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/plans/2026-07-27-browse-symbol-coverage.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/plans/2026-07-27-maintenance-orphan-runs.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/specs/2026-07-25-live-equity-rich-design.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/specs/2026-07-26-browse-recipe-rollup-design.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/specs/2026-07-27-browse-symbol-coverage-design.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/docs/superpowers/specs/2026-07-27-maintenance-orphan-runs-design.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/.gitignore +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/.npmrc +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/.size-limit.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/.storybook/main.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/.storybook/preview.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/CLAUDE.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/README.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/THIRDPARTY_FONTS.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/README.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/historical/SPY_1d.parquet +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/ideas/ideas.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/results/backtest_results.db +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/dual_symbol_qqq.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/dual_symbol_spy.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/ema_trend_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/ema_trend_v2.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/ema_trend_v3.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/idle_recipe_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/idle_recipe_v2.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/momo_breakout.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/no_symbol_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/rsi_reversal.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/data/strategies/sma_cross.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/fixtures/forge/forge.yaml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/helpers/locators.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/samples/sample-fixture.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/screenshots/capture.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/screenshots/equity-tv.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/screenshots/strategy-signal-tv.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/specs/browse.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/specs/compare.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/specs/detail.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/specs/i18n.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/specs/maintenance.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/specs/share.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/visual/README.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/visual/__snapshots__/linux/equity-drawdown-tv.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/visual/__snapshots__/linux/strategy-signal-tv.png +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/e2e/visual/tv-charts.spec.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/eslint.config.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/index.html +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/openapi.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/package.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/playwright.config.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/playwright.samples.config.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/playwright.screenshots.config.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/playwright.visual.config.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/pnpm-lock.yaml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/pnpm-workspace.yaml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/public/favicon.svg +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/public/icons.svg +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/api/__tests__/client.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/api/client.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/api/types.gen.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/api/types.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/CompareEquityTV.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/CompareEquityTV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/EquityDrawdownPaneTV.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/EquityDrawdownPaneTV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/RollingMetricsChartTV.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/RollingMetricsChartTV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/StrategySignalChartTV.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/StrategySignalChartTV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/WFOEquityTV.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/WFOEquityTV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/CompareEquityTV.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/EquityDrawdownPaneTV.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/RollingMetricsChartTV.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/StrategySignalChartTV.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/WFOEquityTV.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/data.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/regimeBands.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/theme.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/__tests__/trades.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/data.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/regimeBands.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/theme.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/tv/trades.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/AnnualReturnsBarV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/CorrelationHeatmapV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/MAEMFEScatterV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/MonthlyHeatmapV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/OptimizeHeatmapV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/OptimizeScatterV.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/Sparkline.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/charts/visx/Sparkline.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/AppFooter.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/AppNav.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/CommandPalette.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/ConfirmActionButton.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/DetailToolbar.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/MetricsSummaryBarV2.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/MetricsSummaryBarV2.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/RootLayout.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/RunLogDetails.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/SettingsToggles.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/ShareCardButton.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/StrategyHero.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/AppFooter.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/AppNav.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/CommandPalette.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/CorrelationHeatmap.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/MetricsSummaryBarV2.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/RootLayout.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/SettingsToggles.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/ShareCardButton.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/ShareCardXButton.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/__tests__/responsive-styles.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/CollapsibleSection.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/CompareFloatingBar.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/FilterBar.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/GroupByToggle.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/Heroline.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/RecipeRow.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/RunHistoryTab.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/SavedViews.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/StrategyRow.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/StrategySlidePanel.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/StrategyTable.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/StrategyTableFooter.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/SymbolCoverageTable.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/CollapsibleSection.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/FilterBar.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/RecipeRow.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/RunHistoryTab.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/StrategyRow.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/StrategyTable.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/StrategyTableFooter.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/browser/__tests__/SymbolCoverageTable.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/AnnualReturnsBar.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/CorrelationHeatmap.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/DrawdownDetailChart.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/MAEMFEScatter.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/MonteCarloChart.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/OptimizeHeatmap.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/OptimizeScatter.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/ReturnDistributionChart.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/VaRChart.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/WFOTimeline.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/charts/WeekdayPerformanceChart.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/jobs/JobRunnerCard.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/LiveKpiRow.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/LivePositionView.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/LivePositionsTable.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/LiveTab.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/SummaryCard.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/__tests__/LiveKpiRow.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/__tests__/LivePositionView.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/__tests__/LivePositionsTable.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/__tests__/LiveTab.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/__tests__/format.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/live/format.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/CarryAdjustedCard.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/CompareTable.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/ISOOSMetrics.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/MetricsGrid.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/RegimeBreakdownCards.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/SignalQualityBadge.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/__tests__/SignalQualityBadge.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/__tests__/evaluateGood.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/metrics/evaluate.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/trades/TradeTable.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/trades/__tests__/TradeTable.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/tuning/DuplicateStrategyCard.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/tuning/TuningPanel.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/tuning/__tests__/DuplicateStrategyCard.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/components/tuning/__tests__/TuningPanel.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/constants/metricDefinitions.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/constants/runSource.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/contexts/DashboardContext.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/contexts/dashboardConstants.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/__tests__/definedTokens.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/__tests__/noHardcodedColors.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/__tests__/tokens.contrast.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/a11y.css +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Button.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Card.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/ChartDataTable.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Chip.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/ConfirmDialog.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Divider.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/ErrorBanner.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/KeyValue.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Loading.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/OverflowMenu.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Pill.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Pill.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/SectionHeader.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/SortHeaderCell.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Stat.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Stat.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/TabBar.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/Toolbar.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/ChartDataTable.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/ConfirmDialog.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/ErrorBanner.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/Loading.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/OverflowMenu.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/Pill.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/SortHeaderCell.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/__tests__/TabBar.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/index.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/primitives/srOnly.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/tokens.css +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/design/useChartTheme.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useDocumentTitle.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useEquityViewport.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useFetchByKey.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useJobRunner.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useLiveAvailability.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useOrphanRuns.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useRunBacktest.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useScrollRestoration.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useStrategyHistorical.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useStrategyList.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useSyncedTimeRange.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useTheme.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useViewerSettings.lang.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/__tests__/useViewerSettings.shared.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useBacktestData.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useDebounce.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useDocumentTitle.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useEquityViewport.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useFetchByKey.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useIdeasList.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useJobRunner.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useLiveAvailability.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useLiveList.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useOrphanRuns.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useRecentStrategies.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useScrollRestoration.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useStrategyHistorical.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useStrategyList.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useSyncedTimeRange.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/hooks/useTheme.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/i18n/__tests__/strings.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/i18n/strings.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/bestSharpe.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/correlation.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/distribution.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/drawdown.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/errorMessage.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/format.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/liveEquity.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/metricLabel.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/monteCarlo.properties.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/monteCarlo.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/optimizeHeatmap.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/recipes.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/rolling.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/searchParams.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/searchStrategies.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/shareCard.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/shareCardMulti.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/shareTweet.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/symbolStats.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/walkForward.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/__tests__/weekday.test.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/assetClass.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/bestSharpe.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/correlation.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/csv.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/distribution.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/drawdown.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/errorMessage.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/exportPng.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/format.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/liveEquity.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/metricLabel.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/monteCarlo.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/optimizeHeatmap.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/recipes.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/rolling.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/searchParams.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/searchStrategies.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/shareCard.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/shareTweet.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/symbolStats.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/walkForward.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/lib/weekday.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/main.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/mock/btData.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/BrowsePage.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/ComparePage.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/DetailPage.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/IdeasPage.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/LivePage.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/MaintenancePage.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/__tests__/ComparePage.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/pages/__tests__/MaintenancePage.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/router.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/BacktestScreen.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/BacktestScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/BrowseScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/CompareScreen.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/CompareScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/ISOOSScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/IdeasScreen.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/IdeasScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/LiveScreen.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/LiveScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/MaintenanceScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/OptimizeScreen.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/OptimizeScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/StrategyScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/WFOScreen.stories.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/WFOScreen.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/__tests__/BacktestScreen.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/__tests__/CompareScreen.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/__tests__/LiveScreen.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/__tests__/MaintenanceScreen.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/__tests__/OptimizeScreen.test.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/screens/strategy/SignalChartCard.tsx +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/src/test-setup.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/tsconfig.app.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/tsconfig.e2e.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/tsconfig.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/tsconfig.node.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/frontend/vite.config.ts +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/lighthouserc.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/release.sh +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/README.en.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/README.md +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/compatibility_matrix.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/ideas_defs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/pseudo_backtest.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/pseudo_grid.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/pseudo_wfo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/strategy_defs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/synthetic_ohlcv.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/_generators/writers.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/build_samples.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/ideas/ideas.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/results/backtest_results.db +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/bbands_breakout_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/donchian_turtle_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/ema_adx_macd_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/macd_crossover_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/range_reversion_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/rsi_reversion_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/sma_crossover_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/data/strategies/supertrend_adx_v1.json +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/samples/sample-forge/forge.yaml +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/scripts/compare_sqlite_dump.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/scripts/generate_openapi.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/scripts/generate_thirdparty_js.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/scripts/verify_build_artifacts.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/app.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/cli.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/db.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/dependencies.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/errors.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/forge_config.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/log_sanitize.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/repositories/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/repositories/backtest_results.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/repositories/ideas.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/repositories/live.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/repositories/optimization.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/repositories/strategies.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/historical.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/ideas.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/jobs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/live.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/maintenance.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/optimize.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/results.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/run.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/strategies.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/routers/wfo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/historical.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/ideas.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/live.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/maintenance.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/optimize.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/results.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/strategies.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/schemas/wfo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/backtest.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/forge_cli.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/historical.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/jobs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/live.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/tuning.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/services/walk_forward.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/fonts-DJsrEZjK.css +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/format-jy8n8zRe.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/format-jy8n8zRe.js.map +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/index-BedmvoEG.css +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/inter-tight-latin-400-normal-BLrFJfvD.woff +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/inter-tight-latin-400-normal-iW8qmuJY.woff2 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/inter-tight-latin-500-normal-BFXNXuvF.woff2 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/inter-tight-latin-500-normal-pobXraBK.woff +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/inter-tight-latin-600-normal-BgSTtRxb.woff2 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/inter-tight-latin-600-normal-D7bG6gX1.woff +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/react-CuMkScR3.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/react-CuMkScR3.js.map +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/react-router-CcOee6vW.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/react-router-CcOee6vW.js.map +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/rolldown-runtime-C0phanGV.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/source-serif-4-latin-600-normal-DMD1h6_f.woff +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/source-serif-4-latin-600-normal-DouSKlru.woff2 +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/tv-CrUgTguZ.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/tv-CrUgTguZ.js.map +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/useDocumentTitle-DPighAM_.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/useDocumentTitle-DPighAM_.js.map +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/visx-HscrFEDZ.js +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/assets/visx-HscrFEDZ.js.map +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/favicon.svg +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/src/alpha_visualizer/static/icons.svg +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/conftest.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/factories.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/fixtures/build_e2e_fixture.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/repositories/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/repositories/test_backtest_results_repo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/repositories/test_ideas_reader.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/repositories/test_live_repo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/repositories/test_optimization_repo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/repositories/test_strategies_repo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_db_mode_write_paths.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_forge_yaml_integration.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_historical.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_ideas.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_jobs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_live.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_maintenance.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_optimize.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_results.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_run.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_strategies.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_strategies_source.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_strategy_duplicate.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_strategy_save.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/routers/test_wfo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_pseudo_backtest.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_pseudo_grid.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_pseudo_wfo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_sample_forge.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_strategy_defs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_synthetic_ohlcv.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/samples/test_writers.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/schemas/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/schemas/test_schemas.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/__init__.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_backtest.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_backtest_properties.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_historical.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_jobs.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_live.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_tuning.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/services/test_wfo.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_app.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_cli.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_compare_sqlite_dump.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_db.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_dependencies.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_errors.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_forge_config.py +0 -0
- {alpha_visualizer-1.2.1 → alpha_visualizer-1.2.2}/tests/test_log_sanitize.py +0 -0
|
@@ -5,6 +5,36 @@ alpha-visualizer の全バージョン変更履歴です。
|
|
|
5
5
|
> **License Change Notice (v0.6.0+):** v0.6.0 以降、ライセンスは MIT から Apache-2.0 に変更されました。v0.5.0 以前のリリースは引き続き MIT ライセンスです。詳細は [LICENSE](LICENSE) を参照してください。
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
## [1.2.1] - 2026-07-28
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### その他
|
|
12
|
+
|
|
13
|
+
- バージョン 1.2.1 にバンプ
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### ドキュメント
|
|
18
|
+
|
|
19
|
+
- CHANGELOG を v1.2.0 に更新
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### バグ修正
|
|
24
|
+
|
|
25
|
+
- audit-licenses の dev 除外を名前の表記ゆれに耐えるようにする (#340)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
- **deps**: Dependabot のセキュリティアラート 2 件とバージョン更新 3 件を解消 (#341)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
- **browse**: 最終実行の日付が折り返して行高が 55px に膨らむ問題を修正 (#344)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
- **design**: 未定義のまま参照されていた CSS 変数 3 種を定義し、再発をテストで防ぐ (#345)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
8
38
|
## [1.2.0] - 2026-07-27
|
|
9
39
|
|
|
10
40
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpha-visualizer
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Web visualization tool for AlphaForge backtest results
|
|
5
5
|
Project-URL: Homepage, https://github.com/alforge-labs/alpha-visualizer
|
|
6
6
|
Project-URL: Repository, https://github.com/alforge-labs/alpha-visualizer
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { render, screen, waitFor } from '@testing-library/react'
|
|
2
|
+
import { MemoryRouter } from 'react-router'
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
4
|
+
import type { BacktestDetail, StrategyListItem, StrategyRun } from '../../../api/types'
|
|
5
|
+
import { StrategySlidePanel } from '../StrategySlidePanel'
|
|
6
|
+
|
|
7
|
+
vi.mock('../../../api/client', async (importOriginal) => {
|
|
8
|
+
const mod = await importOriginal<typeof import('../../../api/client')>()
|
|
9
|
+
return {
|
|
10
|
+
...mod,
|
|
11
|
+
api: {
|
|
12
|
+
...mod.api,
|
|
13
|
+
getStrategyRuns: vi.fn(),
|
|
14
|
+
getBacktest: vi.fn(),
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
import { api } from '../../../api/client'
|
|
20
|
+
|
|
21
|
+
const RUN = {
|
|
22
|
+
run_id: 'run-1',
|
|
23
|
+
run_at: '2026-07-01T00:00:00',
|
|
24
|
+
sharpe_ratio: 1.23,
|
|
25
|
+
total_return_pct: 10,
|
|
26
|
+
max_drawdown_pct: -5,
|
|
27
|
+
source: null,
|
|
28
|
+
} as unknown as StrategyRun
|
|
29
|
+
|
|
30
|
+
const DETAIL = { equity: { values: [1, 2, 3] } } as unknown as BacktestDetail
|
|
31
|
+
|
|
32
|
+
const ITEM: StrategyListItem = {
|
|
33
|
+
strategy_id: 'spy_test_v1',
|
|
34
|
+
name: 'SPY Test',
|
|
35
|
+
symbol: 'SPY',
|
|
36
|
+
timeframe: '1d',
|
|
37
|
+
tags: [],
|
|
38
|
+
target_symbols: [],
|
|
39
|
+
latest_sharpe: null,
|
|
40
|
+
latest_return_pct: null,
|
|
41
|
+
latest_max_drawdown_pct: null,
|
|
42
|
+
latest_profit_factor: null,
|
|
43
|
+
latest_win_rate_pct: null,
|
|
44
|
+
latest_total_trades: null,
|
|
45
|
+
last_run_at: null,
|
|
46
|
+
latest_source: null,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
vi.mocked(api.getStrategyRuns).mockReset().mockResolvedValue([RUN])
|
|
51
|
+
vi.mocked(api.getBacktest).mockReset().mockResolvedValue(DETAIL)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('StrategySlidePanel', () => {
|
|
55
|
+
it('実行履歴と sparkline を表示する', async () => {
|
|
56
|
+
render(
|
|
57
|
+
<MemoryRouter>
|
|
58
|
+
<StrategySlidePanel strategy={ITEM} onClose={() => {}} lang="ja" />
|
|
59
|
+
</MemoryRouter>,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
await waitFor(() => expect(screen.getByText('Sharpe 1.23')).toBeInTheDocument())
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 回帰テスト: パネルを開いている間、sparkline の prefetch が毎レンダー再発火して
|
|
67
|
+
* `/api/strategies/{id}` と `/api/results/{run_id}` を無限に叩き続ける不具合があった。
|
|
68
|
+
* 開いたままの状態で呼び出し回数が増え続けないことを保証する。
|
|
69
|
+
*/
|
|
70
|
+
it('開いたままでも API 呼び出しがループしない', async () => {
|
|
71
|
+
render(
|
|
72
|
+
<MemoryRouter>
|
|
73
|
+
<StrategySlidePanel strategy={ITEM} onClose={() => {}} lang="ja" />
|
|
74
|
+
</MemoryRouter>,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
await waitFor(() => expect(screen.getByText('Sharpe 1.23')).toBeInTheDocument())
|
|
78
|
+
await new Promise((resolve) => setTimeout(resolve, 300))
|
|
79
|
+
|
|
80
|
+
// 実行履歴(useStrategyRuns)で 1 回、sparkline の prefetch で 1 回の計 2 回が上限
|
|
81
|
+
expect(api.getStrategyRuns).toHaveBeenCalledTimes(2)
|
|
82
|
+
expect(api.getBacktest).toHaveBeenCalledTimes(1)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { act, renderHook, waitFor } from '@testing-library/react'
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
+
|
|
4
|
+
vi.mock('../../api/client', () => ({
|
|
5
|
+
api: { getStrategyRuns: vi.fn(), getBacktest: vi.fn() },
|
|
6
|
+
}))
|
|
7
|
+
|
|
8
|
+
import { api } from '../../api/client'
|
|
9
|
+
import type { BacktestDetail, StrategyRun } from '../../api/types'
|
|
10
|
+
import { useSparklineCache } from '../useSparklineCache'
|
|
11
|
+
|
|
12
|
+
const RUN = {
|
|
13
|
+
run_id: 'run-1',
|
|
14
|
+
run_at: '2026-07-01T00:00:00',
|
|
15
|
+
sharpe_ratio: 1.2,
|
|
16
|
+
total_return_pct: 10,
|
|
17
|
+
max_drawdown_pct: -5,
|
|
18
|
+
source: null,
|
|
19
|
+
} as unknown as StrategyRun
|
|
20
|
+
|
|
21
|
+
const DETAIL = { equity: { values: [1, 2, 3] } } as unknown as BacktestDetail
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.mocked(api.getStrategyRuns).mockReset().mockResolvedValue([RUN])
|
|
25
|
+
vi.mocked(api.getBacktest).mockReset().mockResolvedValue(DETAIL)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 呼び出し側(StrategySlidePanel / StrategyTable)は prefetch を useEffect から呼び、
|
|
30
|
+
* 戻り値そのものを依存配列に入れている。そのため本フックには 2 つの契約がある:
|
|
31
|
+
*
|
|
32
|
+
* 1. 戻り値の identity がレンダーごとに変わらないこと
|
|
33
|
+
* (変わると effect が毎レンダー発火し、fetch → setState → 再レンダー の無限ループになる)
|
|
34
|
+
* 2. 重複ガードが React の更新キュー状態に依存しないこと
|
|
35
|
+
* (setEntries の updater は保留中の更新があると即時実行されないため、
|
|
36
|
+
* state を見るガードは同一戦略でも何度も fetch を通してしまう)
|
|
37
|
+
*
|
|
38
|
+
* どちらか一方でも崩れると uvicorn ログが同一 API 呼び出しで埋まる(実測 1.5 秒で約 7,700 回)。
|
|
39
|
+
*/
|
|
40
|
+
describe('useSparklineCache', () => {
|
|
41
|
+
it('同じ戦略を連続 prefetch しても API 呼び出しは 1 回だけ', async () => {
|
|
42
|
+
const { result } = renderHook(() => useSparklineCache())
|
|
43
|
+
|
|
44
|
+
// 1 回目の setEntries が flush される前に 2 回目を呼ぶ(effect 由来の連続呼び出し相当)
|
|
45
|
+
act(() => {
|
|
46
|
+
result.current.prefetch('strat_a')
|
|
47
|
+
result.current.prefetch('strat_a')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
await waitFor(() => expect(result.current.entries['strat_a']).toEqual([1, 2, 3]))
|
|
51
|
+
expect(api.getStrategyRuns).toHaveBeenCalledTimes(1)
|
|
52
|
+
expect(api.getBacktest).toHaveBeenCalledTimes(1)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('state が変わらない再レンダーでは戻り値の identity を保つ', () => {
|
|
56
|
+
const { result, rerender } = renderHook(() => useSparklineCache())
|
|
57
|
+
const first = result.current
|
|
58
|
+
|
|
59
|
+
rerender()
|
|
60
|
+
|
|
61
|
+
expect(result.current).toBe(first)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('取得済みの戦略を再度 prefetch しても再フェッチしない', async () => {
|
|
65
|
+
const { result } = renderHook(() => useSparklineCache())
|
|
66
|
+
|
|
67
|
+
act(() => {
|
|
68
|
+
result.current.prefetch('strat_a')
|
|
69
|
+
})
|
|
70
|
+
await waitFor(() => expect(result.current.entries['strat_a']).toEqual([1, 2, 3]))
|
|
71
|
+
|
|
72
|
+
act(() => {
|
|
73
|
+
result.current.prefetch('strat_a')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
expect(api.getStrategyRuns).toHaveBeenCalledTimes(1)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('戦略ごとに個別に取得する', async () => {
|
|
80
|
+
const { result } = renderHook(() => useSparklineCache())
|
|
81
|
+
|
|
82
|
+
act(() => {
|
|
83
|
+
result.current.prefetch('strat_a')
|
|
84
|
+
result.current.prefetch('strat_b')
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
await waitFor(() => expect(api.getStrategyRuns).toHaveBeenCalledTimes(2))
|
|
88
|
+
expect(vi.mocked(api.getStrategyRuns).mock.calls.map((c) => c[0])).toEqual([
|
|
89
|
+
'strat_a',
|
|
90
|
+
'strat_b',
|
|
91
|
+
])
|
|
92
|
+
})
|
|
93
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useState } from 'react'
|
|
1
|
+
import { useCallback, useMemo, useRef, useState } from 'react'
|
|
2
2
|
import { api } from '../api/client'
|
|
3
3
|
|
|
4
4
|
type SparklineEntry = number[] | 'loading' | 'empty'
|
|
@@ -16,17 +16,15 @@ export interface SparklineCache {
|
|
|
16
16
|
*/
|
|
17
17
|
export function useSparklineCache(): SparklineCache {
|
|
18
18
|
const [entries, setEntries] = useState<Record<string, SparklineEntry>>({})
|
|
19
|
+
// 取得を開始した strategyId。setEntries の updater は保留中の更新があると
|
|
20
|
+
// 即時実行されないため、重複ガードを state 経由で行うと同じ戦略を何度も fetch する。
|
|
21
|
+
// 呼び出し側は prefetch を useEffect から呼ぶため、それがそのまま API の無限ループになる。
|
|
22
|
+
const requested = useRef<Set<string>>(new Set())
|
|
19
23
|
|
|
20
24
|
const prefetch = useCallback((strategyId: string) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
alreadyKnown = true
|
|
25
|
-
return prev
|
|
26
|
-
}
|
|
27
|
-
return { ...prev, [strategyId]: 'loading' }
|
|
28
|
-
})
|
|
29
|
-
if (alreadyKnown) return
|
|
25
|
+
if (requested.current.has(strategyId)) return
|
|
26
|
+
requested.current.add(strategyId)
|
|
27
|
+
setEntries(prev => ({ ...prev, [strategyId]: 'loading' }))
|
|
30
28
|
|
|
31
29
|
void (async () => {
|
|
32
30
|
try {
|
|
@@ -48,5 +46,7 @@ export function useSparklineCache(): SparklineCache {
|
|
|
48
46
|
})()
|
|
49
47
|
}, [])
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
// 呼び出し側は戻り値を useEffect の依存配列に入れるため、identity を安定させる
|
|
50
|
+
// (毎レンダー新しいオブジェクトを返すと effect が再発火し続ける)。
|
|
51
|
+
return useMemo(() => ({ entries, prefetch }), [entries, prefetch])
|
|
52
52
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "alpha-visualizer"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.2"
|
|
4
4
|
description = "Web visualization tool for AlphaForge backtest results"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -86,7 +86,7 @@ dev = [
|
|
|
86
86
|
]
|
|
87
87
|
|
|
88
88
|
[tool.bumpversion]
|
|
89
|
-
current_version = "1.2.
|
|
89
|
+
current_version = "1.2.2"
|
|
90
90
|
commit = true
|
|
91
91
|
message = "chore: バージョン {new_version} にバンプ"
|
|
92
92
|
tag = true
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-C0phanGV.js";import{C as t,d as n,h as r,v as i,y as a}from"./visx-HscrFEDZ.js";import{t as o}from"./react-CuMkScR3.js";import{a as s,l as c,n as l,u}from"./react-router-CcOee6vW.js";import{a as d,b as f,c as p,d as m,l as h,n as g,o as _,r as v,t as y,u as b,v as x,x as S}from"./index-C4Iqvc3f.js";import{r as C,t as w}from"./RunLogDetails-DWwJcvMo.js";import{i as T,o as E,t as D}from"./format-jy8n8zRe.js";import{i as ee,o as te}from"./useBacktestData-ewTBXVEg.js";import{t as ne}from"./SettingsToggles-DfZwmoRM.js";import{t as re}from"./useDocumentTitle-DPighAM_.js";var O=e(t(),1),k=o();function A({label:e,defaultOpen:t=!1,children:n,testId:r}){let[i,a]=(0,O.useState)(t),o=(0,O.useId)();return(0,k.jsxs)(`div`,{"data-testid":r,children:[(0,k.jsxs)(`button`,{type:`button`,"aria-expanded":i,"aria-controls":i?o:void 0,onClick:()=>a(e=>!e),style:{display:`flex`,alignItems:`center`,gap:`var(--space-2)`,width:`100%`,padding:`var(--space-3) var(--layout-gutter)`,background:`var(--bg)`,border:`none`,borderBottom:`1px solid var(--border)`,color:`var(--text2)`,fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:600,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`,cursor:`pointer`,textAlign:`left`},children:[(0,k.jsx)(`span`,{"aria-hidden":!0,style:{display:`inline-block`,width:14,fontFamily:`var(--mono)`,transform:i?`rotate(0deg)`:`rotate(-90deg)`,transition:`transform var(--motion-fast)`},children:`▾`}),e]}),i&&(0,k.jsx)(`div`,{id:o,children:n})]})}var j={width:64,padding:`6px 8px`,background:`var(--surface-2)`,border:`1px solid var(--border)`,borderRadius:`var(--radius-sm)`,color:`var(--text)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,letterSpacing:`var(--tracking-mono)`},ie={width:240,padding:`8px 12px`,background:`var(--surface-2)`,border:`1px solid var(--border)`,borderRadius:`var(--radius-md)`,color:`var(--text)`,fontFamily:`var(--sans)`,fontSize:`var(--fs-body)`},M={fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`};function N({active:e,onClick:t,children:n}){return(0,k.jsx)(`button`,{type:`button`,"aria-pressed":e,onClick:t,style:{padding:`4px 12px`,background:e?`var(--accent-bg)`:`transparent`,border:`1px solid ${e?`var(--accent-glow)`:`var(--border)`}`,borderRadius:`var(--radius-pill)`,color:e?`var(--accent)`:`var(--text2)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,fontWeight:600,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`,cursor:`pointer`,transition:`background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast)`},children:n})}function ae({symbols:e,timeframes:t,lang:n}){let r=f(n),[i,a]=s(),o=(e,t)=>{a(n=>{let r=new URLSearchParams(n);return t?r.set(e,t):r.delete(e),r},{replace:!0})},c=(e,t)=>{a(n=>{let r=new URLSearchParams(n),i=r.get(e)?.split(`,`).filter(Boolean)??[],a=i.includes(t)?i.filter(e=>e!==t):[...i,t];return a.length?r.set(e,a.join(`,`)):r.delete(e),r},{replace:!0})},l=()=>{a(new URLSearchParams,{replace:!0})},u=i.get(`q`)??``,d=i.get(`symbol`)?.split(`,`).filter(Boolean)??[],p=i.get(`tf`)?.split(`,`).filter(Boolean)??[],m=i.get(`sharpe_min`)??``,h=i.get(`dd_max`)??``,g=i.get(`include_unrun`)===`1`,v=u||d.length>0||p.length>0||m||h||g;return(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(_,{children:[(0,k.jsx)(`input`,{style:ie,"aria-label":r(`戦略名・銘柄を検索`,`Search strategy or symbol`),placeholder:r(`戦略名・銘柄を検索…`,`Search strategy or symbol…`),value:u,onChange:e=>o(`q`,e.target.value)}),t.length>0&&(0,k.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`var(--space-2)`},children:[(0,k.jsx)(`span`,{style:M,children:r(`時間軸`,`TF`)}),(0,k.jsx)(`div`,{style:{display:`flex`,gap:6,flexWrap:`wrap`},children:t.map(e=>(0,k.jsx)(N,{active:p.includes(e),onClick:()=>c(`tf`,e),children:e},e))})]}),(0,k.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[(0,k.jsx)(`span`,{style:M,children:`Sharpe ≥`}),(0,k.jsx)(`input`,{style:j,type:`number`,step:`0.1`,min:`0`,"aria-label":r(`Sharpe 下限`,`Sharpe ≥`),value:m,placeholder:`1.0`,onChange:e=>o(`sharpe_min`,e.target.value)})]}),(0,k.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:6},children:[(0,k.jsx)(`span`,{style:M,children:r(`DD ≤ %`,`DD ≤ %`)}),(0,k.jsx)(`input`,{style:j,type:`number`,step:`1`,min:`0`,max:`100`,"aria-label":r(`DD 上限 (%)`,`DD ≤ %`),value:h,placeholder:`30`,onChange:e=>o(`dd_max`,e.target.value)})]}),(0,k.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:6,fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,color:`var(--text2)`,cursor:`pointer`},children:[(0,k.jsx)(`input`,{type:`checkbox`,checked:g,onChange:e=>o(`include_unrun`,e.target.checked?`1`:``),style:{accentColor:`var(--accent)`,cursor:`pointer`}}),r(`未実行を含める`,`Include unrun`)]}),v&&(0,k.jsx)(`button`,{type:`button`,onClick:l,style:{marginLeft:`auto`,background:`transparent`,border:`none`,color:`var(--accent)`,fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:600,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`,cursor:`pointer`,padding:`4px 8px`},children:r(`フィルタを解除`,`Clear filters`)})]}),e.length>0&&(0,k.jsx)(A,{label:r(`銘柄で絞る(${e.length})`,`Filter by symbol (${e.length})`),defaultOpen:d.length>0,testId:`symbol-filter-collapsible`,children:(0,k.jsx)(`div`,{style:{display:`flex`,gap:6,flexWrap:`wrap`,padding:`var(--space-2) 0`},children:e.map(e=>(0,k.jsx)(N,{active:d.includes(e),onClick:()=>c(`symbol`,e),children:e},e))})})]})}function P(e,t,n){let r=new URLSearchParams(e);return n==null||n===``?r.delete(t):r.set(t,n),r}function F(e){return e.symbol||e.target_symbols[0]||null}function I(e){return e.last_run_at!=null&&e.last_run_at!==``}function L(e){return e.last_run_at??``}function oe(e){let t=null;for(let n of e){if(n.latest_sharpe==null)continue;if(t==null){t=n;continue}let e=t.latest_sharpe;(n.latest_sharpe>e||n.latest_sharpe===e&&L(n)>L(t))&&(t=n)}if(t!=null)return t;let n=null;for(let t of e)I(t)&&(n==null||L(t)>L(n))&&(n=t);return n}function se(e,t,n){return`${e}\u0000${t??``}\u0000${n??``}`}function ce(e,t){let n=e.latest_sharpe,r=t.latest_sharpe;return n==null&&r==null?L(t).localeCompare(L(e)):n==null?1:r==null?-1:n===r?L(t).localeCompare(L(e)):r-n}function R(e){let t=new Map;for(let n of e){let e=F(n),r=n.timeframe??null,i=se(n.name,e,r),a=t.get(i);a?a.items.push(n):t.set(i,{name:n.name,symbol:e,timeframe:r,items:[n]})}let n=[];for(let[e,r]of t){let t=[...r.items].sort(ce);n.push({key:e,name:r.name,symbol:r.symbol,timeframe:r.timeframe,variants:t,best:oe(t),variantCount:t.length,runCount:t.filter(I).length})}return n}var le=[`name`,`latest_sharpe`,`latest_return_pct`,`latest_max_drawdown_pct`,`latest_profit_factor`,`latest_win_rate_pct`,`last_run_at`],ue=[`none`,`symbol`,`tf`,`tier`];function de(e){return e===`1`}function fe(e){return le.includes(e??``)?e:`latest_sharpe`}function pe(e){return e===`asc`||e===`desc`?e:`desc`}function me(e){return ue.includes(e??``)?e:`none`}function he(e){return e&&e.length>0?e:null}function z(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean).slice(0,6):[]}function B(e){return e??-1/0}var ge={strong:0,moderate:1,weak:2,no_data:3},_e={strong:`Strong (Sharpe ≥ 1.5)`,moderate:`Moderate (1.0 ≤ Sharpe < 1.5)`,weak:`Weak (Sharpe < 1.0)`,no_data:`No data`};function ve(e){return e==null?`no_data`:e>=1.5?`strong`:e>=1?`moderate`:`weak`}function V(e){let t=null,n=null;for(let r of e){let e=r.best?.latest_sharpe;e!=null&&(t=t==null?e:Math.max(t,e));let i=r.best?.latest_max_drawdown_pct;i!=null&&(n=n==null?i:Math.min(n,i))}return{count:e.length,bestSharpe:t,worstDrawdownPct:n}}function ye(e,t){if(t===`none`)return e.length===0?[]:[{key:`all`,label:`all`,rank:0,items:e,aggregate:V(e)}];if(t===`tier`){let t={strong:[],moderate:[],weak:[],no_data:[]};for(let n of e)t[ve(n.best?.latest_sharpe)].push(n);let n=[];for(let e of Object.keys(t)){let r=t[e];r.length!==0&&n.push({key:`tier:${e}`,label:_e[e],rank:ge[e],items:r,aggregate:V(r)})}return n.sort((e,t)=>e.rank-t.rank)}let n=e=>t===`symbol`?e.symbol??``:e.timeframe??``,r=new Map;for(let t of e){let e=n(t),i=r.get(e);i?i.push(t):r.set(e,[t])}let i=[];for(let[e,n]of r.entries()){let r=!e;i.push({key:`${t}:${e||`_unassigned`}`,label:r?`Unassigned`:e,rank:r?1/0:0,items:n,aggregate:V(n)})}return i.sort((e,t)=>e.rank===t.rank?e.aggregate.count===t.aggregate.count?e.label.localeCompare(t.label):t.aggregate.count-e.aggregate.count:e.rank-t.rank)}function be(){let[e,t]=(0,O.useState)([]),[n,r]=(0,O.useState)(!0),[i,a]=(0,O.useState)(null);return(0,O.useEffect)(()=>{let e=!1;return x.listStrategies().then(n=>{e||(t(n),r(!1))}).catch(t=>{e||(a(t instanceof Error?t.message:String(t)),r(!1))}),()=>{e=!0}},[]),{all:e,loading:n,error:i,symbols:(0,O.useMemo)(()=>[...new Set(e.map(F).filter(e=>!!e))].sort(),[e]),timeframes:(0,O.useMemo)(()=>[...new Set(e.map(e=>e.timeframe).filter(Boolean))].sort(),[e])}}function xe(e,t,n,r,i,a){return(0,O.useMemo)(()=>{let o=t.toLowerCase();return e.filter(e=>{let s=F(e)??``;return!(t&&!e.name.toLowerCase().includes(o)&&!s.toLowerCase().includes(o)||n.length>0&&!n.includes(s)||r.length>0&&!r.includes(e.timeframe??``)||!isNaN(i)&&B(e.latest_sharpe)<i||!isNaN(a)&&Math.abs(B(e.latest_max_drawdown_pct))>a)})},[e,t,n,r,i,a])}function Se(e,t,n){return(0,O.useMemo)(()=>[...e].sort((e,r)=>{let i,a;return t===`name`?(i=e.name,a=r.name):t===`last_run_at`?(i=e.best?.last_run_at??``,a=r.best?.last_run_at??``):(i=B(e.best?.[t]),a=B(r.best?.[t])),i<a?n===`asc`?-1:1:i>a?n===`asc`?1:-1:0}),[e,t,n])}function Ce(e,t){return(0,O.useMemo)(()=>ye(e,t),[e,t])}function we(e,t){return{selectedId:he(e.get(`selected`)),setSelectedId:e=>{t(t=>P(t,`selected`,e),{replace:!0})}}}function Te(e,t){let n=(0,O.useMemo)(()=>z(e.get(`compare`)),[e]),r=e=>e.length===0?null:e.join(`,`);return{compareIds:n,toggleCompareId:e=>{e&&t(t=>{let n=z(t.get(`compare`)),i;return i=n.includes(e)?n.filter(t=>t!==e):n.length<6?[...n,e]:n,P(t,`compare`,r(i))},{replace:!0})},removeCompareId:e=>{t(t=>P(t,`compare`,r(z(t.get(`compare`)).filter(t=>t!==e))),{replace:!0})},clearCompareIds:()=>{t(e=>P(e,`compare`,null),{replace:!0})}}}function Ee(){let[e,t]=s(),{all:n,loading:r,error:i,symbols:a,timeframes:o}=be(),c=fe(e.get(`sort`)),l=pe(e.get(`dir`)),u=me(e.get(`group`)),d=de(e.get(`include_unrun`)),f=xe(n,e.get(`q`)??``,(0,O.useMemo)(()=>(e.get(`symbol`)??``).split(`,`).filter(Boolean),[e]),(0,O.useMemo)(()=>(e.get(`tf`)??``).split(`,`).filter(Boolean),[e]),parseFloat(e.get(`sharpe_min`)??``),parseFloat(e.get(`dd_max`)??``)),p=(0,O.useMemo)(()=>R(f),[f]),m=(0,O.useMemo)(()=>p.filter(e=>e.runCount===0).length,[p]),h=Se((0,O.useMemo)(()=>d?p:p.filter(e=>e.runCount>0),[p,d]),c,l),g=Ce(h,u),_=(0,O.useMemo)(()=>R(n),[n]),v=e=>{t(t=>{let n=new URLSearchParams(t);return n.get(`sort`)===e?n.set(`dir`,n.get(`dir`)===`asc`?`desc`:`asc`):(n.set(`sort`,e),n.set(`dir`,`desc`)),n},{replace:!0})},y=e=>{t(t=>P(t,`group`,e===`none`?null:e),{replace:!0})},{selectedId:b,setSelectedId:x}=we(e,t),S=Te(e,t);return{all:n,allRecipes:_,recipes:h,recipeTotal:_.length,hiddenUnrunRecipeCount:d?0:m,includeUnrun:d,groups:g,loading:r,error:i,sortKey:c,sortDir:l,setSort:v,groupBy:u,setGroupBy:y,symbols:a,timeframes:o,selectedId:b,setSelectedId:x,...S}}function H(){let[e,t]=(0,O.useState)({}),n=(0,O.useRef)(new Set),r=(0,O.useCallback)(e=>{n.current.has(e)||(n.current.add(e),t(t=>({...t,[e]:`loading`})),(async()=>{try{let n=(await x.getStrategyRuns(e))[0];if(!n){t(t=>({...t,[e]:`empty`}));return}let r=(await x.getBacktest(n.run_id)).equity?.values??[];t(t=>({...t,[e]:r.length>0?r:`empty`}))}catch{t(t=>({...t,[e]:`empty`}))}})())},[]);return(0,O.useMemo)(()=>({entries:e,prefetch:r}),[e,r])}i();function U({values:e,width:t,height:i,color:o,strokeWidth:s=1.25}){let c=(0,O.useMemo)(()=>e.map((e,t)=>({x:t,y:e})),[e]),l=(0,O.useMemo)(()=>n({domain:[0,Math.max(1,c.length-1)],range:[1,t-1]}),[c.length,t]),u=(0,O.useMemo)(()=>{if(c.length===0)return n({domain:[0,1],range:[i-1,1]});let e=c.map(e=>e.y),t=Math.min(...e),r=Math.max(...e),a=(r-t||1)*.04;return n({domain:[t-a,r+a],range:[i-1,1]})},[c,i]),d=(0,O.useMemo)(()=>{if(o)return o;if(e.length<2)return`var(--text3)`;let t=e[0];return e[e.length-1]>=t?`var(--success)`:`var(--danger)`},[o,e]);return c.length<2?null:(0,k.jsx)(`svg`,{width:t,height:i,"aria-hidden":!0,style:{display:`block`},children:(0,k.jsx)(r,{data:c,x:e=>l(e.x),y:e=>u(e.y),stroke:d,strokeWidth:s,strokeLinecap:`round`,curve:a,fill:`none`})})}function W(e){return e==null?`var(--text3)`:e>=1.5?`var(--success)`:e>=1?`var(--warn)`:`var(--danger)`}var G={fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-md)`,padding:`8px 12px`,textAlign:`right`,borderBottom:`1px solid var(--border)`,letterSpacing:`var(--tracking-mono)`},K={...G,color:`var(--text3)`,fontSize:`var(--fs-mono-sm)`,whiteSpace:`nowrap`};function De({s:e,selected:t,inCompare:n,maxCompareReached:r,onSelect:i,onToggleCompare:a,onHover:o,sparkValues:s,lang:c,indent:u=!1}){let d=f(c),[p,m]=(0,O.useState)(!1),h=F(e),g=()=>{m(!0),o(e.strategy_id)},_=()=>{m(!1),o(null)},v=t?`var(--accent-bg)`:p?`var(--surface-2)`:`transparent`,y=Array.isArray(s)&&s.length>=2?(0,k.jsx)(U,{values:s,width:120,height:20}):s===`loading`?(0,k.jsx)(`div`,{style:{width:120,height:20,display:`flex`,alignItems:`center`,justifyContent:`flex-end`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`},children:`···`}):null;return(0,k.jsxs)(`tr`,{onMouseEnter:g,onMouseLeave:_,onClick:()=>i(e.strategy_id),title:d(`クリックでプレビュー`,`Click to preview`),style:{background:v,borderLeft:t?`2px solid var(--accent)`:`2px solid transparent`,transition:`background var(--motion-fast)`,cursor:`pointer`},children:[(0,k.jsx)(`td`,{style:{...G,textAlign:`center`,padding:`6px 4px`,width:36},onClick:e=>e.stopPropagation(),children:(0,k.jsx)(`input`,{type:`checkbox`,checked:n,disabled:r,"aria-label":d(`${e.name}(${e.strategy_id})を比較に追加`,`Add ${e.name} (${e.strategy_id}) to compare`),onChange:()=>a(e.strategy_id),style:{cursor:r?`not-allowed`:`pointer`,accentColor:`var(--accent)`}})}),(0,k.jsx)(`td`,{style:{...G,textAlign:`left`,paddingLeft:u?40:12},children:(0,k.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,minWidth:0},children:[(0,k.jsx)(l,{to:`/detail/${e.strategy_id}`,title:e.name,onClick:e=>e.stopPropagation(),style:{flex:`0 1 auto`,minWidth:0,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`,fontFamily:`var(--serif)`,fontSize:`1.0625rem`,fontWeight:600,color:`var(--text)`,letterSpacing:`-0.005em`,lineHeight:1.2,textDecoration:`none`,transition:`color var(--motion-fast)`},onMouseEnter:e=>{e.currentTarget.style.color=`var(--accent)`},onMouseLeave:e=>{e.currentTarget.style.color=`var(--text)`},children:e.name}),(0,k.jsx)(`span`,{title:e.strategy_id,style:{flexShrink:0,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`},children:e.strategy_id}),h?(0,k.jsx)(b,{children:h}):(0,k.jsx)(`span`,{style:{fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`},children:d(`未割当`,`unassigned`)}),e.timeframe?(0,k.jsx)(b,{children:e.timeframe}):null]})}),(0,k.jsxs)(`td`,{style:{...G,color:W(e.latest_sharpe),fontWeight:700,fontSize:`1rem`},children:[T(e.latest_sharpe,{decimals:2}),e.latest_source===`strategy-file`&&(0,k.jsx)(`span`,{"data-testid":`latest-source-badge`,role:`img`,"aria-label":d(`最新ランはチューニング試行(保存していないパラメータ)です`,`Latest run is a tuning trial with unsaved parameters`),title:d(`最新ランはチューニング試行(保存していないパラメータ)です`,`Latest run is a tuning trial with unsaved parameters`),style:{marginLeft:4,color:`var(--warn)`,fontSize:10},children:`⚠`})]}),(0,k.jsx)(`td`,{style:{...G,color:e.latest_return_pct==null?`var(--text3)`:e.latest_return_pct>=0?`var(--success)`:`var(--danger)`},children:T(e.latest_return_pct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{style:{...G,color:e.latest_max_drawdown_pct==null?`var(--text3)`:`var(--danger)`},children:T(e.latest_max_drawdown_pct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text2)`},children:T(e.latest_profit_factor,{decimals:2})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text2)`},children:T(e.latest_win_rate_pct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:K,children:D(e.last_run_at)}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,padding:`6px 12px`,width:132,textAlign:`right`},children:(0,k.jsx)(`div`,{style:{display:`inline-flex`,justifyContent:`flex-end`,minHeight:20},children:y})})]})}function Oe({recipe:e,expanded:t,onToggleExpand:n,selectedId:r,onSelect:i,compareIds:a,onToggleCompare:o,onHover:s,sparkValues:c,lang:u}){let d=f(u),[p,m]=(0,O.useState)(!1),h=e.best,g=h??e.variants[0],_=e.variantCount>1,v=h!=null&&r===h.strategy_id,y=h!=null&&a.includes(h.strategy_id),x=a.length>=6&&!y,S=()=>{m(!0),h&&s(h.strategy_id)},C=()=>{m(!1),s(null)},w=Array.isArray(c)&&c.length>=2?(0,k.jsx)(U,{values:c,width:120,height:20}):c===`loading`?(0,k.jsx)(`div`,{style:{width:120,height:20,display:`flex`,alignItems:`center`,justifyContent:`flex-end`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`},children:`···`}):null;return(0,k.jsxs)(`tr`,{onMouseEnter:S,onMouseLeave:C,onClick:()=>{h&&i(h.strategy_id)},title:d(`クリックでプレビュー`,`Click to preview`),style:{background:v?`var(--accent-bg)`:p?`var(--surface-2)`:`transparent`,borderLeft:v?`2px solid var(--accent)`:`2px solid transparent`,transition:`background var(--motion-fast)`,cursor:h?`pointer`:`default`},children:[(0,k.jsx)(`td`,{style:{...G,textAlign:`center`,padding:`6px 4px`,width:36},onClick:e=>e.stopPropagation(),children:(0,k.jsx)(`input`,{type:`checkbox`,checked:y,disabled:h==null||x,"aria-label":d(`${e.name} の最良試行を比較に追加`,`Add the best trial of ${e.name} to compare`),onChange:()=>{h&&o(h.strategy_id)},style:{cursor:h==null||x?`not-allowed`:`pointer`,accentColor:`var(--accent)`}})}),(0,k.jsx)(`td`,{style:{...G,textAlign:`left`},children:(0,k.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,minWidth:0},children:[_?(0,k.jsx)(`button`,{type:`button`,"aria-expanded":t,"aria-label":t?d(`${e.name} の試行を畳む`,`Collapse trials of ${e.name}`):d(`${e.name} の試行を展開`,`Expand trials of ${e.name}`),onClick:t=>{t.stopPropagation(),n(e.key)},style:{flexShrink:0,width:20,background:`transparent`,border:`none`,color:`var(--text2)`,fontFamily:`var(--mono)`,cursor:`pointer`,padding:0,transform:t?`rotate(0deg)`:`rotate(-90deg)`,transition:`transform var(--motion-fast)`},children:`▾`}):(0,k.jsx)(`span`,{"aria-hidden":!0,style:{flexShrink:0,width:20}}),(0,k.jsx)(l,{to:`/detail/${g.strategy_id}`,title:e.name,onClick:e=>e.stopPropagation(),style:{flex:`0 1 auto`,minWidth:0,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`,fontFamily:`var(--serif)`,fontSize:`1.0625rem`,fontWeight:600,color:`var(--text)`,letterSpacing:`-0.005em`,lineHeight:1.2,textDecoration:`none`,transition:`color var(--motion-fast)`},onMouseEnter:e=>{e.currentTarget.style.color=`var(--accent)`},onMouseLeave:e=>{e.currentTarget.style.color=`var(--text)`},children:e.name}),e.symbol?(0,k.jsx)(b,{children:e.symbol}):(0,k.jsx)(`span`,{style:{fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`},children:d(`未割当`,`unassigned`)}),e.timeframe?(0,k.jsx)(b,{children:e.timeframe}):null,_&&(0,k.jsx)(`span`,{style:{flexShrink:0,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`},children:d(`${e.variantCount} 試行中 ${e.runCount} 件実行`,`${e.runCount} of ${e.variantCount} trials run`)})]})}),(0,k.jsxs)(`td`,{style:{...G,color:W(h?.latest_sharpe),fontWeight:700,fontSize:`1rem`},children:[T(h?.latest_sharpe,{decimals:2}),h?.latest_source===`strategy-file`&&(0,k.jsx)(`span`,{"data-testid":`latest-source-badge`,role:`img`,"aria-label":d(`最新ランはチューニング試行(保存していないパラメータ)です`,`Latest run is a tuning trial with unsaved parameters`),title:d(`最新ランはチューニング試行(保存していないパラメータ)です`,`Latest run is a tuning trial with unsaved parameters`),style:{marginLeft:4,color:`var(--warn)`,fontSize:10},children:`⚠`})]}),(0,k.jsx)(`td`,{style:{...G,color:h?.latest_return_pct==null?`var(--text3)`:h.latest_return_pct>=0?`var(--success)`:`var(--danger)`},children:T(h?.latest_return_pct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{style:{...G,color:h?.latest_max_drawdown_pct==null?`var(--text3)`:`var(--danger)`},children:T(h?.latest_max_drawdown_pct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text2)`},children:T(h?.latest_profit_factor,{decimals:2})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text2)`},children:T(h?.latest_win_rate_pct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:K,children:D(h?.last_run_at)}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,padding:`6px 12px`,width:132,textAlign:`right`},children:(0,k.jsx)(`div`,{style:{display:`inline-flex`,justifyContent:`flex-end`,minHeight:20},children:w})})]})}function ke({visibleRecipeCount:e,recipeTotal:t,hiddenUnrunRecipeCount:n,strategyTotal:r,lang:i}){let a=f(i),o=n>0?a(`(未実行のみ ${n} レシピを非表示)`,` (${n} unrun-only recipes hidden)`):``;return(0,k.jsx)(`div`,{"data-testid":`strategy-table-footer`,style:{padding:`12px 24px`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`,borderTop:`1px solid var(--border)`},children:a(`${e} レシピ表示 / 全 ${t} レシピ${o} · ${r} 戦略`,`${e} of ${t} recipes${o} · ${r} strategies`)})}var Ae=220,je=9,q={fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`,padding:`14px 12px`,textAlign:`right`,cursor:`pointer`,background:`var(--surface)`,borderBottom:`1px solid var(--border)`,userSelect:`none`,whiteSpace:`nowrap`,position:`sticky`,top:0,zIndex:2};function J({col:e,label:t,align:n=`right`,width:r,sortKey:i,sortDir:a,onSort:o,className:s}){let c=i===e;return(0,k.jsx)(C,{label:t,active:c,direction:a,onSort:()=>o(e),align:n,width:r,className:s,baseStyle:{...q,color:c?`var(--text2)`:`var(--text3)`}})}function Me({group:e,collapsed:t,onToggle:n,lang:r}){let i=f(r),{aggregate:a}=e;return(0,k.jsxs)(`tr`,{onClick:()=>n(e.key),style:{background:`var(--surface-2)`,cursor:`pointer`,borderTop:`1px solid var(--border)`},children:[(0,k.jsx)(`td`,{colSpan:2,style:{...G,textAlign:`left`,borderBottom:`1px solid var(--border)`},children:(0,k.jsxs)(`div`,{style:{display:`inline-flex`,alignItems:`center`,gap:`var(--space-2)`},children:[(0,k.jsx)(`span`,{"aria-hidden":!0,style:{display:`inline-block`,width:14,fontFamily:`var(--mono)`,color:`var(--text2)`,transition:`transform var(--motion-fast)`,transform:t?`rotate(-90deg)`:`rotate(0deg)`},children:`▾`}),(0,k.jsx)(`span`,{style:{fontFamily:`var(--serif)`,fontSize:`1.0625rem`,fontWeight:600,color:`var(--text)`,letterSpacing:`-0.005em`},children:e.label}),(0,k.jsx)(`span`,{style:{fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`},children:i(`${a.count}件`,`${a.count} strategies`)})]})}),(0,k.jsx)(`td`,{style:{...G,color:W(a.bestSharpe),fontWeight:700,borderBottom:`1px solid var(--border)`},title:i(`グループ内の最高 Sharpe`,`Best Sharpe in group`),children:T(a.bestSharpe,{decimals:2})}),(0,k.jsx)(`td`,{style:{...G,color:`var(--text3)`,borderBottom:`1px solid var(--border)`},children:`—`}),(0,k.jsx)(`td`,{style:{...G,color:a.worstDrawdownPct==null?`var(--text3)`:`var(--danger)`,borderBottom:`1px solid var(--border)`},title:i(`グループ内の最悪 DD`,`Worst drawdown in group`),children:T(a.worstDrawdownPct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text3)`,borderBottom:`1px solid var(--border)`},children:`—`}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text3)`,borderBottom:`1px solid var(--border)`},children:`—`}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:`var(--text3)`,borderBottom:`1px solid var(--border)`},children:`—`}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,borderBottom:`1px solid var(--border)`}})]})}function Ne({recipes:e,strategyTotal:t,sortKey:n,sortDir:r,onSort:i,selectedId:a,onSelect:o,compareIds:s,onToggleCompare:c,lang:l,groups:u,recipeTotal:d,hiddenUnrunRecipeCount:p}){let m=f(l),h=H(),[g,_]=(0,O.useState)(null),[v,y]=(0,O.useState)(()=>new Set),[b,x]=(0,O.useState)(()=>new Set);(0,O.useEffect)(()=>{if(!g)return;let e=window.setTimeout(()=>{h.prefetch(g)},Ae);return()=>window.clearTimeout(e)},[g,h]);let S=(0,O.useMemo)(()=>!u||u.length<=1?null:u,[u]),w=e=>{y(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},T=e=>{x(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},E=e=>{let t=b.has(e.key),n=(0,k.jsx)(Oe,{recipe:e,expanded:t,onToggleExpand:T,selectedId:a,onSelect:o,compareIds:s,onToggleCompare:c,onHover:_,sparkValues:e.best?h.entries[e.best.strategy_id]:void 0,lang:l},e.key);return t?[n,...e.variants.map(e=>{let t=s.includes(e.strategy_id);return(0,k.jsx)(De,{s:e,selected:a===e.strategy_id,inCompare:t,maxCompareReached:s.length>=6&&!t,onSelect:o,onToggleCompare:c,onHover:_,sparkValues:h.entries[e.strategy_id],lang:l,indent:!0},e.strategy_id)})]:[n]};return(0,k.jsxs)(`div`,{className:`u-scroll-x`,"data-testid":`strategy-table-scroll`,style:{flex:1,minWidth:0,background:`var(--bg)`},children:[(0,k.jsxs)(`table`,{style:{width:`100%`,borderCollapse:`collapse`,minWidth:1080},children:[(0,k.jsx)(`thead`,{children:(0,k.jsxs)(`tr`,{children:[(0,k.jsx)(`th`,{scope:`col`,style:{...q,width:36,padding:`14px 4px`},children:(0,k.jsx)(`span`,{style:{position:`absolute`,width:1,height:1,padding:0,margin:-1,overflow:`hidden`,clip:`rect(0 0 0 0)`,whiteSpace:`nowrap`,border:0},children:m(`選択`,`Select`)})}),(0,k.jsx)(C,{label:m(`戦略`,`Strategy`),active:n===`name`,direction:r,onSort:()=>i(`name`),align:`left`,baseStyle:{...q,color:n===`name`?`var(--text2)`:`var(--text3)`}}),(0,k.jsx)(J,{col:`latest_sharpe`,label:`Sharpe`,sortKey:n,sortDir:r,onSort:i}),(0,k.jsx)(J,{col:`latest_return_pct`,label:m(`リターン`,`Return`),sortKey:n,sortDir:r,onSort:i}),(0,k.jsx)(J,{col:`latest_max_drawdown_pct`,label:`Max DD`,sortKey:n,sortDir:r,onSort:i}),(0,k.jsx)(J,{col:`latest_profit_factor`,label:`Profit F.`,className:`u-col-hide-md-down`,sortKey:n,sortDir:r,onSort:i}),(0,k.jsx)(J,{col:`latest_win_rate_pct`,label:`Win %`,className:`u-col-hide-md-down`,sortKey:n,sortDir:r,onSort:i}),(0,k.jsx)(J,{col:`last_run_at`,label:m(`最終実行`,`Last run`),className:`u-col-hide-md-down`,sortKey:n,sortDir:r,onSort:i}),(0,k.jsx)(`th`,{scope:`col`,className:`u-col-hide-md-down`,style:{...q,width:132,textAlign:`right`},children:m(`推移`,`Trend`)})]})}),(0,k.jsxs)(`tbody`,{children:[S?S.flatMap(e=>{let t=v.has(e.key),n=(0,k.jsx)(Me,{group:e,collapsed:t,onToggle:w,lang:l},`__header__${e.key}`);return t?[n]:[n,...e.items.flatMap(E)]}):e.flatMap(E),e.length===0&&(0,k.jsx)(`tr`,{children:(0,k.jsx)(`td`,{colSpan:je,style:{...G,textAlign:`center`,padding:`48px 24px`,color:`var(--text3)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,letterSpacing:`var(--tracking-mono)`},children:t>0?(0,k.jsxs)(k.Fragment,{children:[m(`該当する戦略はありません`,`No strategies match the current filters`),p>0&&(0,k.jsx)(`div`,{style:{marginTop:8},children:m(`「未実行を含める」にチェックすると表示できます`,`Check "Include unrun" to show them`)})]}):(0,k.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:10,lineHeight:1.8},children:[(0,k.jsx)(`div`,{style:{color:`var(--text2)`},children:m(`まだ戦略がありません`,`No strategies yet`)}),(0,k.jsxs)(`div`,{children:[m(`サンプルデータで試す: `,`Try with bundled samples: `),(0,k.jsx)(`code`,{style:{background:`var(--surface)`,border:`1px solid var(--border)`,borderRadius:4,padding:`2px 6px`},children:`alpha-vis serve --use-bundled-samples`})]}),(0,k.jsx)(`div`,{children:(0,k.jsxs)(`a`,{href:`https://alforgelabs.com/?utm_source=alpha-visualizer&utm_medium=empty_state`,target:`_blank`,rel:`noopener noreferrer`,"aria-label":m(`AlphaForge で最初のバックテストを作る(別タブで開く)`,`Create your first backtest with AlphaForge (opens in new tab)`),style:{color:`var(--accent)`,textDecoration:`none`},children:[m(`AlphaForge で最初のバックテストを作る`,`Create your first backtest with AlphaForge`),(0,k.jsx)(`span`,{"aria-hidden":`true`,children:` ↗`})]})})]})})})]})]}),(0,k.jsx)(ke,{visibleRecipeCount:e.length,recipeTotal:d,hiddenUnrunRecipeCount:p,strategyTotal:t,lang:l})]})}var Y={fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`};function Pe({strategy:e,onClose:t,lang:n}){let r=f(n),[i,a]=(0,O.useState)(0),[o,s]=(0,O.useState)(!1),c=te(e.strategy_id,i),u=c.status===`ready`?c.data.slice(0,5):[],{run:m,running:_,error:y,logTail:x}=ee(),S=H(),C=S.entries[e.strategy_id];(0,O.useEffect)(()=>{S.prefetch(e.strategy_id)},[e.strategy_id,S]);let T=()=>{if(e.symbol){if(e.last_run_at!==null){s(!0);return}E()}},E=async()=>{s(!1),e.symbol&&await m(e.strategy_id,e.symbol)&&a(e=>e+1)};return(0,k.jsxs)(`aside`,{className:`u-drawer-md-down`,"data-open":`true`,"data-testid":`strategy-slide-panel`,style:{width:`var(--slidepanel-width)`,flexShrink:0,alignSelf:`flex-start`,position:`sticky`,top:0,maxHeight:`100vh`,background:`var(--surface)`,borderLeft:`1px solid var(--border)`,display:`flex`,flexDirection:`column`,overflowY:`auto`},children:[(0,k.jsxs)(`header`,{style:{padding:`var(--space-5) var(--space-5) var(--space-4)`,display:`flex`,alignItems:`flex-start`,gap:`var(--space-3)`},children:[(0,k.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,k.jsx)(`h2`,{style:{margin:0,fontFamily:`var(--serif)`,fontSize:`1.375rem`,fontWeight:700,color:`var(--text)`,letterSpacing:`-0.01em`,lineHeight:1.15},children:e.name}),(0,k.jsxs)(`div`,{style:{display:`flex`,gap:6,marginTop:8,flexWrap:`wrap`},children:[e.symbol?(0,k.jsx)(b,{children:e.symbol}):null,e.timeframe?(0,k.jsx)(b,{children:e.timeframe}):null]})]}),(0,k.jsx)(`button`,{type:`button`,onClick:t,"aria-label":r(`閉じる`,`Close`),style:{background:`transparent`,border:`none`,cursor:`pointer`,color:`var(--text3)`,fontSize:18,lineHeight:1,padding:4},children:`✕`})]}),(0,k.jsxs)(`div`,{style:{padding:`0 var(--space-5) var(--space-4)`,display:`flex`,alignItems:`center`,gap:`var(--space-2)`,flexWrap:`wrap`},children:[(0,k.jsxs)(l,{to:`/detail/${e.strategy_id}`,style:{display:`inline-flex`,alignItems:`center`,gap:6,padding:`6px 12px`,background:`var(--accent)`,color:`var(--surface)`,border:`1px solid var(--accent-strong, var(--accent))`,borderRadius:`var(--radius-sm)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,fontWeight:600,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`,textDecoration:`none`,transition:`background var(--motion-fast)`},children:[r(`フル詳細を開く`,`Open full detail`),` →`]}),(0,k.jsx)(h,{variant:`subtle`,size:`sm`,onClick:T,disabled:_||!e.symbol,children:_?r(`実行中…`,`Running…`):r(`バックテスト再実行`,`Re-run backtest`)}),y&&(0,k.jsx)(`p`,{style:{marginTop:12,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--danger)`,padding:`8px 12px`,background:`color-mix(in srgb, var(--danger) 10%, transparent)`,border:`1px solid color-mix(in srgb, var(--danger) 24%, transparent)`,borderRadius:`var(--radius-sm)`,letterSpacing:`var(--tracking-mono)`},children:y}),x&&(0,k.jsx)(`div`,{style:{width:`100%`,marginTop:8},children:(0,k.jsx)(w,{log:x,lang:n})})]}),(0,k.jsx)(d,{}),(0,k.jsxs)(`section`,{style:{padding:`var(--space-4) var(--space-5)`},children:[(0,k.jsx)(`div`,{style:Y,children:r(`エクイティ推移`,`Equity curve`)}),(0,k.jsx)(`div`,{style:{marginTop:`var(--space-3)`,background:`var(--surface-2)`,border:`1px solid var(--border)`,borderRadius:`var(--radius-sm)`,padding:`var(--space-3)`,minHeight:132,display:`flex`,alignItems:`center`,justifyContent:`center`},children:Array.isArray(C)&&C.length>=2?(0,k.jsx)(U,{values:C,width:300,height:108,strokeWidth:1.5}):C===`loading`?(0,k.jsxs)(`span`,{role:`status`,"aria-live":`polite`,"aria-busy":`true`,children:[(0,k.jsx)(g,{width:300,height:108}),(0,k.jsx)(`span`,{style:v,children:r(`読み込み中…`,`Loading…`)})]}):(0,k.jsx)(`span`,{style:{fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`},children:r(`データなし`,`No data`)})})]}),(0,k.jsx)(d,{}),(0,k.jsxs)(`section`,{style:{padding:`var(--space-4) var(--space-5)`},children:[(0,k.jsx)(`div`,{style:Y,children:r(`実行履歴`,`Run history`)}),(0,k.jsxs)(`div`,{style:{marginTop:`var(--space-3)`},children:[u.map((e,t)=>(0,k.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`baseline`,padding:`10px 0`,borderTop:t===0?`none`:`1px solid var(--border)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-md)`,letterSpacing:`var(--tracking-mono)`},children:[(0,k.jsx)(`span`,{style:{color:`var(--text3)`},children:e.run_at.slice(0,10)}),(0,k.jsx)(`span`,{style:{color:e.sharpe_ratio!==null&&e.sharpe_ratio>=1?`var(--success)`:e.sharpe_ratio===null?`var(--text3)`:`var(--warn)`,fontWeight:600},children:e.sharpe_ratio===null?`—`:`Sharpe ${e.sharpe_ratio.toFixed(2)}`}),(0,k.jsx)(`span`,{style:{color:`var(--text2)`,minWidth:60,textAlign:`right`},children:e.total_return_pct===null?`—`:`${e.total_return_pct.toFixed(1)}%`})]},e.run_id)),u.length===0&&c.status===`ready`&&(0,k.jsx)(`p`,{style:{margin:0,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`,padding:`8px 0`},children:r(`履歴はありません`,`No runs yet`)})]})]}),(0,k.jsx)(p,{open:o,title:r(`バックテスト再実行`,`Re-run backtest`),message:r(`再実行すると最新結果が上書きされます。続けますか?`,`Re-running will overwrite the latest result. Continue?`),confirmLabel:_?r(`実行中…`,`Running…`):r(`実行`,`Run`),cancelLabel:r(`やめる`,`Cancel`),onConfirm:E,onCancel:()=>s(!1),tone:`danger`})]})}function Fe({compareIds:e,strategies:t,onRemove:n,lang:r}){let i=f(r),a=u();if(e.length===0)return null;let o=e=>t.find(t=>t.strategy_id===e)?.name??e;return(0,k.jsxs)(`div`,{style:{position:`fixed`,bottom:0,left:0,right:0,zIndex:200,background:`var(--surface)`,borderTop:`1px solid var(--accent-glow)`,boxShadow:`0 -8px 24px color-mix(in srgb, var(--accent) 12%, transparent)`,padding:`14px 24px`,display:`flex`,alignItems:`center`,gap:`var(--space-4)`},children:[(0,k.jsx)(`span`,{style:{fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:600,color:`var(--accent)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`,whiteSpace:`nowrap`},children:i(`${e.length}件選択中`,`${e.length} selected`)}),(0,k.jsx)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`,flex:1,minWidth:0},children:e.map(e=>(0,k.jsxs)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:8,padding:`6px 10px 6px 14px`,background:`var(--accent-bg)`,border:`1px solid var(--accent-glow)`,borderRadius:`var(--radius-pill)`,fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text)`,maxWidth:240},children:[(0,k.jsx)(`span`,{style:{whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:o(e)}),(0,k.jsx)(`button`,{type:`button`,onClick:()=>n(e),"aria-label":i(`外す`,`Remove`),style:{background:`transparent`,border:`none`,cursor:`pointer`,color:`var(--text3)`,fontSize:14,padding:0,lineHeight:1},children:`✕`})]},e))}),(0,k.jsx)(h,{variant:`primary`,size:`md`,onClick:()=>{a(`/compare?ids=${e.join(`,`)}`)},children:i(`比較する →`,`Compare →`)})]})}var Ie={fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`};function Le({groupBy:e,onChange:t,lang:n}){let r=f(n),i=[[`none`,r(`なし`,`None`)],[`symbol`,r(`銘柄`,`Symbol`)],[`tf`,r(`時間軸`,`Timeframe`)],[`tier`,r(`Sharpe階級`,`Sharpe Tier`)]];return(0,k.jsxs)(`div`,{style:{display:`inline-flex`,alignItems:`center`,gap:`var(--space-2)`},children:[(0,k.jsx)(`span`,{style:Ie,children:r(`グループ`,`Group by`)}),(0,k.jsx)(`div`,{role:`radiogroup`,"aria-label":r(`グルーピング`,`Group by`),style:{display:`inline-flex`,background:`var(--surface-2)`,border:`1px solid var(--border)`,borderRadius:`var(--radius-pill)`,padding:2,gap:2},children:i.map(([n,i])=>{let a=n===e;return(0,k.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":a,"aria-label":`${r(`グループ`,`Group by`)}: ${i}`,onClick:()=>t(n),style:{padding:`4px 12px`,borderRadius:`var(--radius-pill)`,border:`none`,background:a?`var(--accent)`:`transparent`,color:a?`var(--surface)`:`var(--text2)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,fontWeight:600,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`,cursor:`pointer`,transition:`background var(--motion-fast), color var(--motion-fast)`},children:i},n)})})]})}var X=7,Re=1440*60*1e3;function ze(e){let t=new Set,n=null,r=0,i=Date.now()-X*Re;for(let a of e){let e=F(a);if(e&&t.add(e),a.latest_sharpe!=null&&(n=n==null?a.latest_sharpe:Math.max(n,a.latest_sharpe)),a.last_run_at){let e=Date.parse(a.last_run_at);!Number.isNaN(e)&&e>=i&&(r+=1)}}return{totalStrategies:e.length,uniqueSymbols:t.size,topSharpe:n,recentRunsCount:r}}function Be(e){return e==null?`neutral`:e>=1.5?`positive`:e>=1?`warning`:`negative`}function Ve({items:e,lang:t}){let n=f(t),r=(0,O.useMemo)(()=>ze(e),[e]);return(0,k.jsxs)(`div`,{role:`group`,"aria-label":n(`全体メトリクス`,`Overview metrics`),style:{display:`flex`,flexWrap:`wrap`,gap:`var(--space-5)`,marginTop:`var(--space-3)`,paddingTop:`var(--space-3)`,borderTop:`1px solid var(--border)`},children:[(0,k.jsx)(m,{size:`md`,label:n(`戦略数`,`Strategies`),value:r.totalStrategies>0?String(r.totalStrategies):`—`,sub:n(`登録済み`,`registered`)}),(0,k.jsx)(m,{size:`md`,label:n(`銘柄数`,`Symbols`),value:r.uniqueSymbols>0?String(r.uniqueSymbols):`—`,sub:n(`割当済`,`with assignments`)}),(0,k.jsx)(m,{size:`md`,tone:Be(r.topSharpe),label:n(`最高 Sharpe`,`Top Sharpe`),value:E(r.topSharpe),sub:n(`最新バックテスト`,`latest backtests`)}),(0,k.jsx)(m,{size:`md`,tone:r.recentRunsCount>0?`accent`:`neutral`,label:n(`直近実行`,`Recent runs`),value:r.recentRunsCount>0?String(r.recentRunsCount):`—`,sub:n(`${X}日以内`,`last ${X} days`)})]})}var He=[{key:`all`,params:{}},{key:`high_sharpe`,params:{sharpe_min:`1.5`,sort:`latest_sharpe`,dir:`desc`}},{key:`recent`,params:{sort:`last_run_at`,dir:`desc`}},{key:`risky`,params:{sort:`latest_max_drawdown_pct`,dir:`asc`}}],Z=[`q`,`symbol`,`tf`,`sharpe_min`,`dd_max`,`include_unrun`,`sort`,`dir`,`selected`,`compare`];function Ue(e,t){let n=f(t);switch(e){case`all`:return n(`すべて`,`All`);case`high_sharpe`:return n(`高 Sharpe`,`High Sharpe`);case`recent`:return n(`最近実行`,`Recent`);case`risky`:return n(`要注意`,`Risky`)}}function We(e,t){let n=f(t);switch(e){case`all`:return n(`フィルタなし`,`No filter`);case`high_sharpe`:return n(`Sharpe 1.5 以上を Sharpe 降順で`,`Sharpe ≥ 1.5, sorted by Sharpe`);case`recent`:return n(`最終実行が新しい順`,`Sorted by last run desc`);case`risky`:return n(`Max DD が深い順`,`Sorted by deepest drawdown`)}}function Ge(e,t){if(e.key===`all`)return Z.every(e=>!t.get(e));for(let[n,r]of Object.entries(e.params))if(t.get(n)!==r)return!1;for(let n of Z)if(!(n in e.params)&&t.get(n))return!1;return!0}function Ke({lang:e}){let t=f(e),[n,r]=s(),i=e=>{r(t=>{let n=new URLSearchParams(t);for(let e of Z)n.delete(e);for(let[t,r]of Object.entries(e.params))n.set(t,r);return n},{replace:!0})};return(0,k.jsxs)(`div`,{role:`radiogroup`,"aria-label":t(`保存ビュー`,`Saved views`),style:{display:`flex`,alignItems:`center`,gap:`var(--space-3)`,padding:`var(--space-3) var(--space-7)`,background:`var(--bg)`,borderBottom:`1px solid var(--border)`,flexWrap:`wrap`},children:[(0,k.jsx)(`span`,{style:{fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`},children:t(`レンズ`,`Lenses`)}),He.map(t=>{let r=Ge(t,n),a=Ue(t.key,e),o=We(t.key,e);return(0,k.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":r,"aria-label":`${a}: ${o}`,title:o,onClick:()=>i(t),style:{padding:`6px 14px`,borderRadius:`var(--radius-pill)`,border:`1px solid ${r?`var(--accent-glow, var(--accent))`:`var(--border)`}`,background:r?`var(--accent-bg)`:`var(--surface-2)`,color:r?`var(--accent)`:`var(--text2)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,fontWeight:600,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`,cursor:`pointer`,transition:`background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast)`},children:a},t.key)})]})}var qe=[`index`,`etf`,`stock`,`fx`,`commodity`,`other`],Je={index:{ja:`指数`,en:`Indices`},etf:{ja:`ETF`,en:`ETFs`},stock:{ja:`個別銘柄`,en:`Stocks`},fx:{ja:`FX`,en:`Forex`},commodity:{ja:`コモディティ`,en:`Commodities`},other:{ja:`その他`,en:`Other`}},Ye=new Set(`SPY.QQQ.TQQQ.SQQQ.VOO.VTI.IVV.VEA.VWO.EFA.EEM.IWM.DIA.GLD.SLV.TLT.IEF.HYG.LQD.XLF.XLE.XLK.XLI.XLP.XLY.XLV.XLU.XBI.SOXL.SOXX.ARKK.SH.UVXY.AGG.BND`.split(`.`)),Xe=new Set([`NAS100`,`SPX500`,`US30`,`US500`,`UK100`,`GER40`,`GER30`,`JPN225`,`HK50`,`AUS200`,`FRA40`,`EU50`]),Ze=new Set([`XAU`,`XAG`,`XPT`,`XPD`,`XBT`]),Qe=/^[A-Z]{6}(=X|_X)$/i;function $e(e){if(!e)return`other`;let t=e.trim();if(!t)return`other`;let n=t.toUpperCase();return t.startsWith(`^`)||Xe.has(n)?`index`:Qe.test(t)?`fx`:t.endsWith(`=F`)||Ze.has(n)?`commodity`:Ye.has(n)?`etf`:/^[A-Z][A-Z0-9.-]*$/i.test(t)?`stock`:`other`}var et=`unrunRecipeCount`,tt=`desc`,nt=[{key:`unrunRecipeCount`,dir:`desc`},{key:`recipeCount`,dir:`desc`},{key:`bestSharpe`,dir:`desc`},{key:`symbol`,dir:`asc`}];function Q(e,t){switch(t){case`symbol`:return e.symbol??``;case`assetClass`:return qe.indexOf(e.assetClass);case`lastRunAt`:return e.lastRunAt??``;case`bestSharpe`:return e.bestSharpe??-1/0;case`avgReturnPct`:return e.avgReturnPct??-1/0;case`recipeCount`:return e.recipeCount;case`runRecipeCount`:return e.runRecipeCount;case`unrunRecipeCount`:return e.unrunRecipeCount}}function $(e,t,n,r){let i=Q(e,n),a=Q(t,n),o;return o=typeof i==`string`&&typeof a==`string`?i.localeCompare(a):typeof i==`number`&&typeof a==`number`?i<a?-1:+(i>a):0,r===`asc`?o:-o}function rt(e,t,n){return[...e].sort((e,r)=>{if(e.symbol===null&&r.symbol!==null)return 1;if(r.symbol===null&&e.symbol!==null)return-1;let i=$(e,r,t,n);if(i!==0)return i;for(let n of nt){if(n.key===t)continue;let i=$(e,r,n.key,n.dir);if(i!==0)return i}return 0})}function it(e,t){let n=null,r=0,i=0,a=null,o=0;for(let e of t){e.runCount>0&&(o+=1);let t=e.best;t!=null&&(t.latest_sharpe!=null&&(n=n==null?t.latest_sharpe:Math.max(n,t.latest_sharpe)),t.latest_return_pct!=null&&(r+=t.latest_return_pct,i+=1));for(let t of e.variants){let e=t.last_run_at;e&&(a==null||e>a)&&(a=e)}}return{symbol:e,assetClass:e==null?`other`:$e(e),recipeCount:t.length,runRecipeCount:o,unrunRecipeCount:t.length-o,bestSharpe:n,avgReturnPct:i>0?r/i:null,lastRunAt:a}}function at(e){let t=new Map,n=[];for(let r of e){let e=r.symbol;if(e==null){n.push(r);continue}let i=t.get(e);i?i.push(r):t.set(e,[r])}let r=[];for(let[e,n]of t.entries())r.push(it(e,n));return n.length>0&&r.push(it(null,n)),r}var ot={fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`,padding:`10px 12px`,background:`var(--surface)`,borderBottom:`1px solid var(--border)`,userSelect:`none`,whiteSpace:`nowrap`},st=[{key:`symbol`,ja:`銘柄`,en:`Symbol`,align:`left`},{key:`assetClass`,ja:`区分`,en:`Class`,align:`left`,hideMdDown:!0},{key:`recipeCount`,ja:`レシピ`,en:`Recipes`,align:`right`},{key:`runRecipeCount`,ja:`実行済`,en:`Run`,align:`right`},{key:`unrunRecipeCount`,ja:`未実行`,en:`Unrun`,align:`right`},{key:`bestSharpe`,ja:`最高 Sharpe`,en:`Best Sharpe`,align:`right`},{key:`avgReturnPct`,ja:`平均 Return`,en:`Avg return`,align:`right`,hideMdDown:!0},{key:`lastRunAt`,ja:`最終実行`,en:`Last run`,align:`right`,hideMdDown:!0}];function ct(e){return e==null?`var(--text3)`:e>=0?`var(--success)`:`var(--danger)`}function lt({stat:e,selected:t,dimmed:n,onToggle:r,lang:i}){let a=f(i),o=e.symbol,s=o??a(`未割当`,`Unassigned`),[c,l]=(0,O.useState)(!1),u=()=>{o!=null&&r(o)};return(0,k.jsxs)(`tr`,{onClick:u,onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),style:{background:t?`var(--accent-bg)`:c&&o!=null?`var(--surface-2)`:`transparent`,borderLeft:t?`2px solid var(--accent)`:`2px solid transparent`,opacity:n?.55:1,cursor:o==null?`default`:`pointer`,transition:`background var(--motion-fast)`},children:[(0,k.jsx)(`td`,{style:{...G,textAlign:`left`},children:(0,k.jsx)(`button`,{type:`button`,"aria-pressed":t,disabled:o==null,onClick:e=>{e.stopPropagation(),u()},style:{background:`transparent`,border:`none`,padding:0,margin:0,fontFamily:`var(--serif)`,fontSize:`1.0625rem`,fontWeight:600,color:o==null?`var(--text3)`:`var(--text)`,letterSpacing:`-0.005em`,cursor:o==null?`default`:`pointer`},children:s})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,textAlign:`left`,color:`var(--text3)`},children:o==null?`—`:Je[e.assetClass][i]}),(0,k.jsx)(`td`,{style:{...G,color:`var(--text2)`},children:e.recipeCount}),(0,k.jsx)(`td`,{style:{...G,color:`var(--text2)`},children:e.runRecipeCount}),(0,k.jsx)(`td`,{style:{...G,color:e.unrunRecipeCount>0?`var(--warn)`:`var(--text3)`,fontWeight:700},children:e.unrunRecipeCount}),(0,k.jsx)(`td`,{style:{...G,color:W(e.bestSharpe),fontWeight:700},children:T(e.bestSharpe,{decimals:2})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:{...G,color:ct(e.avgReturnPct)},children:T(e.avgReturnPct,{suffix:`%`,decimals:1})}),(0,k.jsx)(`td`,{className:`u-col-hide-md-down`,style:K,children:D(e.lastRunAt)})]})}function ut({recipes:e,lang:t}){let n=f(t),[r,i]=s(),[a,o]=(0,O.useState)(et),[c,l]=(0,O.useState)(tt),u=(0,O.useMemo)(()=>at(e),[e]),d=(0,O.useMemo)(()=>rt(u,a,c),[u,a,c]),p=(0,O.useMemo)(()=>(r.get(`symbol`)??``).split(`,`).filter(Boolean),[r]),m=e=>{i(t=>{let n=new URLSearchParams(t),r=n.get(`symbol`)?.split(`,`).filter(Boolean)??[],i=r.includes(e)?r.filter(t=>t!==e):[...r,e];return i.length?n.set(`symbol`,i.join(`,`)):n.delete(`symbol`),n},{replace:!0})},h=e=>{if(e===a){l(e=>e===`desc`?`asc`:`desc`);return}o(e),l(`desc`)};return d.length===0?null:(0,k.jsxs)(`section`,{"aria-label":n(`銘柄カバレッジ`,`Symbol coverage`),style:{padding:`var(--space-4) var(--space-7)`,background:`var(--bg)`,borderBottom:`1px solid var(--border)`,display:`flex`,flexDirection:`column`,gap:`var(--space-3)`},children:[(0,k.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,justifyContent:`space-between`,gap:`var(--space-3)`},children:[(0,k.jsx)(`h2`,{style:{margin:0,fontFamily:`var(--serif)`,fontSize:`1.25rem`,fontWeight:600,color:`var(--text)`,letterSpacing:`-0.005em`},children:n(`銘柄カバレッジ`,`Symbol coverage`)}),(0,k.jsx)(`span`,{style:{fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-sm)`,color:`var(--text3)`,letterSpacing:`var(--tracking-mono)`,textTransform:`uppercase`},children:n(`${d.length} 銘柄 · ${e.length} レシピ`,`${d.length} symbols · ${e.length} recipes`)})]}),(0,k.jsx)(`div`,{className:`u-scroll-x`,"data-testid":`symbol-coverage-scroll`,children:(0,k.jsxs)(`table`,{style:{width:`100%`,borderCollapse:`collapse`},children:[(0,k.jsx)(`thead`,{children:(0,k.jsx)(`tr`,{children:st.map(e=>(0,k.jsx)(C,{label:n(e.ja,e.en),active:a===e.key,direction:c,onSort:()=>h(e.key),align:e.align,className:e.hideMdDown?`u-col-hide-md-down`:void 0,baseStyle:{...ot,color:a===e.key?`var(--text2)`:`var(--text3)`}},e.key))})}),(0,k.jsx)(`tbody`,{children:d.map(e=>{let n=e.symbol!=null&&p.includes(e.symbol);return(0,k.jsx)(lt,{stat:e,selected:n,dimmed:p.length>0&&!n,onToggle:m,lang:t},e.symbol??`__unassigned__`)})})]})})]})}function dt({list:e,lang:t,theme:n,selectedStrategy:r,onUpdateLang:i,onUpdateTheme:a,onSelect:o,onCloseSlidePanel:s}){let c=f(t),u=at(e.allRecipes),d=u.reduce((e,t)=>e+t.unrunRecipeCount,0),p=u.filter(e=>e.symbol!==null).length,m=u.some(e=>e.symbol===null)?c(`銘柄カバレッジ(${p} 銘柄 + 未割当 · 未実行 ${d} レシピ)`,`Symbol coverage (${p} symbols + unassigned · ${d} unrun recipes)`):c(`銘柄カバレッジ(${p} 銘柄 · 未実行 ${d} レシピ)`,`Symbol coverage (${p} symbols · ${d} unrun recipes)`);return(0,k.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,minHeight:`100vh`,background:`var(--bg)`},children:[(0,k.jsxs)(`header`,{className:`u-toolbar-wrap`,style:{padding:`var(--space-4) var(--layout-gutter)`,background:`var(--bg)`,borderBottom:`1px solid var(--border)`,display:`flex`,alignItems:`flex-start`,justifyContent:`space-between`,gap:`var(--space-4)`},children:[(0,k.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,k.jsx)(`div`,{style:{fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`},children:c(`戦略ブラウザ`,`Strategy browser`)}),(0,k.jsx)(`h1`,{style:{margin:`4px 0 0 0`,fontFamily:`var(--serif)`,fontSize:`var(--browse-fs-h1)`,fontWeight:700,color:`var(--text)`,letterSpacing:`-0.01em`,lineHeight:1.1},children:c(`登録済みの戦略を一覧する`,`Browse the strategy library`)}),!e.loading&&(0,k.jsx)(Ve,{items:e.all,lang:t}),(0,k.jsx)(`div`,{style:{display:`flex`,gap:`var(--space-4)`},children:[`/ideas`,`/live`].map(e=>(0,k.jsx)(l,{to:e,style:{display:`inline-flex`,alignItems:`center`,marginTop:`var(--space-3)`,fontFamily:`var(--sans)`,fontSize:`var(--fs-caption)`,fontWeight:500,color:`var(--text3)`,textDecoration:`none`,letterSpacing:`var(--tracking-caption)`,textTransform:`uppercase`},children:e===`/ideas`?c(`Ideas →`,`Ideas →`):c(`Live →`,`Live →`)},e))})]}),(0,k.jsx)(ne,{lang:t,onSetLang:i,theme:n,onSetTheme:a})]}),(0,k.jsx)(Ke,{lang:t}),(0,k.jsx)(ae,{symbols:e.symbols,timeframes:e.timeframes,lang:t}),(0,k.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`var(--space-4)`,padding:`var(--space-3) var(--layout-gutter)`,background:`var(--bg)`,borderBottom:`1px solid var(--border)`},children:(0,k.jsx)(Le,{groupBy:e.groupBy,onChange:e.setGroupBy,lang:t})}),!e.loading&&e.all.length>0&&(0,k.jsx)(A,{label:m,testId:`symbol-coverage-collapsible`,children:(0,k.jsx)(ut,{recipes:e.allRecipes,lang:t})}),(0,k.jsxs)(`div`,{style:{display:`flex`,flex:1},children:[e.loading?(0,k.jsx)(y,{label:c(`読み込み中…`,`Loading…`)}):(0,k.jsx)(Ne,{recipes:e.recipes,groups:e.groups,strategyTotal:e.all.length,recipeTotal:e.recipeTotal,hiddenUnrunRecipeCount:e.hiddenUnrunRecipeCount,sortKey:e.sortKey,sortDir:e.sortDir,onSort:e.setSort,selectedId:e.selectedId,onSelect:o,compareIds:e.compareIds,onToggleCompare:e.toggleCompareId,lang:t}),r&&(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(`div`,{className:`u-drawer-md-down-backdrop u-hide-md-up`,"data-testid":`slide-panel-backdrop`,onClick:s,"aria-hidden":`true`}),(0,k.jsx)(Pe,{strategy:r,onClose:s,lang:t})]})]}),(0,k.jsx)(Fe,{compareIds:e.compareIds,strategies:e.all,onRemove:e.removeCompareId,lang:t})]})}var ft=`alphaforge.scroll:`;function pt(e){let t=`${ft}${c().pathname}`,n=(0,O.useRef)(!1);(0,O.useEffect)(()=>{if(!e||n.current)return;let r=sessionStorage.getItem(t);if(r!==null){let e=Number.parseInt(r,10);Number.isNaN(e)||requestAnimationFrame(()=>{window.scrollTo(0,e)})}n.current=!0},[e,t]),(0,O.useEffect)(()=>{let e=()=>{sessionStorage.setItem(t,String(window.scrollY))};return window.addEventListener(`scroll`,e,{passive:!0}),()=>{window.removeEventListener(`scroll`,e)}},[t])}function mt(){let{settings:e,update:t}=S(),{lang:n,theme:r}=e;re(n===`ja`?`戦略ブラウザ`:`Strategy Browser`);let i=Ee();pt(!i.loading);let a=i.all.find(e=>e.strategy_id===i.selectedId)??null;return(0,O.useEffect)(()=>{if(!i.selectedId)return;let e=e=>{e.key===`Escape`&&i.setSelectedId(null)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[i]),i.error?(0,k.jsx)(`div`,{style:{padding:`var(--space-7)`,fontFamily:`var(--mono)`,fontSize:`var(--fs-mono-md)`,color:`var(--danger)`,letterSpacing:`var(--tracking-mono)`,background:`var(--bg)`,minHeight:`100vh`},children:i.error}):(0,k.jsx)(dt,{list:i,lang:n,theme:r,selectedStrategy:a,onUpdateLang:e=>t(`lang`,e),onUpdateTheme:e=>{t(`theme`,e),t(`variation`,e===`dark`?`lab`:`atelier`)},onSelect:e=>i.setSelectedId(i.selectedId===e?null:e),onCloseSlidePanel:()=>i.setSelectedId(null)})}export{mt as BrowsePage};
|
|
2
|
+
//# sourceMappingURL=BrowsePage-CRD1NFN6.js.map
|