claude-code-workflow 7.2.27 → 7.2.29

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.
Files changed (416) hide show
  1. package/.ccw/specs/architecture-constraints.md +5 -0
  2. package/.claude/skills/_shared/SKILL-DESIGN-SPEC.md +140 -0
  3. package/.claude/skills/investigate/SKILL.md +110 -0
  4. package/.claude/skills/investigate/phases/01-root-cause-investigation.md +132 -0
  5. package/.claude/skills/investigate/phases/02-pattern-analysis.md +126 -0
  6. package/.claude/skills/investigate/phases/03-hypothesis-testing.md +177 -0
  7. package/.claude/skills/investigate/phases/04-implementation.md +139 -0
  8. package/.claude/skills/investigate/phases/05-verification-report.md +153 -0
  9. package/.claude/skills/investigate/specs/debug-report-format.md +226 -0
  10. package/.claude/skills/investigate/specs/iron-law.md +101 -0
  11. package/.claude/skills/security-audit/SKILL.md +125 -0
  12. package/.claude/skills/security-audit/phases/01-supply-chain-scan.md +139 -0
  13. package/.claude/skills/security-audit/phases/02-owasp-review.md +156 -0
  14. package/.claude/skills/security-audit/phases/03-threat-modeling.md +180 -0
  15. package/.claude/skills/security-audit/phases/04-report-tracking.md +177 -0
  16. package/.claude/skills/security-audit/specs/owasp-checklist.md +442 -0
  17. package/.claude/skills/security-audit/specs/scoring-gates.md +141 -0
  18. package/.claude/skills/ship/SKILL.md +105 -0
  19. package/.claude/skills/ship/phases/01-preflight-checks.md +121 -0
  20. package/.claude/skills/ship/phases/02-code-review.md +137 -0
  21. package/.claude/skills/ship/phases/03-version-bump.md +171 -0
  22. package/.claude/skills/ship/phases/04-changelog-commit.md +167 -0
  23. package/.claude/skills/ship/phases/05-pr-creation.md +163 -0
  24. package/.claude/skills/skill-generator/templates/sequential-phase.md +10 -0
  25. package/.claude/skills/skill-generator/templates/skill-md.md +4 -0
  26. package/.claude/skills/team-interactive-craft/SKILL.md +127 -0
  27. package/.claude/skills/team-interactive-craft/roles/a11y-tester/role.md +159 -0
  28. package/.claude/skills/team-interactive-craft/roles/builder/role.md +216 -0
  29. package/.claude/skills/team-interactive-craft/roles/coordinator/commands/analyze.md +71 -0
  30. package/.claude/skills/team-interactive-craft/roles/coordinator/commands/dispatch.md +192 -0
  31. package/.claude/skills/team-interactive-craft/roles/coordinator/commands/monitor.md +183 -0
  32. package/.claude/skills/team-interactive-craft/roles/coordinator/role.md +166 -0
  33. package/.claude/skills/team-interactive-craft/roles/interaction-designer/role.md +144 -0
  34. package/.claude/skills/team-interactive-craft/roles/researcher/role.md +131 -0
  35. package/.claude/skills/team-interactive-craft/specs/interaction-patterns.md +362 -0
  36. package/.claude/skills/team-interactive-craft/specs/pipelines.md +85 -0
  37. package/.claude/skills/team-interactive-craft/specs/team-config.json +105 -0
  38. package/.claude/skills/team-interactive-craft/specs/vanilla-constraints.md +83 -0
  39. package/.claude/skills/team-motion-design/SKILL.md +129 -0
  40. package/.claude/skills/team-motion-design/roles/animator/role.md +194 -0
  41. package/.claude/skills/team-motion-design/roles/choreographer/role.md +164 -0
  42. package/.claude/skills/team-motion-design/roles/coordinator/commands/analyze.md +64 -0
  43. package/.claude/skills/team-motion-design/roles/coordinator/commands/dispatch.md +203 -0
  44. package/.claude/skills/team-motion-design/roles/coordinator/commands/monitor.md +184 -0
  45. package/.claude/skills/team-motion-design/roles/coordinator/role.md +167 -0
  46. package/.claude/skills/team-motion-design/roles/motion-researcher/role.md +115 -0
  47. package/.claude/skills/team-motion-design/roles/motion-tester/role.md +175 -0
  48. package/.claude/skills/team-motion-design/specs/gpu-constraints.md +114 -0
  49. package/.claude/skills/team-motion-design/specs/motion-tokens.md +128 -0
  50. package/.claude/skills/team-motion-design/specs/pipelines.md +74 -0
  51. package/.claude/skills/team-motion-design/specs/reduced-motion.md +129 -0
  52. package/.claude/skills/team-motion-design/specs/team-config.json +99 -0
  53. package/.claude/skills/team-ui-polish/SKILL.md +127 -0
  54. package/.claude/skills/team-ui-polish/roles/coordinator/commands/analyze.md +77 -0
  55. package/.claude/skills/team-ui-polish/roles/coordinator/commands/dispatch.md +194 -0
  56. package/.claude/skills/team-ui-polish/roles/coordinator/commands/monitor.md +180 -0
  57. package/.claude/skills/team-ui-polish/roles/coordinator/role.md +170 -0
  58. package/.claude/skills/team-ui-polish/roles/diagnostician/role.md +160 -0
  59. package/.claude/skills/team-ui-polish/roles/optimizer/role.md +225 -0
  60. package/.claude/skills/team-ui-polish/roles/scanner/role.md +356 -0
  61. package/.claude/skills/team-ui-polish/roles/verifier/role.md +142 -0
  62. package/.claude/skills/team-ui-polish/specs/anti-patterns.md +141 -0
  63. package/.claude/skills/team-ui-polish/specs/design-standards.md +356 -0
  64. package/.claude/skills/team-ui-polish/specs/fix-strategies.md +235 -0
  65. package/.claude/skills/team-ui-polish/specs/pipelines.md +81 -0
  66. package/.claude/skills/team-ui-polish/specs/scoring-guide.md +162 -0
  67. package/.claude/skills/team-ui-polish/specs/team-config.json +73 -0
  68. package/.claude/skills/team-uidesign/SKILL.md +6 -1
  69. package/.claude/skills/team-uidesign/roles/designer/role.md +28 -4
  70. package/.claude/skills/team-uidesign/roles/implementer/role.md +25 -3
  71. package/.claude/skills/team-uidesign/roles/researcher/role.md +21 -2
  72. package/.claude/skills/team-uidesign/roles/reviewer/role.md +19 -17
  73. package/.claude/skills/team-uidesign/specs/anti-patterns.md +211 -0
  74. package/.claude/skills/team-uidesign/specs/design-standards.md +329 -0
  75. package/.claude/skills/team-uidesign/specs/scoring-guide.md +114 -0
  76. package/.claude/skills/team-uidesign/specs/team-config.json +1 -1
  77. package/.claude/skills/team-uidesign/specs/ux-writing.md +86 -0
  78. package/.claude/skills/team-ux-improve/SKILL.md +3 -0
  79. package/.claude/skills/team-ux-improve/roles/designer/role.md +30 -0
  80. package/.claude/skills/team-ux-improve/roles/diagnoser/role.md +16 -1
  81. package/.claude/skills/team-ux-improve/roles/scanner/role.md +43 -1
  82. package/.claude/skills/team-ux-improve/specs/anti-patterns.md +103 -0
  83. package/.claude/skills/team-ux-improve/specs/design-standards.md +54 -0
  84. package/.claude/skills/team-ux-improve/specs/heuristics.md +88 -0
  85. package/.claude/skills/team-ux-improve/wisdom/anti-patterns/common-ux-pitfalls.md +40 -8
  86. package/.claude/skills/team-ux-improve/wisdom/patterns/state-management.md +32 -12
  87. package/.claude/skills/team-ux-improve/wisdom/patterns/ui-feedback.md +35 -11
  88. package/.claude/skills/team-ux-improve/wisdom/principles/general-ux.md +36 -9
  89. package/.claude/skills/team-visual-a11y/SKILL.md +143 -0
  90. package/.claude/skills/team-visual-a11y/roles/color-auditor/role.md +178 -0
  91. package/.claude/skills/team-visual-a11y/roles/coordinator/commands/analyze.md +72 -0
  92. package/.claude/skills/team-visual-a11y/roles/coordinator/commands/dispatch.md +250 -0
  93. package/.claude/skills/team-visual-a11y/roles/coordinator/commands/monitor.md +204 -0
  94. package/.claude/skills/team-visual-a11y/roles/coordinator/role.md +169 -0
  95. package/.claude/skills/team-visual-a11y/roles/fix-implementer/role.md +246 -0
  96. package/.claude/skills/team-visual-a11y/roles/focus-auditor/role.md +222 -0
  97. package/.claude/skills/team-visual-a11y/roles/remediation-planner/role.md +206 -0
  98. package/.claude/skills/team-visual-a11y/roles/typo-auditor/role.md +185 -0
  99. package/.claude/skills/team-visual-a11y/specs/focus-patterns.md +325 -0
  100. package/.claude/skills/team-visual-a11y/specs/oklch-standards.md +130 -0
  101. package/.claude/skills/team-visual-a11y/specs/pipelines.md +98 -0
  102. package/.claude/skills/team-visual-a11y/specs/team-config.json +109 -0
  103. package/.claude/skills/team-visual-a11y/specs/typography-scale.md +165 -0
  104. package/.claude/skills/team-visual-a11y/specs/wcag-matrix.md +133 -0
  105. package/.codex/skills/brainstorm/SKILL.md +3 -3
  106. package/.codex/skills/clean/SKILL.md +3 -3
  107. package/.codex/skills/investigate/agents/investigator.md +392 -0
  108. package/.codex/skills/investigate/orchestrator.md +362 -0
  109. package/.codex/skills/investigate/phases/01-root-cause-investigation.md +212 -0
  110. package/.codex/skills/investigate/phases/02-pattern-analysis.md +181 -0
  111. package/.codex/skills/investigate/phases/03-hypothesis-testing.md +214 -0
  112. package/.codex/skills/investigate/phases/04-implementation.md +195 -0
  113. package/.codex/skills/investigate/phases/05-verification-report.md +240 -0
  114. package/.codex/skills/issue-discover/SKILL.md +13 -13
  115. package/.codex/skills/issue-discover/phases/02-discover.md +4 -4
  116. package/.codex/skills/issue-discover/phases/03-discover-by-prompt.md +3 -3
  117. package/.codex/skills/parallel-dev-cycle/SKILL.md +4 -4
  118. package/.codex/skills/parallel-dev-cycle/phases/02-agent-execution.md +6 -6
  119. package/.codex/skills/parallel-dev-cycle/phases/03-result-aggregation.md +10 -10
  120. package/.codex/skills/review-cycle/SKILL.md +10 -10
  121. package/.codex/skills/review-cycle/phases/02-parallel-review.md +6 -6
  122. package/.codex/skills/review-cycle/phases/04-iterative-deep-dive.md +4 -4
  123. package/.codex/skills/review-cycle/phases/07-fix-parallel-planning.md +4 -4
  124. package/.codex/skills/review-cycle/phases/08-fix-execution.md +2 -2
  125. package/.codex/skills/roadmap-with-file/SKILL.md +14 -14
  126. package/.codex/skills/security-audit/agents/security-auditor.md +341 -0
  127. package/.codex/skills/security-audit/orchestrator.md +384 -0
  128. package/.codex/skills/security-audit/phases/01-supply-chain-scan.md +226 -0
  129. package/.codex/skills/security-audit/phases/02-owasp-review.md +232 -0
  130. package/.codex/skills/security-audit/phases/03-threat-modeling.md +249 -0
  131. package/.codex/skills/security-audit/phases/04-report-tracking.md +300 -0
  132. package/.codex/skills/ship/agents/ship-operator.md +318 -0
  133. package/.codex/skills/ship/orchestrator.md +426 -0
  134. package/.codex/skills/ship/phases/01-preflight-checks.md +198 -0
  135. package/.codex/skills/ship/phases/02-code-review.md +228 -0
  136. package/.codex/skills/ship/phases/03-version-bump.md +259 -0
  137. package/.codex/skills/ship/phases/04-changelog-commit.md +263 -0
  138. package/.codex/skills/ship/phases/05-pr-creation.md +280 -0
  139. package/.codex/skills/spec-generator/README.md +1 -1
  140. package/.codex/skills/spec-generator/SKILL.md +184 -88
  141. package/.codex/skills/spec-generator/phases/01-5-requirement-clarification.md +4 -7
  142. package/.codex/skills/spec-generator/phases/01-discovery.md +30 -11
  143. package/.codex/skills/spec-generator/phases/02-product-brief.md +2 -5
  144. package/.codex/skills/spec-generator/phases/03-requirements.md +4 -6
  145. package/.codex/skills/spec-generator/phases/04-architecture.md +4 -6
  146. package/.codex/skills/spec-generator/phases/05-epics-stories.md +4 -6
  147. package/.codex/skills/spec-generator/phases/06-5-auto-fix.md +4 -5
  148. package/.codex/skills/spec-generator/phases/06-readiness-check.md +8 -8
  149. package/.codex/skills/spec-generator/phases/07-issue-export.md +2 -2
  150. package/.codex/skills/spec-setup/SKILL.md +4 -4
  151. package/.codex/skills/team-interactive-craft/SKILL.md +220 -0
  152. package/.codex/skills/team-interactive-craft/roles/a11y-tester/role.md +159 -0
  153. package/.codex/skills/team-interactive-craft/roles/builder/role.md +216 -0
  154. package/.codex/skills/team-interactive-craft/roles/coordinator/commands/analyze.md +71 -0
  155. package/.codex/skills/team-interactive-craft/roles/coordinator/commands/dispatch.md +162 -0
  156. package/.codex/skills/team-interactive-craft/roles/coordinator/commands/monitor.md +233 -0
  157. package/.codex/skills/team-interactive-craft/roles/coordinator/role.md +209 -0
  158. package/.codex/skills/team-interactive-craft/roles/interaction-designer/role.md +144 -0
  159. package/.codex/skills/team-interactive-craft/roles/researcher/role.md +131 -0
  160. package/.codex/skills/team-interactive-craft/specs/interaction-patterns.md +362 -0
  161. package/.codex/skills/team-interactive-craft/specs/pipelines.md +85 -0
  162. package/.codex/skills/team-interactive-craft/specs/team-config.json +105 -0
  163. package/.codex/skills/team-interactive-craft/specs/vanilla-constraints.md +83 -0
  164. package/.codex/skills/team-motion-design/SKILL.md +222 -0
  165. package/.codex/skills/team-motion-design/roles/animator/role.md +194 -0
  166. package/.codex/skills/team-motion-design/roles/choreographer/role.md +164 -0
  167. package/.codex/skills/team-motion-design/roles/coordinator/commands/analyze.md +64 -0
  168. package/.codex/skills/team-motion-design/roles/coordinator/commands/dispatch.md +168 -0
  169. package/.codex/skills/team-motion-design/roles/coordinator/commands/monitor.md +242 -0
  170. package/.codex/skills/team-motion-design/roles/coordinator/role.md +210 -0
  171. package/.codex/skills/team-motion-design/roles/motion-researcher/role.md +115 -0
  172. package/.codex/skills/team-motion-design/roles/motion-tester/role.md +175 -0
  173. package/.codex/skills/team-motion-design/specs/gpu-constraints.md +114 -0
  174. package/.codex/skills/team-motion-design/specs/motion-tokens.md +128 -0
  175. package/.codex/skills/team-motion-design/specs/pipelines.md +74 -0
  176. package/.codex/skills/team-motion-design/specs/reduced-motion.md +129 -0
  177. package/.codex/skills/team-motion-design/specs/team-config.json +99 -0
  178. package/.codex/skills/team-ui-polish/SKILL.md +218 -0
  179. package/.codex/skills/team-ui-polish/roles/coordinator/commands/analyze.md +77 -0
  180. package/.codex/skills/team-ui-polish/roles/coordinator/commands/dispatch.md +167 -0
  181. package/.codex/skills/team-ui-polish/roles/coordinator/commands/monitor.md +230 -0
  182. package/.codex/skills/team-ui-polish/roles/coordinator/role.md +213 -0
  183. package/.codex/skills/team-ui-polish/roles/diagnostician/role.md +164 -0
  184. package/.codex/skills/team-ui-polish/roles/optimizer/role.md +229 -0
  185. package/.codex/skills/team-ui-polish/roles/scanner/role.md +360 -0
  186. package/.codex/skills/team-ui-polish/roles/verifier/role.md +142 -0
  187. package/.codex/skills/team-ui-polish/specs/anti-patterns.md +141 -0
  188. package/.codex/skills/team-ui-polish/specs/design-standards.md +356 -0
  189. package/.codex/skills/team-ui-polish/specs/fix-strategies.md +235 -0
  190. package/.codex/skills/team-ui-polish/specs/pipelines.md +81 -0
  191. package/.codex/skills/team-ui-polish/specs/scoring-guide.md +162 -0
  192. package/.codex/skills/team-ui-polish/specs/team-config.json +73 -0
  193. package/.codex/skills/team-visual-a11y/SKILL.md +319 -0
  194. package/.codex/skills/team-visual-a11y/roles/color-auditor/role.md +178 -0
  195. package/.codex/skills/team-visual-a11y/roles/coordinator/commands/analyze.md +72 -0
  196. package/.codex/skills/team-visual-a11y/roles/coordinator/commands/dispatch.md +188 -0
  197. package/.codex/skills/team-visual-a11y/roles/coordinator/commands/monitor.md +281 -0
  198. package/.codex/skills/team-visual-a11y/roles/coordinator/role.md +213 -0
  199. package/.codex/skills/team-visual-a11y/roles/fix-implementer/role.md +246 -0
  200. package/.codex/skills/team-visual-a11y/roles/focus-auditor/role.md +222 -0
  201. package/.codex/skills/team-visual-a11y/roles/remediation-planner/role.md +206 -0
  202. package/.codex/skills/team-visual-a11y/roles/typo-auditor/role.md +185 -0
  203. package/.codex/skills/team-visual-a11y/specs/focus-patterns.md +325 -0
  204. package/.codex/skills/team-visual-a11y/specs/oklch-standards.md +130 -0
  205. package/.codex/skills/team-visual-a11y/specs/pipelines.md +98 -0
  206. package/.codex/skills/team-visual-a11y/specs/team-config.json +109 -0
  207. package/.codex/skills/team-visual-a11y/specs/typography-scale.md +165 -0
  208. package/.codex/skills/team-visual-a11y/specs/wcag-matrix.md +133 -0
  209. package/.codex/skills/workflow-plan/SKILL.md +6 -6
  210. package/.codex/skills/workflow-tdd-plan/SKILL.md +5 -5
  211. package/.codex/skills/workflow-test-fix-cycle/SKILL.md +19 -19
  212. package/.codex/skills/workflow-test-fix-cycle/phases/01-test-fix-gen.md +5 -5
  213. package/.codex/skills/workflow-test-fix-cycle/phases/02-test-cycle-execute.md +5 -5
  214. package/README.md +8 -0
  215. package/ccw/dist/core/hooks/hook-templates.d.ts.map +1 -1
  216. package/ccw/dist/core/hooks/hook-templates.js +114 -1
  217. package/ccw/dist/core/hooks/hook-templates.js.map +1 -1
  218. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  219. package/ccw/dist/core/routes/cli-routes.js +34 -0
  220. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  221. package/ccw/dist/core/routes/system-routes.js +2 -2
  222. package/ccw/dist/core/routes/system-routes.js.map +1 -1
  223. package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js → AlertDialog-exlTDW81.js} +3 -3
  224. package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js.map → AlertDialog-exlTDW81.js.map} +1 -1
  225. package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js → AnalysisPage-cgV9LfAI.js} +2 -2
  226. package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js.map → AnalysisPage-cgV9LfAI.js.map} +1 -1
  227. package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js → ApiSettingsPage-Dk5jJdWt.js} +2 -2
  228. package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js.map → ApiSettingsPage-Dk5jJdWt.js.map} +1 -1
  229. package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js → CliModeToggle-Be9xsPiv.js} +2 -2
  230. package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js.map → CliModeToggle-Be9xsPiv.js.map} +1 -1
  231. package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js → CliSessionSharePage-Bh9jBtPI.js} +2 -2
  232. package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js.map → CliSessionSharePage-Bh9jBtPI.js.map} +1 -1
  233. package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js → CliViewerPage-BrE-oyEq.js} +2 -2
  234. package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js.map → CliViewerPage-BrE-oyEq.js.map} +1 -1
  235. package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js → CodexLensPage-Cd3nrC93.js} +2 -2
  236. package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js.map → CodexLensPage-Cd3nrC93.js.map} +1 -1
  237. package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js → Collapsible-DXFl3VKF.js} +2 -2
  238. package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js.map → Collapsible-DXFl3VKF.js.map} +1 -1
  239. package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js → CommandsManagerPage-IV8zpjgX.js} +2 -2
  240. package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js.map → CommandsManagerPage-IV8zpjgX.js.map} +1 -1
  241. package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js → DeepWikiPage-CpDxtmRX.js} +2 -2
  242. package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js.map → DeepWikiPage-CpDxtmRX.js.map} +1 -1
  243. package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js → EndpointsPage-BchjWe7s.js} +2 -2
  244. package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js.map → EndpointsPage-BchjWe7s.js.map} +1 -1
  245. package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js → ExplorerPage-CbWvaJ0y.js} +2 -2
  246. package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js.map → ExplorerPage-CbWvaJ0y.js.map} +1 -1
  247. package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js → FixSessionPage-YMjVRiCk.js} +2 -2
  248. package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js.map → FixSessionPage-YMjVRiCk.js.map} +1 -1
  249. package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js → FloatingFileBrowser-JW2ehYY_.js} +2 -2
  250. package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js.map → FloatingFileBrowser-JW2ehYY_.js.map} +1 -1
  251. package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js → FloatingPanel-BtqzqDVq.js} +2 -2
  252. package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js.map → FloatingPanel-BtqzqDVq.js.map} +1 -1
  253. package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js → GraphExplorerPage-BsJL_W4d.js} +3 -3
  254. package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js.map → GraphExplorerPage-BsJL_W4d.js.map} +1 -1
  255. package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js → HistoryPage-BuWpQ7k5.js} +2 -2
  256. package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js.map → HistoryPage-BuWpQ7k5.js.map} +1 -1
  257. package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js → HookManagerPage-D0BtMIWy.js} +2 -2
  258. package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js.map → HookManagerPage-D0BtMIWy.js.map} +1 -1
  259. package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js → InstallationsPage-C7dwsAKG.js} +2 -2
  260. package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js.map → InstallationsPage-C7dwsAKG.js.map} +1 -1
  261. package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js → IssueHubPage-D0nCNaeB.js} +2 -2
  262. package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js.map → IssueHubPage-D0nCNaeB.js.map} +1 -1
  263. package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js → LiteTasksPage-B5c2Kb9r.js} +3 -3
  264. package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js.map → LiteTasksPage-B5c2Kb9r.js.map} +1 -1
  265. package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js → McpManagerPage-C-S5CehM.js} +2 -2
  266. package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js.map → McpManagerPage-C-S5CehM.js.map} +1 -1
  267. package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js → MemoryPage-P_B0JVUQ.js} +2 -2
  268. package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js.map → MemoryPage-P_B0JVUQ.js.map} +1 -1
  269. package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js → NotFoundPage-S4Jn9LUE.js} +2 -2
  270. package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js.map → NotFoundPage-S4Jn9LUE.js.map} +1 -1
  271. package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js → OrchestratorPage-C2Zlr7AC.js} +2 -2
  272. package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js.map → OrchestratorPage-C2Zlr7AC.js.map} +1 -1
  273. package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js → ProjectOverviewPage-CMVfz8s5.js} +2 -2
  274. package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js.map → ProjectOverviewPage-CMVfz8s5.js.map} +1 -1
  275. package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js → PromptHistoryPage-YEMjFARX.js} +3 -3
  276. package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js.map → PromptHistoryPage-YEMjFARX.js.map} +1 -1
  277. package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js → ReviewSessionPage-DnTm55nG.js} +2 -2
  278. package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js.map → ReviewSessionPage-DnTm55nG.js.map} +1 -1
  279. package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js → RulesManagerPage-CUwebtO2.js} +2 -2
  280. package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js.map → RulesManagerPage-CUwebtO2.js.map} +1 -1
  281. package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js → SessionDetailPage-0qyH1Z5P.js} +2 -2
  282. package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js.map → SessionDetailPage-0qyH1Z5P.js.map} +1 -1
  283. package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js → SessionsPage-BpgP4087.js} +2 -2
  284. package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js.map → SessionsPage-BpgP4087.js.map} +1 -1
  285. package/ccw/frontend/dist/assets/SettingsPage-C3SJajeT.js +150 -0
  286. package/ccw/frontend/dist/assets/SettingsPage-C3SJajeT.js.map +1 -0
  287. package/ccw/frontend/dist/assets/SkillsManagerPage-vD9PTsmy.js +7 -0
  288. package/ccw/frontend/dist/assets/SkillsManagerPage-vD9PTsmy.js.map +1 -0
  289. package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js → SpecsSettingsPage-DT-yTVkD.js} +4 -4
  290. package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js.map → SpecsSettingsPage-DT-yTVkD.js.map} +1 -1
  291. package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js → Switch-CYSPdqWk.js} +2 -2
  292. package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js.map → Switch-CYSPdqWk.js.map} +1 -1
  293. package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js → TabsNavigation-CPh6Zor1.js} +2 -2
  294. package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js.map → TabsNavigation-CPh6Zor1.js.map} +1 -1
  295. package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js → TaskDrawer-Ds-8830B.js} +2 -2
  296. package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js.map → TaskDrawer-Ds-8830B.js.map} +1 -1
  297. package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js → TeamPage-CJODUxBk.js} +2 -2
  298. package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js.map → TeamPage-CJODUxBk.js.map} +1 -1
  299. package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js → TerminalDashboardPage-Cn3fGUuO.js} +3 -3
  300. package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js.map → TerminalDashboardPage-Cn3fGUuO.js.map} +1 -1
  301. package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js → archive-CjwVpw6k.js} +2 -2
  302. package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js.map → archive-CjwVpw6k.js.map} +1 -1
  303. package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js → archive-restore-2vZa9Ic3.js} +2 -2
  304. package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js.map → archive-restore-2vZa9Ic3.js.map} +1 -1
  305. package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js → arrow-right-CUU5XDgT.js} +2 -2
  306. package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js.map → arrow-right-CUU5XDgT.js.map} +1 -1
  307. package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js → bookmark-plus-Cc3nKRZ5.js} +2 -2
  308. package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js.map → bookmark-plus-Cc3nKRZ5.js.map} +1 -1
  309. package/ccw/frontend/dist/assets/{bot-BLkaQscs.js → bot-BwpSRDUa.js} +2 -2
  310. package/ccw/frontend/dist/assets/{bot-BLkaQscs.js.map → bot-BwpSRDUa.js.map} +1 -1
  311. package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js → braces-DBzUW1XC.js} +2 -2
  312. package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js.map → braces-DBzUW1XC.js.map} +1 -1
  313. package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js → circle-stop-CGNNsjvE.js} +2 -2
  314. package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js.map → circle-stop-CGNNsjvE.js.map} +1 -1
  315. package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js → cpu-D27G86Ul.js} +2 -2
  316. package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js.map → cpu-D27G86Ul.js.map} +1 -1
  317. package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js → ellipsis-vertical-C1Ij47Yz.js} +2 -2
  318. package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js.map → ellipsis-vertical-C1Ij47Yz.js.map} +1 -1
  319. package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js → eye-C6MOB7Au.js} +2 -2
  320. package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js.map → eye-C6MOB7Au.js.map} +1 -1
  321. package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js → eye-off-BxfBlZ26.js} +2 -2
  322. package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js.map → eye-off-BxfBlZ26.js.map} +1 -1
  323. package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js → file-json-NI237wA-.js} +2 -2
  324. package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js.map → file-json-NI237wA-.js.map} +1 -1
  325. package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js → file-text-Byn2_2v6.js} +2 -2
  326. package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js.map → file-text-Byn2_2v6.js.map} +1 -1
  327. package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js → filter-D-7PhZjx.js} +2 -2
  328. package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js.map → filter-D-7PhZjx.js.map} +1 -1
  329. package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js → folder-BoAsK_FL.js} +2 -2
  330. package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js.map → folder-BoAsK_FL.js.map} +1 -1
  331. package/ccw/frontend/dist/assets/{gauge-kazFexTr.js → gauge-DCSxJIS4.js} +2 -2
  332. package/ccw/frontend/dist/assets/{gauge-kazFexTr.js.map → gauge-DCSxJIS4.js.map} +1 -1
  333. package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js → globe-CHS3prza.js} +2 -2
  334. package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js.map → globe-CHS3prza.js.map} +1 -1
  335. package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js → grid-3x3-D7K35U7S.js} +2 -2
  336. package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js.map → grid-3x3-D7K35U7S.js.map} +1 -1
  337. package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js → hard-drive-eq9xE07G.js} +2 -2
  338. package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js.map → hard-drive-eq9xE07G.js.map} +1 -1
  339. package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js → hash-C1DMpBua.js} +2 -2
  340. package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js.map → hash-C1DMpBua.js.map} +1 -1
  341. package/ccw/frontend/dist/assets/{history-ujQnmMC9.js → history-Di5SBCY-.js} +2 -2
  342. package/ccw/frontend/dist/assets/{history-ujQnmMC9.js.map → history-Di5SBCY-.js.map} +1 -1
  343. package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js → index--_R7COnA.js} +2 -2
  344. package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js.map → index--_R7COnA.js.map} +1 -1
  345. package/ccw/frontend/dist/assets/{index-Dff4bg3u.js → index-BUol9HDD.js} +3 -3
  346. package/ccw/frontend/dist/assets/{index-Dff4bg3u.js.map → index-BUol9HDD.js.map} +1 -1
  347. package/ccw/frontend/dist/assets/{index-B76AGix5.js → index-CT9oykfw.js} +2 -2
  348. package/ccw/frontend/dist/assets/{index-B76AGix5.js.map → index-CT9oykfw.js.map} +1 -1
  349. package/ccw/frontend/dist/assets/{index-CxzXz6o1.js → index-Ddwvf87H.js} +2 -2
  350. package/ccw/frontend/dist/assets/{index-CxzXz6o1.js.map → index-Ddwvf87H.js.map} +1 -1
  351. package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js → layout-grid-LiX0qZbN.js} +2 -2
  352. package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js.map → layout-grid-LiX0qZbN.js.map} +1 -1
  353. package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js → lightbulb-CL3DVEwb.js} +2 -2
  354. package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js.map → lightbulb-CL3DVEwb.js.map} +1 -1
  355. package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js → link-2-CC5cFeq6.js} +2 -2
  356. package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js.map → link-2-CC5cFeq6.js.map} +1 -1
  357. package/ccw/frontend/dist/assets/{link-5yXdZBch.js → link-ngFQ9bs0.js} +2 -2
  358. package/ccw/frontend/dist/assets/{link-5yXdZBch.js.map → link-ngFQ9bs0.js.map} +1 -1
  359. package/ccw/frontend/dist/assets/{list-9lHhC_U_.js → list-BEU6I0KK.js} +2 -2
  360. package/ccw/frontend/dist/assets/{list-9lHhC_U_.js.map → list-BEU6I0KK.js.map} +1 -1
  361. package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js → map-pin-BWZdLA6y.js} +2 -2
  362. package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js.map → map-pin-BWZdLA6y.js.map} +1 -1
  363. package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js → messages-square-K6_Chm7n.js} +2 -2
  364. package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js.map → messages-square-K6_Chm7n.js.map} +1 -1
  365. package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js → minimize-2-CWkphauf.js} +2 -2
  366. package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js.map → minimize-2-CWkphauf.js.map} +1 -1
  367. package/ccw/frontend/dist/assets/{package-BjOw1ldU.js → package-DrNgkamn.js} +2 -2
  368. package/ccw/frontend/dist/assets/{package-BjOw1ldU.js.map → package-DrNgkamn.js.map} +1 -1
  369. package/ccw/frontend/dist/assets/{plug-9dAARpE1.js → plug-CMo3sw5_.js} +2 -2
  370. package/ccw/frontend/dist/assets/{plug-9dAARpE1.js.map → plug-CMo3sw5_.js.map} +1 -1
  371. package/ccw/frontend/dist/assets/{power-K2S39x7f.js → power-DppNTW5e.js} +2 -2
  372. package/ccw/frontend/dist/assets/{power-K2S39x7f.js.map → power-DppNTW5e.js.map} +1 -1
  373. package/ccw/frontend/dist/assets/{save-D9-CoT3x.js → save-CD8aPMbZ.js} +2 -2
  374. package/ccw/frontend/dist/assets/{save-D9-CoT3x.js.map → save-CD8aPMbZ.js.map} +1 -1
  375. package/ccw/frontend/dist/assets/{send-Bunw9NtC.js → send-B4z90fQD.js} +2 -2
  376. package/ccw/frontend/dist/assets/{send-Bunw9NtC.js.map → send-B4z90fQD.js.map} +1 -1
  377. package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js → settings-2-CAKRU_QC.js} +2 -2
  378. package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js.map → settings-2-CAKRU_QC.js.map} +1 -1
  379. package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js → square-check-big-KhI3HrzX.js} +2 -2
  380. package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js.map → square-check-big-KhI3HrzX.js.map} +1 -1
  381. package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js → square-pen-BtdGIpuq.js} +2 -2
  382. package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js.map → square-pen-BtdGIpuq.js.map} +1 -1
  383. package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js → star-ZoBUkXoD.js} +2 -2
  384. package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js.map → star-ZoBUkXoD.js.map} +1 -1
  385. package/ccw/frontend/dist/assets/{style-BbREPmRj.js → style-CltxQP-P.js} +2 -2
  386. package/ccw/frontend/dist/assets/{style-BbREPmRj.js.map → style-CltxQP-P.js.map} +1 -1
  387. package/ccw/frontend/dist/assets/{target-CElrCVhR.js → target-C32OUSGf.js} +2 -2
  388. package/ccw/frontend/dist/assets/{target-CElrCVhR.js.map → target-C32OUSGf.js.map} +1 -1
  389. package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js → test-tube-0IxoyAVZ.js} +2 -2
  390. package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js.map → test-tube-0IxoyAVZ.js.map} +1 -1
  391. package/ccw/frontend/dist/assets/{upload-BD1F07wG.js → upload-4eKCkyBn.js} +2 -2
  392. package/ccw/frontend/dist/assets/{upload-BD1F07wG.js.map → upload-4eKCkyBn.js.map} +1 -1
  393. package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js → useApiSettings-zLTUWqhi.js} +2 -2
  394. package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js.map → useApiSettings-zLTUWqhi.js.map} +1 -1
  395. package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js → useCli-BtN2vpOX.js} +2 -2
  396. package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js.map → useCli-BtN2vpOX.js.map} +1 -1
  397. package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js → useCommands-_spj49qL.js} +2 -2
  398. package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js.map → useCommands-_spj49qL.js.map} +1 -1
  399. package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js → useDebounce-Bm9KFZvd.js} +2 -2
  400. package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js.map → useDebounce-Bm9KFZvd.js.map} +1 -1
  401. package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js → useFileExplorer-DOmpm6v9.js} +2 -2
  402. package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js.map → useFileExplorer-DOmpm6v9.js.map} +1 -1
  403. package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js → useLocale-D2rj4rea.js} +2 -2
  404. package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js.map → useLocale-D2rj4rea.js.map} +1 -1
  405. package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js → useSkills-OskEpomF.js} +3 -3
  406. package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js.map → useSkills-OskEpomF.js.map} +1 -1
  407. package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js → useSystemSettings-BjMgsNSF.js} +2 -2
  408. package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js.map → useSystemSettings-BjMgsNSF.js.map} +1 -1
  409. package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js → wand-sparkles-CLhyYWa7.js} +2 -2
  410. package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js.map → wand-sparkles-CLhyYWa7.js.map} +1 -1
  411. package/ccw/frontend/dist/index.html +1 -1
  412. package/package.json +105 -105
  413. package/ccw/frontend/dist/assets/SettingsPage-BPDbXPSM.js +0 -150
  414. package/ccw/frontend/dist/assets/SettingsPage-BPDbXPSM.js.map +0 -1
  415. package/ccw/frontend/dist/assets/SkillsManagerPage-D3LzbpJY.js +0 -7
  416. package/ccw/frontend/dist/assets/SkillsManagerPage-D3LzbpJY.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"mappings":";y5CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,GAAUC,GAAiB,UAAW,CAC1C,CAAC,OAAQ,CAAE,EAAG,6CAA8C,IAAK,QAAQ,CAAE,EAC3E,CAAC,OAAQ,CAAE,EAAG,0CAA2C,IAAK,QAAQ,CAAE,EACxE,CAAC,OAAQ,CAAE,EAAG,iCAAkC,IAAK,QAAQ,CAAE,EAC/D,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC,ECdD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,GAAgBD,GAAiB,gBAAiB,CACtD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,SAAU,EACzD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,EAC/C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAME,GAAYF,GAAiB,YAAa,CAC9C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAQ,CAAE,EAC9C,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,SAAU,IAAK,QAAQ,CAAE,EACvC,CAAC,OAAQ,CAAE,EAAG,mBAAoB,IAAK,QAAQ,CAAE,EACjD,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC,EChBD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMG,GAAkBH,GAAiB,kBAAmB,CAC1D,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,KAAM,EAAG,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,OAAO,CAAE,EAC5E,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,KAAM,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC7E,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,KAAM,EAAG,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,CAChF,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMI,GAAoBJ,GAAiB,oBAAqB,CAC9D,CAAC,OAAQ,CAAE,EAAG,gEAAiE,IAAK,QAAQ,CAAE,EAC9F,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMK,GAAUL,GAAiB,UAAW,CAC1C,CACE,OACA,CACE,EAAG,2KACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,sBAAuB,IAAK,QAAQ,CAAE,EACpD,CAAC,OAAQ,CAAE,EAAG,oCAAqC,IAAK,QAAQ,CAAE,CACpE,CAAC,ECID,SAASM,IAA8B,CACrC,MAAMC,EAAQ,SAAS,OAAO,MAAM,oBAAoB,EACxD,OAAOA,EAAQ,mBAAmBA,EAAM,CAAC,CAAC,EAAI,IAChD,CAKA,eAAsBC,GACpBC,EACAC,EAAO,EACPC,EAAU,GACqB,CAC/B,MAAMC,EAAS,IAAI,gBAAgB,CACjC,MAAAH,EACA,KAAM,OAAOC,CAAI,EACjB,SAAU,OAAOC,CAAO,EACzB,EAEKE,EAAW,MAAM,MAAM,wBAAwBD,CAAM,GAAI,CAC7D,YAAa,cACd,EAED,GAAI,CAACC,EAAS,GAAI,CAChB,MAAMC,EAAO,MAAMD,EAAS,OAAO,MAAM,KAAO,GAAG,EACnD,MAAM,IAAI,MAAMC,EAAK,OAAS,2BAA2BD,EAAS,MAAM,EAAE,CAC5E,CAEA,OAAOA,EAAS,MAClB,CAMA,eAAsBE,GAAsBC,EAAwD,CAClG,MAAMC,EAAkC,CACtC,eAAgBD,EAAK,KACrB,aAAc,mBAAmBA,EAAK,IAAI,GAEtCE,EAAYZ,GAAA,EACdY,IACFD,EAAQ,cAAc,EAAIC,GAG5B,MAAML,EAAW,MAAM,MAAM,yBAA0B,CACrD,OAAQ,OACR,QAAAI,EACA,YAAa,cACb,KAAMD,CAAA,CACP,EAED,GAAI,CAACH,EAAS,GAAI,CAChB,MAAMC,EAAO,MAAMD,EAAS,OAAO,MAAM,KAAO,GAAG,EACnD,MAAM,IAAI,MAAMC,EAAK,OAAS,kBAAkBD,EAAS,MAAM,EAAE,CACnE,CAEA,OAAOA,EAAS,MAClB,CAKA,eAAsBM,GAAwBC,EAAyC,CACrF,MAAMH,EAAkC,CACtC,eAAgB,oBAEZC,EAAYZ,GAAA,EACdY,IACFD,EAAQ,cAAc,EAAIC,GAG5B,MAAM,MAAM,yBAA0B,CACpC,OAAQ,OACR,QAAAD,EACA,YAAa,cACb,KAAM,KAAK,UAAU,CAAE,iBAAAG,EAAkB,EAC1C,CACH,CC7FO,SAASC,GAAkBZ,EAAeC,EAAO,EAAGC,EAAU,GAAI,CACvE,KAAM,CAACW,EAAgBC,CAAiB,EAAIC,WAASf,CAAK,EAE1DgB,mBAAU,IAAM,CACd,MAAMC,EAAQ,WAAW,IAAM,CAC7BH,EAAkBd,CAAK,CACzB,EAAG,GAAG,EACN,MAAO,IAAM,aAAaiB,CAAK,CACjC,EAAG,CAACjB,CAAK,CAAC,EAEHkB,GAA+B,CACpC,SAAU,CAAC,kBAAmBL,EAAgBZ,EAAMC,CAAO,EAC3D,QAAS,IAAMH,GAAec,EAAgBZ,EAAMC,CAAO,EAC3D,QAASW,EAAe,OAAO,OAAS,EACxC,UAAW,IAAS,IACpB,MAAO,EACR,CACH,CCjBA,MAAMM,GAAsD,CAC1D,CAAE,MAAO,gBAAiB,QAAS,sCACnC,CAAE,MAAO,aAAc,QAAS,mCAChC,CAAE,MAAO,iBAAkB,QAAS,sCACtC,EAOO,SAASC,IAAwB,CACtC,KAAM,CAAE,cAAAC,CAAA,EAAkBC,EAAA,EACpB,CACJ,iBAAAC,EACA,kBAAAC,EACA,mBAAAC,EACA,uBAAAC,CAAA,EACEC,GAAA,EAEE,CAACC,EAAaC,CAAc,EAAId,WAAS,EAAE,EAC3C,CAACd,EAAM6B,CAAO,EAAIf,WAAS,CAAC,EAC5B,CAACgB,EAAWC,CAAY,EAAIjB,WAAS,EAAE,EACvC,CAACkB,EAAaC,CAAc,EAAInB,WAAS,EAAK,EAC9C,CAACoB,EAAaC,CAAc,EAAIrB,WAAwB,IAAI,EAC5DsB,EAAeC,SAAyB,IAAI,EAE5C,CAAE,KAAAC,EAAM,UAAAC,EAAW,QAAAC,EAAS,MAAAC,GAAU9B,GAAkBgB,EAAa3B,CAAI,EAEzE0C,EAAoBpB,EAAiB,OAAS,gBAE9CqB,EAAoBC,cAAY,MAAOC,GAAyB,CACpErB,EAAmBqB,EAAM,WAAY,CACnC,iBAAkBA,EAAM,aACxB,gBAAiBA,EAAM,gBACvB,SAAUA,EAAM,SACjB,EAEDpC,GAAwBoC,EAAM,gBAAgB,EAAE,MAAM,IAAM,CAAC,CAAC,CAChE,EAAG,CAACrB,CAAkB,CAAC,EAEjBsB,EAAuBF,cAAY,IAAM,CACzCd,EAAU,SACZN,EAAmBM,EAAU,OAAQ,IAAI,EACzCC,EAAa,EAAE,EAEnB,EAAG,CAACD,EAAWN,CAAkB,CAAC,EAE5BuB,EAAoBH,cAAY,IAAM,CAC1CpB,EAAmB,KAAM,IAAI,CAC/B,EAAG,CAACA,CAAkB,CAAC,EAEjBwB,EAAmBJ,cAAY,MAAOK,GAA2C,OACrF,MAAM3C,GAAO4C,EAAAD,EAAE,OAAO,QAAT,YAAAC,EAAiB,GAC9B,GAAK5C,EAOL,IAJA2C,EAAE,OAAO,MAAQ,GAEjBd,EAAe,IAAI,EAEf7B,EAAK,KAAO,GAAK,KAAO,KAAM,CAChC6B,EAAef,EAAc,CAAE,GAAI,gCAAiC,CAAC,EACrE,MACF,CAEA,GAAI,CAACd,EAAK,KAAK,WAAW,QAAQ,GAAK,CAAC,CAAC,aAAc,YAAa,aAAc,WAAW,EAAE,SAASA,EAAK,IAAI,EAAG,CAClH6B,EAAef,EAAc,CAAE,GAAI,+BAAgC,CAAC,EACpE,MACF,CAEAa,EAAe,EAAI,EACnB,GAAI,CACF,MAAMkB,EAAS,MAAM9C,GAAsBC,CAAI,EAC/CkB,EAAmB2B,EAAO,IAAK,IAAI,CACrC,OAASC,EAAK,CACZjB,EAAgBiB,EAAc,SAAWhC,EAAc,CAAE,GAAI,+BAAgC,CAAC,CAChG,SACEa,EAAe,EAAK,CACtB,EACF,EAAG,CAACb,EAAeI,CAAkB,CAAC,EAEtC,OACE6B,OAAC,OAAI,UAAU,YAEb,UAAAC,MAAC,MAAG,UAAU,gCACX,SAAAlC,EAAc,CAAE,GAAI,yBAA0B,EACjD,EAGAkC,MAAC,OACC,UAAU,aACV,KAAK,aACL,aAAYlC,EAAc,CAAE,GAAI,yBAA0B,EAEzD,YAAM,IAAI,CAAC,CAAE,MAAAmC,EAAO,QAAAC,KACnBF,MAAC,UAEC,QAAS,IAAM/B,EAAkBgC,CAAK,EACtC,KAAK,QACL,eAAcjC,EAAiB,OAASiC,EACxC,UAAW;AAAA;AAAA;AAAA,gBAGPjC,EAAiB,OAASiC,EACxB,qCACA,sCACJ;AAAA;AAAA,cAID,SAAAnC,EAAc,CAAE,GAAIoC,CAAA,CAAS,GAdzBD,CAAA,CAgBR,IAIFb,GACCW,OAAC,OAAI,UAAU,YAEZ,UAAA/B,EAAiB,UAChB+B,OAAC,OAAI,UAAU,2DACb,UAAAC,MAAC,OACC,IAAKhC,EAAiB,SACtB,IAAI,qBACJ,UAAU,6BAEZgC,MAAC,UACC,QAASP,EACT,UAAU,8GAET,SAAA3B,EAAc,CAAE,GAAI,+BAAgC,IAGtDE,EAAiB,aAChB+B,OAAC,OAAI,UAAU,4EAA4E,qBAChF,IACTC,MAAC,KACC,KAAM,GAAGhC,EAAiB,YAAY,eAAe,sCACrD,OAAO,SACP,IAAI,sBACJ,UAAU,YAET,WAAiB,YAAY,mBAC3B,IAAI,KACN,IACHgC,MAAC,KACC,KAAK,2DACL,OAAO,SACP,IAAI,sBACJ,UAAU,YACX,qBAED,EACF,GAEJ,EAIFA,MAAC,SACC,KAAK,OACL,MAAO3B,EACP,SAAWsB,GAAM,CAAErB,EAAeqB,EAAE,OAAO,KAAK,EAAGpB,EAAQ,CAAC,CAAG,EAC/D,YAAaT,EAAc,CAAE,GAAI,qCAAsC,EACvE,UAAU;AAAA,uFAKXmB,SACE,OAAI,UAAU,2BACb,SAAAe,MAAC,OAAI,UAAU,2EAA2E,EAC5F,EAGDd,GACCc,MAAC,KAAE,UAAU,gCACT,UAAAb,GAAA,YAAAA,EAAiB,UAAWrB,EAAc,CAAE,GAAI,+BAAgC,EACpF,EAGDkB,GAAQA,EAAK,OAAO,OAAS,GAC5Be,OAAAI,WAAA,CACE,UAAAH,MAAC,OAAI,UAAU,kDACZ,WAAK,OAAO,IAAKT,GAChBS,MAAC,UAEC,QAAS,IAAMX,EAAkBE,CAAK,EACtC,UAAW;AAAA;AAAA;AAAA,wBAGPvB,EAAiB,WAAauB,EAAM,WAClC,mCACA,oBACJ;AAAA,sBAGF,SAAAS,MAAC,OACC,IAAKT,EAAM,SACX,IAAK,YAAYA,EAAM,YAAY,GACnC,UAAU,2BACV,QAAQ,QACV,EAhBKA,EAAM,GAkBd,EACH,EAGCP,EAAK,WAAa,GACjBe,OAAC,OAAI,UAAU,oCACb,UAAAC,MAAC,UACC,QAAS,IAAMzB,EAAS6B,GAAM,KAAK,IAAI,EAAGA,EAAI,CAAC,CAAC,EAChD,SAAU1D,GAAQ,EAClB,UAAU,sFAET,SAAAoB,EAAc,CAAE,GAAI,wBAAyB,IAEhDiC,OAAC,QAAK,UAAU,8BACb,UAAArD,EAAK,MAAIsC,EAAK,YACjB,EACAgB,MAAC,UACC,QAAS,IAAMzB,EAAS6B,GAAM,KAAK,IAAIpB,EAAK,WAAYoB,EAAI,CAAC,CAAC,EAC9D,SAAU1D,GAAQsC,EAAK,WACvB,UAAU,sFAET,SAAAlB,EAAc,CAAE,GAAI,wBAAyB,GAChD,EACF,GAEJ,EAGDkB,GAAQA,EAAK,OAAO,SAAW,GAAKX,EAAY,QAC/C2B,MAAC,KAAE,UAAU,+CACV,SAAAlC,EAAc,CAAE,GAAI,6BAA8B,EACrD,EAIFiC,OAAC,OAAI,UAAU,aACb,UAAAC,MAAC,SACC,KAAK,MACL,MAAOxB,EACP,SAAWmB,GAAMlB,EAAakB,EAAE,OAAO,KAAK,EAC5C,YAAa7B,EAAc,CAAE,GAAI,wCAAyC,EAC1E,UAAU;AAAA,yFAGZkC,MAAC,UACC,QAASR,EACT,SAAU,CAAChB,EAAU,OACrB,UAAU,4GAET,SAAAV,EAAc,CAAE,GAAI,yBAA0B,GACjD,EACF,EAGAiC,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,SACC,IAAKlB,EACL,KAAK,OACL,OAAO,4CACP,SAAUY,EACV,UAAU,WAEZM,MAAC,UACC,QAAS,WAAM,OAAAJ,EAAAd,EAAa,UAAb,YAAAc,EAAsB,SACrC,SAAUlB,EACV,UAAU;AAAA;AAAA,2FAIT,WACCqB,OAAAI,WAAA,CACE,UAAAH,MAAC,OAAI,UAAU,+EAA+E,EAC7FlC,EAAc,CAAE,GAAI,6BAA8B,GACrD,EAEAA,EAAc,CAAE,GAAI,0BAA2B,IAGlDc,GACCoB,MAAC,KAAE,UAAU,2BAA4B,SAAApB,CAAA,CAAY,GAEzD,GACF,EAIDQ,GACCW,OAAC,OAAI,UAAU,wCACb,UAAAC,MAAC,MAAG,UAAU,0CACX,SAAAlC,EAAc,CAAE,GAAI,2BAA4B,EACnD,EAGAiC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,uBACb,UAAAC,MAAC,SAAM,UAAU,oBACd,SAAAlC,EAAc,CAAE,GAAI,wBAAyB,EAChD,EACAiC,OAAC,QAAK,UAAU,8BAA+B,UAAA/B,EAAiB,QAAQ,KAAK,MAAE,GACjF,EACAgC,MAAC,SACC,KAAK,QACL,IAAI,IACJ,IAAI,KACJ,KAAK,IACL,MAAOhC,EAAiB,QAAQ,KAChC,SAAW2B,GAAMxB,EAAuB,OAAQ,OAAOwB,EAAE,OAAO,KAAK,CAAC,EACtE,UAAU,sCACZ,EACF,EAGAI,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,uBACb,UAAAC,MAAC,SAAM,UAAU,oBACd,SAAAlC,EAAc,CAAE,GAAI,0BAA2B,EAClD,EACAiC,OAAC,QAAK,UAAU,8BAA+B,UAAA/B,EAAiB,QAAQ,cAAc,KAAC,GACzF,EACAgC,MAAC,SACC,KAAK,QACL,IAAI,IACJ,IAAI,KACJ,KAAK,IACL,MAAOhC,EAAiB,QAAQ,cAChC,SAAW2B,GAAMxB,EAAuB,gBAAiB,OAAOwB,EAAE,OAAO,KAAK,CAAC,EAC/E,UAAU,sCACZ,EACF,EAGAI,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,uBACb,UAAAC,MAAC,SAAM,UAAU,oBACd,SAAAlC,EAAc,CAAE,GAAI,8BAA+B,EACtD,EACAiC,OAAC,QAAK,UAAU,8BAA+B,UAAA/B,EAAiB,QAAQ,WAAW,KAAC,GACtF,EACAgC,MAAC,SACC,KAAK,QACL,IAAI,IACJ,IAAI,MACJ,KAAK,IACL,MAAOhC,EAAiB,QAAQ,WAChC,SAAW2B,GAAMxB,EAAuB,aAAc,OAAOwB,EAAE,OAAO,KAAK,CAAC,EAC5E,UAAU,sCACZ,EACF,EAGAI,OAAC,SAAM,UAAU,yCACf,UAAAC,MAAC,SACC,KAAK,WACL,QAAShC,EAAiB,QAAQ,mBAClC,SAAW2B,GAAMxB,EAAuB,qBAAsBwB,EAAE,OAAO,OAAO,EAC9E,UAAU,iGAEZK,MAAC,QAAK,UAAU,oBACb,WAAc,CAAE,GAAI,gCAAiC,EACxD,GACF,EAGAD,OAAC,SAAM,UAAU,yCACf,UAAAC,MAAC,SACC,KAAK,WACL,QAAShC,EAAiB,QAAQ,YAClC,SAAW2B,GAAMxB,EAAuB,cAAewB,EAAE,OAAO,OAAO,EACvE,UAAU,iGAEZK,MAAC,QAAK,UAAU,oBACb,WAAc,CAAE,GAAI,yBAA0B,EACjD,GACF,EAGAD,OAAC,SAAM,UAAU,yCACf,UAAAC,MAAC,SACC,KAAK,WACL,QAAShC,EAAiB,QAAQ,eAClC,SAAW2B,GAAMxB,EAAuB,iBAAkBwB,EAAE,OAAO,OAAO,EAC1E,UAAU,iGAEZK,MAAC,QAAK,UAAU,oBACb,WAAc,CAAE,GAAI,4BAA6B,EACpD,GACF,GACF,GAEJ,CAEJ,CChXO,SAASK,IAAgB,CAC9B,KAAM,CAAE,cAAAvC,CAAA,EAAkBC,EAAA,EACpB,CACJ,YAAAuC,EACA,cAAAC,EACA,UAAAC,EACA,cAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,0BAAAC,EACA,iBAAAC,EACA,eAAAC,EACA,SAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,mBAAAC,EACA,6BAAAC,EACA,oBAAAC,EACA,UAAAC,EACA,aAAAC,EACA,WAAAC,EACA,aAAAC,EACA,WAAAC,EACA,cAAAC,EACA,SAAAC,EACA,WAAAC,EACA,WAAAC,EACA,eAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,oBAAAC,CAAA,EACE7D,GAAA,EACE,CAAE,SAAA8D,EAAU,YAAAC,CAAA,EAAgBC,GAAA,EAG5B,CAACC,EAAYC,CAAa,EAAI9E,WAAwBgD,CAAS,EAG/D,CAAC+B,GAAkBC,EAAmB,EAAIhF,WAA2B,EAAE,EACvE,CAACiF,GAAeC,EAAgB,EAAIlF,WAA0C,EAAE,EAChF,CAACmF,EAAqBC,EAAsB,EAAIpF,WAAS,EAAK,EAG9D,CAACqF,GAAgBC,CAAiB,EAAItF,WAA6B,IAAI,EACvE,CAACuF,EAAaC,CAAc,EAAIxF,WAAS,EAAE,EAC3C,CAACyF,EAAmBC,CAAoB,EAAI1F,WAA6B,IAAI,EAC7E2F,GAAiBpE,SAAyB,IAAI,EAC9CqE,GAAiBrE,SAAsB,IAAI,EAG3C,CAACsE,GAAiBC,EAAkB,EAAI9F,WAAS,EAAK,EACtD,CAAC+F,GAAYC,EAAa,EAAIhG,WAAS,EAAE,EACzC,CAACiG,EAAeC,EAAgB,EAAIlG,WAAmC,IAAI,EAC3E,CAACmG,GAAeC,EAAgB,EAAIpG,WAAwB,IAAI,EAChE,CAACqG,GAAaC,EAAc,EAAItG,WAAwB,IAAI,EAC5D,CAACuG,GAAcC,EAAe,EAAIxG,WAAS,EAAK,EAGtDC,YAAU,IAAM,CACd6E,EAAc9B,CAAS,CACzB,EAAG,CAACA,CAAS,CAAC,EAGd,MAAMyD,GAAkB1D,EAGlB2D,GAAmBC,GAAqB,CAG5C,MAAMC,EADSC,GADHhC,GAAc,IACe4B,EAAI,EACrBE,CAAQ,EAChC,OAAOC,EAAW,OAAOA,CAAQ,IAAM,MACzC,EAGME,GAA0E,CAC9E,CAAE,GAAI,OAAQ,QAAS,uBAAwB,QAAS,4BACxD,CAAE,GAAI,WAAY,QAAS,2BAA4B,QAAS,gCAChE,CAAE,GAAI,gBAAiB,QAAS,+BAAgC,QAAS,mCAAmC,EAIxGC,GAAwBC,GAAqE,CAEjG,MAAMC,EAAWJ,GADC7D,GAAa,IACkByD,EAAI,EAC/CS,EAAaF,IAAS,WAAaC,EAAWE,GAAeF,EAAUD,EAAMP,EAAI,EACvF,MAAO,CACL,GAAIS,EAAW,MAAM,EAAI,OAAOA,EAAW,MAAM,CAAC,IAAM,OACxD,QAASA,EAAW,WAAW,EAAI,OAAOA,EAAW,WAAW,CAAC,IAAM,OACvE,OAAQA,EAAW,UAAU,EAAI,OAAOA,EAAW,UAAU,CAAC,IAAM,OAExE,EAEME,GAAsBC,GAAwB,CAE9CpE,GACFO,EAAa,IAAI,EAEnBF,EAAe+D,CAAM,CACvB,EAEMC,GAAqB,IAAM,CAE3BtE,IAAc,MAChBQ,EAAa,GAAG,CAEpB,EAEM+D,GAAgB,IAAM,CAC1B,GAAI1C,IAAe,KAAM,CACvBrB,EAAaqB,CAAU,EAIvB,MAAM2C,EAAOX,GAAqBhC,EADV9B,CAC0B,EAE5C0E,EADUC,GAAmBF,CAAI,EACd,OAAOG,IAAK,CAACA,GAAE,MAAM,EAE9C,GAAIF,EAAS,OAAS,EAAG,CACvBzC,GAAoByC,CAAQ,EAE5B,MAAMG,GAAyC,GAC/C,UAAWC,MAAWJ,EAAU,CAC9B,MAAMK,GAAM,GAAGD,GAAQ,KAAK,IAAIA,GAAQ,KAAK,GAC7CD,GAAME,EAAG,EAAIC,GAAoBF,GAAQ,MAAOA,GAAQ,MAAOL,EAAMK,GAAQ,QAAQ,CACvF,CACA3C,GAAiB0C,EAAK,EACtBxC,GAAuB,EAAI,CAC7B,MACEJ,GAAoB,EAAE,EACtBE,GAAiB,EAAE,EACnBE,GAAuB,EAAK,CAEhC,CACF,EAEM4C,GAAiB,IAAM,CAC3BxE,EAAa,IAAI,EACjBsB,EAAc,IAAI,CACpB,EAEMmD,GAAoBC,GAAuB,CAC/C3E,EAAS2E,CAAO,CAClB,EAEMC,GAAiBhG,GAA2B,CAChD,GAAIA,EAAE,MAAQ,cAAgBA,EAAE,MAAQ,YAAa,CACnDA,EAAE,iBAEF,MAAMiG,GADeC,GAAc,UAAUC,GAAKA,EAAE,KAAOxF,CAAW,EACpC,GAAKuF,GAAc,OACrDjB,GAAmBiB,GAAcD,CAAS,EAAE,EAAE,CAChD,SAAWjG,EAAE,MAAQ,aAAeA,EAAE,MAAQ,UAAW,CACvDA,EAAE,iBAEF,MAAMiG,GADeC,GAAc,UAAUC,GAAKA,EAAE,KAAOxF,CAAW,EACpC,EAAIuF,GAAc,QAAUA,GAAc,OAC5EjB,GAAmBiB,GAAcD,CAAS,EAAE,EAAE,CAChD,CACF,EAIMG,GAAmBzG,cAAa0G,GAAwB,CACxDA,IAAWxE,GACbE,EAAcsE,CAAM,CAExB,EAAG,CAACxE,EAAcE,CAAa,CAAC,EAE1BuE,GAAiB3G,cAAY,IAAM,CAClCmC,GACLE,EAAA,CACF,EAAG,CAACF,EAAYE,CAAQ,CAAC,EAEnBuE,GAAoB5G,cAAY,CAAC0G,EAAqBG,IAAwB,CAClFrD,EAAkBkD,CAAM,EACxBhD,EAAemD,CAAW,EAE1B,WAAW,WAAM,OAAAvG,EAAAuD,GAAe,UAAf,YAAAvD,EAAwB,SAAS,CAAC,CACrD,EAAG,EAAE,EAECwG,GAAsB9G,cAAY,IAAM,CACxCuD,IAAkBE,EAAY,QAChCnB,EAAWiB,GAAgBE,EAAY,MAAM,EAE/CD,EAAkB,IAAI,EACtBE,EAAe,EAAE,CACnB,EAAG,CAACH,GAAgBE,EAAanB,CAAU,CAAC,EAEtCyE,GAAqB/G,cAAY,IAAM,CAC3CwD,EAAkB,IAAI,EACtBE,EAAe,EAAE,CACnB,EAAG,EAAE,EAECsD,GAAsBhH,cAAaK,GAA6C,CAChFA,EAAE,MAAQ,SACZA,EAAE,iBACFyG,GAAA,GACSzG,EAAE,MAAQ,WACnBA,EAAE,iBACF0G,GAAA,EAEJ,EAAG,CAACD,GAAqBC,EAAkB,CAAC,EAEtCE,GAAsBjH,cAAY,IAAM,CAC5C,GAAI,CAAC2D,EAAmB,OAExBpB,EAAWoB,CAAiB,EAC5BC,EAAqB,IAAI,EAGrBE,GAAe,SACjBjB,EAAYiB,GAAe,OAAO,EAIpC,MAAMoD,EAAUtE,EAAS,OACvBpE,EAAc,CAAE,GAAI,wBAAyB,EAC7C,OACA,CACE,SAAU,IACV,YAAa,GACb,OAAQ,CACN,MAAOA,EAAc,CAAE,GAAI,kBAAmB,EAC9C,QAAS,IAAM,CACbgE,EAAA,EACAK,EAAYqE,CAAO,EACnBpD,GAAe,QAAU,IAC3B,EACF,CACF,EAEFA,GAAe,QAAUoD,CAC3B,EAAG,CAACvD,EAAmBpB,EAAYK,EAAUC,EAAaL,EAAgBhE,CAAa,CAAC,EAElF2I,GAAqBnH,cAAY,IAAM,CAC3C4D,EAAqB,IAAI,CAC3B,EAAG,EAAE,EAICwD,GAAsBpH,cAAY,SAAY,CAClD,GAAI,CACF,MAAMqH,EAAO5E,EAAA,EACb,MAAM,UAAU,UAAU,UAAU4E,CAAI,EACxC3C,GAAgB,EAAI,EACpB,WAAW,IAAMA,GAAgB,EAAK,EAAG,GAAI,CAC/C,MAAQ,CAEN9B,EAAS,QAAS,6BAA6B,CACjD,CACF,EAAG,CAACH,EAAiBG,CAAQ,CAAC,EAExB0E,GAAmBtH,cAAY,IAAM,CACzCgE,GAAmB,EAAI,EACvBE,GAAc,EAAE,EAChBE,GAAiB,IAAI,EACrBE,GAAiB,IAAI,EACrBE,GAAe,IAAI,CACrB,EAAG,EAAE,EAEC+C,GAAoBvH,cAAY,IAAM,CAC1CgE,GAAmB,EAAK,EACxBE,GAAc,EAAE,EAChBE,GAAiB,IAAI,EACrBE,GAAiB,IAAI,EACrBE,GAAe,IAAI,CACrB,EAAG,EAAE,EAECgD,GAAyBxH,cAAaW,GAAkB,CAM5D,GALAuD,GAAcvD,CAAK,EACnB6D,GAAe,IAAI,EACnBF,GAAiB,IAAI,EACrBF,GAAiB,IAAI,EAEjB,CAACzD,EAAM,OAAQ,OAEnB,MAAMJ,EAASmC,EAAgB/B,CAAK,EAChCJ,EAAO,IACT6D,GAAiB7D,EAAO,OAAO,EAC3BA,EAAO,SACT+D,GAAiB/D,EAAO,OAAO,GAGjCiE,GAAejE,EAAO,KAAK,CAE/B,EAAG,CAACmC,CAAe,CAAC,EAEd+E,GAAoBzH,cAAY,IAAM,CACrCmE,IAGD,CAAChC,GAAcD,IAAiB,WAE9BiC,EAAc,YAAc,KAC9BzC,EAAayC,EAAc,SAAS,GAEpCzC,EAAa,IAAI,EACjBF,EAAe2C,EAAc,WAAW,GAE1CxC,EAAiBwC,EAAc,aAAa,EAC5CvC,EAAmBuC,EAAc,eAAe,EAChDtC,EAA6BsC,EAAc,yBAAyB,EACpEnC,EAAamC,EAAc,SAAS,GAC3BhC,GAETE,EAAA,EAEI8B,EAAc,YAAc,KAC9BzC,EAAayC,EAAc,SAAS,GAEpCzC,EAAa,IAAI,EACjBF,EAAe2C,EAAc,WAAW,GAE1CxC,EAAiBwC,EAAc,aAAa,EAC5CvC,EAAmBuC,EAAc,eAAe,EAChDtC,EAA6BsC,EAAc,yBAAyB,EACpEnC,EAAamC,EAAc,SAAS,IAGhCA,EAAc,YAAc,KAC9BzC,EAAayC,EAAc,SAAS,GAEpCzC,EAAa,IAAI,EACjBF,EAAe2C,EAAc,WAAW,GAE1CxC,EAAiBwC,EAAc,aAAa,EAC5CvC,EAAmBuC,EAAc,eAAe,EAChDtC,EAA6BsC,EAAc,yBAAyB,EACpEnC,EAAamC,EAAc,SAAS,GAItCxB,EAAoBwB,EAAc,kBAAoBuD,EAAyB,EAE/E9E,EAAS,UAAWpE,EAAc,CAAE,GAAI,4BAA6B,CAAC,EACtE+I,GAAA,EACF,EAAG,CACDpD,EAAehC,EAAYD,EAAcG,EACzCX,EAAcF,EAAgBG,EAC9BC,EAAoBC,EAA8BG,EAClDW,EACAC,EAAUpE,EAAe+I,EAAA,CAC1B,EAGKI,GAAyB3H,cAAa4H,GAA+B,CACzE,MAAMC,EAAMD,EAAQ,WAAa,IAC3BzC,EAAWJ,GAAqB8C,EAAKlD,EAAI,EACzCS,EAAawC,EAAQ,YAAc,WACrCzC,EACAE,GAAeF,EAAUyC,EAAQ,UAAWjD,EAAI,EACpD,MAAO,CACL,GAAIS,EAAW,MAAM,EAAI,OAAOA,EAAW,MAAM,CAAC,IAAM,OACxD,QAASA,EAAW,WAAW,EAAI,OAAOA,EAAW,WAAW,CAAC,IAAM,OACvE,OAAQA,EAAW,UAAU,EAAI,OAAOA,EAAW,UAAU,CAAC,IAAM,OACpE,KAAMA,EAAW,QAAQ,EAAI,OAAOA,EAAW,QAAQ,CAAC,IAAM,OAElE,EAAG,CAACT,EAAI,CAAC,EAGHmD,GAA0BC,GAA6B,CAC3D,OAAQA,EAAA,CACN,IAAK,uBACH,MAAO,kCACT,QACE,MAAO,0BAEb,EAGA5J,mBAAU,IAAM,CACVoF,IAAkBM,GAAe,UACnCA,GAAe,QAAQ,QACvBA,GAAe,QAAQ,SAE3B,EAAG,CAACN,EAAc,CAAC,EAGjB9C,OAAC,OAAI,UAAU,YAEb,UAAAA,OAAC,OACC,UAAAA,OAAC,OAAI,UAAU,yCACb,UAAAC,MAAC,MAAG,UAAU,gCACX,SAAAlC,EAAc,CAAE,GAAI,mBAAoB,EAC3C,EACAiC,OAAC,UACC,QAASkG,GACT,SAAU,CAACxE,EACX,MACEA,EACI3D,EAAc,CAAE,GAAI,kBAAmB,EACvCA,EAAc,CAAE,GAAI,2BAA6B,CAAE,MAAOwJ,GAAkB,EAElF,UAAW;AAAA;AAAA;AAAA,gBAGP7F,EACE,gGACA,6CACJ;AAAA;AAAA,cAGH,eACI3D,EAAc,CAAE,GAAI,kBAAmB,IAC5C,EACF,QAEC,OAAI,UAAU,aAAa,KAAK,UAAU,aAAYA,EAAc,CAAE,GAAI,mBAAoB,EAC5F,SAAAyD,EAAW,IAAKgG,GAAS,CACxB,MAAMC,EAAWD,EAAK,KAAO/F,EACvBiG,EAAaF,EAAK,KAAO1E,GAE/B,OACE9C,OAAC,OAEC,KAAK,MACL,gBAAeyH,EACf,SAAUA,EAAW,EAAI,GACzB,QAAS,IAAMzB,GAAiBwB,EAAK,EAAE,EACvC,UAAW;AAAA;AAAA;AAAA,oBAGPC,EACE,qCACA,sCACJ;AAAA;AAAA,kBAKD,UAAAA,GACCxH,MAAC,QAAK,UAAU,iFAAiF,EAInGA,MAAC,OAAI,UAAU,kCACZ,SAAAyH,EACCzH,MAAC,SACC,IAAKmD,GACL,KAAK,OACL,MAAOJ,EACP,SAAWpD,GAAMqD,EAAerD,EAAE,OAAO,KAAK,EAC9C,UAAW2G,GACX,OAAQF,GACR,QAAUzG,GAAMA,EAAE,kBAClB,UAAU;AAAA;AAAA;AAAA;AAAA,wBAKV,UAAW,KAGbK,MAAC,QACC,UAAU,yCACV,MAAOuH,EAAK,KACZ,cAAgB5H,GAAM,CACpBA,EAAE,kBACG4H,EAAK,WACRrB,GAAkBqB,EAAK,GAAIA,EAAK,IAAI,CAExC,EAEC,SAAAA,EAAK,OAGZ,EAGCC,GAAY,CAACC,GACZzH,MAAC,QAAK,UAAU,mDACb,SAAAlC,EAAc,CAAE,GAAI,oBAAqB,EAC5C,EAID,CAACyJ,EAAK,WAAa,CAACE,GACnB1H,OAAC,OAAI,UAAU;AAAA;AAAA;AAAA,oBAIb,UAAAC,MAAC,UACC,QAAUL,GAAM,CACdA,EAAE,kBACFuG,GAAkBqB,EAAK,GAAIA,EAAK,IAAI,CACtC,EACA,MAAOzJ,EAAc,CAAE,GAAI,oBAAqB,EAChD,UAAU;AAAA;AAAA;AAAA,wBAKV,SAAAkC,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,6BAChE,eAAC,QAAK,EAAE,yCAAyC,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,eAAe,QAAO,EACvI,IAEFA,MAAC,UACC,QAAUL,GAAM,CACdA,EAAE,kBACFuD,EAAqBqE,EAAK,EAAE,CAC9B,EACA,MAAOzJ,EAAc,CAAE,GAAI,oBAAqB,EAChD,UAAU;AAAA;AAAA;AAAA,wBAKV,SAAAkC,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,6BAChE,SAAAA,MAAC,QAAK,EAAE,uBAAuB,OAAO,eAAe,YAAY,MAAM,cAAc,QAAO,EAC9F,GACF,EACF,EAIDuH,EAAK,WACJvH,MAAC,OAAI,UAAU;AAAA;AAAA;AAAA,oBAIb,SAAAA,MAAC,UACC,SAAQ,GACR,MAAOlC,EAAc,CAAE,GAAI,iCAAkC,EAC7D,UAAU,mDAEV,SAAAkC,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,6BAChE,SAAAA,MAAC,QAAK,EAAE,uBAAuB,OAAO,eAAe,YAAY,MAAM,cAAc,QAAO,EAC9F,GACF,CACF,IAnHGuH,EAAK,GAuHhB,CAAC,EACH,GACF,SAGC,OACC,UAAAvH,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,0BAA2B,EAClD,EACAiC,OAAC,OACC,UAAU,yBACV,KAAK,QACL,aAAW,yBACX,UAAW4F,GAEV,UAAAE,GAAc,IAAKhB,GAClB9E,OAAC,UAEC,QAAS,IAAM6E,GAAmBC,EAAO,EAAE,EAC3C,aAAY/G,EAAc,CAAE,GAAI,4BAA8B,CAAE,KAAMA,EAAc,CAAE,GAAI,qBAAqB+G,EAAO,EAAE,GAAI,EAAG,EAC/H,gBAAevE,IAAgBuE,EAAO,IAAM,CAACpE,EAC7C,KAAK,QACL,UAAW;AAAA;AAAA;AAAA,kBAGPH,IAAgBuE,EAAO,IAAM,CAACpE,EAC5B,qCACA,sCACJ;AAAA;AAAA,gBAKF,UAAAT,MAAC,OACC,UAAU,wDACV,MAAO,CAAE,gBAAiB6E,EAAO,aACjC,cAAY,SAGd7E,MAAC,QAAK,UAAU,4CACb,SAAAlC,EAAc,CAAE,GAAI,qBAAqB+G,EAAO,EAAE,GAAI,EACzD,IAxBKA,EAAO,GA0Bf,EAGD9E,OAAC,UACC,QAAS+E,GACT,aAAYhH,EAAc,CAAE,GAAI,4BAA8B,CAAE,KAAMA,EAAc,CAAE,GAAI,2BAA4B,EAAG,EACzH,gBAAe2C,EACf,KAAK,QACL,UAAW;AAAA;AAAA;AAAA,gBAGPA,EACE,qCACA,sCACJ;AAAA;AAAA,cAKF,UAAAT,MAAC,OACC,UAAU,wDACV,MAAO,CACL,WAAY,2BAA2BkE,GAAgB,UAAU,CAAC,KAAKA,GAAgB,WAAW,CAAC,KAErG,cAAY,SAGdlE,MAAC,QAAK,UAAU,4CACb,WAAc,CAAE,GAAI,2BAA4B,EACnD,IACF,GACF,EACF,EAGCS,GACCV,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,wBAAyB,EAChD,EAGAiC,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,OAAI,UAAU,oCACb,SAAAA,MAAC,SAAM,QAAQ,aAAa,UAAU,8BACnC,SAAAlC,EAAc,CAAE,GAAI,kBAAoB,CAAE,MAAOuE,GAAc,IAAK,EACvE,EACF,EACArC,MAAC,SACC,GAAG,aACH,KAAK,QACL,IAAI,IACJ,IAAI,MACJ,KAAK,IACL,MAAOqC,GAAc,IACrB,SAAW1C,GAAM2C,EAAc,OAAO3C,EAAE,OAAO,KAAK,CAAC,EACrD,UAAU,uDACV,MAAO,CACL,WAAY;AAAA;AAAA,oGAId,aAAY7B,EAAc,CAAE,GAAI,wBAAyB,IAI3DiC,OAAC,OAAI,UAAU,uBACb,UAAAA,OAAC,QAAK,UAAU,mCACb,UAAAjC,EAAc,CAAE,GAAI,gBAAiB,EAAE,KAC1C,EACAiC,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,OACC,UAAU,qDACV,MAAO,CAAE,gBAAiBkE,GAAgB,MAAM,EAAE,GAEpDlE,MAAC,QAAK,UAAU,iCAAkC,WAAc,CAAE,GAAI,2BAA4B,EAAE,GACtG,EACAD,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,OACC,UAAU,qDACV,MAAO,CAAE,gBAAiBkE,GAAgB,WAAW,EAAE,GAEzDlE,MAAC,QAAK,UAAU,iCAAkC,WAAc,CAAE,GAAI,wBAAyB,EAAE,GACnG,EACAD,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,OACC,UAAU,qDACV,MAAO,CAAE,gBAAiBkE,GAAgB,UAAU,EAAE,GAExDlE,MAAC,QAAK,UAAU,iCAAkC,WAAc,CAAE,GAAI,uBAAwB,EAAE,GAClG,GACF,EAGAD,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC,UACC,QAAS+E,GACT,SAAU1C,IAAe7B,EACzB,UAAW;AAAA;AAAA;AAAA,oBAGP6B,IAAe7B,EACb,8CACA,+FACJ;AAAA,kBAGD,SAAA1C,EAAc,CAAE,GAAI,aAAc,IAErCkC,MAAC,UACC,QAASwF,GACT,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,kBAOT,SAAA1H,EAAc,CAAE,GAAI,cAAe,GACtC,EACF,GACF,GACF,SAID,OACC,UAAAkC,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,wBAAyB,EAChD,EACAkC,MAAC,OACC,UAAU,yBACV,KAAK,aACL,aAAYlC,EAAc,CAAE,GAAI,wBAAyB,EAExD,SAAAwG,GAAY,IAAKE,GAAS,CACzB,MAAMkD,EAAUnD,GAAqBC,EAAK,EAAE,EACtCmD,EAAatG,IAAcmD,EAAK,GACtC,OACEzE,OAAC,UAEC,QAAS,IAAMuB,EAAakD,EAAK,EAAE,EACnC,KAAK,QACL,eAAcmD,EACd,UAAW;AAAA;AAAA;AAAA,oBAGPA,EACE,qCACA,sCACJ;AAAA;AAAA,kBAKF,UAAA5H,OAAC,OAAI,UAAU,aAAa,cAAY,OACtC,UAAAC,MAAC,OACC,UAAU,0CACV,MAAO,CAAE,gBAAiB0H,EAAQ,GAAG,GAEvC1H,MAAC,OACC,UAAU,0CACV,MAAO,CAAE,gBAAiB0H,EAAQ,QAAQ,GAE5C1H,MAAC,OACC,UAAU,0CACV,MAAO,CAAE,gBAAiB0H,EAAQ,OAAO,EAC3C,EACF,EAEA1H,MAAC,QAAK,UAAU,4CACb,SAAAlC,EAAc,CAAE,GAAI0G,EAAK,QAAS,EACrC,EAEAxE,MAAC,QAAK,UAAU,2DACb,SAAAlC,EAAc,CAAE,GAAI0G,EAAK,QAAS,EACrC,IApCKA,EAAK,GAuChB,CAAC,GACH,EACF,SAGC,OACC,UAAAxE,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,uBAAwB,EAC/C,EAGAiC,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,OACC,UAAU,aACV,KAAK,aACL,aAAYlC,EAAc,CAAE,GAAI,uBAAwB,EAEtD,UAAC,MAAO,WAAY,UAAU,EAAY,IAAK8J,GAC/C5H,MAAC,UAEC,QAAS,IAAMiB,EAAiB2G,CAAK,EACrC,KAAK,QACL,eAAclH,IAAkBkH,EAChC,UAAW;AAAA;AAAA;AAAA,oBAGPlH,IAAkBkH,EAChB,qCACA,sCACJ;AAAA;AAAA,kBAID,WAAc,CAAE,GAAI,kBAAkBA,CAAK,GAAI,GAd3CA,CAAA,CAgBR,IAIH7H,OAAC,SAAM,UAAU,yCACf,UAAAC,MAAC,SACC,KAAK,WACL,QAASW,EACT,SAAWhB,GAAMuB,EAAmBvB,EAAE,OAAO,OAAO,EACpD,UAAU;AAAA;AAAA;AAAA,kBAKZK,MAAC,QAAK,UAAU,oBACb,WAAc,CAAE,GAAI,2BAA4B,EACnD,GACF,EAGAD,OAAC,SAAM,UAAU,yCACf,UAAAC,MAAC,SACC,KAAK,WACL,QAASY,EACT,SAAWjB,GAAMwB,EAA6BxB,EAAE,OAAO,OAAO,EAC9D,UAAU;AAAA;AAAA;AAAA,kBAKZK,MAAC,QAAK,UAAU,oBACb,WAAc,CAAE,GAAI,6BAA8B,EACrD,GACF,GACF,GACF,QAGCnC,GAAA,EAAsB,SAGtB,OACC,UAAAmC,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,qBAAsB,EAC7C,EACAkC,MAAC,OACC,UAAU,aACV,KAAK,aACL,aAAYlC,EAAc,CAAE,GAAI,qBAAsB,EAEpD,UAAC,SAAU,SAAU,QAAQ,EAAY,IAAK+J,GAC9C7H,MAAC,UAEC,QAAS,IAAMoB,EAAoByG,CAAI,EACvC,KAAK,QACL,eAAchH,IAAqBgH,EACnC,UAAW;AAAA;AAAA;AAAA,kBAGPhH,IAAqBgH,EACnB,qCACA,sCACJ;AAAA;AAAA,gBAID,WAAc,CAAE,GAAI,gBAAgBA,CAAI,GAAI,GAdxCA,CAAA,CAgBR,GACH,EACF,EAGClF,GAAuBJ,GAAiB,OAAS,GAChDxC,OAAC,OAAI,UAAU,oFACb,UAAAC,MAAC,KAAE,UAAU,sBACV,SAAAlC,EAAc,CAAE,GAAI,sCAAuC,EAC9D,QACC,MAAG,UAAU,oBACX,SAAAyE,GAAiB,IAAKuF,GAAM,CAC3B,MAAMxC,EAAM,GAAGwC,EAAE,KAAK,IAAIA,EAAE,KAAK,GAC3B1C,EAAQ3C,GAAc6C,CAAG,GAAK,GACpC,OACEvF,OAAC,MAAa,UAAU,YACtB,UAAAA,OAAC,QACE,UAAA+H,EAAE,MAAM,MAAIA,EAAE,MAAM,KAAGA,EAAE,MAAM,WAASA,EAAE,SAAS,OACtD,EACC1C,EAAM,OAAS,SACb,OAAI,UAAU,mBACZ,SAAAA,EAAM,MAAM,EAAG,CAAC,EAAE,IAAI,CAAC2C,EAAKC,KAC3BhI,MAAC,QAAa,UAAU,QACrB,SAAAlC,EACC,CAAE,GAAI,qCACN,CACE,OAAQiK,EAAI,SAAW,KAAOD,EAAE,MAAQA,EAAE,MAC1C,SAAUC,EAAI,SACd,UAAWA,EAAI,UACf,MAAOA,EAAI,YACb,CACF,EATSC,EAUX,CACD,EACH,IAnBK1C,CAqBT,CAEJ,CAAC,EACH,EACAtF,MAAC,UACC,QAAS,IAAM4C,GAAuB,EAAK,EAC3C,UAAU,gCAET,SAAA9E,EAAc,CAAE,GAAI,8BAA+B,GACtD,EACF,SAID,OACC,UAAAkC,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,wBAAyB,EAChD,EACAkC,MAAC,OACC,UAAU,yBACV,KAAK,QACL,aAAW,uBAEV,SAAAiI,GAAY,IAAKC,GAChBnI,OAAC,UAEC,QAAS,IAAM0F,GAAiByC,EAAW,EAAE,EAC7C,aAAYpK,EAAc,CAAE,GAAI,0BAA4B,CAAE,KAAMA,EAAc,CAAE,GAAI,mBAAmBoK,EAAW,EAAE,GAAI,EAAG,EAC/H,gBAAejE,KAASiE,EAAW,GACnC,KAAK,QACL,UAAW;AAAA;AAAA;AAAA,kBAGPjE,KAASiE,EAAW,GAClB,qCACA,sCACJ;AAAA;AAAA,gBAKF,UAAAlI,MAAC,QAAK,UAAU,UAAU,cAAY,OACnC,SAAAkI,EAAW,KAAO,QAAU,KAAO,KACtC,EAEAlI,MAAC,QAAK,UAAU,gCACb,SAAAlC,EAAc,CAAE,GAAI,mBAAmBoK,EAAW,EAAE,GAAI,EAC3D,IAtBKA,EAAW,GAwBnB,GACH,EACF,EAGAlI,MAAC,OAAI,UAAU,iDACb,eAAC,KAAE,UAAU,8BACV,SAAAlC,EAAc,CAAE,GAAI,iBAAmB,CAAE,KAAMqK,GAAa7H,EAAa2D,EAAI,EAAG,EACnF,EACF,SAGC,OACC,UAAAjE,MAAC,MAAG,UAAU,qCACX,SAAAlC,EAAc,CAAE,GAAI,oBAAqB,EAC5C,EAEAiC,OAAC,OAAI,UAAU,aAEb,UAAAC,MAAC,UACC,QAAS0G,GACT,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,cAOT,SACG5I,EADHiG,GACiB,CAAE,GAAI,sBACN,CAAE,GAAI,uBADsB,CACE,GAKlD/D,MAAC,UACC,QAASqD,GAAkBwD,GAAoBD,GAC/C,UAAW;AAAA;AAAA;AAAA,gBAGPvD,GACE,qCACA,gDACJ;AAAA;AAAA,cAID,SAAAvF,EAAc,CAAE,GAAI,qBAAsB,GAC7C,EACF,EAGCuF,IACCtD,OAAC,OAAI,UAAU,iBAEb,UAAAC,MAAC,YACC,MAAOuD,GACP,SAAW5D,GAAMmH,GAAuBnH,EAAE,OAAO,KAAK,EACtD,YAAa7B,EAAc,CAAE,GAAI,oBAAqB,EACtD,KAAM,EACN,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,kBASX+F,IACC7D,MAAC,OAAI,UAAU,4EACZ,SAAAlC,EAAc,CAAE,GAAIsJ,GAAuBvD,EAAW,EAAG,EAC5D,EAIDF,IAAiB,CAACE,IACjB7D,MAAC,OAAI,UAAU,kFACZ,SAAAlC,EAAc,CAAE,GAAI,6BAA8B,EACrD,EAID2F,GAAiB,CAACI,IACjB9D,OAAC,OAAI,UAAU,2DACb,UAAAC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CAAE,GAAI,sBAAuB,EAC9C,EAGAkC,MAAC,OAAI,UAAU,uBACX,cAAM,CACN,MAAMoI,EAAgBnB,GAAuBxD,CAAa,EAC1D,OACE1D,OAAAI,WAAA,CACE,UAAAJ,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,OACC,UAAU,qDACV,MAAO,CAAE,gBAAiBoI,EAAc,GAAG,GAE7CpI,MAAC,QAAK,UAAU,iCACb,WAAc,CAAE,GAAI,2BAA4B,EACnD,GACF,EACAD,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,OACC,UAAU,qDACV,MAAO,CAAE,gBAAiBoI,EAAc,QAAQ,GAElDpI,MAAC,QAAK,UAAU,iCACb,WAAc,CAAE,GAAI,wBAAyB,EAChD,GACF,EACAD,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,OACC,UAAU,qDACV,MAAO,CAAE,gBAAiBoI,EAAc,OAAO,GAEjDpI,MAAC,QAAK,UAAU,iCACb,WAAc,CAAE,GAAI,uBAAwB,EAC/C,GACF,GACF,CAEJ,IAAG,CACL,EAGAD,OAAC,OAAI,UAAU,wCACb,UAAAA,OAAC,KACE,UAAAjC,EAAc,CAAE,GAAI,wBAAyB,EAAE,KAAGA,EAAc,CAAE,GAAI,mBAAmB2F,EAAc,YAAc,gBAAkB,eAAiBA,EAAc,SAAS,GAAI,GACtL,SACC,KACE,UAAA3F,EAAc,CAAE,GAAI,uBAAwB,EAAE,KAAGA,EAAc,CAAE,GAAI,kBAAkB2F,EAAc,aAAa,GAAI,GACzH,EACCA,EAAc,YAAc,MAC3BzD,MAAC,KACE,SAAAlC,EAAc,CAAE,GAAI,kBAAoB,CAAE,MAAO2F,EAAc,UAAW,EAC7E,EAEDA,EAAc,YAAc,MAC3B1D,OAAC,KACE,UAAAjC,EAAc,CAAE,GAAI,0BAA2B,EAAE,KAAGA,EAAc,CAAE,GAAI,qBAAqB2F,EAAc,WAAW,GAAI,GAC7H,GAEJ,EAGA1D,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC,UACC,QAAS+G,GACT,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,sBAOT,SAAAjJ,EAAc,CAAE,GAAI,oBAAqB,IAE5CkC,MAAC,UACC,QAAS6G,GACT,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,sBAOT,SAAA/I,EAAc,CAAE,GAAI,qBAAsB,GAC7C,EACF,GACF,GAEJ,EAIFkC,MAACqI,IAAY,KAAMpF,IAAsB,KAAM,aAAcwD,GAC3D,gBAAC6B,GAAA,CACC,UAAAvI,OAACwI,GAAA,CACC,UAAAvI,MAACwI,IAAiB,8BAAkB,EACpCxI,MAACyI,IAAuB,qFAExB,GACF,SACCC,GAAA,CACC,UAAA1I,MAAC2I,GAAA,CAAkB,QAASlC,GAAoB,kBAAM,EACtDzG,MAAC4I,GAAA,CAAkB,QAASrC,GAAqB,kBAAM,GACzD,GACF,EACF,GACF,GACF,CAEJ,CC5nCA,MAAMsC,GAAmB,CACvB,CAAE,MAAO,KAAe,MAAO,UAAW,KAAM,QAChD,CAAE,MAAO,KAAe,MAAO,KAAM,KAAM,OAC7C,EAMO,SAASC,GAAiB,CAAE,QAAAC,EAAU,GAAO,UAAAC,GAAoC,CACtF,KAAM,CAAE,OAAAC,EAAQ,UAAAC,CAAA,EAAcC,GAAA,EAE9B,OACEpJ,OAACqJ,GAAA,CAAO,MAAOH,EAAQ,cAAeC,EACpC,UAAAlJ,MAACqJ,GAAA,CACC,UAAWC,EACTP,EAAU,YAAc,YACxB,QACAC,CAAA,EAEF,aAAW,kBAEV,WACCjJ,OAAAI,WAAA,CACE,UAAAH,MAAC9D,GAAA,CAAU,UAAU,UAAU,QAC9BqN,GAAA,EAAY,GACf,QAECA,GAAA,EAAY,IAGjBvJ,MAACwJ,GAAA,CACE,SAAAX,GAAiB,IAAKY,GACrBzJ,MAAC0J,GAAA,CAA8B,MAAOD,EAAO,MAC3C,SAAA1J,OAAC,QAAK,UAAU,0BACd,UAAAC,MAAC,QAAK,UAAU,YAAa,SAAAyJ,EAAO,KAAK,EACzCzJ,MAAC,QAAM,SAAAyJ,EAAO,MAAM,GACtB,GAJeA,EAAO,KAKxB,CACD,EACH,GACF,CAEJ,CC+FO,MAAME,GAA4D,CACvE,QAAS,CACP,GAAI,UACJ,KAAM,UACN,KAAM,iBACN,YAAa,qDACb,eAAgB,CAAC,YAAY,GAE/B,SAAU,CACR,GAAI,WACJ,KAAM,WACN,KAAM,OACN,YAAa,+CACb,eAAgB,CAAC,WAAY,QAAQ,GAEvC,OAAQ,CACN,GAAI,SACJ,KAAM,SACN,KAAM,iBACN,YAAa,yEACb,eAAgB,CAAC,YAAY,GAE/B,SAAU,CACR,GAAI,WACJ,KAAM,WACN,KAAM,OACN,YAAa,6CACb,eAAgB,CAAC,YAAY,GAE/B,MAAO,CACL,GAAI,QACJ,KAAM,QACN,KAAM,QACN,YAAa,wDACb,eAAgB,CAAC,YAAY,GAE/B,MAAO,CACL,GAAI,QACJ,KAAM,QACN,KAAM,OACN,YAAa,oCACb,eAAgB,CAAC,OAAQ,WAAY,WAAY,OAAQ,IAAI,GAE/D,QAAS,CACP,GAAI,UACJ,KAAM,iBACN,KAAM,OACN,YAAa,+CACb,eAAgB,CAAC,KAAK,EAE1B,EAKaC,GAAuD,CAClE,oBAAqB,CACnB,GAAI,oBACJ,KAAM,oBACN,YAAa,+DACb,KAAM,eAER,gBAAiB,CACf,GAAI,gBACJ,KAAM,gBACN,YAAa,yCACb,KAAM,QAER,cAAe,CACb,GAAI,cACJ,KAAM,cACN,YAAa,uCACb,KAAM,UAER,iBAAkB,CAChB,GAAI,iBACJ,KAAM,iBACN,YAAa,kDACb,KAAM,gBAER,cAAe,CACb,GAAI,cACJ,KAAM,cACN,YAAa,iCACb,KAAM,eAEV,EAKO,SAASC,IAA6C,CAC3D,MAAO,CACL,QAAS,GACT,UAAW,GACX,OAAQ,CACN,CAAE,MAAO,oBAAqB,UAAW,CAAC,UAAW,UAAU,EAAG,QAAS,IAC3E,CAAE,MAAO,gBAAiB,UAAW,GAAI,QAAS,IAClD,CAAE,MAAO,cAAe,UAAW,GAAI,QAAS,IAChD,CAAE,MAAO,iBAAkB,UAAW,GAAI,QAAS,IACnD,CAAE,MAAO,cAAe,UAAW,CAAC,UAAW,UAAU,EAAG,QAAS,GAAK,EAE5E,QAAS,IAEb,CChNO,SAASC,GAAoB,CAClC,OAAAC,EACA,iBAAAC,EACA,QAAAC,EACA,eAAAC,EACA,eAAAC,EACA,OAAAC,EACA,OAAAC,EACA,OAAAC,CACF,EAA6B,CAC3B,KAAM,CAAE,cAAAxM,CAAA,EAAkBC,EAAA,EAEpBwM,EAAoC,CAAC,UAAW,WAAY,SAAU,WAAY,QAAS,QAAS,SAAS,EAE7GC,EAAmBC,GAAmC,CAC1D,OAAQA,EAAA,CACN,IAAK,UACH,OAAOzK,MAAC0K,GAAA,CAAc,UAAU,UAAU,EAC5C,IAAK,WACH,OAAO1K,MAAC2K,GAAA,CAAK,UAAU,UAAU,EACnC,IAAK,SACH,OAAO3K,MAAC4K,GAAA,CAAc,UAAU,UAAU,EAC5C,IAAK,WACH,OAAO5K,MAAC6K,GAAA,CAAK,UAAU,UAAU,EACnC,IAAK,QACH,OAAO7K,MAAC8K,GAAA,CAAM,UAAU,UAAU,EACpC,IAAK,QACH,OAAO9K,MAAC+K,GAAA,CAAK,UAAU,UAAU,EACnC,IAAK,UACH,OAAO/K,MAACgL,GAAA,CAAK,UAAU,UAAU,EAEvC,EAEMC,EACJR,GAC+G,CAC/G,OAAQA,EAAA,CACN,IAAK,UACH,OAAOV,EAAO,UAAU,SAAW,CAAE,QAAS,GAAO,WAAY,IACnE,IAAK,WACH,OAAOA,EAAO,UAAU,UAAY,CAAE,QAAS,GAAO,SAAU,GAAI,OAAQ,IAC9E,IAAK,SACH,OAAOA,EAAO,UAAU,QAAU,CAAE,QAAS,GAAO,WAAY,IAClE,IAAK,WACH,OAAOA,EAAO,UAAU,UAAY,CAAE,QAAS,GAAO,WAAY,IACpE,IAAK,QACH,OAAOA,EAAO,UAAU,OAAS,CAAE,QAAS,GAAO,WAAY,IACjE,IAAK,QACH,OAAOA,EAAO,UAAU,OAAS,CAAE,QAAS,GAAO,KAAM,GAAI,KAAM,IAAK,SAAU,GAAI,SAAU,GAAI,KAAM,GAAI,GAAI,EAAC,EACrH,IAAK,UACH,OAAOA,EAAO,UAAU,SAAW,CAAE,QAAS,GAAO,IAAK,GAAI,OAAQ,OAAO,CAEnF,EAEMmB,EAAgBT,GAA4C,OAChE,MAAMU,EAAiBF,EAAkBR,CAAQ,EACjD,OAAQA,EAAA,CACN,IAAK,UACH,MAAO,CAAC,CAAEU,EAAiC,WAC7C,IAAK,WACH,MAAO,CAAC,CAAEA,EAAkC,UAAY,CAAC,CAAEA,EAAkC,OAC/F,IAAK,SACH,MAAO,CAAC,CAAEA,EAAgC,WAC5C,IAAK,WACH,MAAO,CAAC,CAAEA,EAAkC,WAC9C,IAAK,QACH,MAAO,CAAC,CAAEA,EAA+B,WAC3C,IAAK,QACH,MAAMC,EAAcD,EACpB,MAAO,CAAC,EAAEC,EAAY,MAAQA,EAAY,UAAYA,EAAY,UAAYA,EAAY,QAAQxL,EAAAwL,EAAY,KAAZ,YAAAxL,EAAgB,QAAS,GAC7H,IAAK,UACH,MAAO,CAAC,CAAEuL,EAAiC,IAEjD,EAEA,aACG,OAAI,UAAU,aACZ,SAAAZ,EAAU,IAAKE,GAAa,CAC3B,MAAMY,EAAO1B,GAAcc,CAAQ,EAC7BU,EAAiBF,EAAkBR,CAAQ,EAC3Ca,EAAaJ,EAAaT,CAAQ,EAClCc,EAAWvB,IAAqBS,EAEtC,OACE1K,OAACyL,EAAA,CAAoB,UAAU,kBAE7B,UAAAxL,MAAC,OACC,UAAU,yDACV,QAAS,IAAMkK,EAAeqB,EAAW,KAAOd,CAAQ,EAExD,SAAA1K,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,OAAI,UAAWsJ,EACd,iBACA6B,EAAe,SAAWG,EACtB,6BACA,kCAEH,SAAAd,EAAgBC,CAAQ,EAC3B,SACC,OACC,UAAA1K,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAU,sBAAuB,SAAAqL,EAAK,KAAK,EAChDC,GACCvL,OAAC0L,EAAA,CAAM,QAAQ,UAAU,UAAU,6CACjC,UAAAzL,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,0CAA2C,GAClE,GAEJ,EACAkC,MAAC,KAAE,UAAU,uCAAwC,WAAK,YAAY,GACxE,GACF,EACAD,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC2L,EAAA,CACC,QAASR,EAAe,QAAU,UAAY,UAC9C,KAAK,KACL,UAAU,MACV,QAAUxL,GAAM,CACdA,EAAE,kBACFwK,EAAeM,EAAU,CAAE,QAAS,CAACU,EAAe,QAAS,CAC/D,EAEC,SAAAA,EAAe,QACdnL,MAAC0L,GAAA,CAAM,UAAU,cAAc,EAE/B1L,MAAC4L,GAAA,CAAE,UAAU,cAAc,IAG9BL,QACEM,GAAA,CAAU,UAAU,gCAAgC,EAErD7L,MAAC8L,GAAA,CAAY,UAAU,gCAAgC,GAE3D,GACF,IAIDP,GACCxL,OAAC,OAAI,UAAU,mDACZ,UAAA0K,IAAa,WACZzK,MAAC+L,GAAA,CACC,OAAQZ,EACR,SAAWa,GAAY7B,EAAe,UAAW6B,CAAO,IAG3DvB,IAAa,YACZzK,MAACiM,GAAA,CACC,OAAQd,EACR,SAAWa,GAAY7B,EAAe,WAAY6B,CAAO,IAG5DvB,IAAa,UACZzK,MAACkM,GAAA,CACC,OAAQf,EACR,SAAWa,GAAY7B,EAAe,SAAU6B,CAAO,IAG1DvB,IAAa,YACZzK,MAACmM,GAAA,CACC,OAAQhB,EACR,SAAWa,GAAY7B,EAAe,WAAY6B,CAAO,IAG5DvB,IAAa,SACZzK,MAACoM,GAAA,CACC,OAAQjB,EACR,SAAWa,GAAY7B,EAAe,QAAS6B,CAAO,IAGzDvB,IAAa,SACZzK,MAACqM,GAAA,CACC,OAAQlB,EACR,SAAWa,GAAY7B,EAAe,QAAS6B,CAAO,IAGzDvB,IAAa,WACZzK,MAACsM,GAAA,CACC,OAAQnB,EACR,SAAWa,GAAY7B,EAAe,UAAW6B,CAAO,IAK5DjM,OAAC,OAAI,UAAU,+BACb,UAAAA,OAAC4L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMvB,EAAOK,EAAUU,CAAc,EAC9C,SAAUlB,IAAYQ,GAAY,CAACa,EAEnC,UAAAtL,MAACuM,IAAS,UAAWjD,EAAG,mBAAoBW,IAAYQ,GAAY,eAAe,EAAG,EACrF3M,EAAc,CAAE,GAAI,8CAA+C,KAEtEkC,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAStB,EACT,SAAUC,EAET,SAAAxM,EAAc,CAAE,GAAI,oCAAqC,GAC5D,EACF,GACF,IAxHO2M,CA0HX,CAEJ,CAAC,EACH,CAEJ,CAIA,SAASsB,GAAkB,CACzB,OAAAhC,EACA,SAAAyC,CACF,EAGG,CACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EACpB,CAAC0O,EAASC,CAAU,EAAIlP,WAAS,EAAK,EAE5C,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,kDAAmD,EAC1E,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,KAAMF,EAAU,OAAS,WACzB,MAAO1C,EAAO,YAAc,GAC5B,SAAWpK,GAAM6M,EAAS,CAAE,WAAY7M,EAAE,OAAO,MAAO,EACxD,YAAY,uCACZ,UAAU,WAEZK,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,WACV,QAAS,IAAMe,EAAW,CAACD,CAAO,EAEjC,SAAAA,QAAWG,GAAA,CAAO,UAAU,UAAU,EAAK5M,MAAC6M,GAAA,CAAI,UAAU,UAAU,GACvE,EACF,EACA7M,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,sDAAuD,EAC9E,GACF,SACC,OACC,UAAAA,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,gDAAiD,EACxE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,UAAY,GAC1B,SAAWpK,GAAM6M,EAAS,CAAE,SAAU7M,EAAE,OAAO,MAAO,EACtD,YAAY,mBACZ,UAAU,QACZ,EACF,GACF,CAEJ,CAIA,SAASsM,GAAmB,CAC1B,OAAAlC,EACA,SAAAyC,CACF,EAGG,CACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EACpB,CAAC+O,EAAWC,CAAY,EAAIvP,WAAS,EAAK,EAEhD,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,iDAAkD,EACzE,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,KAAMG,EAAY,OAAS,WAC3B,MAAO/C,EAAO,UAAY,GAC1B,SAAWpK,GAAM6M,EAAS,CAAE,SAAU7M,EAAE,OAAO,MAAO,EACtD,YAAY,wCACZ,UAAU,WAEZK,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,WACV,QAAS,IAAMoB,EAAa,CAACD,CAAS,EAErC,SAAAA,QAAaF,GAAA,CAAO,UAAU,UAAU,EAAK5M,MAAC6M,GAAA,CAAI,UAAU,UAAU,GACzE,EACF,EACA7M,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,qDAAsD,EAC7E,GACF,SACC,OACC,UAAAA,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,+CAAgD,EACvE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,QAAU,GACxB,SAAWpK,GAAM6M,EAAS,CAAE,OAAQ7M,EAAE,OAAO,MAAO,EACpD,YAAY,iBACZ,UAAU,SAEZK,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,mDAAoD,EAC3E,GACF,GACF,CAEJ,CAIA,SAASsM,GAAkB,CACzB,OAAAvC,EACA,SAAAyC,CACF,EAGG,CACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EAE1B,OACEgC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,2CAA4C,EACnE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,KAAO,GACrB,SAAWpK,GAAM6M,EAAS,CAAE,IAAK7M,EAAE,OAAO,MAAO,EACjD,YAAY,kCACZ,UAAU,QACZ,EACF,SACC,OACC,UAAAK,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,8CAA+C,EACtE,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2L,EAAA,CACC,QAAS5B,EAAO,SAAW,OAAS,UAAY,UAChD,KAAK,KACL,QAAS,IAAMyC,EAAS,CAAE,OAAQ,OAAQ,EAC3C,kBAGDxM,MAAC2L,EAAA,CACC,QAAS5B,EAAO,SAAW,MAAQ,UAAY,UAC/C,KAAK,KACL,QAAS,IAAMyC,EAAS,CAAE,OAAQ,MAAO,EAC1C,gBAED,EACF,GACF,SACC,OACC,UAAAxM,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,+CAAgD,EACvE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,QAAU,KAAK,UAAUA,EAAO,OAAO,EAAI,GACzD,SAAWpK,GAAM,CACf,GAAI,CACF,MAAM1C,EAAU0C,EAAE,OAAO,MAAQ,KAAK,MAAMA,EAAE,OAAO,KAAK,EAAI,OAC9D6M,EAAS,CAAE,QAAAvP,EAAS,CACtB,MAAQ,CAER,CACF,EACA,YAAY,oCACZ,UAAU,2BAEZ+C,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,mDAAoD,EAC3E,GACF,GACF,CAEJ,CAIA,SAASkM,GAAiB,CACxB,OAAAnC,EACA,SAAAyC,CACF,EAGG,CACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EACpB,CAAC0O,EAASC,CAAU,EAAIlP,WAAS,EAAK,EAE5C,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,iDAAkD,EACzE,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,KAAMF,EAAU,OAAS,WACzB,MAAO1C,EAAO,YAAc,GAC5B,SAAWpK,GAAM6M,EAAS,CAAE,WAAY7M,EAAE,OAAO,MAAO,EACxD,YAAY,mDACZ,UAAU,WAEZK,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,WACV,QAAS,IAAMe,EAAW,CAACD,CAAO,EAEjC,SAAAA,QAAWG,GAAA,CAAO,UAAU,UAAU,EAAK5M,MAAC6M,GAAA,CAAI,UAAU,UAAU,GACvE,EACF,EACA7M,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,qDAAsD,EAC7E,GACF,EACAD,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,SACC,KAAK,WACL,GAAG,iBACH,QAAS+J,EAAO,SAAW,GAC3B,SAAWpK,GAAM6M,EAAS,CAAE,QAAS7M,EAAE,OAAO,QAAS,EACvD,UAAU,0BAEZK,MAAC,SAAM,QAAQ,iBAAiB,UAAU,sCACvC,SAAAlC,EAAc,CAAE,GAAI,8CAA+C,EACtE,GACF,EACAkC,MAAC,KAAE,UAAU,sCACV,WAAc,CAAE,GAAI,kDAAmD,EAC1E,SACC,OACC,UAAAA,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,4CAA6C,EACpE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,OAAS,GACvB,SAAWpK,GAAM6M,EAAS,CAAE,MAAO7M,EAAE,OAAO,MAAO,EACnD,YAAY,mBACZ,UAAU,QACZ,EACF,GACF,CAEJ,CAIA,SAASwM,GAAmB,CAC1B,OAAApC,EACA,SAAAyC,CACF,EAGG,OACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EACpB,CAAC0O,EAASC,CAAU,EAAIlP,WAAS,EAAK,EAE5C,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,mDAAoD,EAC3E,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,KAAMF,EAAU,OAAS,WACzB,MAAO1C,EAAO,YAAc,GAC5B,SAAWpK,GAAM6M,EAAS,CAAE,WAAY7M,EAAE,OAAO,MAAO,EACxD,YAAY,wDACZ,UAAU,WAEZK,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,WACV,QAAS,IAAMe,EAAW,CAACD,CAAO,EAEjC,SAAAA,QAAWG,GAAA,CAAO,UAAU,UAAU,EAAK5M,MAAC6M,GAAA,CAAI,UAAU,UAAU,GACvE,EACF,EACA7M,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,uDAAwD,EAC/E,GACF,SACC,OACC,UAAAA,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,iDAAkD,EACzE,EACAkC,MAAC2M,EAAA,CACC,QAAO/M,EAAAmK,EAAO,WAAP,YAAAnK,EAAiB,KAAK,QAAS,GACtC,SAAWD,GAAM6M,EAAS,CAAE,SAAU7M,EAAE,OAAO,MAAM,MAAM,GAAG,EAAE,OAASqN,EAAE,MAAM,EAAE,OAAO,OAAO,EAAG,EACpG,YAAY,qBACZ,UAAU,SAEZhN,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,qDAAsD,EAC7E,GACF,GACF,CAEJ,CAIA,SAASoM,GAAgB,CACvB,OAAArC,EACA,SAAAyC,CACF,EAGG,OACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EACpB,CAAC0O,EAASC,CAAU,EAAIlP,WAAS,EAAK,EAE5C,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,gDAAiD,EACxE,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,KAAMF,EAAU,OAAS,WACzB,MAAO1C,EAAO,YAAc,GAC5B,SAAWpK,GAAM6M,EAAS,CAAE,WAAY7M,EAAE,OAAO,MAAO,EACxD,YAAY,2DACZ,UAAU,WAEZK,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,WACV,QAAS,IAAMe,EAAW,CAACD,CAAO,EAEjC,SAAAA,QAAWG,GAAA,CAAO,UAAU,UAAU,EAAK5M,MAAC6M,GAAA,CAAI,UAAU,UAAU,GACvE,EACF,EACA7M,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,oDAAqD,EAC5E,GACF,SACC,OACC,UAAAA,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,mDAAoD,EAC3E,EACAkC,MAAC2M,EAAA,CACC,QAAO/M,EAAAmK,EAAO,gBAAP,YAAAnK,EAAsB,KAAK,QAAS,GAC3C,SAAWD,GAAM6M,EAAS,CAAE,cAAe7M,EAAE,OAAO,MAAM,MAAM,GAAG,EAAE,OAASsN,EAAE,MAAM,EAAE,OAAO,OAAO,EAAG,EACzG,YAAY,yBACZ,UAAU,SAEZjN,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,uDAAwD,EAC/E,GACF,GACF,CAEJ,CAIA,SAASqM,GAAgB,CACvB,OAAAtC,EACA,SAAAyC,CACF,EAGG,OACD,KAAM,CAAE,cAAA1O,CAAA,EAAkBC,EAAA,EACpB,CAACmP,EAAcC,CAAe,EAAI3P,WAAS,EAAK,EAEtD,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,yBACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,0CAA2C,EAClE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,MAAQ,GACtB,SAAWpK,GAAM6M,EAAS,CAAE,KAAM7M,EAAE,OAAO,MAAO,EAClD,YAAY,iBACZ,UAAU,SAEZK,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,8CAA+C,EACtE,GACF,SACC,OACC,UAAAA,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,0CAA2C,EAClE,EACAkC,MAAC2M,EAAA,CACC,KAAK,SACL,MAAO5C,EAAO,MAAQ,IACtB,SAAWpK,GAAM6M,EAAS,CAAE,KAAM,SAAS7M,EAAE,OAAO,MAAO,EAAE,GAAK,IAAK,EACvE,YAAY,MACZ,UAAU,QACZ,EACF,GACF,EACAI,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,SACC,KAAK,WACL,GAAG,eACH,QAAS+J,EAAO,QAAU,GAC1B,SAAWpK,GAAM6M,EAAS,CAAE,OAAQ7M,EAAE,OAAO,QAAS,EACtD,UAAU,0BAEZK,MAAC,SAAM,QAAQ,eAAe,UAAU,sCACrC,SAAAlC,EAAc,CAAE,GAAI,4CAA6C,EACpE,GACF,SACC,OACC,UAAAkC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,8CAA+C,EACtE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,UAAY,GAC1B,SAAWpK,GAAM6M,EAAS,CAAE,SAAU7M,EAAE,OAAO,MAAO,EACtD,YAAY,uBACZ,UAAU,QACZ,EACF,SACC,OACC,UAAAK,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,8CAA+C,EACtE,EACAiC,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,KAAMO,EAAe,OAAS,WAC9B,MAAOnD,EAAO,UAAY,GAC1B,SAAWpK,GAAM6M,EAAS,CAAE,SAAU7M,EAAE,OAAO,MAAO,EACtD,YAAY,WACZ,UAAU,WAEZK,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,WACV,QAAS,IAAMwB,EAAgB,CAACD,CAAY,EAE3C,SAAAA,QAAgBN,GAAA,CAAO,UAAU,UAAU,EAAK5M,MAAC6M,GAAA,CAAI,UAAU,UAAU,GAC5E,EACF,GACF,SACC,OACC,UAAA7M,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,0CAA2C,EAClE,EACAkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,MAAQ,GACtB,SAAWpK,GAAM6M,EAAS,CAAE,KAAM7M,EAAE,OAAO,MAAO,EAClD,YAAY,sBACZ,UAAU,QACZ,EACF,SACC,OACC,UAAAK,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,wCAAyC,EAChE,EACAkC,MAAC2M,EAAA,CACC,QAAO/M,EAAAmK,EAAO,KAAP,YAAAnK,EAAW,KAAK,QAAS,GAChC,SAAWD,GAAM6M,EAAS,CAAE,GAAI7M,EAAE,OAAO,MAAM,MAAM,GAAG,EAAE,OAASyN,EAAE,MAAM,EAAE,OAAO,OAAO,EAAG,EAC9F,YAAY,uCACZ,UAAU,SAEZpN,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,4CAA6C,EACpE,GACF,GACF,CAEJ,CCnsBO,SAASqN,GAA0B,CAAE,UAAArE,GAA6C,CACvF,KAAM,CAAE,cAAAlL,CAAA,EAAkBC,EAAA,EACpB,CAACgM,EAAQuD,CAAS,EAAI9P,WAA0C,IAAI,EACpE,CAAC+P,EAASC,CAAU,EAAIhQ,WAAS,EAAI,EACrC,CAAC8M,EAAQmD,CAAS,EAAIjQ,WAAS,EAAK,EACpC,CAACyM,EAASyD,CAAU,EAAIlQ,WAAsC,IAAI,EAClE,CAACwM,EAAkB2D,CAAmB,EAAInQ,WAAsC,IAAI,EACpF,CAACoQ,EAAeC,CAAgB,EAAIrQ,WAAwB,IAAI,EAGhEsQ,EAAaxO,cAAY,SAAY,CACzCkO,EAAW,EAAI,EACf,GAAI,CACF,MAAM3Q,EAAW,MAAM,MAAM,kCAAkC,EAC/D,GAAIA,EAAS,GAAI,CACf,MAAMmC,EAAO,MAAMnC,EAAS,OAC5ByQ,EAAUtO,CAAI,CAChB,MAEEsO,EAAUzD,IAAkB,CAEhC,OAAS1K,EAAO,CACd,QAAQ,MAAM,6CAA8CA,CAAK,EACjEmO,EAAUzD,IAAkB,CAC9B,SACE2D,EAAW,EAAK,CAClB,CACF,EAAG,EAAE,EAEL/P,YAAU,IAAM,CACdqQ,EAAA,CACF,EAAG,CAACA,CAAU,CAAC,EAGf,MAAMC,EAAazO,cAAY,MAAO0O,GAAwC,CAC5EP,EAAU,EAAI,EACd,GAAI,CACF,MAAM5Q,EAAW,MAAM,MAAM,mCAAoC,CAC/D,OAAQ,OACR,QAAS,CAAE,eAAgB,oBAC3B,KAAM,KAAK,UAAUmR,CAAS,EAC/B,EAED,GAAInR,EAAS,GAAI,CACf,MAAMmC,EAAO,MAAMnC,EAAS,OAC5ByQ,EAAUtO,EAAK,MAAM,EACrBiP,EAAM,QAAQnQ,EAAc,CAAE,GAAI,qCAAsC,CAAC,CAC3E,KACE,OAAM,IAAI,MAAM,QAAQjB,EAAS,MAAM,EAAE,CAE7C,MAAgB,CACdoR,EAAM,MAAMnQ,EAAc,CAAE,GAAI,yCAA0C,CAAC,CAC7E,SACE2P,EAAU,EAAK,CACjB,CACF,EAAG,CAAC3P,CAAa,CAAC,EAGZoQ,EAAe5O,cAAY,MAC/BmL,EACAU,IACG,CACHuC,EAAWjD,CAAQ,EACnB,GAAI,CAOF,MAAM5K,EAAS,MANE,MAAM,MAAM,iCAAkC,CAC7D,OAAQ,OACR,QAAS,CAAE,eAAgB,oBAC3B,KAAM,KAAK,UAAU,CAAE,SAAA4K,EAAU,OAAQU,EAAgB,EAC1D,GAE6B,OAE1BtL,EAAO,QACToO,EAAM,QACJnQ,EAAc,CAAE,GAAI,2CAA4C,EAChE,CAAE,YAAa,GAAG+B,EAAO,YAAY,KAAK,EAG5CoO,EAAM,MACJnQ,EAAc,CAAE,GAAI,0CAA2C,EAC/D,CAAE,YAAa+B,EAAO,MAAM,CAGlC,MAAgB,CACdoO,EAAM,MAAMnQ,EAAc,CAAE,GAAI,yCAA0C,CAAC,CAC7E,SACE4P,EAAW,IAAI,CACjB,CACF,EAAG,CAAC5P,CAAa,CAAC,EAGZqQ,EAAgB,IAAM,CACrBpE,GACLgE,EAAW,CAAE,GAAGhE,EAAQ,QAAS,CAACA,EAAO,QAAS,CACpD,EAGMqE,EAAuB,CAC3B3D,EACAuB,IACG,CACH,GAAI,CAACjC,EAAQ,OACb,MAAMiE,EAAY,CAChB,GAAGjE,EACH,UAAW,CACT,GAAGA,EAAO,UACV,CAACU,CAAQ,EAAG,CACV,GAAGV,EAAO,UAAUU,CAAyC,EAC7D,GAAGuB,CAAA,CACL,CACF,EAEFsB,EAAUU,CAAS,CACrB,EAGMK,EAAoB,CAACC,EAAoBtC,IAAkC,CAC/E,GAAI,CAACjC,EAAQ,OACb,MAAMwE,EAAY,CAAC,GAAGxE,EAAO,MAAM,EACnCwE,EAAUD,CAAU,EAAI,CAAE,GAAGC,EAAUD,CAAU,EAAG,GAAGtC,CAAA,EACvDsB,EAAU,CAAE,GAAGvD,EAAQ,OAAQwE,EAAW,CAC5C,EAGMC,EAAsB,CAACF,EAAoB7D,IAAmC,CAClF,GAAI,CAACV,EAAQ,OACb,MAAM0E,EAAc1E,EAAO,OAAOuE,CAAU,EACtC/D,EAAYkE,EAAY,UAAU,SAAShE,CAAQ,EACrDgE,EAAY,UAAU,OAAQrO,GAAMA,IAAMqK,CAAQ,EAClD,CAAC,GAAGgE,EAAY,UAAWhE,CAAQ,EACvC4D,EAAkBC,EAAY,CAAE,UAAA/D,EAAW,CAC7C,EAGMmE,EAAuC,CAAC,UAAW,WAAY,SAAU,WAAY,QAAS,QAAS,SAAS,EAGhHC,EAAc,SAAY,CAC9B,GAAK,QAAQ7Q,EAAc,CAAE,GAAI,4CAA6C,CAAC,EAG/E,GAAI,CACF,MAAMjB,EAAW,MAAM,MAAM,kCAAmC,CAC9D,OAAQ,OACT,EACD,GAAIA,EAAS,GAAI,CACf,MAAMmC,EAAO,MAAMnC,EAAS,OAC5ByQ,EAAUtO,EAAK,MAAM,EACrBiP,EAAM,QAAQnQ,EAAc,CAAE,GAAI,4CAA6C,CAAC,CAClF,CACF,MAAQ,CACNmQ,EAAM,MAAMnQ,EAAc,CAAE,GAAI,0CAA2C,CAAC,CAC9E,CACF,EAEA,OAAIyP,QAEC/B,EAAA,CAAK,UAAWlC,EAAG,MAAON,CAAS,EAClC,SAAAhJ,MAAC,OAAI,UAAU,wCACb,SAAAA,MAAC4O,GAAA,CAAU,UAAU,6CAA6C,EACpE,EACF,EAIC7E,SAKFyB,EAAA,CAAK,UAAWlC,EAAG,MAAON,CAAS,EAElC,UAAAjJ,OAAC,OAAI,UAAU,yCACb,UAAAA,OAAC,MAAG,UAAU,gEACX,UAAAgK,EAAO,cACLc,GAAA,CAAK,UAAU,uBAAuB,EAEvC7K,MAACjE,GAAA,CAAQ,UAAU,gCAAgC,EAEpD+B,EAAc,CAAE,GAAI,qCAAsC,GAC7D,EACAiC,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMmC,EAAA,EACf,SAAUP,EAEV,eAACqB,GAAA,CAAU,UAAWtF,EAAG,cAAeiE,GAAW,cAAc,EAAG,IAEtEvN,MAAC2L,EAAA,CACC,QAAS5B,EAAO,QAAU,UAAY,UACtC,KAAK,KACL,QAASoE,EAER,SAAApE,EAAO,QACNhK,OAAAI,WAAA,CACE,UAAAH,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,uCAAwC,GAC/D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAAC4L,GAAA,CAAE,UAAU,eAAe,EAC3B9N,EAAc,CAAE,GAAI,wCAAyC,GAChE,GAEJ,EACF,GACF,EAGAkC,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,2CAA4C,EACnE,EAEC+J,EAAO,SACNhK,OAAAI,WAAA,CAEE,UAAAJ,OAAC,OAAI,UAAU,iBACb,UAAAC,MAAC,MAAG,UAAU,sCACX,SAAAlC,EAAc,CAAE,GAAI,yCAA0C,EACjE,EACAkC,MAAC8J,GAAA,CACC,OAAAC,EACA,iBAAAC,EACA,QAAAC,EACA,eAAgB0D,EAChB,eAAgBS,EAChB,OAAQF,EACR,OAAQ,IAAMH,EAAWhE,CAAM,EAC/B,OAAAO,CAAA,EACF,EACF,EAGAvK,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,MAAG,UAAU,sCACX,SAAAlC,EAAc,CAAE,GAAI,sCAAuC,EAC9D,EACAkC,MAAC,OAAI,UAAU,aACZ,WAAO,OAAO,IAAI,CAACyO,EAAaI,IAAU,CACzC,MAAMxD,EAAOzB,GAAW6E,EAAY,KAAK,EACnCK,EAAalB,IAAkBiB,EACrC,OACE9O,OAAC,OAEC,UAAU,8DAGV,UAAAA,OAAC,OACC,UAAU,2FACV,QAAS,IAAM8N,EAAiBiB,EAAa,KAAOD,CAAK,EAEzD,UAAA9O,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,OAAI,UAAWsJ,EACd,iBACAmF,EAAY,QAAU,6BAA+B,kCAErD,SAAAzO,MAAC,QAAK,UAAU,UAAW,SAAAqL,EAAK,KAAK,EACvC,SACC,OACC,UAAArL,MAAC,KAAE,UAAU,sBAAuB,SAAAqL,EAAK,KAAK,EAC9CrL,MAAC,KAAE,UAAU,gCAAiC,WAAK,YAAY,GACjE,GACF,EACAD,OAAC,OAAI,UAAU,0BAEb,UAAAA,OAAC,OAAI,UAAU,gCACZ,UAAA0O,EAAY,UAAU,MAAM,EAAG,CAAC,EAAE,IAAKhE,GACtCzK,MAACyL,GAAqB,QAAQ,YAAY,UAAU,UACjD,SAAA9B,GAAcc,CAAQ,EAAE,MADfA,CAEZ,CACD,EACAgE,EAAY,UAAU,OAAS,UAC7BhD,EAAA,CAAM,QAAQ,YAAY,UAAU,UAAU,cAC3CgD,EAAY,UAAU,OAAS,GACnC,EAEDA,EAAY,UAAU,SAAW,SAC/BhD,EAAA,CAAM,QAAQ,UAAU,UAAU,gCAChC,SAAA3N,EAAc,CAAE,GAAI,2CAA4C,EACnE,GAEJ,EAEAkC,MAAC2L,EAAA,CACC,QAAS8C,EAAY,QAAU,UAAY,UAC3C,KAAK,KACL,UAAU,MACV,QAAU9O,GAAM,CACdA,EAAE,kBACF0O,EAAkBQ,EAAO,CAAE,QAAS,CAACJ,EAAY,QAAS,CAC5D,EAEC,SAAAA,EAAY,QACXzO,MAAC0L,GAAA,CAAM,UAAU,cAAc,EAE/B1L,MAAC4L,GAAA,CAAE,UAAU,cAAc,IAI9BkD,QACEjD,GAAA,CAAU,UAAU,gCAAgC,EAErD7L,MAAC8L,GAAA,CAAY,UAAU,gCAAgC,GAE3D,KAIDgD,GACC/O,OAAC,OAAI,UAAU,mDACb,UAAAC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CAAE,GAAI,+CAAgD,EACvE,QACC,OAAI,UAAU,uBACZ,SAAA4Q,EAAa,IAAKjE,GAAa,CAC9B,MAAM9C,EAAa8G,EAAY,UAAU,SAAShE,CAAQ,EACpDsE,EAAepF,GAAcc,CAAQ,EACrCU,EAAiBpB,EAAO,UAAUU,CAAQ,EAC1CS,EAAeC,GAAA,YAAAA,EAAgB,QACrC,OACEpL,OAAC4L,EAAA,CAEC,QAAShE,EAAa,UAAY,UAClC,KAAK,KACL,UAAW2B,EACT,MACA,CAAC4B,GAAgB,CAACvD,GAAc,cAElC,QAAS,IAAM6G,EAAoBK,EAAOpE,CAAQ,EAEjD,UAAA9C,GAAc3H,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC9CqD,EAAa,KACb,CAAC7D,GAAgB,CAACvD,GACjB3H,MAACgP,GAAA,CAAK,UAAU,0BAA0B,IAZvCvE,CAAA,CAgBX,CAAC,EACH,GACF,IAhGGgE,EAAY,MAoGvB,CAAC,EACH,GACF,EAGA1O,OAAC,OAAI,UAAU,qEACb,UAAAC,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASgD,EAER,SAAA7Q,EAAc,CAAE,GAAI,qCAAsC,IAE7DiC,OAAC4L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMoC,EAAWhE,CAAM,EAChC,SAAUO,EAEV,UAAAtK,MAACiP,GAAA,CAAK,UAAU,eAAe,EAE3BnR,EADHwM,EACiB,CAAE,GAAI,uCACN,CAAE,GAAI,oCADuC,CACF,GAC/D,EACF,GACF,GAEJ,EA9MO,IAgNX,CCzYA,SAAS4E,GAAY,CAAE,MAAAjP,EAAO,MAAAkP,EAAO,YAAAC,EAAa,SAAAC,EAAU,QAAAC,GAA6B,CACvF,MAAMC,EAA8C,CAClD,YACG,OAAI,UAAU,8EACb,SAAAvP,MAAC,OAAI,UAAU,2CAA2C,EAC5D,EAEF,aACG,OAAI,UAAU,8EACb,SAAAA,MAAC,OAAI,UAAU,2CAA2C,EAC5D,EAEF,YACG,OAAI,UAAU,iFACb,SAAAA,MAAC,OAAI,UAAU,2CAA2C,EAC5D,EAEF,iBACG,OAAI,UAAU,8EACb,SAAAA,MAAC,OAAI,UAAU,2CAA2C,EAC5D,GAIJ,OACED,OAAC,UACC,KAAK,SACL,QAAAuP,EACA,UAAWhG,EACT,0EACA,qBACA+F,EACI,4CACA,uCAGL,UAAAE,EAAMtP,CAAK,EACZF,OAAC,OAAI,UAAU,cACb,UAAAC,MAAC,OAAI,UAAWsJ,EAAG,sBAAuB+F,GAAY,cAAc,EAAI,SAAAF,EAAM,EAC9EnP,MAAC,OAAI,UAAU,gCAAiC,SAAAoP,CAAA,CAAY,GAC9D,IAGN,CAUA,SAASI,GAAe,CAAE,MAAAvP,EAAO,SAAAwP,EAAU,SAAAC,GAAiC,CAC1E,MAAMC,EAAU,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAG,EAE5C,aACG,OAAI,UAAU,uBACZ,SAAAA,EAAQ,IAAKC,GACZ7P,OAAC4L,EAAA,CAEC,KAAK,SACL,QAAS1L,IAAU2P,EAAU,UAAY,UACzC,KAAK,KACL,SAAAF,EACA,QAAS,IAAMD,EAASG,CAAO,EAE9B,UAAAA,EAAQ,MAPJA,CAAA,CASR,EACH,CAEJ,CAIO,SAASC,IAAyB,CACvC,KAAM,CAAE,cAAA/R,CAAA,EAAkBC,EAAA,EACpB,CAAE,YAAA+R,EAAa,iBAAAC,EAAkB,iBAAAC,CAAA,EAAqBC,GAAA,EAEtDC,EAAkF,CACtF,CACE,MAAO,QACP,MAAOpS,EAAc,CAAE,GAAI,2BAA4B,eAAgB,QAAS,EAChF,YAAaA,EAAc,CAAE,GAAI,+BAAgC,eAAgB,WAAY,GAE/F,CACE,MAAO,SACP,MAAOA,EAAc,CAAE,GAAI,4BAA6B,eAAgB,SAAU,EAClF,YAAaA,EAAc,CAAE,GAAI,gCAAiC,eAAgB,aAAc,GAElG,CACE,MAAO,QACP,MAAOA,EAAc,CAAE,GAAI,2BAA4B,eAAgB,QAAS,EAChF,YAAaA,EAAc,CAAE,GAAI,+BAAgC,eAAgB,SAAU,GAE7F,CACE,MAAO,aACP,MAAOA,EAAc,CAAE,GAAI,gCAAiC,eAAgB,aAAc,EAC1F,YAAaA,EAAc,CAAE,GAAI,oCAAqC,eAAgB,cAAe,EACvG,EAGF,OACEiC,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAAC4K,GAAA,CAAc,UAAU,UAAU,EAClC9M,EAAc,CAAE,GAAI,yBAA0B,eAAgB,mBAAoB,GACrF,EAEAiC,OAAC,OAAI,UAAU,YAEb,UAAAA,OAAC,OAAI,UAAU,YACb,UAAAA,OAACoQ,GAAA,CAAM,UAAU,8CACf,UAAAnQ,MAAC7D,GAAA,CAAgB,UAAU,UAAU,EACpC2B,EAAc,CAAE,GAAI,4BAA6B,eAAgB,eAAgB,GACpF,EACAkC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CACb,GAAI,gCACJ,eAAgB,wCACjB,EACH,QACC,OAAI,UAAU,yBACZ,SAAAoS,EAAa,IAAKzG,GACjBzJ,MAACkP,GAAA,CAEC,MAAOzF,EAAO,MACd,MAAOA,EAAO,MACd,YAAaA,EAAO,YACpB,SAAUqG,EAAY,cAAgBrG,EAAO,MAC7C,QAAS,IAAMsG,EAAiB,cAAetG,EAAO,KAAK,GALtDA,EAAO,MAOf,EACH,GACF,EAGA1J,OAAC,OAAI,UAAU,gEACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAACoQ,GAAA,CAAS,UAAU,gCAAgC,SACnD,OACC,UAAApQ,MAAC,KAAE,UAAU,sBACV,SAAAlC,EAAc,CAAE,GAAI,0BAA2B,eAAgB,aAAc,EAChF,EACAkC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CACb,GAAI,8BACJ,eAAgB,2CACjB,EACH,GACF,GACF,EACAkC,MAAC2L,EAAA,CACC,QAASmE,EAAY,iBAAmB,UAAY,UACpD,KAAK,KACL,QAAS,IAAMC,EAAiB,mBAAoB,CAACD,EAAY,gBAAgB,EAEhF,WAAY,iBACThS,EAAc,CAAE,GAAI,iBAAkB,eAAgB,UAAW,EACjEA,EAAc,CAAE,GAAI,kBAAmB,eAAgB,WAAY,GACzE,EACF,EAGAiC,OAAC,OAAI,UAAU,wCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAACqQ,GAAA,CAAM,UAAU,gCAAgC,EACjDrQ,MAACmQ,GAAA,CAAM,UAAU,sBACd,SAAArS,EAAc,CAAE,GAAI,sCAAuC,eAAgB,0BAA2B,EACzG,GACF,EACAkC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CACb,GAAI,0CACJ,eAAgB,iDACjB,EACH,EACAkC,MAACwP,GAAA,CACC,MAAOM,EAAY,sBACnB,SAAWQ,GAAMP,EAAiB,wBAAyBO,CAAC,GAC9D,EACF,EAGAvQ,OAAC,OAAI,UAAU,gEACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,sBACV,SAAAlC,EAAc,CAAE,GAAI,mCAAoC,eAAgB,uBAAwB,EACnG,EACAkC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CACb,GAAI,uCACJ,eAAgB,oDACjB,EACH,GACF,EACAkC,MAAC2L,EAAA,CACC,QAASmE,EAAY,mBAAqB,UAAY,UACtD,KAAK,KACL,QAAS,IAAMC,EAAiB,qBAAsB,CAACD,EAAY,kBAAkB,EAEpF,WAAY,mBACThS,EAAc,CAAE,GAAI,iBAAkB,eAAgB,UAAW,EACjEA,EAAc,CAAE,GAAI,kBAAmB,eAAgB,WAAY,GACzE,EACF,EAGAiC,OAAC,OAAI,UAAU,gEACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC3D,GAAA,CAAQ,UAAU,gCAAgC,SAClD,OACC,UAAA2D,MAAC,KAAE,UAAU,sBACV,SAAAlC,EAAc,CAAE,GAAI,kCAAmC,eAAgB,qBAAsB,EAChG,EACAkC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CACb,GAAI,sCACJ,eAAgB,mDACjB,EACH,GACF,GACF,EACAkC,MAAC2L,EAAA,CACC,QAASmE,EAAY,0BAA4B,UAAY,UAC7D,KAAK,KACL,QAAS,IAAMC,EAAiB,4BAA6B,CAACD,EAAY,yBAAyB,EAElG,WAAY,0BACThS,EAAc,CAAE,GAAI,iBAAkB,eAAgB,UAAW,EACjEA,EAAc,CAAE,GAAI,kBAAmB,eAAgB,WAAY,GACzE,EACF,EAGAiC,OAAC,OAAI,UAAU,gEACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,sBACV,SAAAlC,EAAc,CAAE,GAAI,kCAAmC,eAAgB,sBAAuB,EACjG,EACAkC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CACb,GAAI,sCACJ,eAAgB,+CACjB,EACH,GACF,EACAkC,MAAC2L,EAAA,CACC,QAASmE,EAAY,wBAA0B,UAAY,UAC3D,KAAK,KACL,QAAS,IAAMC,EAAiB,0BAA2B,CAACD,EAAY,uBAAuB,EAE9F,WAAY,wBACThS,EAAc,CAAE,GAAI,iBAAkB,eAAgB,UAAW,EACjEA,EAAc,CAAE,GAAI,kBAAmB,eAAgB,WAAY,GACzE,EACF,EAGAkC,MAAC,OAAI,UAAU,+CACb,eAAC2L,EAAA,CAAO,QAAQ,UAAU,KAAK,KAAK,QAASqE,EAC1C,SAAAlS,EAAc,CAAE,GAAI,yBAA0B,eAAgB,oBAAqB,EACtF,EACF,GACF,GACF,CAEJ,CC1QA,MAAMyS,GAAgB,CAAC,GAAI,MAAO,SAAU,MAAM,EAC5CC,GAAiB,CAAC,GAAI,MAAO,SAAU,OAAQ,KAAK,EACpDC,GAAuB,CAAC,SAAU,OAAQ,QAAS,SAAS,EAC5DC,GAAmB,CAAC,GAAI,UAAW,cAAe,UAAW,oBAAqB,MAAM,EACxFC,GAAiB,CAAC,GAAI,OAAQ,UAAW,OAAO,EAChDC,GAAoB,CAAC,GAAI,UAAU,EACnCC,GAAgB,CAAC,GAAI,SAAU,OAAQ,SAAU,QAAS,KAAK,EAC/DC,GAAc,CAAC,aAAc,cAAe,MAAM,EAElDC,GAAc,6DACdC,EAAa,yCAInB,SAASC,GAAoBC,EAAwB,CACnD,GAAI,CAACA,EAAM,MAAO,GAClB,MAAMC,EAAoB,GACpBC,EAAQF,EAAK,MAAM;AAAA,CAAI,EAC7B,UAAWG,KAAQD,EAAO,CACxB,MAAM7U,EAAQ8U,EAAK,MAAM,eAAe,EACpC9U,GAAO4U,EAAQ,KAAK5U,EAAM,CAAC,EAAE,MAAM,CACzC,CACA,OAAO4U,CACT,CAEA,SAASG,GAAwBH,EAA2B,CAC1D,OAAIA,EAAQ,SAAW,EAAU,GAC1B;AAAA,EAAgBA,EAAQ,IAAIrL,GAAK,OAAOA,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,CAAC,EAChE,CAaA,SAASyL,GAAeL,EAA2B,CACjD,MAAMrR,EAAsB,CAAE,WAAY,GAAI,YAAa,GAAI,KAAM,EAAC,EACtE,GAAI,CAACqR,EAAM,OAAOrR,EAElB,IAAI2R,EAA8B,KAC9BC,EAAgC,KACpC,MAAML,EAAQF,EAAK,MAAM;AAAA,CAAI,EAE7B,UAAWG,KAAQD,EAAO,CAExB,MAAMM,EAAaL,EAAK,MAAM,iBAAiB,EAC/C,GAAIK,GAAeA,EAAW,CAAC,IAAK7R,EAAS,CAC3C2R,EAAeE,EAAW,CAAC,EAC3BD,EAAiB,KACjB,QACF,CAEA,MAAME,EAAeN,EAAK,MAAM,0CAA0C,EAC1E,GAAIM,GAAgBH,EAAc,CAChCC,EAAiBE,EAAa,CAAC,EAAE,OACjC,QACF,CAEA,MAAMC,EAAeP,EAAK,MAAM,sCAAsC,EACtE,GAAIO,GAAgBJ,GAAgBC,IAAmB,KAAM,CAC3D5R,EAAO2R,CAAiC,EAAE,KAAK,CAC7C,QAASC,EACT,QAASG,EAAa,CAAC,EAAE,MAAK,CAC/B,EACDH,EAAiB,KACjB,QACF,CAEF,CACA,OAAO5R,CACT,CAEA,SAASgS,GAAmBC,EAA4B,CACtD,MAAMC,EAAkB,GACxB,UAAWC,KAASlB,GAAa,CAC/B,MAAMmB,EAAUH,EAAME,CAA0B,EAChD,GAAIC,EAAQ,SAAW,EACvB,CAAAF,EAAM,KAAK,KAAKC,CAAK,GAAG,EACxB,UAAWE,KAASD,EAClBF,EAAM,KAAK,mBAAmBG,EAAM,OAAO,GAAG,EAC9CH,EAAM,KAAK,cAAc,EACzBA,EAAM,KAAK,yBAAyB,EACpCA,EAAM,KAAK,uBAAuBG,EAAM,OAAO,GAAG,EAEtD,CACA,OAAIH,EAAM,SAAW,EAAU,GACxB;AAAA,EAAWA,EAAM,KAAK;AAAA,CAAI,CAAC,EACpC,CASA,SAASI,GAAiB,CAAE,MAAAC,EAAO,QAAAC,GAAkC,CAEnE,KAAM,CAACC,EAAOC,CAAQ,EAAI/U,WAAS4U,EAAM,KAAK,EACxC,CAACI,EAAgBC,CAAiB,EAAIjV,WAAS4U,EAAM,cAAc,EACnE,CAACM,EAAQC,CAAS,EAAInV,WAAS4U,EAAM,MAAM,EAC3C,CAACQ,EAAUC,CAAW,EAAIrV,WAAS4U,EAAM,QAAQ,EACjD,CAACU,EAAYC,CAAa,EAAIvV,WAAS4U,EAAM,aAAe,MAAM,EAClE,CAACY,EAAWC,CAAY,EAAIzV,WAAS4U,EAAM,SAAS,EAGpD,CAACc,EAAOC,CAAQ,EAAI3V,WAAS4U,EAAM,KAAK,EACxC,CAACgB,EAAiBC,CAAkB,EAAI7V,WAAS4U,EAAM,eAAe,EACtE,CAACkB,EAAQC,CAAS,EAAI/V,WAAS4U,EAAM,MAAM,EAG3C,CAACoB,EAAkBC,CAAmB,EAAIjW,WAAmB,EAAE,EAC/D,CAACkW,EAAiBC,CAAkB,EAAInW,WAAmB,IAAMyT,GAAoBmB,EAAM,UAAU,CAAC,EACtG,CAACwB,EAAYC,CAAa,EAAIrW,WAAS,EAAK,EAC5C,CAACsW,EAAcC,CAAe,EAAIvW,WAAS,EAAE,EAG7C,CAACsU,EAAOkC,CAAQ,EAAIxW,WAAsB,IAAM+T,GAAea,EAAM,KAAK,CAAC,EAC3E,CAAC6B,EAAcC,CAAe,EAAI1W,WAAS,YAAY,EAEvD,CAAC8M,EAAQmD,EAAS,EAAIjQ,WAAS,EAAK,EAG1CC,YAAU,IAAM,CACd,IAAI0W,EAAY,GAChB,OAAAN,EAAc,EAAI,EAClBO,GAAA,EACG,KAAMrK,GAAW,CAChB,GAAIoK,EAAW,OACf,MAAME,MAAY,IAEdtK,EAAO,aAAa,OAAO,KAAKA,EAAO,WAAW,EAAE,QAAQuK,GAAKD,EAAM,IAAIC,CAAC,CAAC,EAC7EvK,EAAO,eAAe,OAAO,KAAKA,EAAO,aAAa,EAAE,QAAQuK,GAAKD,EAAM,IAAIC,CAAC,CAAC,EACjFvK,EAAO,UACT,OAAO,OAAOA,EAAO,QAAQ,EAAE,QAASwK,GAAc,CAChDA,GAAA,MAAAA,EAAM,YAAY,OAAO,KAAKA,EAAK,UAAU,EAAE,QAAQD,GAAKD,EAAM,IAAIC,CAAC,CAAC,CAC9E,CAAC,EAEHb,EAAoB,MAAM,KAAKY,CAAK,EAAE,MAAM,CAC9C,CAAC,EACA,MAAM,IAAM,CAAC,CAAC,EACd,QAAQ,IAAM,CAAOF,GAAWN,EAAc,EAAK,CAAG,CAAC,EACnD,IAAM,CAAEM,EAAY,EAAM,CACnC,EAAG,EAAE,EAGL1W,YAAU,IAAM,CACd8U,EAASH,EAAM,KAAK,EACpBK,EAAkBL,EAAM,cAAc,EACtCO,EAAUP,EAAM,MAAM,EACtBS,EAAYT,EAAM,QAAQ,EAC1BW,EAAcX,EAAM,aAAe,MAAM,EACzCa,EAAab,EAAM,SAAS,EAC5Be,EAASf,EAAM,KAAK,EACpBiB,EAAmBjB,EAAM,eAAe,EACxCmB,EAAUnB,EAAM,MAAM,EACtBuB,EAAmB1C,GAAoBmB,EAAM,UAAU,CAAC,EACxD4B,EAASzC,GAAea,EAAM,KAAK,CAAC,CACtC,EAAG,CAACA,CAAK,CAAC,EAEV,MAAMoC,GAAalV,cAAY,SAAY,CACzCmO,GAAU,EAAI,EACd,GAAI,CACF,MAAM3Q,EAAgE,CAAE,SAAUsV,EAAM,UAGpFE,IAAUF,EAAM,QAAOtV,EAAK,MAAQwV,GACpCE,IAAmBJ,EAAM,iBAAgBtV,EAAK,eAAiB0V,GAC/DE,IAAWN,EAAM,SAAQtV,EAAK,OAAS4V,GACvCE,IAAaR,EAAM,WAAUtV,EAAK,SAAW8V,GACjD,MAAM6B,EAAQ3B,EAAa,OAAS,GAChC2B,IAAUrC,EAAM,aAAYtV,EAAK,WAAa2X,GAC9CzB,IAAcZ,EAAM,YAAWtV,EAAK,UAAYkW,GAChDE,IAAUd,EAAM,QAAOtV,EAAK,MAAQoW,GACpCE,IAAoBhB,EAAM,kBAAiBtV,EAAK,gBAAkBsW,GAClEE,IAAWlB,EAAM,SAAQtV,EAAK,OAASwW,GAG3C,MAAMoB,EAAapD,GAAwBoC,CAAe,EACtDgB,IAAetC,EAAM,aAAYtV,EAAK,WAAa4X,GAGvD,MAAMC,EAAe9C,GAAmBC,CAAK,EAK7C,GAJI6C,IAAiBvC,EAAM,QAAOtV,EAAK,MAAQ6X,GAG3B,OAAO,KAAK7X,CAAI,EAAE,OAAOkQ,IAAKA,KAAM,UAAU,EAClD,SAAW,EAAG,CAC5BiB,EAAM,KAAK,oBAAoB,EAC/B,MACF,CAEA,MAAM2G,GAAsBxC,EAAM,KAAMA,EAAM,KAAMtV,CAAI,EACxDmR,EAAM,QAAQ,WAAWmE,EAAM,IAAI,oBAAoB,EACvDC,EAAA,CACF,OAASvS,EAAK,CACZmO,EAAM,MAAM,WAAYnO,EAAc,OAAO,EAAE,CACjD,SACE2N,GAAU,EAAK,CACjB,CACF,EAAG,CAAC2E,EAAOE,EAAOE,EAAgBE,EAAQE,EAAUE,EAAYE,EAAWE,EAAOE,EAAiBE,EAAQI,EAAiB5B,EAAOO,CAAO,CAAC,EAErIwC,GAAgBC,GAAiB,CACrCnB,EAAmBoB,GACjBA,EAAK,SAASD,CAAI,EAAIC,EAAK,OAAOjP,GAAKA,IAAMgP,CAAI,EAAI,CAAC,GAAGC,EAAMD,CAAI,EAEvE,EAEME,GAAkB,IAAM,CAC5B,MAAMF,EAAOhB,EAAa,OACtBgB,GAAQ,CAACpB,EAAgB,SAASoB,CAAI,IACxCnB,EAAmBoB,GAAQ,CAAC,GAAGA,EAAMD,CAAI,CAAC,EAC1Cf,EAAgB,EAAE,EAEtB,EAEMkB,EAAU,IAAM,CACpBjB,EAASe,IAAS,CAChB,GAAGA,EACH,CAACd,CAAY,EAAG,CAAC,GAAGc,EAAKd,CAAiC,EAAG,CAAE,QAAS,GAAI,QAAS,GAAI,GACzF,CACJ,EAEMiB,GAAa,CAAClD,EAAemD,IAAgB,CACjDnB,EAASe,IAAS,CAChB,GAAGA,EACH,CAAC/C,CAAK,EAAG+C,EAAK/C,CAA0B,EAAE,OAAO,CAACoD,EAAGpN,IAAMA,IAAMmN,CAAG,GACpE,CACJ,EAEME,GAAa,CAACrD,EAAemD,EAAaG,EAA8BrV,IAAkB,CAC9F+T,EAASe,IAAS,CAChB,GAAGA,EACH,CAAC/C,CAAK,EAAG+C,EAAK/C,CAA0B,EAAE,IAAI,CAACuD,GAAGvN,KAAMA,KAAMmN,EAAM,CAAE,GAAGI,GAAG,CAACD,CAAK,EAAGrV,CAAA,EAAUsV,EAAC,GAChG,CACJ,EAEA,OACExV,OAAC,OAAI,UAAU,sEAEb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,kBAAM,EACnChR,MAAC,UAAO,UAAW+Q,GAAa,MAAOuB,EAAO,SAAU3S,GAAK4S,EAAS5S,EAAE,OAAO,KAAK,EACjF,SAAAkR,GAAc,IAAI2E,GAAKxV,MAAC,UAAe,MAAOwV,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EACvE,GACF,EACAzV,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,uBAAW,EACxChR,MAAC,UAAO,UAAW+Q,GAAa,MAAOyB,EAAgB,SAAU7S,GAAK8S,EAAkB9S,EAAE,OAAO,KAAK,EACnG,SAAA+Q,GAAiB,IAAItQ,GAAKJ,MAAC,UAAe,MAAOI,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EAC1E,GACF,EACAL,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,mBAAO,EACpChR,MAAC,UAAO,UAAW+Q,GAAa,MAAO2B,EAAQ,SAAU/S,GAAKgT,EAAUhT,EAAE,OAAO,KAAK,EACnF,SAAAgR,GAAe,IAAI1D,GAAKjN,MAAC,UAAe,MAAOiN,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EACxE,GACF,EACAlN,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,qBAAS,EACtChR,MAAC2M,EAAA,CACC,UAAU,uBACV,KAAK,SACL,MAAOiG,EACP,SAAUjT,GAAKkT,EAAYlT,EAAE,OAAO,KAAK,EACzC,YAAY,KACd,EACF,EACAI,OAAC,OAAI,UAAU,4BACb,UAAAC,MAACyV,GAAA,CACC,QAAS3C,EACT,gBAAkBxC,GAAMyC,EAAczC,IAAM,EAAI,IAElDtQ,MAAC,QAAK,UAAWgR,EAAY,sBAAU,GACzC,EACAjR,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,sBAAU,EACvChR,MAAC,UAAO,UAAW+Q,GAAa,MAAOiC,EAAW,SAAUrT,GAAKsT,EAAatT,EAAE,OAAO,KAAK,EACzF,SAAAiR,GAAkB,IAAI5I,GAAKhI,MAAC,UAAe,MAAOgI,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EAC3E,GACF,GACF,EAGAjI,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,kBAAM,EACnChR,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAOuG,EACP,SAAUvT,GAAKwT,EAASxT,EAAE,OAAO,KAAK,EACtC,YAAY,iCACd,EACF,EACAI,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,uBAAW,EACxChR,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAOyG,EACP,SAAUzT,GAAK0T,EAAmB1T,EAAE,OAAO,KAAK,EAChD,YAAY,aACd,EACF,EACAI,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,mBAAO,EACpChR,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAO2G,EACP,SAAU3T,GAAK4T,EAAU5T,EAAE,OAAO,KAAK,EACvC,YAAY,wCACd,EACF,GACF,EAGAI,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,QAAK,UAAU,4CAA4C,wBAAY,EACvE4T,EACC5T,MAAC,QAAK,UAAU,qCAAqC,sBAAU,EAE/DD,OAAC,OAAI,UAAU,4BACZ,UAAAyT,EAAiB,IAAIsB,GACpB/U,OAAC,SAAiB,UAAU,mDAC1B,UAAAC,MAACyV,GAAA,CACC,QAAS/B,EAAgB,SAASoB,CAAI,EACtC,gBAAiB,IAAMD,GAAaC,CAAI,IAE1C9U,MAAC,QAAK,UAAU,kBAAmB,SAAA8U,CAAA,CAAK,IAL9BA,CAMZ,CACD,EAEApB,EAAgB,OAAO5N,GAAK,CAAC0N,EAAiB,SAAS1N,CAAC,CAAC,EAAE,IAAIgP,GAC9D/U,OAAC,SAAiB,UAAU,mDAC1B,UAAAC,MAACyV,IAAS,QAAO,GAAC,gBAAiB,IAAMZ,GAAaC,CAAI,EAAG,EAC7D9U,MAAC,QAAK,UAAU,yBAA0B,SAAA8U,CAAA,CAAK,IAFrCA,CAGZ,CACD,EACD/U,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC2M,EAAA,CACC,UAAU,wBACV,MAAOmH,EACP,SAAUnU,GAAKoU,EAAgBpU,EAAE,OAAO,KAAK,EAC7C,YAAY,WACZ,UAAWA,GAAK,CAAMA,EAAE,MAAQ,SAASqV,GAAA,CAAmB,UAE7DrJ,EAAA,CAAO,QAAQ,QAAQ,KAAK,KAAK,UAAU,WAAW,QAASqJ,GAAiB,SAAU,CAAClB,EAAa,OACvG,eAAC9E,GAAA,CAAK,UAAU,UAAU,EAC5B,GACF,GACF,GAEJ,EAGAjP,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,QAAK,UAAU,4CAA4C,kBAAM,EACjE8Q,GAAY,IAAIkB,GAAS,CACxB,MAAMC,EAAUH,EAAME,CAA0B,EAChD,OAAIC,EAAQ,SAAW,EAAU,KAE/BlS,OAAC,OAAgB,UAAU,iBACzB,UAAAA,OAAC,QAAK,UAAU,4CAA6C,UAAAiS,EAAM,KAAC,EACnEC,EAAQ,IAAI,CAACC,EAAOiD,IACnBpV,OAAC,OAAc,UAAU,+BACvB,UAAAC,MAAC2M,EAAA,CACC,UAAU,wBACV,MAAOuF,EAAM,QACb,YAAemD,GAAWrD,EAAOmD,EAAK,UAAWxV,EAAE,OAAO,KAAK,EAC/D,YAAY,wBAEdK,MAAC,QAAK,UAAU,gCAAgC,aAAM,EACtDA,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAOuF,EAAM,QACb,YAAemD,GAAWrD,EAAOmD,EAAK,UAAWxV,EAAE,OAAO,KAAK,EAC/D,YAAY,YAEdK,MAAC,UACC,KAAK,SACL,UAAU,iEACV,QAAS,IAAMkV,GAAWlD,EAAOmD,CAAG,EAEpC,SAAAnV,MAAC4L,GAAA,CAAE,UAAU,UAAU,GACzB,GApBQuJ,CAqBV,CACD,IAzBOnD,CA0BV,CAEJ,CAAC,EACDjS,OAAC,OAAI,UAAU,+BACb,UAAAC,MAAC,UAAO,UAAW+Q,GAAa,MAAOkD,EAAc,SAAUtU,GAAKuU,EAAgBvU,EAAE,OAAO,KAAK,EAC/F,SAAAmR,GAAY,OAAS9Q,MAAC,UAAe,MAAOL,EAAI,SAAAA,CAAA,EAAdA,CAAgB,CAAS,EAC9D,EACAI,OAAC4L,GAAO,QAAQ,UAAU,KAAK,KAAK,UAAU,mBAAmB,QAASsJ,EACxE,UAAAjV,MAACgP,GAAA,CAAK,UAAU,eAAe,EAAE,YAEnC,GACF,GACF,EAGAhP,MAAC,OAAI,UAAU,mBACb,gBAAC2L,EAAA,CAAO,QAAQ,UAAU,KAAK,KAAK,UAAU,MAAM,SAAUrB,EAAQ,QAASkK,GAC7E,UAAAxU,MAACiP,GAAA,CAAK,UAAU,eAAe,EAC9B3E,EAAS,YAAc,iBAC1B,EACF,GACF,CAEJ,CASA,SAASoL,GAAU,CAAE,MAAAtD,EAAO,QAAAC,GAA2B,CACrD,KAAM,CAACsD,EAAOC,CAAQ,EAAIpY,WAAS4U,EAAM,KAAK,EACxC,CAACyD,EAAQC,CAAS,EAAItY,WAAS4U,EAAM,MAAM,EAC3C,CAAC9H,EAAQmD,CAAS,EAAIjQ,WAAS,EAAK,EACpC,CAACuY,EAAcC,CAAe,EAAIxY,WAAS,EAAK,EAEhDyY,EAAUN,IAAUvD,EAAM,OAASyD,IAAWzD,EAAM,OACpD8D,EAAgB9D,EAAM,OAAS,QAAU7B,GAAgBC,GAEzDgE,EAAalV,cAAY,SAAY,CACzCmO,EAAU,EAAI,EACd,GAAI,CACF,MAAM3Q,EAAgE,CAAE,SAAUsV,EAAM,UACpFuD,IAAUvD,EAAM,QAAOtV,EAAK,MAAQ6Y,GACpCE,IAAWzD,EAAM,SAAQtV,EAAK,OAAS+Y,GAC3C,MAAMjB,GAAsBxC,EAAM,KAAMA,EAAM,KAAMtV,CAAI,EACxDmR,EAAM,QAAQ,WAAWmE,EAAM,IAAI,EAAE,EACrCC,EAAA,CACF,OAASvS,EAAK,CACZmO,EAAM,MAAM,oBAAoBmE,EAAM,IAAI,KAAMtS,EAAc,OAAO,EAAE,CACzE,SACE2N,EAAU,EAAK,CACjB,CACF,EAAG,CAAC2E,EAAOuD,EAAOE,EAAQxD,CAAO,CAAC,EAGlC5U,mBAAU,IAAM,CACdmY,EAASxD,EAAM,KAAK,EACpB0D,EAAU1D,EAAM,MAAM,CACxB,EAAG,CAACA,EAAM,MAAOA,EAAM,MAAM,CAAC,SAG3B,OACC,UAAArS,OAAC,OAAI,UAAU,iHACb,UAAAC,MAACyL,EAAA,CAAM,QAAS2G,EAAM,OAAS,QAAU,UAAY,YAAa,UAAU,mBACzE,SAAAA,EAAM,KACT,EACApS,MAAC,QAAK,UAAU,6DAA6D,MAAOoS,EAAM,KACvF,WAAM,KACT,EAGArS,OAAC,OAAI,UAAU,yCACb,UAAAC,MAAC,QAAK,UAAU,yCAAyC,kBAAM,EAC9DoS,EAAM,OAAS,SACdrS,OAAC,OAAI,UAAU,4BACb,UAAAA,OAAC,UACC,UAAU,sEACV,MAAO0Q,GAAqB,SAASkF,CAAK,EAAIA,EAAQ,aACtD,SAAWhW,GAAM,CACXA,EAAE,OAAO,QAAU,cACvBiW,EAASjW,EAAE,OAAO,KAAK,CACzB,EAEC,UAAA8Q,GAAqB,OACpBzQ,MAAC,UAAe,MAAOiN,EAAI,SAAAA,GAAK,UAAnBA,CAA4B,CAC1C,EACA,CAACwD,GAAqB,SAASkF,CAAK,GACnC3V,MAAC,UAAO,MAAM,aAAa,kBAAM,KAGpC,CAACyQ,GAAqB,SAASkF,CAAK,GACnC3V,MAAC2M,EAAA,CACC,UAAU,mCACV,MAAOgJ,EACP,SAAWhW,GAAMiW,EAASjW,EAAE,OAAO,KAAK,EACxC,YAAY,YACd,EAEJ,EAEAK,MAAC2M,EAAA,CACC,UAAU,mCACV,MAAOgJ,EACP,SAAWhW,GAAMiW,EAASjW,EAAE,OAAO,KAAK,EACxC,YAAY,YACd,EAEJ,EAGAI,OAAC,OAAI,UAAU,mCACb,UAAAC,MAAC,QAAK,UAAU,gCAAgC,mBAAO,EACvDA,MAAC,UACC,UAAU,6DACV,MAAO6V,EACP,SAAWlW,GAAMmW,EAAUnW,EAAE,OAAO,KAAK,EAExC,SAAAuW,EAAc,IAAIvW,GACjBK,MAAC,UAAe,MAAOL,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CACrC,GACH,EACF,EAGAI,OAAC4L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,oBACV,SAAU,CAACsK,GAAW3L,EACtB,QAASkK,EAET,UAAAxU,MAACiP,GAAA,CAAK,UAAU,eAAe,EAC9B3E,EAAS,MAAQ,UAInB8H,EAAM,OAAS,UACdpS,MAAC,UACC,KAAK,SACL,UAAWsJ,EACT,gDACAyM,GAAgB,gBAElB,QAAS,IAAMC,EAAgB,CAACD,CAAY,EAC5C,MAAM,oBAEN,SAAA/V,MAACmW,GAAA,CAAU,UAAU,UAAU,GACjC,EAEJ,EAGCJ,GAAgB3D,EAAM,OAAS,UAC9BpS,MAACmS,GAAA,CAAiB,MAAAC,EAAc,QAAAC,CAAA,CAAkB,GAEtD,CAEJ,CAUA,SAAS+D,GAAkB,CAAE,iBAAAC,EAAkB,OAAAC,EAAQ,QAAAjE,GAAmC,CACxF,KAAM,CAAC9G,EAAUgL,CAAW,EAAI/Y,WAAS,EAAI,EAE7C,OACEuC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,UACC,KAAK,SACL,UAAU,qFACV,QAAS,IAAMwW,EAAY,CAAChL,CAAQ,EAEnC,UAAAA,EAAWvL,MAAC8L,IAAY,UAAU,UAAU,EAAK9L,MAACwW,GAAA,CAAa,UAAU,UAAU,QACnF,QAAK,UAAU,+CAA+C,MAAOH,EACnE,SAAAA,EACH,EACAtW,OAAC0L,EAAA,CAAM,QAAQ,UAAU,UAAU,2BAChC,UAAA6K,EAAO,OAAO,WACjB,KAED/K,GACCvL,MAAC,OAAI,UAAU,iBACZ,WAAO,IAAKoS,GACXpS,MAAC0V,IAA+B,MAAAtD,EAAc,QAAAC,CAAA,EAA9BD,EAAM,QAA0C,CACjE,EACH,GAEJ,CAEJ,CAIO,SAASqE,IAA0B,CACxC,KAAM,CAACH,EAAQI,CAAS,EAAIlZ,WAA4B,EAAE,EACpD,CAAC+P,EAASC,CAAU,EAAIhQ,WAAS,EAAI,EACrC,CAACmZ,EAAYC,CAAa,EAAIpZ,WAAS,EAAE,EACzC,CAACqZ,EAAaC,CAAc,EAAItZ,WAAS,EAAE,EAC3C,CAACuZ,EAAWC,CAAY,EAAIxZ,WAAqC,KAAK,EACtE,CAACyZ,EAAYC,CAAa,EAAI1Z,WAAS,EAAE,EACzC,CAAC2Z,EAAiBC,CAAkB,EAAI5Z,WAAS,EAAE,EACnD,CAAC6Z,EAAaC,CAAc,EAAI9Z,WAAS,EAAE,EAC3C,CAAC+Z,EAAeC,CAAgB,EAAIha,WAAS,EAAE,EAC/C,CAACia,EAAiBC,CAAkB,EAAIla,WAAgC,EAAE,EAC1E,CAACma,EAAgBC,CAAiB,EAAIpa,WAAS,EAAE,EACjD,CAACqa,EAAYC,CAAa,EAAIta,WAAS,EAAE,EACzC,CAACua,EAAsBC,CAAuB,EAAIxa,WAAS,EAAE,EAC7D,CAACya,EAAaC,CAAc,EAAI1a,WAAS,EAAE,EAC3C,CAAC2a,EAAmBC,CAAoB,EAAI5a,WAAS,EAAK,EAC1D,CAAC6a,EAAaC,CAAc,EAAI9a,WAAS,EAAK,EAE9C+a,EAAajZ,cAAY,SAAY,CACzC,GAAI,CACFkO,EAAW,EAAI,EACf,MAAMxO,EAAO,MAAMwZ,GAAA,EACnB9B,EAAU1X,EAAK,MAAM,CACvB,OAASc,EAAK,CACZmO,EAAM,MAAM,0BAA2BnO,EAAc,OAAO,EAAE,CAChE,SACE0N,EAAW,EAAK,CAClB,CACF,EAAG,EAAE,EAEL/P,YAAU,IAAM,CAAE8a,EAAA,CAAc,EAAG,CAACA,CAAU,CAAC,EAG/C,MAAME,GAAUnC,EAAO,OAA0C,CAACoC,EAAKtG,IAAU,CAC/E,MAAM9M,EAAM8M,EAAM,iBAClB,OAAKsG,EAAIpT,CAAG,IAAGoT,EAAIpT,CAAG,EAAI,IAC1BoT,EAAIpT,CAAG,EAAE,KAAK8M,CAAK,EACZsG,CACT,EAAG,EAAE,EAECC,GAAerC,EAAO,OAAO,GAAKS,IAAc,OAAS,EAAE,OAASA,CAAS,EAC7E6B,GAAwBD,GAAa,KAAK,GAAK,EAAE,OAAS,QAAQ,EAClEE,GAAqB9B,IAAc,QACrCxG,GACAwG,IAAc,SACZvG,GACA,CAAC,GAAI,MAAO,SAAU,OAAQ,mBAAmB,EAGjDsI,EAA4C,GAC9C7B,MAA8B,MAAQA,GACtCE,MAAmC,eAAiBA,GACpDE,MAA+B,OAASA,GACxCE,MAAiC,SAAWA,GAC5CE,MAAmC,WAAaA,GAChDE,MAAkC,UAAYA,GAC9CE,MAA8B,MAAQA,GACtCE,MAAwC,gBAAkBA,GAC1DE,MAA+B,OAASA,GAC5C,MAAMc,GAAuB,OAAO,KAAKD,CAAiB,EAAE,OAAS,EAE/DE,GAAmB1Z,cAAY,SAAY,CAE/C,GAAI,EADgBqX,GAAcE,GAAekC,IAC/B,CAChB9K,EAAM,MAAM,8BAA8B,EAC1C,MACF,CACA,GAAI0K,GAAa,SAAW,EAAG,CAC7B1K,EAAM,MAAM,mCAAmC,EAC/C,MACF,CAEAqK,EAAe,EAAI,EACnB,GAAI,CAEF,GAAI3B,GAAcE,EAAa,CAC7B,MAAMoC,EAAUN,GAAa,IAAIO,IAAM,CAAE,SAAUA,EAAE,SAAU,KAAMA,EAAE,MAAO,EACxErZ,EAAS,MAAMsZ,GAA4B,CAC/C,QAAAF,EACA,MAAOtC,GAAc,OACrB,OAAQE,GAAe,OACxB,EACD5I,EAAM,QAAQ,yBAAyBpO,EAAO,OAAO,IAAIA,EAAO,KAAK,SAAS,CAChF,CAGA,GAAIkZ,IAAwBH,GAAuB,CACjD,MAAMQ,EAAgBT,GAAa,OAAOO,GAAKA,EAAE,OAAS,QAAQ,EAClE,IAAIG,EAAU,EACd,UAAWjH,KAASgH,EAClB,GAAI,CACF,MAAMtc,EAAgE,CACpE,SAAUsV,EAAM,SAChB,GAAG0G,CAAA,EAEL,MAAMlE,GAAsBxC,EAAM,KAAMA,EAAM,KAAMtV,CAAI,EACxDuc,GACF,MAAQ,CAAoB,CAE9BpL,EAAM,QAAQ,0BAA0BoL,CAAO,IAAID,EAAc,MAAM,SAAS,CAClF,CAEAb,EAAA,CACF,OAASzY,EAAK,CACZmO,EAAM,MAAM,wBAAyBnO,EAAc,OAAO,EAAE,CAC9D,SACEwY,EAAe,EAAK,CACtB,CACF,EAAG,CAACK,GAAcC,GAAuBjC,EAAYE,EAAakC,GAAsBD,EAAmBP,CAAU,CAAC,EAEtH,OACExY,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,OAAI,UAAU,yCACb,UAAAA,OAAC,MAAG,UAAU,gEACZ,UAAAC,MAACsZ,GAAA,CAAI,UAAU,UAAU,EAAE,qBAE7B,EACAvZ,OAAC4L,GAAO,QAAQ,QAAQ,KAAK,KAAK,QAAS4M,EAAY,SAAUhL,EAC/D,UAAAvN,MAAC4O,IAAU,UAAWtF,EAAG,eAAgBiE,GAAW,cAAc,EAAG,EAAE,WAEzE,GACF,EAGAxN,OAAC,OAAI,UAAU,iEAEb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAC,MAAC,QAAK,UAAU,qDAAqD,kBAAM,EAC3ED,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,mBAAO,EACpCjR,OAAC,UACC,UAAWgR,GACX,MAAOgG,EACP,SAAWpX,GAAMqX,EAAarX,EAAE,OAAO,KAAmC,EAE1E,UAAAI,OAAC,UAAO,MAAM,MAAM,kBAAMuW,EAAO,OAAO,KAAC,EACzCvW,OAAC,UAAO,MAAM,QAAQ,oBAAQuW,EAAO,OAAO,GAAK,EAAE,OAAS,OAAO,EAAE,OAAO,KAAC,EAC7EvW,OAAC,UAAO,MAAM,SAAS,qBAASuW,EAAO,OAAO,GAAK,EAAE,OAAS,QAAQ,EAAE,OAAO,KAAC,IAClF,EACF,EACAvW,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,kBAAM,EACnChR,MAAC2M,EAAA,CACC,UAAU,wBACV,MAAOgK,EACP,SAAWhX,GAAMiX,EAAcjX,EAAE,OAAO,KAAK,EAC7C,YAAY,SACd,EACF,EACAI,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,mBAAO,EACpChR,MAAC,UACC,UAAW+Q,GACX,MAAO8F,EACP,SAAWlX,GAAMmX,EAAenX,EAAE,OAAO,KAAK,EAE7C,SAAAkZ,GAAmB,IAAIlZ,GAAK,CAC3B,MAAM4Z,EAAM5Z,EAAE,WAAW,KAAK,EAAI,MAAQA,EAC1C,aAAQ,UAAe,MAAO4Z,EAAM,SAAA5Z,GAAK,KAArBA,CAAyB,CAC/C,CAAC,GACH,EACF,EAECoX,IAAc,SACb/W,MAAC,UACC,KAAK,SACL,UAAWsJ,EACT,gDACA6O,GAAqB,gBAEvB,QAAS,IAAMC,EAAqB,CAACD,CAAiB,EACtD,MAAM,iCAEN,SAAAnY,MAACmW,GAAA,CAAU,UAAU,UAAU,IAGnCnW,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,MACV,SAAU0M,GAAgB,CAAC1B,GAAc,CAACE,GAAe,CAACkC,GAC1D,QAASC,GAER,SAAAX,EAAc,cAAgB,YAAYtB,IAAc,MAAQ,MAAQA,CAAS,KAAK4B,GAAa,MAAM,KAC5G,EACF,EAGCR,GAAqBpB,IAAc,SAClChX,OAAC,OAAI,UAAU,wCACb,UAAAA,OAAC,QAAK,UAAU,4CAA4C,gCAAoBgX,IAAc,OAAS,kCAAkC,KAAC,EAE1IhX,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,kBAAM,EACnChR,MAAC,UAAO,UAAW+Q,GAAa,MAAOkG,EAAY,SAAUtX,GAAKuX,EAAcvX,EAAE,OAAO,KAAK,EAC3F,SAAAkR,GAAc,IAAI2E,GAAKxV,MAAC,UAAe,MAAOwV,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EACvE,GACF,EACAzV,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,uBAAW,EACxChR,MAAC,UAAO,UAAW+Q,GAAa,MAAOoG,EAAiB,SAAUxX,GAAKyX,EAAmBzX,EAAE,OAAO,KAAK,EACrG,SAAA+Q,GAAiB,IAAItQ,GAAKJ,MAAC,UAAe,MAAOI,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EAC1E,GACF,EACAL,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,mBAAO,EACpChR,MAAC,UAAO,UAAW+Q,GAAa,MAAOsG,EAAa,SAAU1X,GAAK2X,EAAe3X,EAAE,OAAO,KAAK,EAC7F,SAAAgR,GAAe,IAAI1D,GAAKjN,MAAC,UAAe,MAAOiN,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EACxE,GACF,EACAlN,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,qBAAS,EACtChR,MAAC2M,EAAA,CACC,UAAU,uBACV,KAAK,SACL,MAAO4K,EACP,SAAU5X,GAAK6X,EAAiB7X,EAAE,OAAO,KAAK,EAC9C,YAAY,KACd,EACF,EACAI,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,uBAAW,EACxCjR,OAAC,UAAO,UAAWgR,GAAa,MAAO0G,EAAiB,SAAU9X,GAAK+X,EAAmB/X,EAAE,OAAO,KAA8B,EAC/H,UAAAK,MAAC,UAAO,MAAM,GAAG,aAAC,EAClBA,MAAC,UAAO,MAAM,OAAO,gBAAI,EACzBA,MAAC,UAAO,MAAM,QAAQ,iBAAK,GAC7B,GACF,EACAD,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,sBAAU,EACvChR,MAAC,UAAO,UAAW+Q,GAAa,MAAO4G,EAAgB,SAAUhY,GAAKiY,EAAkBjY,EAAE,OAAO,KAAK,EACnG,SAAAiR,GAAkB,IAAI5I,GAAKhI,MAAC,UAAe,MAAOgI,EAAI,SAAAA,GAAK,KAAnBA,CAAuB,CAAS,EAC3E,GACF,GACF,EAEAjI,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,+CACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,kBAAM,EACnChR,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAOkL,EACP,SAAUlY,GAAKmY,EAAcnY,EAAE,OAAO,KAAK,EAC3C,YAAY,iCACd,EACF,EACAI,OAAC,OAAI,UAAU,+CACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,uBAAW,EACxChR,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAOoL,EACP,SAAUpY,GAAKqY,EAAwBrY,EAAE,OAAO,KAAK,EACrD,YAAY,aACd,EACF,EACAI,OAAC,OAAI,UAAU,+CACb,UAAAC,MAAC,QAAK,UAAWgR,EAAY,mBAAO,EACpChR,MAAC2M,EAAA,CACC,UAAU,qBACV,MAAOsL,EACP,SAAUtY,GAAKuY,EAAevY,EAAE,OAAO,KAAK,EAC5C,YAAY,wBACd,EACF,GACF,GACF,GAEJ,EAGC4N,EACCvN,MAAC,OAAI,UAAU,iDAAiD,6BAAiB,EAC/EsW,EAAO,SAAW,EACpBtW,MAAC,OAAI,UAAU,iDAAiD,uEAEhE,EAEAA,MAAC,OAAI,UAAU,YACZ,gBAAO,QAAQyY,EAAO,EAAE,IAAI,CAAC,CAACe,EAAMC,CAAW,IAC9CzZ,MAACoW,GAAA,CAEC,iBAAkBoD,EAClB,OAAQC,EACR,QAASlB,CAAA,EAHJiB,CAAA,CAKR,EACH,GAEJ,CAEJ,CC30BA,SAASld,IAA8B,CACrC,MAAMC,EAAQ,SAAS,OAAO,MAAM,oBAAoB,EACxD,OAAOA,EAAQ,mBAAmBA,EAAM,CAAC,CAAC,EAAI,IAChD,CAeA,SAASmd,GAAc,CAAE,MAAAzZ,EAAO,SAAAwP,EAAU,YAAAkK,GAAmC,CAC3E,KAAM,CAACC,EAAcC,CAAe,EAAIrc,WAAS,EAAK,EAChD,CAACsc,EAAWC,CAAY,EAAIvc,WAAwB,IAAI,EACxDwc,EAAiBC,GAAYha,EAAO,GAAG,EAE7CxC,YAAU,IAAM,CACd,GAAIuc,EAAgB,CAClBH,EAAgB,EAAI,EACpBE,EAAa,IAAI,EAEjB,MAAMG,EAAY,WAAW,IAAM,CAG7BF,EAAe,OAAO,OAAS,EACjCD,EAAa,IAAI,EAEjBA,EAAa,uBAAuB,EAEtCF,EAAgB,EAAK,CACvB,EAAG,GAAI,EAEP,MAAO,IAAM,aAAaK,CAAS,CACrC,MACEH,EAAa,IAAI,EACjBF,EAAgB,EAAK,CAEzB,EAAG,CAACG,CAAc,CAAC,EAEnB,MAAMG,EAAe,SAAY,CAC/B,KAAM,CAAE,WAAAC,CAAA,EAAe,MAAAC,GAAA,2BAAAD,CAAA,OAAM,QAAO,qBAAoB,OAAA9F,KAAA,sBAAA8F,CAAA,2BAClDE,EAAara,EAAQA,EAAM,QAAQ,gBAAiB,EAAE,EAAI,OAC1DJ,EAAS,MAAMua,EAAWE,CAAU,EACtCza,EAAO,MAAQ,CAACA,EAAO,WAAa,CAACA,EAAO,OAC9C4P,EAAS5P,EAAO,IAAI,CAExB,EAEA,cACG,OACC,UAAAE,OAAC,OAAI,UAAU,0BACb,UAAAA,OAAC,OAAI,UAAU,kBACb,UAAAC,MAAC2M,EAAA,CACC,MAAA1M,EACA,SAAWN,GAAM8P,EAAS9P,EAAE,OAAO,KAAK,EACxC,YAAAga,EACA,UAAWrQ,EACT,SACAwQ,GAAa,qBACf,GAEDF,SACE,OAAI,UAAU,oDACb,SAAA5Z,MAACua,GAAA,CAAQ,UAAU,6CAA6C,EAClE,GAEJ,EACAva,MAAC2L,EAAA,CACC,KAAK,SACL,QAAQ,UACR,KAAK,KACL,UAAU,eACV,QAASwO,EACT,MAAM,SAEN,SAAAna,MAACwa,GAAA,CAAW,UAAU,UAAU,GAClC,EACF,EACCV,GACC9Z,MAAC,KAAE,UAAU,gCAAiC,SAAA8Z,CAAA,CAAU,GAE5D,CAEJ,CAKA,MAAMW,GAAiB,IAAI,IAAI,CAAC,SAAU,OAAQ,UAAU,CAAC,EAEvDC,GAAsB,IAAI,IAAI,CAAC,QAAQ,CAAC,EAC9C,SAASC,GAAkBC,EAAqD,CAC9E,OAAIH,GAAe,IAAIG,CAAM,EAAU,UACnCF,GAAoB,IAAIE,CAAM,EAAU,eACrC,MACT,CAuBA,SAASC,GAAY,CACnB,OAAAD,EACA,OAAA7Q,EACA,UAAA+Q,EACA,WAAAhM,EACA,cAAAiM,EACA,SAAAC,EACA,eAAA9Q,EACA,gBAAA+Q,EACA,aAAAC,EACA,cAAAC,EACA,aAAAC,EACA,wBAAAC,EACA,gBAAAC,EACA,qBAAAC,EACA,eAAAC,EACA,gBAAAC,CACF,EAAqB,CACnB,KAAM,CAAE,cAAA3d,CAAA,EAAkBC,EAAA,EAGpB,CAAC2d,EAAUC,CAAW,EAAIne,WAAS,EAAE,EACrC,CAACoe,EAAYC,CAAa,EAAIre,WAAS,EAAE,EAGzCse,EAAe,IAAM,CACzB,MAAMC,EAASL,EAAS,OACpBK,GAAU,CAAChS,EAAO,KAAK,SAASgS,CAAM,IACxCX,EAAa,CAAC,GAAGrR,EAAO,KAAMgS,CAAM,CAAC,EACrCJ,EAAY,EAAE,EAElB,EAGMK,EAAmBC,GAAwB,CAC/Cb,EAAarR,EAAO,KAAK,OAAQqD,GAAMA,IAAM6O,CAAW,CAAC,CAC3D,EAGMC,EAAiB,IAAM,CAC3B,MAAMC,EAAWP,EAAW,OACtBQ,EAAgBrS,EAAO,iBAAmB,GAC5CoS,GAAY,CAACC,EAAc,SAASD,CAAQ,IAC9Cd,EAAwB,CAAC,GAAGe,EAAeD,CAAQ,CAAC,EACpDN,EAAc,EAAE,EAEpB,EAGMQ,EAAqBC,GAA0B,CACnD,MAAMF,EAAgBrS,EAAO,iBAAmB,GAChDsR,EAAwBe,EAAc,OAAQnP,GAAMA,IAAMqP,CAAa,CAAC,CAC1E,EAGMC,EAAiB,CAAC,KAAM,QAAS,iBAAkB,cAAe,SAAS,EAE3EC,EAAiB7B,GAAkBC,CAAM,EAE/C,OACE7a,OAACyL,GAAK,UAAWlC,EAAG,kBAAmB,CAACS,EAAO,SAAW,YAAY,EAEpE,UAAAhK,OAAC,OACC,UAAU,yDACV,QAASmK,EAET,UAAAnK,OAAC,OAAI,UAAU,0CACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,OAAI,UAAWsJ,EACd,iBACAS,EAAO,QAAU,gBAAkB,YAEnC,SAAA/J,MAACyc,GAAA,CAAI,UAAWnT,EACd,UACAS,EAAO,QAAU,eAAiB,yBACjC,EACL,SACC,OACC,UAAAhK,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAU,iDACb,SAAA4a,EACH,EACCE,GACC9a,MAACyL,EAAA,CAAM,QAAQ,UAAU,UAAU,UAAW,SAAA3N,EAAc,CAAE,GAAI,4BAA6B,EAAE,QAElG2N,EAAA,CAAM,QAAQ,UAAU,UAAU,UAAW,WAAO,KAAK,EACzDsP,IAAkB,QACjB/a,MAAC,QAAK,UAAWsJ,EACf,oCACAyR,EAAgB,eAAiB,cAChC,MAAOA,EAAgB,YAAc,cAAe,GAE3D,EACA/a,MAAC,KAAE,UAAU,uCACV,WAAO,aACV,GACF,GACF,EACAD,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC2L,EAAA,CACC,QAAS5B,EAAO,QAAU,UAAY,UACtC,KAAK,KACL,UAAU,MACV,QAAUpK,GAAM,CACdA,EAAE,kBACFsb,EAAA,CACF,EAEC,SAAAlR,EAAO,QACNhK,OAAAI,WAAA,CACE,UAAAH,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,4BAA6B,GACpD,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAAC4L,GAAA,CAAE,UAAU,eAAe,EAC3B9N,EAAc,CAAE,GAAI,6BAA8B,GACrD,IAGHgR,QACEjD,GAAA,CAAU,UAAU,gCAAgC,EAErD7L,MAAC8L,GAAA,CAAY,UAAU,gCAAgC,GAE3D,GACF,EAGC/B,EAAO,MAAQA,EAAO,KAAK,OAAS,GACnC/J,MAAC,OAAI,UAAU,4BACZ,SAAA+J,EAAO,KAAK,IAAK2S,GAChB1c,MAACyL,EAAA,CAAgB,QAAQ,YAAY,UAAU,UAC5C,SAAAiR,CAAA,EADSA,CAEZ,CACD,EACH,KAKH5N,GACC/O,OAAC,OAAI,UAAU,mDACb,UAAAA,OAAC,OAAI,UAAU,4BACb,UAAAA,OAAC,OACC,UAAAC,MAAC,SAAM,UAAU,sCAAuC,SAAAlC,EAAc,CAAE,GAAI,iCAAkC,EAAE,EAChHkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,aACd,SAAWpK,GAAMwb,EAAc,eAAgBxb,EAAE,OAAO,KAAK,EAC7D,UAAU,QACZ,EACF,SACC,OACC,UAAAK,MAAC,SAAM,UAAU,sCAAuC,SAAAlC,EAAc,CAAE,GAAI,mCAAoC,EAAE,EAClHkC,MAAC2M,EAAA,CACC,MAAO5C,EAAO,eACd,SAAWpK,GAAMwb,EAAc,iBAAkBxb,EAAE,OAAO,KAAK,EAC/D,UAAU,QACZ,EACF,GACF,EAGAI,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,+BAAgC,EACvD,EACAkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0CAA2C,EAClE,EACAD,OAAC,OAAI,UAAU,aACb,UAAAA,OAAC,OAAI,UAAU,oKACZ,UAAAgK,EAAO,KAAK,IAAK2S,GAChB3c,OAAC,QAEC,UAAU,4FAET,UAAA2c,EACD1c,MAAC,UACC,KAAK,SACL,QAAS,IAAMgc,EAAgBU,CAAG,EAClC,UAAU,2CACV,aAAY5e,EAAc,CAAE,GAAI,oCAAqC,EAErE,SAAAkC,MAAC4L,GAAA,CAAE,UAAU,UAAU,GACzB,GAXK8Q,CAAA,CAaR,EACD1c,MAAC,SACC,KAAK,OACL,MAAO0b,EACP,SAAW/b,GAAMgc,EAAYhc,EAAE,OAAO,KAAK,EAC3C,UAAYA,GAAM,CACZA,EAAE,MAAQ,UACZA,EAAE,iBACFmc,EAAA,EAEJ,EACA,YAAa/R,EAAO,KAAK,SAAW,EAAIjM,EAAc,CAAE,GAAI,8CAA+C,EAAI,GAC/G,UAAU,uGACZ,EACF,EACAkC,MAAC2L,EAAA,CACC,KAAK,SACL,KAAK,KACL,QAASmQ,EACT,QAAQ,UACR,UAAU,WAEV,SAAA9b,MAACgP,GAAA,CAAK,UAAU,UAAU,GAC5B,EACF,EAEAjP,OAAC,OAAI,UAAU,uBACb,UAAAA,OAAC,QAAK,UAAU,gCACb,UAAAjC,EAAc,CAAE,GAAI,yCAA0C,EAAE,KACnE,EACCye,EAAe,IAAKI,GACnB3c,MAAC,UAEC,KAAK,SACL,QAAS,IAAM,CACR+J,EAAO,KAAK,SAAS4S,CAAa,GACrCvB,EAAa,CAAC,GAAGrR,EAAO,KAAM4S,CAAa,CAAC,CAEhD,EACA,SAAU5S,EAAO,KAAK,SAAS4S,CAAa,EAC5C,UAAU,oIAET,SAAAA,CAAA,EAVIA,CAAA,CAYR,GACH,GACF,EAGA5c,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,0CAA2C,EAClE,EACAiC,OAAC,OAAI,UAAU,aACb,UAAAA,OAAC,OAAI,UAAU,oKACX,WAAAgK,EAAO,iBAAmB,IAAI,IAAK4L,GACnC5V,OAAC,QAEC,UAAU,4FAET,UAAA4V,EACD3V,MAAC,UACC,KAAK,SACL,QAAS,IAAMqc,EAAkB1G,CAAK,EACtC,UAAU,2CAEV,SAAA3V,MAAC4L,GAAA,CAAE,UAAU,UAAU,GACzB,GAVK+J,CAAA,CAYR,EACD3V,MAAC,SACC,KAAK,OACL,MAAO4b,EACP,SAAWjc,GAAMkc,EAAclc,EAAE,OAAO,KAAK,EAC7C,UAAYA,GAAM,CACZA,EAAE,MAAQ,UACZA,EAAE,iBACFuc,EAAA,EAEJ,EACA,aAAcnS,EAAO,iBAAmB,IAAI,SAAW,EAAIjM,EAAc,CAAE,GAAI,qDAAsD,EAAI,GACzI,UAAU,uGACZ,EACF,EACAkC,MAAC2L,EAAA,CACC,KAAK,SACL,KAAK,KACL,QAASuQ,EACT,QAAQ,UACR,UAAU,WAEV,SAAAlc,MAACgP,GAAA,CAAK,UAAU,UAAU,GAC5B,EACF,EACAhP,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,8CAA+C,EACtE,GACF,EAGCwc,IAAmB,WAClBzc,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,4BAA6B,EACpD,EACAkC,MAAC0Z,GAAA,CACC,MAAO3P,EAAO,SAAW,GACzB,SAAWuG,GAAMgL,EAAgBhL,GAAK,MAAS,EAC/C,YAAaxS,EAAc,CAAE,GAAI,uCAAwC,IAE3EkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,gCAAiC,EACxD,GACF,EAIDwc,IAAmB,gBAClBzc,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,uCAAwC,EAC/D,EACAkC,MAAC0Z,GAAA,CACC,MAAO3P,EAAO,cAAgB,GAC9B,SAAWuG,GAAMiL,EAAqBjL,GAAK,MAAS,EACpD,YAAaxS,EAAc,CAAE,GAAI,kDAAmD,IAEtFkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,2CAA4C,EACnE,GACF,EAIDwc,IAAmB,gBAClBzc,OAAC,OAAI,UAAU,YACb,UAAAC,MAAC,SAAM,UAAU,sCACd,SAAAlC,EAAc,CAAE,GAAI,2BAA4B,EACnD,EACAkC,MAAC,OAAI,UAAU,aACX,UAAC,MAAO,SAAU,MAAM,EAAY,IAAK4H,GAAU,CACnD,MAAMgV,EAAkB7S,EAAO,QAAU,OACnC7J,EAAU,2BAA2B0H,EAAM,OAAO,CAAC,EAAE,cAAgBA,EAAM,MAAM,CAAC,CAAC,GACzF,OACE5H,MAAC,UAEC,KAAK,SACL,QAAS,IAAMwb,EAAe5T,IAAU,QAAU,CAACmC,EAAO,OAAS,OAAYnC,CAAK,EACpF,UAAW0B,EACT,0DACAsT,IAAoBhV,EAChB,oDACA,gCAGL,SAAA9J,EAAc,CAAE,GAAIoC,CAAA,CAAS,GAVzB0H,CAAA,CAaX,CAAC,EACH,EACA5H,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,+BAAgC,EACvD,GACF,EAIFD,OAAC,OAAI,UAAU,0BACZ,WAAC+a,GAAa/Q,EAAO,SACpB/J,MAAC2L,EAAA,CAAO,QAAQ,UAAU,KAAK,KAAK,QAASuP,EAC1C,SAAApd,EAAc,CAAE,GAAI,+BAAgC,EACvD,EAEFiC,OAAC4L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS8P,EACT,SAAUT,EAEV,UAAAhb,MAACiP,GAAA,CAAK,UAAU,eAAe,EAE3BnR,EADHkd,EACiB,CAAE,GAAI,4BACN,CAAE,GAAI,iCAD4B,CACM,GAC5D,EACF,GACF,GAEJ,CAEJ,CAIA,SAAS6B,IAA0B,CACjC,KAAM,CAAE,cAAA/e,CAAA,EAAkBC,EAAA,EACpB,CAAE,KAAM+e,EAAe,UAAWC,CAAA,EAAmBC,GAAA,EACrD,CAAE,OAAQC,EAAe,UAAWC,CAAA,EAAoBC,GAAA,EACxD,CAAE,KAAMC,EAAe,UAAWC,CAAA,EAAmBC,GAAA,EACrD,CAAE,OAAQC,EAAe,UAAWC,CAAA,EAAoBC,GAAA,EACxD,CAAE,KAAMC,EAAc,UAAWC,CAAA,EAAkBC,GAAA,EACnD,CAAE,OAAQC,EAAc,UAAWC,CAAA,EAAmBC,GAAA,EACtD,CAAE,QAASC,EAAe,UAAWC,CAAA,EAAeC,GAAA,EACpD,CAAE,eAAgBC,EAAU,UAAWC,CAAA,EAAcC,GAAA,EACrD,CAAE,eAAgBC,EAAU,UAAWC,CAAA,EAAcC,GAAA,EACrD1f,EAAeC,SAAyB,IAAI,EAE5C0f,EAAenf,cAAY,SAAY,CAC3C,GAAI,CACF,MAAMN,EAAO,MAAMmf,EAAA,EACbO,EAAO,IAAI,KAAK,CAAC,KAAK,UAAU1f,EAAM,KAAM,CAAC,CAAC,EAAG,CAAE,KAAM,mBAAoB,EAC7E2f,EAAM,IAAI,gBAAgBD,CAAI,EAC9BxF,EAAI,SAAS,cAAc,GAAG,EAC9B0F,EAAY,IAAI,OAAO,cAAc,QAAQ,QAAS,GAAG,EAAE,MAAM,EAAG,EAAE,EAC5E1F,EAAE,KAAOyF,EACTzF,EAAE,SAAW,gBAAgB0F,CAAS,QACtC,SAAS,KAAK,YAAY1F,CAAC,EAC3BA,EAAE,QACF,SAAS,KAAK,YAAYA,CAAC,EAC3B,IAAI,gBAAgByF,CAAG,EACvB1Q,EAAM,QAAQnQ,EAAc,CAAE,GAAI,0CAA2C,CAAC,CAChF,MAAgB,CACdmQ,EAAM,MAAMnQ,EAAc,CAAE,GAAI,wCAAyC,CAAC,CAC5E,CACF,EAAG,CAACqgB,EAAUrgB,CAAa,CAAC,EAEtB+gB,EAAmBvf,cAAY,MAAOK,GAA2C,OACrF,MAAM3C,GAAO4C,EAAAD,EAAE,OAAO,QAAT,YAAAC,EAAiB,GAC9B,GAAK5C,EAML,IAHA2C,EAAE,OAAO,MAAQ,GAGb,CAAC3C,EAAK,KAAK,SAAS,OAAO,GAAKA,EAAK,OAAS,mBAAoB,CACpEiR,EAAM,MAAMnQ,EAAc,CAAE,GAAI,8CAA+C,CAAC,EAChF,MACF,CAEA,GAAI,CACF,MAAMghB,EAAO,MAAM9hB,EAAK,OAClBgC,EAAO,KAAK,MAAM8f,CAAI,EAG5B,GAAI,CAAC9f,EAAK,SAAW,CAACA,EAAK,UAAW,CACpCiP,EAAM,MAAMnQ,EAAc,CAAE,GAAI,mDAAoD,CAAC,EACrF,MACF,CAEA,MAAM+B,EAAS,MAAMye,EAAStf,CAAI,EAE9Ba,EAAO,QACToO,EAAM,QACJnQ,EACE,CAAE,GAAI,2CACN,CAAE,SAAU+B,EAAO,SAAU,QAASA,EAAO,QAAQ,CACvD,EAGFoO,EAAM,MAAMnQ,EAAc,CAAE,GAAI,wCAAyC,CAAC,CAE9E,OAASqB,EAAO,CACVA,aAAiB,YACnB8O,EAAM,MAAMnQ,EAAc,CAAE,GAAI,8CAA+C,CAAC,EAEhFmQ,EAAM,MAAMnQ,EAAc,CAAE,GAAI,wCAAyC,CAAC,CAE9E,EACF,EAAG,CAACwgB,EAAUxgB,CAAa,CAAC,EAE5B,OACEiC,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAAC5D,GAAA,CAAkB,UAAU,UAAU,EACtC0B,EAAc,CAAE,GAAI,qCAAsC,GAC7D,EACAiC,OAAC,OAAI,UAAU,4BAEb,UAAAA,OAAC,OAAI,UAAU,gDACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAU,sBAAuB,SAAAlC,EAAc,CAAE,GAAI,0CAA2C,EAAE,QACvG2N,EAAA,CAAM,QAAQ,UAAU,UAAU,UAAU,kBAAM,GACrD,EACAzL,MAAC2L,EAAA,CACC,QAASmR,GAAA,MAAAA,EAAe,cAAgB,UAAY,UACpD,KAAK,KACL,UAAU,MACV,SAAUC,GAAkBG,EAC5B,QAAS,IAAMD,EAAc,EAACH,GAAA,MAAAA,EAAe,eAAe,QAAQ,EAEnE,SAAAA,GAAA,MAAAA,EAAe,cACd/c,OAAAI,WAAA,CACE,UAAAH,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,oCAAqC,GAC5D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAAC4L,GAAA,CAAE,UAAU,eAAe,EAC3B9N,EAAc,CAAE,GAAI,qCAAsC,GAC7D,GAEJ,EACF,EACAkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,8CAA+C,EACtE,GACF,EAGAD,OAAC,OAAI,UAAU,gDACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAU,sBAAuB,SAAAlC,EAAc,CAAE,GAAI,yCAA0C,EAAE,QACtG2N,EAAA,CAAM,QAAQ,YAAY,UAAU,UAAU,iBAAK,GACtD,EACAzL,MAAC2L,EAAA,CACC,QAASmR,GAAA,MAAAA,EAAe,aAAe,UAAY,UACnD,KAAK,KACL,UAAU,MACV,SAAUC,GAAkBG,EAC5B,QAAS,IAAMD,EAAc,EAACH,GAAA,MAAAA,EAAe,cAAc,OAAO,EAEjE,SAAAA,GAAA,MAAAA,EAAe,aACd/c,OAAAI,WAAA,CACE,UAAAH,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,oCAAqC,GAC5D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAAC4L,GAAA,CAAE,UAAU,eAAe,EAC3B9N,EAAc,CAAE,GAAI,qCAAsC,GAC7D,GAEJ,EACF,EACAkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,6CAA8C,EACrE,GACC8c,GAAA,YAAAA,EAAe,sBACd/c,OAAC,KAAE,UAAU,0BACX,UAAAC,MAAC+e,GAAA,CAAc,UAAU,sBAAsB,EAC9CjhB,EAAc,CAAE,GAAI,6CAA8C,GACrE,GAEJ,EAGAiC,OAAC,OAAI,UAAU,gDACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAACgf,GAAA,CAAQ,UAAU,gCAAgC,EACnDhf,MAAC,QAAK,UAAU,sBAAuB,WAAc,CAAE,GAAI,4CAA6C,EAAE,GAC5G,EACAA,MAAC2L,EAAA,CACC,QAASyR,GAAA,MAAAA,EAAe,QAAU,UAAY,UAC9C,KAAK,KACL,UAAU,MACV,SAAUC,GAAkBG,EAC5B,QAAS,IAAMD,EAAc,EAACH,GAAA,MAAAA,EAAe,QAAO,EAEnD,SAAAA,GAAA,MAAAA,EAAe,QACdrd,OAAAI,WAAA,CACE,UAAAH,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,oCAAqC,GAC5D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAAC4L,GAAA,CAAE,UAAU,eAAe,EAC3B9N,EAAc,CAAE,GAAI,qCAAsC,GAC7D,GAEJ,EACF,EACAkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,gDAAiD,EACxE,GACF,EAGAD,OAAC,OAAI,UAAU,gDACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAACif,GAAA,CAAS,UAAU,gCAAgC,EACpDjf,MAAC,QAAK,UAAU,sBAAuB,WAAc,CAAE,GAAI,2CAA4C,EAAE,QACxGyL,EAAA,CAAM,QAAQ,YAAY,UAAU,UAAU,iBAAK,GACtD,EACA1L,OAAC,OAAI,UAAU,0BACZ,WAAA2d,GAAA,YAAAA,EAAc,UACb1d,MAAC2L,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,SAAUgS,GAAiBM,EAC3B,QAAS,IAAMD,EAAA,EACf,MAAOlgB,EAAc,CAAE,GAAI,0CAA2C,EAEtE,eAAC8Q,GAAA,CAAU,UAAWtF,EAAG,cAAe2U,GAAc,cAAc,EAAG,IAG3Eje,MAAC2L,EAAA,CACC,QAAS+R,GAAA,MAAAA,EAAc,QAAU,UAAY,UAC7C,KAAK,KACL,UAAU,MACV,SAAUC,GAAiBG,EAC3B,QAAS,IAAMD,EAAa,EAACH,GAAA,MAAAA,EAAc,QAAO,EAEjD,SAAAA,GAAA,MAAAA,EAAc,QACb3d,OAAAI,WAAA,CACE,UAAAH,MAAC0L,GAAA,CAAM,UAAU,eAAe,EAC/B5N,EAAc,CAAE,GAAI,oCAAqC,GAC5D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAAC4L,GAAA,CAAE,UAAU,eAAe,EAC3B9N,EAAc,CAAE,GAAI,qCAAsC,GAC7D,GAEJ,EACF,GACF,EACAkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,+CAAgD,EACvE,GACC0d,GAAA,YAAAA,EAAc,UACb1d,MAAC,KAAE,UAAU,mCACV,SAAAlC,EAAc,CAAE,GAAI,+CAAgD,EACvE,GAEJ,GACF,QAGC,OAAI,UAAU,mCACb,SAAAiC,OAAC,OAAI,UAAU,oCACb,UAAAC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CAAE,GAAI,6CAA8C,EACrE,EACAiC,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,SACC,IAAKlB,EACL,KAAK,OACL,OAAO,yBACP,SAAU+f,EACV,UAAU,WAEZ7e,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,MACV,SAAU4S,EACV,QAAS,WAAM,OAAA3e,EAAAd,EAAa,UAAb,YAAAc,EAAsB,SAEpC,WACCG,OAAAI,WAAA,CACE,UAAAH,MAAC,OAAI,UAAU,oFAAoF,EAClGlC,EAAc,CAAE,GAAI,sCAAuC,GAC9D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAACkf,GAAA,CAAO,UAAU,mBAAmB,EACpCphB,EAAc,CAAE,GAAI,mCAAoC,GAC3D,IAGJkC,MAAC2L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,UAAU,MACV,SAAUyS,EACV,QAASK,EAER,WACC1e,OAAAI,WAAA,CACE,UAAAH,MAAC,OAAI,UAAU,oFAAoF,EAClGlC,EAAc,CAAE,GAAI,sCAAuC,GAC9D,EAEAiC,OAAAI,WAAA,CACE,UAAAH,MAACmf,GAAA,CAAS,UAAU,mBAAmB,EACtCrhB,EAAc,CAAE,GAAI,mCAAoC,GAC3D,GAEJ,EACF,GACF,EACF,GACF,CAEJ,CAaA,SAASshB,IAAsB,CAC7B,KAAM,CAAE,cAAAthB,CAAA,EAAkBC,EAAA,EACpB,CAACshB,EAAaC,CAAc,EAAI9hB,WAA6B,IAAI,EACjE,CAAC+hB,EAAUC,CAAW,EAAIhiB,WAAS,EAAK,EACxC,CAAC2B,EAAOsgB,CAAQ,EAAIjiB,WAAwB,IAAI,EAChD,CAACkiB,EAAaC,CAAc,EAAIniB,WAAsB,IAAI,EAC1D,CAACoiB,EAAWC,CAAY,EAAIriB,WAAS,IAAM,CAC/C,GAAI,CACF,MAAMsiB,EAAQ,aAAa,QAAQ,gBAAgB,EACnD,OAAOA,IAAU,KAAO,GAAO,KAAK,MAAMA,CAAK,CACjD,MAAQ,CACN,MAAO,EACT,CACF,CAAC,EAEKC,EAAe,MAAOC,EAAS,KAAU,CACxCA,GAAQR,EAAY,EAAI,EAC7BC,EAAS,IAAI,EACb,GAAI,CACF,MAAM5iB,EAAW,MAAM,MAAM,oBAAoB,EACjD,GAAI,CAACA,EAAS,GAAI,MAAM,IAAI,MAAM,QAAQA,EAAS,MAAM,EAAE,EAE3D,MAAMmC,EAAoB,MAAMnC,EAAS,OACzC,GAAI,CAACmC,EAAK,eAAgB,MAAM,IAAI,MAAM,kBAAkB,EAE5DsgB,EAAetgB,CAAI,EACnB2gB,EAAe,IAAI,IAAM,CAC3B,OAAS7f,EAAK,CACPkgB,GAAQP,EAAS3f,aAAe,MAAQA,EAAI,QAAU,eAAe,CAC5E,SACE0f,EAAY,EAAK,CACnB,CACF,EAEA/hB,YAAU,IAAM,CAId,GAFAsiB,EAAa,EAAI,EAEb,CAACH,EAAW,OAChB,MAAMK,EAAW,YAAY,IAAMF,EAAa,EAAI,EAAG,KAAU,GAAI,EACrE,MAAO,IAAM,cAAcE,CAAQ,CACrC,EAAG,CAACL,CAAS,CAAC,EAEd,MAAMM,EAAmBC,GAAqB,CAC5CN,EAAaM,CAAO,EACpB,aAAa,QAAQ,iBAAkB,KAAK,UAAUA,CAAO,CAAC,CAChE,EAEA,OACEpgB,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,OAAI,UAAU,yCACb,UAAAA,OAAC,MAAG,UAAU,gEACZ,UAAAC,MAACogB,GAAA,CAAc,UAAU,UAAU,EAClCtiB,EAAc,CAAE,GAAI,8BAA+B,GACtD,EACAiC,OAAC4L,EAAA,CACC,QAAQ,UACR,KAAK,KACL,SAAU4T,EACV,QAAS,IAAMQ,EAAA,EAEf,UAAA/f,MAAC4O,IAAU,UAAWtF,EAAG,qBAAsBiW,GAAY,cAAc,EAAG,EAExEzhB,EADHyhB,EACiB,CAAE,GAAI,kCACN,CAAE,GAAI,iCADkC,CACA,GAC5D,EACF,EAEAxf,OAAC,OAAI,UAAU,YAEb,UAAAA,OAAC,OAAI,UAAU,gDACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAC,MAAC,QAAK,UAAU,gCACb,SAAAlC,EAAc,CAAE,GAAI,uCAAwC,EAC/D,EACAkC,MAACyL,GAAM,QAAQ,YAAY,UAAU,oBAClC,UAAA4T,GAAA,YAAAA,EAAa,iBAAkB,MAClC,GACF,EACAtf,OAAC,OAAI,UAAU,oCACb,UAAAC,MAAC,QAAK,UAAU,gCACb,SAAAlC,EAAc,CAAE,GAAI,sCAAuC,EAC9D,EACAkC,MAACyL,EAAA,CACC,QAAS4T,GAAA,MAAAA,EAAa,UAAY,UAAY,YAC9C,UAAU,oBAET,2BAAa,gBAAiB,OACjC,EACF,EAGCA,GACCtf,OAAC,OAAI,UAAU,gEACb,UAAAC,MAAC,QAAK,UAAU,sBACb,SAAAqf,EAAY,UACTvhB,EAAc,CAAE,GAAI,wCAAyC,EAC7DA,EAAc,CAAE,GAAI,iCAAkC,EAC5D,EACAkC,MAAC,QAAK,UAAWsJ,EACf,wCACA+V,EAAY,UAAY,gBAAkB,eAC5C,CAAG,GACL,EAGDlgB,GACCY,OAAC,OAAI,UAAU,sDACb,UAAAC,MAAC+e,GAAA,CAAc,UAAU,yCAAyC,EAClEhf,OAAC,QAAK,UAAU,2BACb,UAAAjC,EAAc,CAAE,GAAI,oCAAqC,EAAE,KAAGqB,CAAA,EACjE,GACF,GAEJ,GAGCkgB,GAAA,YAAAA,EAAa,YACZtf,OAAC,OAAI,UAAU,uEACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,2CACV,SAAAlC,EAAc,CAAE,GAAI,sCAAuC,EAC9D,EACAkC,MAAC,QAAK,UAAU,uDACb,WAAY,cACf,GACF,QACC2L,EAAA,CAAO,QAAQ,UAAU,KAAK,KAAK,QAAO,GACzC,SAAA3L,MAAC,KACC,KAAK,0CACL,OAAO,SACP,IAAI,sBACJ,UAAU,mCAET,SAAAlC,EAAc,CAAE,GAAI,oCAAqC,GAC5D,CACF,GACF,EAIFiC,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,SAAM,UAAU,yCACf,UAAAC,MAAC,SACC,KAAK,WACL,QAAS4f,EACT,SAAWjgB,GAAMugB,EAAgBvgB,EAAE,OAAO,OAAO,EACjD,UAAU,gCAEX,OACC,UAAAK,MAAC,QAAK,UAAU,sBAAuB,SAAAlC,EAAc,CAAE,GAAI,kCAAmC,EAAE,EAChGkC,MAAC,KAAE,UAAU,gCAAiC,WAAc,CAAE,GAAI,sCAAuC,EAAE,GAC7G,GACF,EACAD,OAAC,QAAK,UAAU,gCACb,UAAAjC,EAAc,CAAE,GAAI,oCAAqC,EAAE,IAAE,IAC7D4hB,EAAcA,EAAY,qBAAuB5hB,EAAc,CAAE,GAAI,8BAA+B,GACvG,GACF,GACF,GACF,CAEJ,CAIA,SAASuiB,IAAsB,CAC7B,KAAM,CAAE,cAAAviB,CAAA,EAAkBC,EAAA,EACpB,CAAE,cAAAuiB,EAAe,UAAArhB,EAAW,QAAAshB,CAAA,EAAYC,GAAA,EACxC,CAAE,QAAAC,EAAS,UAAWC,CAAA,EAAcC,GAAA,EACpC,CAAE,KAAMC,CAAA,EAAeC,GAAA,EAE7B,OACE9gB,OAACyL,EAAA,CAAK,UAAU,MAEd,UAAAzL,OAAC,OAAI,UAAU,yCACb,UAAAA,OAAC,MAAG,UAAU,gEACZ,UAAAC,MAAC8gB,GAAA,CAAQ,UAAU,UAAU,EAC5BhjB,EAAc,CAAE,GAAI,8BAA+B,EACnD,CAACmB,GACAc,OAAC,QAAK,UAAU,4CACb,UAAAugB,EAAc,OAAO,IAAExiB,EAAc,CAAE,GAAI,sCAAuC,GACrF,GAEJ,EACAkC,MAAC,OAAI,UAAU,0BACb,SAAAA,MAAC2L,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS,IAAM4U,EAAA,EACf,MAAOziB,EAAc,CAAE,GAAI,gCAAiC,EAE5D,eAAC8Q,GAAA,CAAU,UAAWtF,EAAG,cAAerK,GAAa,cAAc,EAAG,GACxE,CACF,GACF,EAGCA,EACCe,MAAC,OAAI,UAAU,iDACZ,SAAAlC,EAAc,CAAE,GAAI,iCAAkC,EACzD,EACEwiB,EAAc,SAAW,EAC3BvgB,OAAC,OAAI,UAAU,6BACb,UAAAC,MAAC,KAAE,UAAU,gCACV,SAAAlC,EAAc,CAAE,GAAI,wCAAyC,EAChE,EACAkC,MAAC,OAAI,UAAU,0CACb,eAAC,QAAK,UAAU,oBAAoB,uBAAW,EACjD,GACF,EAEAD,OAAC,OAAI,UAAU,YACZ,UAAAugB,EAAc,IAAKS,GAAS,CAC3B,MAAMC,EAAWD,EAAK,oBAAsB,SACtCE,EAAc,IAAI,KAAKF,EAAK,iBAAiB,EAAE,qBAC/CG,EAAUH,EAAK,sBAAwB,UAAYA,EAAK,oBAAsBA,EAAK,kBAEzF,OACEhhB,OAAC,OAEC,UAAU,gDAGV,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OAAI,UAAU,0BACb,UAAAC,MAAC,QAAK,UAAWsJ,EACf,6DACA0X,EAAW,6BAA+B,oCAEzC,SAAAA,EAAWhhB,MAACmhB,GAAA,CAAK,UAAU,UAAU,EAAKnhB,MAACohB,GAAA,CAAO,UAAU,UAAU,EACzE,QACC,QAAK,UAAU,sBACb,SACGtjB,EADHkjB,EACiB,CAAE,GAAI,gCACN,CAAE,GAAI,6BADgC,EAE1D,EACAjhB,OAAC0L,EAAA,CAAM,QAAQ,YAAY,UAAU,oBAAoB,cACrDyV,CAAA,EACJ,GACF,EACAnhB,OAAC4L,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,MACV,SAAU+U,EACV,QAAS,IAAMD,EAAQM,EAAK,iBAAiB,EAE7C,UAAA/gB,MAACogB,IAAc,UAAW9W,EAAG,mBAAoBoX,GAAa,cAAc,EAAG,EAE3E5iB,EADH4iB,EACiB,CAAE,GAAI,mCACN,CAAE,GAAI,gCADmC,CACF,GAC3D,EACF,EAGA1gB,MAAC,OAAI,UAAU,iFAAiF,MAAO+gB,EAAK,kBACzG,WAAK,kBACR,EAGAhhB,OAAC,OAAI,UAAU,wDACb,UAAAA,OAAC,QAAK,UAAU,iCACd,UAAAC,MAACqhB,GAAA,CAAS,UAAU,UAAU,EAC7BJ,CAAA,EACH,EACAlhB,OAAC,QAAK,UAAU,iCACd,UAAAC,MAACshB,GAAA,CAAK,UAAU,UAAU,EACzBP,EAAK,YAAY,IAAEjjB,EAAc,CAAE,GAAI,8BAA+B,GACzE,GACF,IAlDKijB,EAAK,YAqDhB,CAAC,EAGAH,GAAc,CAACA,EAAW,WAAaA,EAAW,aAAa,OAAS,GACvE7gB,OAAC,OAAI,UAAU,uEACb,UAAAA,OAAC,OAAI,UAAU,mFACb,UAAAC,MAAC+e,GAAA,CAAc,UAAU,UAAU,EAClCjhB,EAAc,CAAE,GAAI,mCAAoC,EAAE,MAAU8iB,EAAW,aAAa,OAAO,IAAE9iB,EAAc,CAAE,GAAI,qCAAsC,EAAE,aAAY,EAChL,EACAiC,OAAC,MAAG,UAAU,sDACX,UAAA6gB,EAAW,aAAa,MAAM,EAAG,CAAC,EAAE,IAAKW,GACxCvhB,MAAC,MAAY,SAAAuhB,CAAA,EAAJA,CAAM,CAChB,EACAX,EAAW,aAAa,OAAS,UAC/B,MAAG,cAAEA,EAAW,aAAa,OAAS,EAAE,YAAQ,GAErD,EACA7gB,OAAC,OAAI,UAAU,6BACb,UAAAA,OAAC,KAAE,UAAU,2BAA4B,UAAAjC,EAAc,CAAE,GAAI,iCAAkC,EAAE,KAAC,EAClGkC,MAAC,QAAK,UAAU,0DAA0D,uBAAW,GACvF,GACF,GAEJ,GAEJ,CAEJ,CAsBA,SAASwhB,GAAmB,CAC1B,SAAAC,EACA,eAAAC,EACA,cAAAC,EACA,YAAAC,EACA,eAAA1X,EACA,gBAAA+Q,EACA,aAAAC,EACA,cAAAC,EACA,aAAAC,EACA,wBAAAC,EACA,gBAAAC,EACA,qBAAAC,EACA,eAAAC,EACA,gBAAAC,EACA,cAAA3d,CACF,EAA4B,CAC1B,KAAM,CAAE,KAAM+jB,CAAA,EAAeC,GAAA,EAE7B,OACE/hB,OAAAI,WAAA,CACE,UAAAJ,OAAC,KAAE,UAAU,qCACV,UAAAjC,EAAc,CAAE,GAAI,gCAAiC,EAAE,IAACkC,MAAC,UAAO,UAAU,kBAAmB,SAAA0hB,CAAA,CAAe,GAC/G,EACA1hB,MAAC,OAAI,UAAU,YACZ,gBAAO,QAAQyhB,CAAQ,EAAE,IAAI,CAAC,CAAC7G,EAAQ7Q,CAAM,IAAM,CAClD,MAAMgY,EAASF,GAAA,YAAAA,EAAajH,GAC5B,OACE5a,MAAC6a,GAAA,CAEC,OAAAD,EACA,OAAA7Q,EACA,UAAW6Q,IAAW8G,EACtB,WAAYC,EAAc,IAAI/G,CAAM,EACpC,cAAemH,GAAA,YAAAA,EAAQ,UACvB,SAAUH,EAAY,IAAIhH,CAAM,EAChC,eAAgB,IAAM1Q,EAAe0Q,CAAM,EAC3C,gBAAiB,IAAMK,EAAgBL,CAAM,EAC7C,aAAc,IAAMM,EAAaN,CAAM,EACvC,cAAe,CAACtF,EAAOrV,IAAUkb,EAAcP,EAAQtF,EAAOrV,CAAK,EACnE,aAAe+hB,GAAS5G,EAAaR,EAAQoH,CAAI,EACjD,wBAA0BC,GAAW5G,EAAwBT,EAAQqH,CAAM,EAC3E,gBAAkBC,GAAY5G,EAAgBV,EAAQsH,CAAO,EAC7D,qBAAuBC,GAAiB5G,EAAqBX,EAAQuH,CAAY,EACjF,eAAiBtM,GAAW2F,EAAeZ,EAAQ/E,CAAM,EACzD,gBAAiB,IAAM4F,EAAgBb,CAAM,GAhBxCA,CAAA,CAmBX,CAAC,EACH,GACF,CAEJ,CAIO,SAASwH,IAAe,CAC7B,KAAM,CAAE,cAAAtkB,CAAA,EAAkBC,EAAA,EACpB,CAAE,MAAAskB,EAAO,SAAAthB,CAAA,EAAa3C,GAAA,EACtBqjB,EAAWa,GAAeC,EAAc,EACxCb,EAAiBY,GAAeE,EAAoB,EACpDC,EAAkBH,GAAeI,EAAqB,EACtD,CAAE,cAAAC,EAAe,kBAAAC,EAAmB,mBAAAC,EAAoB,qBAAAC,CAAA,EAAyBR,GAAA,EAEjF,CAACX,EAAeoB,CAAgB,EAAIvlB,WAAsB,IAAI,GAAK,EACnE,CAACokB,EAAaoB,CAAc,EAAIxlB,WAAsB,IAAI,GAAK,EAE/DylB,EAAoBrI,GAAmB,CAC3CmI,EAAkBhO,GAAS,CACzB,MAAMmO,EAAO,IAAI,IAAInO,CAAI,EACzB,OAAImO,EAAK,IAAItI,CAAM,EACjBsI,EAAK,OAAOtI,CAAM,EAElBsI,EAAK,IAAItI,CAAM,EAEVsI,CACT,CAAC,CACH,EAEMC,EAA2BvI,GAAmB,CAClD+H,EAAc/H,EAAQ,CAAE,QAAS,CAAC6G,EAAS7G,CAAM,EAAE,QAAS,CAC9D,EAEMwI,EAAwBxI,GAAmB,CAC/CgI,EAAkBhI,CAAM,CAC1B,EAEMyI,EAAoB,CAACzI,EAAgBtF,EAA0CrV,IAAkB,CACrG0iB,EAAc/H,EAAQ,CAAE,CAACtF,CAAK,EAAGrV,EAAO,CAC1C,EAEMqjB,EAAmB,CAAC1I,EAAgBoH,IAAmB,CAC3DW,EAAc/H,EAAQ,CAAE,KAAAoH,EAAM,CAChC,EAEMuB,EAA8B,CAAC3I,EAAgB4I,IAA8B,CACjFb,EAAc/H,EAAQ,CAAE,gBAAA4I,EAAiB,CAC3C,EAEMC,EAAsB,CAAC7I,EAAgBsH,IAAgC,CAC3ES,EAAc/H,EAAQ,CAAE,QAAAsH,EAAS,CACnC,EAEMwB,EAA2B,CAAC9I,EAAgBuH,IAAqC,CACrFQ,EAAc/H,EAAQ,CAAE,aAAAuH,EAAc,CACxC,EAEMwB,EAAqB,CAAC/I,EAAgB/E,IAA+B,CACzE8M,EAAc/H,EAAQ,CAAE,OAAA/E,EAAQ,CAClC,EAGM+N,EAAsBtkB,cAAY,MAAOsb,GAAmB,CAChE,MAAM7Q,EAAS0X,EAAS7G,CAAM,EAC9B,GAAK7Q,EAEL,CAAAiZ,EAAgBjO,GAAS,IAAI,IAAIA,CAAI,EAAE,IAAI6F,CAAM,CAAC,EAClD,GAAI,CACF,MAAM9d,EAAgC,CACpC,QAASiN,EAAO,QAChB,aAAcA,EAAO,aACrB,eAAgBA,EAAO,eACvB,KAAMA,EAAO,KACb,gBAAiBA,EAAO,iBAIpByS,EAAiB7B,GAAkBC,CAAM,EAC3C4B,IAAmB,UACrB1f,EAAK,QAAUiN,EAAO,SAAW,KACxByS,IAAmB,iBAC5B1f,EAAK,aAAeiN,EAAO,cAAgB,KAC3CjN,EAAK,OAASiN,EAAO,QAAU,MAGjC,MAAM7M,EAAYZ,GAAA,EACZW,EAAkC,CAAE,eAAgB,oBACtDC,IACFD,EAAQ,cAAc,EAAIC,GAG5B,MAAM2mB,EAAM,MAAM,MAAM,mBAAmBjJ,CAAM,GAAI,CACnD,OAAQ,MACR,QAAA3d,EACA,KAAM,KAAK,UAAUH,CAAI,EACzB,YAAa,cACd,EAED,GAAI,CAAC+mB,EAAI,GACP,MAAM,IAAI,MAAM,QAAQA,EAAI,MAAM,EAAE,EAGtC5V,EAAM,QAAQnQ,EAAc,CAAE,GAAI,gCAAiC,EAAG,CACpE,YAAa8c,CAAA,CACd,CACH,MAAQ,CACN3M,EAAM,MAAMnQ,EAAc,CAAE,GAAI,oCAAqC,EAAG,CACtE,YAAa8c,CAAA,CACd,CACH,SACEoI,EAAgBjO,GAAS,CACvB,MAAMmO,EAAO,IAAI,IAAInO,CAAI,EACzB,OAAAmO,EAAK,OAAOtI,CAAM,EACXsI,CACT,CAAC,CACH,EACF,EAAG,CAACzB,EAAU3jB,CAAa,CAAC,EAEtBgmB,EAAyB,CAACxe,EAA4BrF,IAAmB,CAC7E4iB,EAAmB,CAAE,CAACvd,CAAG,EAAGrF,EAAO,CACrC,EAEA,OACEF,OAAC,OAAI,UAAU,8BAEb,UAAAA,OAAC,OACC,UAAAA,OAAC,MAAG,UAAU,6DACZ,UAAAC,MAAC+jB,GAAA,CAAS,UAAU,uBAAuB,EAC1CjmB,EAAc,CAAE,GAAI,iBAAkB,GACzC,EACAkC,MAAC,KAAE,UAAU,6BACV,WAAc,CAAE,GAAI,uBAAwB,EAC/C,GACF,EAGAD,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAACgkB,GAAA,CAAK,UAAU,UAAU,EACzBlmB,EAAc,CAAE,GAAI,+BAAgC,GACvD,EACAiC,OAAC,OAAI,UAAU,YAEb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,mCACV,SAAAlC,EAAc,CAAE,GAAI,4BAA6B,EACpD,EACAkC,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,kCAAmC,EAC1D,QACCK,GAAA,EAAc,GACjB,EAGAN,OAAC,OAAI,UAAU,gEACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,8BAA+B,SAAAlC,EAAc,CAAE,GAAI,mCAAoC,EAAE,EACtGkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,uCAAwC,EAC/D,GACF,EACAA,MAAC2L,EAAA,CACC,QAAS0W,IAAU,SAAW,UAAY,UAC1C,KAAK,KACL,QAAS,IAAMthB,EAAS,QAAQ,EAE/B,SAAAjD,EAAc,CAAE,GAAI,0CAA2C,GAClE,EACF,GACF,GACF,EAGAiC,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAAC9D,GAAA,CAAU,UAAU,UAAU,EAC9B4B,EAAc,CAAE,GAAI,6BAA8B,GACrD,QACC,OAAI,UAAU,YACb,SAAAiC,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,8BAA+B,SAAAlC,EAAc,CAAE,GAAI,oCAAqC,EAAE,EACvGkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,mCAAoC,EAC3D,GACF,QACC8I,GAAA,EAAiB,GACpB,EACF,GACF,QAGC+T,GAAA,EAAwB,QAGxBhN,GAAA,EAAuB,QAGvBwQ,GAAA,EAAoB,QAGpBjB,GAAA,EAAoB,EAGrBrf,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAACyc,GAAA,CAAI,UAAU,UAAU,EACxB3e,EAAc,CAAE,GAAI,6BAA8B,GACrD,EACAkC,MAACwhB,GAAA,CACC,SAAAC,EACA,eAAAC,EACA,cAAAC,EACA,YAAAC,EACA,eAAgBqB,EAChB,gBAAiBE,EACjB,aAAcC,EACd,cAAeC,EACf,aAAcC,EACd,wBAAyBC,EACzB,gBAAiBE,EACjB,qBAAsBC,EACtB,eAAgBC,EAChB,gBAAiBC,EACjB,cAAA9lB,CAAA,EACF,EACF,QAGC2Y,GAAA,EAAwB,EAGzB1W,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAAC4O,GAAA,CAAU,UAAU,UAAU,EAC9B9Q,EAAc,CAAE,GAAI,6BAA8B,GACrD,EACAiC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,8BAA+B,SAAAlC,EAAc,CAAE,GAAI,mCAAoC,EAAE,EACtGkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,uCAAwC,EAC/D,GACF,EACAA,MAAC2L,EAAA,CACC,QAAS8W,EAAgB,YAAc,UAAY,UACnD,KAAK,KACL,QAAS,IAAMqB,EAAuB,cAAe,CAACrB,EAAgB,WAAW,EAEhF,SAAAA,EAAgB,YAAc3kB,EAAc,CAAE,GAAI,+BAAgC,EAAIA,EAAc,CAAE,GAAI,gCAAiC,GAC9I,EACF,EAEC2kB,EAAgB,aACf1iB,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,8BAA+B,SAAAlC,EAAc,CAAE,GAAI,uCAAwC,EAAE,EAC1GkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,2CAA4C,EACnE,GACF,EACAA,MAAC,OAAI,UAAU,aACZ,UAAC,KAAO,IAAO,IAAO,IAAM,EAAE,IAAKigB,GAClClgB,OAAC4L,EAAA,CAEC,QAAS8W,EAAgB,kBAAoBxC,EAAW,UAAY,UACpE,KAAK,KACL,QAAS,IAAM6D,EAAuB,kBAAmB7D,CAAQ,EAEhE,UAAAA,EAAW,IAAK,MALZA,CAAA,CAOR,EACH,GACF,GAEJ,GACF,EAGAlgB,OAACyL,EAAA,CAAK,UAAU,MACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAAC6K,GAAA,CAAK,UAAU,UAAU,EACzB/M,EAAc,CAAE,GAAI,+BAAgC,GACvD,EACAiC,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,8BAA+B,SAAAlC,EAAc,CAAE,GAAI,6CAA8C,EAAE,EAChHkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,iDAAkD,EACzE,GACF,EACAA,MAAC2L,EAAA,CACC,QAAS8W,EAAgB,qBAAuB,UAAY,UAC5D,KAAK,KACL,QAAS,IAAMqB,EAAuB,uBAAwB,CAACrB,EAAgB,oBAAoB,EAElG,SAAAA,EAAgB,qBAAuB3kB,EAAc,CAAE,GAAI,+BAAgC,EAAIA,EAAc,CAAE,GAAI,gCAAiC,GACvJ,EACF,EAEAiC,OAAC,OAAI,UAAU,oCACb,UAAAA,OAAC,OACC,UAAAC,MAAC,KAAE,UAAU,8BAA+B,SAAAlC,EAAc,CAAE,GAAI,sCAAuC,EAAE,EACzGkC,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0CAA2C,EAClE,GACF,EACAA,MAAC2L,EAAA,CACC,QAAS8W,EAAgB,aAAe,UAAY,UACpD,KAAK,KACL,QAAS,IAAMqB,EAAuB,eAAgB,CAACrB,EAAgB,YAAY,EAElF,SAAAA,EAAgB,aAAe3kB,EAAc,CAAE,GAAI,4BAA6B,EAAIA,EAAc,CAAE,GAAI,6BAA8B,GACzI,EACF,GACF,GACF,QAGCuP,GAAA,EAA0B,EAG3BtN,OAACyL,EAAA,CAAK,UAAU,4BACd,UAAAzL,OAAC,MAAG,UAAU,qEACZ,UAAAC,MAACikB,GAAA,CAAU,UAAU,UAAU,EAC9BnmB,EAAc,CAAE,GAAI,uBAAwB,GAC/C,EACAkC,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,6BAA8B,EACrD,EACAD,OAAC4L,EAAA,CACC,QAAQ,cACR,QAAS,IAAM,CACT,QAAQ7N,EAAc,CAAE,GAAI,yBAA0B,CAAC,GACzDglB,EAAA,CAEJ,EAEA,UAAA9iB,MAACikB,GAAA,CAAU,UAAU,eAAe,EACnCnmB,EAAc,CAAE,GAAI,iCAAkC,IACzD,EACF,GACF,CAEJ","names":["BellOff","createLucideIcon","CircleArrowUp","Languages","LayoutPanelLeft","MessageSquareText","Volume2","getCsrfToken","match","searchUnsplash","query","page","perPage","params","response","body","uploadBackgroundImage","file","headers","csrfToken","triggerUnsplashDownload","downloadLocation","useUnsplashSearch","debouncedQuery","setDebouncedQuery","useState","useEffect","timer","useQuery","MODES","BackgroundImagePicker","formatMessage","useIntl","backgroundConfig","setBackgroundMode","setBackgroundImage","updateBackgroundEffect","useTheme","searchQuery","setSearchQuery","setPage","customUrl","setCustomUrl","isUploading","setIsUploading","uploadError","setUploadError","fileInputRef","useRef","data","isLoading","isError","error","showImageControls","handlePhotoSelect","useCallback","photo","handleCustomUrlApply","handleRemoveImage","handleFileUpload","e","_a","result","err","jsxs","jsx","value","labelId","Fragment","p","ThemeSelector","colorScheme","resolvedTheme","customHue","isCustomTheme","gradientLevel","enableHoverGlow","enableBackgroundAnimation","motionPreference","setColorScheme","setTheme","setCustomHue","setGradientLevel","setEnableHoverGlow","setEnableBackgroundAnimation","setMotionPreference","styleTier","setStyleTier","themeSlots","activeSlotId","canAddSlot","setActiveSlot","copySlot","renameSlot","deleteSlot","undoDeleteSlot","exportThemeCode","importThemeCode","setBackgroundConfig","addToast","removeToast","useNotifications","previewHue","setPreviewHue","contrastWarnings","setContrastWarnings","contrastFixes","setContrastFixes","showContrastWarning","setShowContrastWarning","renamingSlotId","setRenamingSlotId","renameValue","setRenameValue","pendingDeleteSlot","setPendingDeleteSlot","renameInputRef","undoToastIdRef","showImportPanel","setShowImportPanel","importCode","setImportCode","importPreview","setImportPreview","importWarning","setImportWarning","importError","setImportError","copyFeedback","setCopyFeedback","mode","getPreviewColor","variable","hslValue","generateThemeFromHue","STYLE_TIERS","getTierPreviewColors","tier","baseVars","tieredVars","applyStyleTier","handleSchemeSelect","scheme","handleCustomSelect","handleHueSave","vars","failures","checkThemeContrast","r","fixes","failure","key","generateContrastFix","handleHueReset","handleModeSelect","newMode","handleKeyDown","nextIndex","COLOR_SCHEMES","s","handleSlotSelect","slotId","handleCopySlot","handleStartRename","currentName","handleConfirmRename","handleCancelRename","handleRenameKeyDown","handleConfirmDelete","toastId","handleCancelDelete","handleCopyThemeCode","code","handleOpenImport","handleCloseImport","handleImportCodeChange","handleApplyImport","DEFAULT_BACKGROUND_CONFIG","getImportPreviewColors","payload","hue","getShareErrorMessageId","errorKey","THEME_SLOT_LIMIT","slot","isActive","isRenaming","preview","isSelected","level","pref","w","fix","i","THEME_MODES","modeOption","getThemeName","previewColors","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","LANGUAGE_OPTIONS","LanguageSwitcher","compact","className","locale","setLocale","useLocale","Select","SelectTrigger","cn","SelectValue","SelectContent","option","SelectItem","PLATFORM_INFO","EVENT_INFO","getDefaultConfig","PlatformConfigCards","config","expandedPlatform","testing","onToggleExpand","onUpdateConfig","onTest","onSave","saving","platforms","getPlatformIcon","platform","MessageCircle","Send","MessageSquare","Bell","Users","Mail","Link","getPlatformConfig","isConfigured","platformConfig","emailConfig","info","configured","expanded","Card","Badge","Check","Button","X","ChevronUp","ChevronDown","DiscordConfigForm","updates","TelegramConfigForm","FeishuConfigForm","DingTalkConfigForm","WeComConfigForm","EmailConfigForm","WebhookConfigForm","TestTube","onUpdate","showUrl","setShowUrl","Input","EyeOff","Eye","showToken","setShowToken","k","m","showPassword","setShowPassword","t","RemoteNotificationSection","setConfig","loading","setLoading","setSaving","setTesting","setExpandedPlatform","expandedEvent","setExpandedEvent","loadConfig","saveConfig","newConfig","toast","testPlatform","toggleEnabled","updatePlatformConfig","updateEventConfig","eventIndex","newEvents","toggleEventPlatform","eventConfig","allPlatforms","resetConfig","RefreshCw","index","isExpanded","platformInfo","Plus","Save","StyleOption","label","description","selected","onClick","icons","DurationSlider","onChange","disabled","presets","seconds","A2UIPreferencesSection","preferences","updatePreference","resetPreferences","useDialogStyleContext","styleOptions","Label","Sparkles","Clock","v","CODEX_EFFORTS","CLAUDE_EFFORTS","CLAUDE_MODEL_PRESETS","PERMISSION_MODES","MEMORY_OPTIONS","ISOLATION_OPTIONS","COLOR_OPTIONS","HOOK_EVENTS","selectClass","labelClass","parseMcpServersYaml","yaml","servers","lines","line","serializeMcpServersYaml","parseHooksYaml","currentEvent","currentMatcher","eventMatch","matcherMatch","commandMatch","serializeHooksYaml","hooks","parts","event","entries","entry","AdvancedSettings","agent","onSaved","color","setColor","permissionMode","setPermissionMode","memory","setMemory","maxTurns","setMaxTurns","background","setBackground","isolation","setIsolation","tools","setTools","disallowedTools","setDisallowedTools","skills","setSkills","installedServers","setInstalledServers","selectedServers","setSelectedServers","mcpLoading","setMcpLoading","customServer","setCustomServer","setHooks","newHookEvent","setNewHookEvent","cancelled","fetchMcpConfig","names","n","proj","handleSave","bgStr","newMcpYaml","newHooksYaml","updateAgentDefinition","toggleServer","name","prev","addCustomServer","addHook","removeHook","idx","_","updateHook","field","h","c","Checkbox","AgentCard","model","setModel","effort","setEffort","showAdvanced","setShowAdvanced","isDirty","effortOptions","Settings2","InstallationGroup","installationPath","agents","setExpanded","ChevronRight","AgentDefinitionsSection","setAgents","batchModel","setBatchModel","batchEffort","setBatchEffort","batchType","setBatchType","batchColor","setBatchColor","batchPermission","setBatchPermission","batchMemory","setBatchMemory","batchMaxTurns","setBatchMaxTurns","batchBackground","setBatchBackground","batchIsolation","setBatchIsolation","batchTools","setBatchTools","batchDisallowedTools","setBatchDisallowedTools","batchSkills","setBatchSkills","batchShowAdvanced","setBatchShowAdvanced","batchSaving","setBatchSaving","loadAgents","fetchAgentDefinitions","grouped","acc","batchTargets","batchHasClaudeTargets","batchEffortOptions","claudeBatchFields","hasClaudeBatchFields","handleBatchApply","targets","a","batchUpdateAgentDefinitions","claudeTargets","updated","Bot","val","path","groupAgents","FilePathInput","placeholder","isValidating","setIsValidating","pathError","setPathError","debouncedValue","useDebounce","timeoutId","handleBrowse","selectFile","__vitePreload","initialDir","Loader2","FolderOpen","ENV_FILE_TOOLS","SETTINGS_FILE_TOOLS","getConfigFileType","toolId","CliToolCard","isDefault","toolAvailable","isSaving","onToggleEnabled","onSetDefault","onUpdateModel","onUpdateTags","onUpdateAvailableModels","onUpdateEnvFile","onUpdateSettingsFile","onUpdateEffort","onSaveToBackend","tagInput","setTagInput","modelInput","setModelInput","handleAddTag","newTag","handleRemoveTag","tagToRemove","handleAddModel","newModel","currentModels","handleRemoveModel","modelToRemove","predefinedTags","configFileType","Cpu","tag","predefinedTag","effectiveEffort","ResponseLanguageSection","chineseStatus","chineseLoading","useChineseResponseStatus","toggleChinese","chineseToggling","useToggleChineseResponse","windowsStatus","windowsLoading","useWindowsPlatformStatus","toggleWindows","windowsToggling","useToggleWindowsPlatform","cliEnhStatus","cliEnhLoading","useCodexCliEnhancementStatus","toggleCliEnh","cliEnhToggling","useToggleCodexCliEnhancement","refreshCliEnh","refreshing","useRefreshCodexCliEnhancement","doExport","exporting","useExportSettings","doImport","importing","useImportSettings","handleExport","blob","url","timestamp","handleFileImport","text","AlertTriangle","Monitor","Terminal","Upload","Download","VersionCheckSection","versionData","setVersionData","checking","setChecking","setError","lastChecked","setLastChecked","autoCheck","setAutoCheck","saved","checkVersion","silent","interval","toggleAutoCheck","enabled","ArrowUpCircle","SystemStatusSection","installations","refetch","useCcwInstallations","upgrade","upgrading","useUpgradeCcwInstallation","ccwInstall","useCcwInstallStatus","Package","inst","isGlobal","installDate","version","Home","Folder","Calendar","File","f","CliToolsWithStatus","cliTools","defaultCliTool","expandedTools","savingTools","toolStatus","useCliToolStatus","status","tags","models","envFile","settingsFile","SettingsPage","theme","useConfigStore","selectCliTools","selectDefaultCliTool","userPreferences","selectUserPreferences","updateCliTool","setDefaultCliTool","setUserPreferences","resetUserPreferences","setExpandedTools","setSavingTools","toggleToolExpand","next","handleToggleToolEnabled","handleSetDefaultTool","handleUpdateModel","handleUpdateTags","handleUpdateAvailableModels","availableModels","handleUpdateEnvFile","handleUpdateSettingsFile","handleUpdateEffort","handleSaveToBackend","res","handlePreferenceChange","Settings","Moon","RotateCcw"],"ignoreList":[0,1,2,3,4,5],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/bell-off.js","../../../../node_modules/lucide-react/dist/esm/icons/circle-arrow-up.js","../../../../node_modules/lucide-react/dist/esm/icons/languages.js","../../../../node_modules/lucide-react/dist/esm/icons/layout-panel-left.js","../../../../node_modules/lucide-react/dist/esm/icons/message-square-text.js","../../../../node_modules/lucide-react/dist/esm/icons/volume-2.js","../../src/lib/unsplash.ts","../../src/hooks/useUnsplashSearch.ts","../../src/components/shared/BackgroundImagePicker.tsx","../../src/components/shared/ThemeSelector.tsx","../../src/components/layout/LanguageSwitcher.tsx","../../src/types/remote-notification.ts","../../src/components/settings/PlatformConfigCards.tsx","../../src/components/settings/RemoteNotificationSection.tsx","../../src/components/settings/A2UIPreferencesSection.tsx","../../src/components/settings/AgentDefinitionsSection.tsx","../../src/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst BellOff = createLucideIcon(\"BellOff\", [\n [\"path\", { d: \"M8.7 3A6 6 0 0 1 18 8a21.3 21.3 0 0 0 .6 5\", key: \"o7mx20\" }],\n [\"path\", { d: \"M17 17H3s3-2 3-9a4.67 4.67 0 0 1 .3-1.7\", key: \"16f1lm\" }],\n [\"path\", { d: \"M10.3 21a1.94 1.94 0 0 0 3.4 0\", key: \"qgo35s\" }],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { BellOff as default };\n//# sourceMappingURL=bell-off.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleArrowUp = createLucideIcon(\"CircleArrowUp\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m16 12-4-4-4 4\", key: \"177agl\" }],\n [\"path\", { d: \"M12 16V8\", key: \"1sbj14\" }]\n]);\n\nexport { CircleArrowUp as default };\n//# sourceMappingURL=circle-arrow-up.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Languages = createLucideIcon(\"Languages\", [\n [\"path\", { d: \"m5 8 6 6\", key: \"1wu5hv\" }],\n [\"path\", { d: \"m4 14 6-6 2-3\", key: \"1k1g8d\" }],\n [\"path\", { d: \"M2 5h12\", key: \"or177f\" }],\n [\"path\", { d: \"M7 2h1\", key: \"1t2jsx\" }],\n [\"path\", { d: \"m22 22-5-10-5 10\", key: \"don7ne\" }],\n [\"path\", { d: \"M14 18h6\", key: \"1m8k6r\" }]\n]);\n\nexport { Languages as default };\n//# sourceMappingURL=languages.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst LayoutPanelLeft = createLucideIcon(\"LayoutPanelLeft\", [\n [\"rect\", { width: \"7\", height: \"18\", x: \"3\", y: \"3\", rx: \"1\", key: \"2obqm\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"3\", rx: \"1\", key: \"6d4xhi\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"14\", rx: \"1\", key: \"nxv5o0\" }]\n]);\n\nexport { LayoutPanelLeft as default };\n//# sourceMappingURL=layout-panel-left.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MessageSquareText = createLucideIcon(\"MessageSquareText\", [\n [\"path\", { d: \"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\", key: \"1lielz\" }],\n [\"path\", { d: \"M13 8H7\", key: \"14i4kc\" }],\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }]\n]);\n\nexport { MessageSquareText as default };\n//# sourceMappingURL=message-square-text.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Volume2 = createLucideIcon(\"Volume2\", [\n [\n \"path\",\n {\n d: \"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\",\n key: \"uqj9uw\"\n }\n ],\n [\"path\", { d: \"M16 9a5 5 0 0 1 0 6\", key: \"1q6k2b\" }],\n [\"path\", { d: \"M19.364 18.364a9 9 0 0 0 0-12.728\", key: \"ijwkga\" }]\n]);\n\nexport { Volume2 as default };\n//# sourceMappingURL=volume-2.js.map\n","/**\n * Unsplash API Client\n * Frontend functions to search Unsplash via the backend proxy.\n */\n\nexport interface UnsplashPhoto {\n id: string;\n thumbUrl: string;\n smallUrl: string;\n regularUrl: string;\n photographer: string;\n photographerUrl: string;\n photoUrl: string;\n blurHash: string | null;\n downloadLocation: string;\n}\n\nexport interface UnsplashSearchResult {\n photos: UnsplashPhoto[];\n total: number;\n totalPages: number;\n}\n\nfunction getCsrfToken(): string | null {\n const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);\n return match ? decodeURIComponent(match[1]) : null;\n}\n\n/**\n * Search Unsplash photos via backend proxy.\n */\nexport async function searchUnsplash(\n query: string,\n page = 1,\n perPage = 20\n): Promise<UnsplashSearchResult> {\n const params = new URLSearchParams({\n query,\n page: String(page),\n per_page: String(perPage),\n });\n\n const response = await fetch(`/api/unsplash/search?${params}`, {\n credentials: 'same-origin',\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n throw new Error(body.error || `Unsplash search failed: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Upload a local image as background.\n * Sends raw binary to avoid base64 overhead.\n */\nexport async function uploadBackgroundImage(file: File): Promise<{ url: string; filename: string }> {\n const headers: Record<string, string> = {\n 'Content-Type': file.type,\n 'X-Filename': encodeURIComponent(file.name),\n };\n const csrfToken = getCsrfToken();\n if (csrfToken) {\n headers['X-CSRF-Token'] = csrfToken;\n }\n\n const response = await fetch('/api/background/upload', {\n method: 'POST',\n headers,\n credentials: 'same-origin',\n body: file,\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n throw new Error(body.error || `Upload failed: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Trigger Unsplash download event (required by API guidelines).\n */\nexport async function triggerUnsplashDownload(downloadLocation: string): Promise<void> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n const csrfToken = getCsrfToken();\n if (csrfToken) {\n headers['X-CSRF-Token'] = csrfToken;\n }\n\n await fetch('/api/unsplash/download', {\n method: 'POST',\n headers,\n credentials: 'same-origin',\n body: JSON.stringify({ downloadLocation }),\n });\n}\n","/**\n * React Query hook for searching Unsplash photos with debounce.\n */\nimport { useState, useEffect } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { searchUnsplash } from '@/lib/unsplash';\nimport type { UnsplashSearchResult } from '@/lib/unsplash';\n\nexport function useUnsplashSearch(query: string, page = 1, perPage = 20) {\n const [debouncedQuery, setDebouncedQuery] = useState(query);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedQuery(query);\n }, 500);\n return () => clearTimeout(timer);\n }, [query]);\n\n return useQuery<UnsplashSearchResult>({\n queryKey: ['unsplash-search', debouncedQuery, page, perPage],\n queryFn: () => searchUnsplash(debouncedQuery, page, perPage),\n enabled: debouncedQuery.trim().length > 0,\n staleTime: 5 * 60 * 1000, // 5 minutes\n retry: 1,\n });\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { useIntl } from 'react-intl';\nimport { useTheme } from '@/hooks/useTheme';\nimport { useUnsplashSearch } from '@/hooks/useUnsplashSearch';\nimport { triggerUnsplashDownload, uploadBackgroundImage } from '@/lib/unsplash';\nimport type { UnsplashPhoto } from '@/lib/unsplash';\nimport type { BackgroundMode } from '@/types/store';\n\nconst MODES: { value: BackgroundMode; labelId: string }[] = [\n { value: 'gradient-only', labelId: 'theme.background.mode.gradientOnly' },\n { value: 'image-only', labelId: 'theme.background.mode.imageOnly' },\n { value: 'image-gradient', labelId: 'theme.background.mode.imageGradient' },\n];\n\n/**\n * BackgroundImagePicker Component\n * Allows users to search Unsplash, pick a background image,\n * adjust visual effects, and switch between background modes.\n */\nexport function BackgroundImagePicker() {\n const { formatMessage } = useIntl();\n const {\n backgroundConfig,\n setBackgroundMode,\n setBackgroundImage,\n updateBackgroundEffect,\n } = useTheme();\n\n const [searchQuery, setSearchQuery] = useState('');\n const [page, setPage] = useState(1);\n const [customUrl, setCustomUrl] = useState('');\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const { data, isLoading, isError, error } = useUnsplashSearch(searchQuery, page);\n\n const showImageControls = backgroundConfig.mode !== 'gradient-only';\n\n const handlePhotoSelect = useCallback(async (photo: UnsplashPhoto) => {\n setBackgroundImage(photo.regularUrl, {\n photographerName: photo.photographer,\n photographerUrl: photo.photographerUrl,\n photoUrl: photo.photoUrl,\n });\n // Trigger download event per Unsplash API guidelines\n triggerUnsplashDownload(photo.downloadLocation).catch(() => {});\n }, [setBackgroundImage]);\n\n const handleCustomUrlApply = useCallback(() => {\n if (customUrl.trim()) {\n setBackgroundImage(customUrl.trim(), null);\n setCustomUrl('');\n }\n }, [customUrl, setBackgroundImage]);\n\n const handleRemoveImage = useCallback(() => {\n setBackgroundImage(null, null);\n }, [setBackgroundImage]);\n\n const handleFileUpload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n // Reset file input so the same file can be re-selected\n e.target.value = '';\n\n setUploadError(null);\n\n if (file.size > 10 * 1024 * 1024) {\n setUploadError(formatMessage({ id: 'theme.background.fileTooLarge' }));\n return;\n }\n\n if (!file.type.startsWith('image/') || !['image/jpeg', 'image/png', 'image/webp', 'image/gif'].includes(file.type)) {\n setUploadError(formatMessage({ id: 'theme.background.invalidType' }));\n return;\n }\n\n setIsUploading(true);\n try {\n const result = await uploadBackgroundImage(file);\n setBackgroundImage(result.url, null);\n } catch (err) {\n setUploadError((err as Error).message || formatMessage({ id: 'theme.background.uploadError' }));\n } finally {\n setIsUploading(false);\n }\n }, [formatMessage, setBackgroundImage]);\n\n return (\n <div className=\"space-y-4\">\n {/* Section title */}\n <h3 className=\"text-sm font-medium text-text\">\n {formatMessage({ id: 'theme.background.title' })}\n </h3>\n\n {/* Background mode selector */}\n <div\n className=\"flex gap-2\"\n role=\"radiogroup\"\n aria-label={formatMessage({ id: 'theme.background.title' })}\n >\n {MODES.map(({ value, labelId }) => (\n <button\n key={value}\n onClick={() => setBackgroundMode(value)}\n role=\"radio\"\n aria-checked={backgroundConfig.mode === value}\n className={`\n flex-1 px-3 py-2 rounded-lg text-xs font-medium\n transition-all duration-200 border-2\n ${backgroundConfig.mode === value\n ? 'border-accent bg-surface shadow-md'\n : 'border-border bg-bg hover:bg-surface'\n }\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\n `}\n >\n {formatMessage({ id: labelId })}\n </button>\n ))}\n </div>\n\n {/* Image selection area */}\n {showImageControls && (\n <div className=\"space-y-3\">\n {/* Current image preview */}\n {backgroundConfig.imageUrl && (\n <div className=\"relative rounded-lg overflow-hidden border border-border\">\n <img\n src={backgroundConfig.imageUrl}\n alt=\"Current background\"\n className=\"w-full h-32 object-cover\"\n />\n <button\n onClick={handleRemoveImage}\n className=\"absolute top-2 right-2 px-2 py-1 text-xs bg-black/60 text-white rounded hover:bg-black/80 transition-colors\"\n >\n {formatMessage({ id: 'theme.background.removeImage' })}\n </button>\n {/* Unsplash attribution */}\n {backgroundConfig.attribution && (\n <div className=\"absolute bottom-0 left-0 right-0 px-2 py-1 bg-black/50 text-white text-xs\">\n Photo by{' '}\n <a\n href={`${backgroundConfig.attribution.photographerUrl}?utm_source=ccw&utm_medium=referral`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline\"\n >\n {backgroundConfig.attribution.photographerName}\n </a>{' '}\n on{' '}\n <a\n href=\"https://unsplash.com/?utm_source=ccw&utm_medium=referral\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline\"\n >\n Unsplash\n </a>\n </div>\n )}\n </div>\n )}\n\n {/* Search box */}\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => { setSearchQuery(e.target.value); setPage(1); }}\n placeholder={formatMessage({ id: 'theme.background.searchPlaceholder' })}\n className=\"w-full px-3 py-2 text-sm rounded-lg border border-border bg-bg text-text\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1\"\n />\n\n {/* Photo grid */}\n {isLoading && (\n <div className=\"flex justify-center py-4\">\n <div className=\"w-5 h-5 border-2 border-border border-t-accent rounded-full animate-spin\" />\n </div>\n )}\n\n {isError && (\n <p className=\"text-xs text-destructive py-2\">\n {(error as Error)?.message || formatMessage({ id: 'theme.background.searchError' })}\n </p>\n )}\n\n {data && data.photos.length > 0 && (\n <>\n <div className=\"grid grid-cols-3 gap-2 max-h-60 overflow-y-auto\">\n {data.photos.map((photo) => (\n <button\n key={photo.id}\n onClick={() => handlePhotoSelect(photo)}\n className={`\n relative rounded overflow-hidden border-2 transition-all\n hover:border-accent focus:outline-none focus:ring-2 focus:ring-accent\n ${backgroundConfig.imageUrl === photo.regularUrl\n ? 'border-accent ring-2 ring-accent'\n : 'border-transparent'\n }\n `}\n >\n <img\n src={photo.thumbUrl}\n alt={`Photo by ${photo.photographer}`}\n className=\"w-full h-20 object-cover\"\n loading=\"lazy\"\n />\n </button>\n ))}\n </div>\n\n {/* Pagination */}\n {data.totalPages > 1 && (\n <div className=\"flex items-center justify-between\">\n <button\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n disabled={page <= 1}\n className=\"px-2 py-1 text-xs rounded border border-border disabled:opacity-50 hover:bg-surface\"\n >\n {formatMessage({ id: 'theme.background.prev' })}\n </button>\n <span className=\"text-xs text-text-secondary\">\n {page} / {data.totalPages}\n </span>\n <button\n onClick={() => setPage((p) => Math.min(data.totalPages, p + 1))}\n disabled={page >= data.totalPages}\n className=\"px-2 py-1 text-xs rounded border border-border disabled:opacity-50 hover:bg-surface\"\n >\n {formatMessage({ id: 'theme.background.next' })}\n </button>\n </div>\n )}\n </>\n )}\n\n {data && data.photos.length === 0 && searchQuery.trim() && (\n <p className=\"text-xs text-text-secondary py-2 text-center\">\n {formatMessage({ id: 'theme.background.noResults' })}\n </p>\n )}\n\n {/* Custom URL input */}\n <div className=\"flex gap-2\">\n <input\n type=\"url\"\n value={customUrl}\n onChange={(e) => setCustomUrl(e.target.value)}\n placeholder={formatMessage({ id: 'theme.background.customUrlPlaceholder' })}\n className=\"flex-1 px-3 py-2 text-xs rounded-lg border border-border bg-bg text-text\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1\"\n />\n <button\n onClick={handleCustomUrlApply}\n disabled={!customUrl.trim()}\n className=\"px-3 py-2 text-xs rounded-lg bg-accent text-white disabled:opacity-50 hover:opacity-90 transition-opacity\"\n >\n {formatMessage({ id: 'theme.background.apply' })}\n </button>\n </div>\n\n {/* Upload local image */}\n <div className=\"space-y-1\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/jpeg,image/png,image/webp,image/gif\"\n onChange={handleFileUpload}\n className=\"hidden\"\n />\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={isUploading}\n className=\"w-full px-3 py-2 text-xs rounded-lg border border-dashed border-border\n bg-bg text-text hover:bg-surface hover:border-accent\n disabled:opacity-50 transition-all flex items-center justify-center gap-2\"\n >\n {isUploading ? (\n <>\n <div className=\"w-3.5 h-3.5 border-2 border-border border-t-accent rounded-full animate-spin\" />\n {formatMessage({ id: 'theme.background.uploading' })}\n </>\n ) : (\n formatMessage({ id: 'theme.background.upload' })\n )}\n </button>\n {uploadError && (\n <p className=\"text-xs text-destructive\">{uploadError}</p>\n )}\n </div>\n </div>\n )}\n\n {/* Effects panel */}\n {showImageControls && (\n <div className=\"space-y-3 pt-2 border-t border-border\">\n <h4 className=\"text-xs font-medium text-text-secondary\">\n {formatMessage({ id: 'theme.background.effects' })}\n </h4>\n\n {/* Blur slider */}\n <div className=\"space-y-1\">\n <div className=\"flex justify-between\">\n <label className=\"text-xs text-text\">\n {formatMessage({ id: 'theme.background.blur' })}\n </label>\n <span className=\"text-xs text-text-secondary\">{backgroundConfig.effects.blur}px</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"20\"\n step=\"1\"\n value={backgroundConfig.effects.blur}\n onChange={(e) => updateBackgroundEffect('blur', Number(e.target.value))}\n className=\"w-full accent-[hsl(var(--accent))]\"\n />\n </div>\n\n {/* Darken slider */}\n <div className=\"space-y-1\">\n <div className=\"flex justify-between\">\n <label className=\"text-xs text-text\">\n {formatMessage({ id: 'theme.background.darken' })}\n </label>\n <span className=\"text-xs text-text-secondary\">{backgroundConfig.effects.darkenOpacity}%</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"80\"\n step=\"1\"\n value={backgroundConfig.effects.darkenOpacity}\n onChange={(e) => updateBackgroundEffect('darkenOpacity', Number(e.target.value))}\n className=\"w-full accent-[hsl(var(--accent))]\"\n />\n </div>\n\n {/* Saturation slider */}\n <div className=\"space-y-1\">\n <div className=\"flex justify-between\">\n <label className=\"text-xs text-text\">\n {formatMessage({ id: 'theme.background.saturation' })}\n </label>\n <span className=\"text-xs text-text-secondary\">{backgroundConfig.effects.saturation}%</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"200\"\n step=\"5\"\n value={backgroundConfig.effects.saturation}\n onChange={(e) => updateBackgroundEffect('saturation', Number(e.target.value))}\n className=\"w-full accent-[hsl(var(--accent))]\"\n />\n </div>\n\n {/* Frosted glass checkbox */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={backgroundConfig.effects.enableFrostedGlass}\n onChange={(e) => updateBackgroundEffect('enableFrostedGlass', e.target.checked)}\n className=\"w-4 h-4 rounded border-border text-accent focus:ring-2 focus:ring-accent focus:ring-offset-2\"\n />\n <span className=\"text-sm text-text\">\n {formatMessage({ id: 'theme.background.frostedGlass' })}\n </span>\n </label>\n\n {/* Grain checkbox */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={backgroundConfig.effects.enableGrain}\n onChange={(e) => updateBackgroundEffect('enableGrain', e.target.checked)}\n className=\"w-4 h-4 rounded border-border text-accent focus:ring-2 focus:ring-accent focus:ring-offset-2\"\n />\n <span className=\"text-sm text-text\">\n {formatMessage({ id: 'theme.background.grain' })}\n </span>\n </label>\n\n {/* Vignette checkbox */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={backgroundConfig.effects.enableVignette}\n onChange={(e) => updateBackgroundEffect('enableVignette', e.target.checked)}\n className=\"w-4 h-4 rounded border-border text-accent focus:ring-2 focus:ring-accent focus:ring-offset-2\"\n />\n <span className=\"text-sm text-text\">\n {formatMessage({ id: 'theme.background.vignette' })}\n </span>\n </label>\n </div>\n )}\n </div>\n );\n}\n","import React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useTheme } from '@/hooks/useTheme';\r\nimport { useNotifications } from '@/hooks/useNotifications';\r\nimport { COLOR_SCHEMES, THEME_MODES, getThemeName, THEME_SLOT_LIMIT, DEFAULT_BACKGROUND_CONFIG } from '@/lib/theme';\r\nimport type { ColorScheme, ThemeMode } from '@/lib/theme';\r\nimport type { ThemeSlotId, StyleTier } from '@/types/store';\r\nimport { generateThemeFromHue, applyStyleTier } from '@/lib/colorGenerator';\r\nimport { checkThemeContrast, generateContrastFix } from '@/lib/accessibility';\r\nimport type { ContrastResult, FixSuggestion } from '@/lib/accessibility';\r\nimport type { ThemeSharePayload } from '@/lib/themeShare';\r\nimport { BackgroundImagePicker } from './BackgroundImagePicker';\r\nimport {\r\n AlertDialog,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\n\r\n/**\r\n * Theme Selector Component\r\n * Allows users to select from 4 color schemes (blue/green/orange/purple)\r\n * and 2 theme modes (light/dark), plus custom hue customization\r\n *\r\n * Features:\r\n * - 8 preset theme combinations + custom hue support\r\n * - Keyboard navigation support (Arrow keys)\r\n * - ARIA labels for accessibility\r\n * - Visual feedback for selected theme\r\n * - System dark mode detection\r\n * - Custom hue slider (0-360) with real-time preview\r\n */\r\nexport function ThemeSelector() {\r\n const { formatMessage } = useIntl();\r\n const {\r\n colorScheme,\r\n resolvedTheme,\r\n customHue,\r\n isCustomTheme,\r\n gradientLevel,\r\n enableHoverGlow,\r\n enableBackgroundAnimation,\r\n motionPreference,\r\n setColorScheme,\r\n setTheme,\r\n setCustomHue,\r\n setGradientLevel,\r\n setEnableHoverGlow,\r\n setEnableBackgroundAnimation,\r\n setMotionPreference,\r\n styleTier,\r\n setStyleTier,\r\n themeSlots,\r\n activeSlotId,\r\n canAddSlot,\r\n setActiveSlot,\r\n copySlot,\r\n renameSlot,\r\n deleteSlot,\r\n undoDeleteSlot,\r\n exportThemeCode,\r\n importThemeCode,\r\n setBackgroundConfig,\r\n } = useTheme();\r\n const { addToast, removeToast } = useNotifications();\r\n\r\n // Local state for preview hue (uncommitted changes)\r\n const [previewHue, setPreviewHue] = useState<number | null>(customHue);\r\n\r\n // Contrast warning state (non-blocking)\r\n const [contrastWarnings, setContrastWarnings] = useState<ContrastResult[]>([]);\r\n const [contrastFixes, setContrastFixes] = useState<Record<string, FixSuggestion[]>>({});\r\n const [showContrastWarning, setShowContrastWarning] = useState(false);\r\n\r\n // Slot management state\r\n const [renamingSlotId, setRenamingSlotId] = useState<ThemeSlotId | null>(null);\r\n const [renameValue, setRenameValue] = useState('');\r\n const [pendingDeleteSlot, setPendingDeleteSlot] = useState<ThemeSlotId | null>(null);\r\n const renameInputRef = useRef<HTMLInputElement>(null);\r\n const undoToastIdRef = useRef<string | null>(null);\r\n\r\n // Share/import state (local to component, not in store)\r\n const [showImportPanel, setShowImportPanel] = useState(false);\r\n const [importCode, setImportCode] = useState('');\r\n const [importPreview, setImportPreview] = useState<ThemeSharePayload | null>(null);\r\n const [importWarning, setImportWarning] = useState<string | null>(null);\r\n const [importError, setImportError] = useState<string | null>(null);\r\n const [copyFeedback, setCopyFeedback] = useState(false);\r\n\r\n // Sync preview with customHue from store\r\n useEffect(() => {\r\n setPreviewHue(customHue);\r\n }, [customHue]);\r\n\r\n // Resolved mode is either 'light' or 'dark'\r\n const mode: ThemeMode = resolvedTheme;\r\n\r\n // Get preview colors for the custom theme swatches\r\n const getPreviewColor = (variable: string) => {\r\n const hue = previewHue ?? 180; // Default to cyan if null\r\n const colors = generateThemeFromHue(hue, mode);\r\n const hslValue = colors[variable];\r\n return hslValue ? `hsl(${hslValue})` : '#888';\r\n };\r\n\r\n // Style tier definitions for the selector UI\r\n const STYLE_TIERS: Array<{ id: StyleTier; nameKey: string; descKey: string }> = [\r\n { id: 'soft', nameKey: 'theme.styleTier.soft', descKey: 'theme.styleTier.softDesc' },\r\n { id: 'standard', nameKey: 'theme.styleTier.standard', descKey: 'theme.styleTier.standardDesc' },\r\n { id: 'high-contrast', nameKey: 'theme.styleTier.highContrast', descKey: 'theme.styleTier.highContrastDesc' },\r\n ];\r\n\r\n // Get tier preview swatch colors (bg, surface, accent for a sample tier)\r\n const getTierPreviewColors = (tier: StyleTier): { bg: string; surface: string; accent: string } => {\r\n const sampleHue = customHue ?? 220; // Use current hue or default blue\r\n const baseVars = generateThemeFromHue(sampleHue, mode);\r\n const tieredVars = tier === 'standard' ? baseVars : applyStyleTier(baseVars, tier, mode);\r\n return {\r\n bg: tieredVars['--bg'] ? `hsl(${tieredVars['--bg']})` : '#888',\r\n surface: tieredVars['--surface'] ? `hsl(${tieredVars['--surface']})` : '#888',\r\n accent: tieredVars['--accent'] ? `hsl(${tieredVars['--accent']})` : '#888',\r\n };\r\n };\r\n\r\n const handleSchemeSelect = (scheme: ColorScheme) => {\r\n // When selecting a preset scheme, reset custom hue\r\n if (isCustomTheme) {\r\n setCustomHue(null);\r\n }\r\n setColorScheme(scheme);\r\n };\r\n\r\n const handleCustomSelect = () => {\r\n // Set custom hue to a default value if null\r\n if (customHue === null) {\r\n setCustomHue(180); // Default cyan\r\n }\r\n };\r\n\r\n const handleHueSave = () => {\r\n if (previewHue !== null) {\r\n setCustomHue(previewHue);\r\n\r\n // Run contrast check on the new custom theme\r\n const mode: ThemeMode = resolvedTheme;\r\n const vars = generateThemeFromHue(previewHue, mode);\r\n const results = checkThemeContrast(vars);\r\n const failures = results.filter(r => !r.passed);\r\n\r\n if (failures.length > 0) {\r\n setContrastWarnings(failures);\r\n // Generate fixes for each failing pair\r\n const fixes: Record<string, FixSuggestion[]> = {};\r\n for (const failure of failures) {\r\n const key = `${failure.fgVar}|${failure.bgVar}`;\r\n fixes[key] = generateContrastFix(failure.fgVar, failure.bgVar, vars, failure.required);\r\n }\r\n setContrastFixes(fixes);\r\n setShowContrastWarning(true);\r\n } else {\r\n setContrastWarnings([]);\r\n setContrastFixes({});\r\n setShowContrastWarning(false);\r\n }\r\n }\r\n };\r\n\r\n const handleHueReset = () => {\r\n setCustomHue(null);\r\n setPreviewHue(null);\r\n };\r\n\r\n const handleModeSelect = (newMode: ThemeMode) => {\r\n setTheme(newMode);\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\r\n e.preventDefault();\r\n const currentIndex = COLOR_SCHEMES.findIndex(s => s.id === colorScheme);\r\n const nextIndex = (currentIndex + 1) % COLOR_SCHEMES.length;\r\n handleSchemeSelect(COLOR_SCHEMES[nextIndex].id);\r\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\r\n e.preventDefault();\r\n const currentIndex = COLOR_SCHEMES.findIndex(s => s.id === colorScheme);\r\n const nextIndex = (currentIndex - 1 + COLOR_SCHEMES.length) % COLOR_SCHEMES.length;\r\n handleSchemeSelect(COLOR_SCHEMES[nextIndex].id);\r\n }\r\n };\r\n\r\n // ========== Slot Management Handlers ==========\r\n\r\n const handleSlotSelect = useCallback((slotId: ThemeSlotId) => {\r\n if (slotId !== activeSlotId) {\r\n setActiveSlot(slotId);\r\n }\r\n }, [activeSlotId, setActiveSlot]);\r\n\r\n const handleCopySlot = useCallback(() => {\r\n if (!canAddSlot) return;\r\n copySlot();\r\n }, [canAddSlot, copySlot]);\r\n\r\n const handleStartRename = useCallback((slotId: ThemeSlotId, currentName: string) => {\r\n setRenamingSlotId(slotId);\r\n setRenameValue(currentName);\r\n // Focus input after render\r\n setTimeout(() => renameInputRef.current?.focus(), 0);\r\n }, []);\r\n\r\n const handleConfirmRename = useCallback(() => {\r\n if (renamingSlotId && renameValue.trim()) {\r\n renameSlot(renamingSlotId, renameValue.trim());\r\n }\r\n setRenamingSlotId(null);\r\n setRenameValue('');\r\n }, [renamingSlotId, renameValue, renameSlot]);\r\n\r\n const handleCancelRename = useCallback(() => {\r\n setRenamingSlotId(null);\r\n setRenameValue('');\r\n }, []);\r\n\r\n const handleRenameKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (e.key === 'Enter') {\r\n e.preventDefault();\r\n handleConfirmRename();\r\n } else if (e.key === 'Escape') {\r\n e.preventDefault();\r\n handleCancelRename();\r\n }\r\n }, [handleConfirmRename, handleCancelRename]);\r\n\r\n const handleConfirmDelete = useCallback(() => {\r\n if (!pendingDeleteSlot) return;\r\n\r\n deleteSlot(pendingDeleteSlot);\r\n setPendingDeleteSlot(null);\r\n\r\n // Remove previous undo toast if exists\r\n if (undoToastIdRef.current) {\r\n removeToast(undoToastIdRef.current);\r\n }\r\n\r\n // Show undo toast with 10-second duration\r\n const toastId = addToast('info',\r\n formatMessage({ id: 'theme.slot.undoDelete' }),\r\n undefined,\r\n {\r\n duration: 10000,\r\n dismissible: true,\r\n action: {\r\n label: formatMessage({ id: 'theme.slot.undo' }),\r\n onClick: () => {\r\n undoDeleteSlot();\r\n removeToast(toastId);\r\n undoToastIdRef.current = null;\r\n },\r\n },\r\n }\r\n );\r\n undoToastIdRef.current = toastId;\r\n }, [pendingDeleteSlot, deleteSlot, addToast, removeToast, undoDeleteSlot, formatMessage]);\r\n\r\n const handleCancelDelete = useCallback(() => {\r\n setPendingDeleteSlot(null);\r\n }, []);\r\n\r\n // ========== Share/Import Handlers ==========\r\n\r\n const handleCopyThemeCode = useCallback(async () => {\r\n try {\r\n const code = exportThemeCode();\r\n await navigator.clipboard.writeText(code);\r\n setCopyFeedback(true);\r\n setTimeout(() => setCopyFeedback(false), 2000);\r\n } catch {\r\n // Clipboard API may not be available\r\n addToast('error', 'Failed to copy to clipboard');\r\n }\r\n }, [exportThemeCode, addToast]);\r\n\r\n const handleOpenImport = useCallback(() => {\r\n setShowImportPanel(true);\r\n setImportCode('');\r\n setImportPreview(null);\r\n setImportWarning(null);\r\n setImportError(null);\r\n }, []);\r\n\r\n const handleCloseImport = useCallback(() => {\r\n setShowImportPanel(false);\r\n setImportCode('');\r\n setImportPreview(null);\r\n setImportWarning(null);\r\n setImportError(null);\r\n }, []);\r\n\r\n const handleImportCodeChange = useCallback((value: string) => {\r\n setImportCode(value);\r\n setImportError(null);\r\n setImportWarning(null);\r\n setImportPreview(null);\r\n\r\n if (!value.trim()) return;\r\n\r\n const result = importThemeCode(value);\r\n if (result.ok) {\r\n setImportPreview(result.payload);\r\n if (result.warning) {\r\n setImportWarning(result.warning);\r\n }\r\n } else {\r\n setImportError(result.error);\r\n }\r\n }, [importThemeCode]);\r\n\r\n const handleApplyImport = useCallback(() => {\r\n if (!importPreview) return;\r\n\r\n // Check if we can add a slot or overwrite current\r\n if (!canAddSlot && activeSlotId === 'default') {\r\n // Apply to the default slot directly via individual setters\r\n if (importPreview.customHue !== null) {\r\n setCustomHue(importPreview.customHue);\r\n } else {\r\n setCustomHue(null);\r\n setColorScheme(importPreview.colorScheme);\r\n }\r\n setGradientLevel(importPreview.gradientLevel);\r\n setEnableHoverGlow(importPreview.enableHoverGlow);\r\n setEnableBackgroundAnimation(importPreview.enableBackgroundAnimation);\r\n setStyleTier(importPreview.styleTier);\r\n } else if (canAddSlot) {\r\n // Create a new slot via copySlot then apply settings\r\n copySlot();\r\n // After copySlot, the new slot is active. Apply imported settings.\r\n if (importPreview.customHue !== null) {\r\n setCustomHue(importPreview.customHue);\r\n } else {\r\n setCustomHue(null);\r\n setColorScheme(importPreview.colorScheme);\r\n }\r\n setGradientLevel(importPreview.gradientLevel);\r\n setEnableHoverGlow(importPreview.enableHoverGlow);\r\n setEnableBackgroundAnimation(importPreview.enableBackgroundAnimation);\r\n setStyleTier(importPreview.styleTier);\r\n } else {\r\n // Apply to current active slot via individual setters\r\n if (importPreview.customHue !== null) {\r\n setCustomHue(importPreview.customHue);\r\n } else {\r\n setCustomHue(null);\r\n setColorScheme(importPreview.colorScheme);\r\n }\r\n setGradientLevel(importPreview.gradientLevel);\r\n setEnableHoverGlow(importPreview.enableHoverGlow);\r\n setEnableBackgroundAnimation(importPreview.enableBackgroundAnimation);\r\n setStyleTier(importPreview.styleTier);\r\n }\r\n\r\n // Apply background config from import (v2+ feature)\r\n setBackgroundConfig(importPreview.backgroundConfig ?? DEFAULT_BACKGROUND_CONFIG);\r\n\r\n addToast('success', formatMessage({ id: 'theme.share.importSuccess' }));\r\n handleCloseImport();\r\n }, [\r\n importPreview, canAddSlot, activeSlotId, copySlot,\r\n setCustomHue, setColorScheme, setGradientLevel,\r\n setEnableHoverGlow, setEnableBackgroundAnimation, setStyleTier,\r\n setBackgroundConfig,\r\n addToast, formatMessage, handleCloseImport,\r\n ]);\r\n\r\n /** Generate preview swatch colors from an import payload */\r\n const getImportPreviewColors = useCallback((payload: ThemeSharePayload) => {\r\n const hue = payload.customHue ?? 220;\r\n const baseVars = generateThemeFromHue(hue, mode);\r\n const tieredVars = payload.styleTier === 'standard'\r\n ? baseVars\r\n : applyStyleTier(baseVars, payload.styleTier, mode);\r\n return {\r\n bg: tieredVars['--bg'] ? `hsl(${tieredVars['--bg']})` : '#888',\r\n surface: tieredVars['--surface'] ? `hsl(${tieredVars['--surface']})` : '#888',\r\n accent: tieredVars['--accent'] ? `hsl(${tieredVars['--accent']})` : '#888',\r\n text: tieredVars['--text'] ? `hsl(${tieredVars['--text']})` : '#888',\r\n };\r\n }, [mode]);\r\n\r\n /** Map error keys to i18n message IDs */\r\n const getShareErrorMessageId = (errorKey: string): string => {\r\n switch (errorKey) {\r\n case 'incompatible_version':\r\n return 'theme.share.incompatibleVersion';\r\n default:\r\n return 'theme.share.invalidCode';\r\n }\r\n };\r\n\r\n // Focus rename input when entering rename mode\r\n useEffect(() => {\r\n if (renamingSlotId && renameInputRef.current) {\r\n renameInputRef.current.focus();\r\n renameInputRef.current.select();\r\n }\r\n }, [renamingSlotId]);\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Theme Slot Switcher */}\r\n <div>\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <h3 className=\"text-sm font-medium text-text\">\r\n {formatMessage({ id: 'theme.slot.title' })}\r\n </h3>\r\n <button\r\n onClick={handleCopySlot}\r\n disabled={!canAddSlot}\r\n title={\r\n canAddSlot\r\n ? formatMessage({ id: 'theme.slot.copy' })\r\n : formatMessage({ id: 'theme.slot.limitReached' }, { limit: THEME_SLOT_LIMIT })\r\n }\r\n className={`\r\n px-2 py-1 rounded text-xs font-medium\r\n transition-all duration-200\r\n ${canAddSlot\r\n ? 'bg-accent text-white hover:bg-accent-hover focus:ring-2 focus:ring-accent focus:ring-offset-1'\r\n : 'bg-muted text-muted-text cursor-not-allowed'\r\n }\r\n focus:outline-none\r\n `}\r\n >\r\n + {formatMessage({ id: 'theme.slot.copy' })}\r\n </button>\r\n </div>\r\n\r\n <div className=\"flex gap-2\" role=\"tablist\" aria-label={formatMessage({ id: 'theme.slot.title' })}>\r\n {themeSlots.map((slot) => {\r\n const isActive = slot.id === activeSlotId;\r\n const isRenaming = slot.id === renamingSlotId;\r\n\r\n return (\r\n <div\r\n key={slot.id}\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n tabIndex={isActive ? 0 : -1}\r\n onClick={() => handleSlotSelect(slot.id)}\r\n className={`\r\n relative flex-1 min-w-0 p-2.5 rounded-lg cursor-pointer\r\n transition-all duration-200 border-2 group\r\n ${isActive\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1\r\n `}\r\n >\r\n {/* Active indicator */}\r\n {isActive && (\r\n <span className=\"absolute -top-1 -right-1 w-2.5 h-2.5 rounded-full bg-accent border-2 border-bg\" />\r\n )}\r\n\r\n {/* Slot name - inline rename or display */}\r\n <div className=\"flex items-center gap-1 min-w-0\">\r\n {isRenaming ? (\r\n <input\r\n ref={renameInputRef}\r\n type=\"text\"\r\n value={renameValue}\r\n onChange={(e) => setRenameValue(e.target.value)}\r\n onKeyDown={handleRenameKeyDown}\r\n onBlur={handleConfirmRename}\r\n onClick={(e) => e.stopPropagation()}\r\n className=\"\r\n w-full px-1 py-0.5 text-xs font-medium text-text\r\n bg-bg border border-accent rounded\r\n focus:outline-none focus:ring-1 focus:ring-accent\r\n \"\r\n maxLength={20}\r\n />\r\n ) : (\r\n <span\r\n className=\"text-xs font-medium text-text truncate\"\r\n title={slot.name}\r\n onDoubleClick={(e) => {\r\n e.stopPropagation();\r\n if (!slot.isDefault) {\r\n handleStartRename(slot.id, slot.name);\r\n }\r\n }}\r\n >\r\n {slot.name}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Active label */}\r\n {isActive && !isRenaming && (\r\n <span className=\"text-[10px] text-accent font-medium mt-0.5 block\">\r\n {formatMessage({ id: 'theme.slot.active' })}\r\n </span>\r\n )}\r\n\r\n {/* Action buttons - show on hover for non-default slots */}\r\n {!slot.isDefault && !isRenaming && (\r\n <div className=\"\r\n absolute top-1 right-1 flex gap-0.5\r\n opacity-0 group-hover:opacity-100 transition-opacity duration-150\r\n \">\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n handleStartRename(slot.id, slot.name);\r\n }}\r\n title={formatMessage({ id: 'theme.slot.rename' })}\r\n className=\"\r\n p-0.5 rounded text-text-tertiary hover:text-text hover:bg-surface-hover\r\n transition-colors duration-150 focus:outline-none\r\n \"\r\n >\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M11.5 1.5L14.5 4.5L5 14H2V11L11.5 1.5Z\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n <button\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setPendingDeleteSlot(slot.id);\r\n }}\r\n title={formatMessage({ id: 'theme.slot.delete' })}\r\n className=\"\r\n p-0.5 rounded text-text-tertiary hover:text-error hover:bg-error-light\r\n transition-colors duration-150 focus:outline-none\r\n \"\r\n >\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M4 4L12 12M12 4L4 12\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Default slot: show disabled delete tooltip */}\r\n {slot.isDefault && (\r\n <div className=\"\r\n absolute top-1 right-1 flex gap-0.5\r\n opacity-0 group-hover:opacity-100 transition-opacity duration-150\r\n \">\r\n <button\r\n disabled\r\n title={formatMessage({ id: 'theme.slot.cannotDeleteDefault' })}\r\n className=\"p-0.5 rounded text-muted-text cursor-not-allowed\"\r\n >\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M4 4L12 12M12 4L4 12\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Color Scheme Selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.title.colorScheme' })}\r\n </h3>\r\n <div\r\n className=\"grid grid-cols-5 gap-3\"\r\n role=\"group\"\r\n aria-label=\"Color scheme selection\"\r\n onKeyDown={handleKeyDown}\r\n >\r\n {COLOR_SCHEMES.map((scheme) => (\r\n <button\r\n key={scheme.id}\r\n onClick={() => handleSchemeSelect(scheme.id)}\r\n aria-label={formatMessage({ id: 'theme.select.colorScheme' }, { name: formatMessage({ id: `theme.colorScheme.${scheme.id}` }) })}\r\n aria-selected={colorScheme === scheme.id && !isCustomTheme}\r\n role=\"radio\"\r\n className={`\r\n flex flex-col items-center gap-2 p-3 rounded-lg\r\n transition-all duration-200 border-2\r\n ${colorScheme === scheme.id && !isCustomTheme\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {/* Color swatch */}\r\n <div\r\n className=\"w-8 h-8 rounded-full border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: scheme.accentColor }}\r\n aria-hidden=\"true\"\r\n />\r\n {/* Label */}\r\n <span className=\"text-xs font-medium text-text text-center\">\r\n {formatMessage({ id: `theme.colorScheme.${scheme.id}` })}\r\n </span>\r\n </button>\r\n ))}\r\n\r\n {/* Custom Color Option */}\r\n <button\r\n onClick={handleCustomSelect}\r\n aria-label={formatMessage({ id: 'theme.select.colorScheme' }, { name: formatMessage({ id: 'theme.colorScheme.custom' }) })}\r\n aria-selected={isCustomTheme}\r\n role=\"radio\"\r\n className={`\r\n flex flex-col items-center gap-2 p-3 rounded-lg\r\n transition-all duration-200 border-2\r\n ${isCustomTheme\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {/* Gradient swatch showing current custom hue */}\r\n <div\r\n className=\"w-8 h-8 rounded-full border-2 border-border shadow-sm\"\r\n style={{\r\n background: `linear-gradient(135deg, ${getPreviewColor('--accent')}, ${getPreviewColor('--primary')})`\r\n }}\r\n aria-hidden=\"true\"\r\n />\r\n {/* Label */}\r\n <span className=\"text-xs font-medium text-text text-center\">\r\n {formatMessage({ id: 'theme.colorScheme.custom' })}\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Custom Hue Selection - Only shown when custom theme is active */}\r\n {isCustomTheme && (\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.title.customHue' })}\r\n </h3>\r\n\r\n {/* Hue Slider */}\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center justify-between\">\r\n <label htmlFor=\"hue-slider\" className=\"text-xs text-text-secondary\">\r\n {formatMessage({ id: 'theme.hueValue' }, { value: previewHue ?? 180 })}\r\n </label>\r\n </div>\r\n <input\r\n id=\"hue-slider\"\r\n type=\"range\"\r\n min=\"0\"\r\n max=\"360\"\r\n step=\"1\"\r\n value={previewHue ?? 180}\r\n onChange={(e) => setPreviewHue(Number(e.target.value))}\r\n className=\"w-full h-2 rounded-lg appearance-none cursor-pointer\"\r\n style={{\r\n background: `linear-gradient(to right,\r\n hsl(0, 70%, 60%), hsl(60, 70%, 60%), hsl(120, 70%, 60%),\r\n hsl(180, 70%, 60%), hsl(240, 70%, 60%), hsl(300, 70%, 60%), hsl(360, 70%, 60%))`\r\n }}\r\n aria-label={formatMessage({ id: 'theme.title.customHue' })}\r\n />\r\n\r\n {/* Preview Swatches */}\r\n <div className=\"flex gap-3 items-end\">\r\n <span className=\"text-xs text-text-secondary pb-1\">\r\n {formatMessage({ id: 'theme.preview' })}:\r\n </span>\r\n <div className=\"flex flex-col items-center gap-1\">\r\n <div\r\n className=\"w-10 h-10 rounded border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: getPreviewColor('--bg') }}\r\n />\r\n <span className=\"text-[10px] text-text-tertiary\">{formatMessage({ id: 'theme.preview.background' })}</span>\r\n </div>\r\n <div className=\"flex flex-col items-center gap-1\">\r\n <div\r\n className=\"w-10 h-10 rounded border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: getPreviewColor('--surface') }}\r\n />\r\n <span className=\"text-[10px] text-text-tertiary\">{formatMessage({ id: 'theme.preview.surface' })}</span>\r\n </div>\r\n <div className=\"flex flex-col items-center gap-1\">\r\n <div\r\n className=\"w-10 h-10 rounded border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: getPreviewColor('--accent') }}\r\n />\r\n <span className=\"text-[10px] text-text-tertiary\">{formatMessage({ id: 'theme.preview.accent' })}</span>\r\n </div>\r\n </div>\r\n\r\n {/* Save and Reset Buttons */}\r\n <div className=\"flex gap-2 pt-2\">\r\n <button\r\n onClick={handleHueSave}\r\n disabled={previewHue === customHue}\r\n className={`\r\n flex-1 px-4 py-2 rounded-lg text-sm font-medium\r\n transition-all duration-200\r\n ${previewHue === customHue\r\n ? 'bg-muted text-muted-text cursor-not-allowed'\r\n : 'bg-accent text-white hover:bg-accent-hover focus:ring-2 focus:ring-accent focus:ring-offset-2'\r\n }\r\n `}\r\n >\r\n {formatMessage({ id: 'theme.save' })}\r\n </button>\r\n <button\r\n onClick={handleHueReset}\r\n className=\"\r\n px-4 py-2 rounded-lg text-sm font-medium\r\n border-2 border-border bg-bg text-text\r\n hover:bg-surface transition-all duration-200\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n \"\r\n >\r\n {formatMessage({ id: 'theme.reset' })}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Style Tier Selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.styleTier.label' })}\r\n </h3>\r\n <div\r\n className=\"grid grid-cols-3 gap-3\"\r\n role=\"radiogroup\"\r\n aria-label={formatMessage({ id: 'theme.styleTier.label' })}\r\n >\r\n {STYLE_TIERS.map((tier) => {\r\n const preview = getTierPreviewColors(tier.id);\r\n const isSelected = styleTier === tier.id;\r\n return (\r\n <button\r\n key={tier.id}\r\n onClick={() => setStyleTier(tier.id)}\r\n role=\"radio\"\r\n aria-checked={isSelected}\r\n className={`\r\n flex flex-col items-center gap-2 p-3 rounded-lg\r\n transition-all duration-200 border-2\r\n ${isSelected\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {/* Preview swatches */}\r\n <div className=\"flex gap-1\" aria-hidden=\"true\">\r\n <div\r\n className=\"w-5 h-5 rounded-sm border border-border\"\r\n style={{ backgroundColor: preview.bg }}\r\n />\r\n <div\r\n className=\"w-5 h-5 rounded-sm border border-border\"\r\n style={{ backgroundColor: preview.surface }}\r\n />\r\n <div\r\n className=\"w-5 h-5 rounded-sm border border-border\"\r\n style={{ backgroundColor: preview.accent }}\r\n />\r\n </div>\r\n {/* Tier name */}\r\n <span className=\"text-xs font-medium text-text text-center\">\r\n {formatMessage({ id: tier.nameKey })}\r\n </span>\r\n {/* Description */}\r\n <span className=\"text-[10px] text-text-tertiary text-center leading-tight\">\r\n {formatMessage({ id: tier.descKey })}\r\n </span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Gradient Effects Settings */}\r\n <div>\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.gradient.title' })}\r\n </h3>\r\n\r\n {/* Gradient Level Selection */}\r\n <div className=\"space-y-4\">\r\n <div\r\n className=\"flex gap-2\"\r\n role=\"radiogroup\"\r\n aria-label={formatMessage({ id: 'theme.gradient.title' })}\r\n >\r\n {(['off', 'standard', 'enhanced'] as const).map((level) => (\r\n <button\r\n key={level}\r\n onClick={() => setGradientLevel(level)}\r\n role=\"radio\"\r\n aria-checked={gradientLevel === level}\r\n className={`\r\n flex-1 px-3 py-2 rounded-lg text-sm font-medium\r\n transition-all duration-200 border-2\r\n ${gradientLevel === level\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {formatMessage({ id: `theme.gradient.${level}` })}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Hover Glow Checkbox */}\r\n <label className=\"flex items-center gap-3 cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={enableHoverGlow}\r\n onChange={(e) => setEnableHoverGlow(e.target.checked)}\r\n className=\"\r\n w-4 h-4 rounded border-border text-accent\r\n focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n \"\r\n />\r\n <span className=\"text-sm text-text\">\r\n {formatMessage({ id: 'theme.gradient.hoverGlow' })}\r\n </span>\r\n </label>\r\n\r\n {/* Background Animation Checkbox */}\r\n <label className=\"flex items-center gap-3 cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={enableBackgroundAnimation}\r\n onChange={(e) => setEnableBackgroundAnimation(e.target.checked)}\r\n className=\"\r\n w-4 h-4 rounded border-border text-accent\r\n focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n \"\r\n />\r\n <span className=\"text-sm text-text\">\r\n {formatMessage({ id: 'theme.gradient.bgAnimation' })}\r\n </span>\r\n </label>\r\n </div>\r\n </div>\r\n\r\n {/* Background Image */}\r\n <BackgroundImagePicker />\r\n\r\n {/* Motion Preference */}\r\n <div>\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.motion.label' })}\r\n </h3>\r\n <div\r\n className=\"flex gap-2\"\r\n role=\"radiogroup\"\r\n aria-label={formatMessage({ id: 'theme.motion.label' })}\r\n >\r\n {(['system', 'reduce', 'enable'] as const).map((pref) => (\r\n <button\r\n key={pref}\r\n onClick={() => setMotionPreference(pref)}\r\n role=\"radio\"\r\n aria-checked={motionPreference === pref}\r\n className={`\r\n flex-1 px-3 py-2 rounded-lg text-sm font-medium\r\n transition-all duration-200 border-2\r\n ${motionPreference === pref\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {formatMessage({ id: `theme.motion.${pref}` })}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Contrast Warning Banner (non-blocking) */}\r\n {showContrastWarning && contrastWarnings.length > 0 && (\r\n <div className=\"p-3 rounded-lg bg-warning-light border border-warning text-warning-text space-y-2\">\r\n <p className=\"text-xs font-medium\">\r\n {formatMessage({ id: 'theme.accessibility.contrastWarning' })}\r\n </p>\r\n <ul className=\"text-xs space-y-1\">\r\n {contrastWarnings.map((w) => {\r\n const key = `${w.fgVar}|${w.bgVar}`;\r\n const fixes = contrastFixes[key] || [];\r\n return (\r\n <li key={key} className=\"space-y-1\">\r\n <span>\r\n {w.fgVar} / {w.bgVar}: {w.ratio}:1 (min {w.required}:1)\r\n </span>\r\n {fixes.length > 0 && (\r\n <div className=\"ml-2 text-[10px]\">\r\n {fixes.slice(0, 1).map((fix, i) => (\r\n <span key={i} className=\"block\">\r\n {formatMessage(\r\n { id: 'theme.accessibility.fixSuggestion' },\r\n {\r\n target: fix.target === 'fg' ? w.fgVar : w.bgVar,\r\n original: fix.original,\r\n suggested: fix.suggested,\r\n ratio: fix.resultRatio,\r\n }\r\n )}\r\n </span>\r\n ))}\r\n </div>\r\n )}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n <button\r\n onClick={() => setShowContrastWarning(false)}\r\n className=\"text-xs font-medium underline\"\r\n >\r\n {formatMessage({ id: 'theme.accessibility.dismiss' })}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Theme Mode Selection */}\r\n <div>\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.title.themeMode' })}\r\n </h3>\r\n <div\r\n className=\"grid grid-cols-2 gap-3\"\r\n role=\"group\"\r\n aria-label=\"Theme mode selection\"\r\n >\r\n {THEME_MODES.map((modeOption) => (\r\n <button\r\n key={modeOption.id}\r\n onClick={() => handleModeSelect(modeOption.id)}\r\n aria-label={formatMessage({ id: 'theme.select.themeMode' }, { name: formatMessage({ id: `theme.themeMode.${modeOption.id}` }) })}\r\n aria-selected={mode === modeOption.id}\r\n role=\"radio\"\r\n className={`\r\n flex items-center justify-center gap-2 p-3 rounded-lg\r\n transition-all duration-200 border-2\r\n ${mode === modeOption.id\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {/* Icon */}\r\n <span className=\"text-lg\" aria-hidden=\"true\">\r\n {modeOption.id === 'light' ? '☀️' : '🌙'}\r\n </span>\r\n {/* Label */}\r\n <span className=\"text-sm font-medium text-text\">\r\n {formatMessage({ id: `theme.themeMode.${modeOption.id}` })}\r\n </span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Current Theme Display */}\r\n <div className=\"p-3 rounded-lg bg-surface border border-border\">\r\n <p className=\"text-xs text-text-secondary\">\r\n {formatMessage({ id: 'theme.current' }, { name: getThemeName(colorScheme, mode) })}\r\n </p>\r\n </div>\r\n\r\n {/* Theme Sharing Section */}\r\n <div>\r\n <h3 className=\"text-sm font-medium text-text mb-3\">\r\n {formatMessage({ id: 'theme.share.label' })}\r\n </h3>\r\n\r\n <div className=\"flex gap-2\">\r\n {/* Copy Theme Code button */}\r\n <button\r\n onClick={handleCopyThemeCode}\r\n className=\"\r\n flex-1 px-3 py-2 rounded-lg text-sm font-medium\r\n border-2 border-border bg-bg text-text\r\n hover:bg-surface transition-all duration-200\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n \"\r\n >\r\n {copyFeedback\r\n ? formatMessage({ id: 'theme.share.copied' })\r\n : formatMessage({ id: 'theme.share.copyCode' })\r\n }\r\n </button>\r\n\r\n {/* Import Theme button */}\r\n <button\r\n onClick={showImportPanel ? handleCloseImport : handleOpenImport}\r\n className={`\r\n flex-1 px-3 py-2 rounded-lg text-sm font-medium\r\n transition-all duration-200 border-2\r\n ${showImportPanel\r\n ? 'border-accent bg-surface shadow-md'\r\n : 'border-border bg-bg text-text hover:bg-surface'\r\n }\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n `}\r\n >\r\n {formatMessage({ id: 'theme.share.import' })}\r\n </button>\r\n </div>\r\n\r\n {/* Import Panel */}\r\n {showImportPanel && (\r\n <div className=\"mt-3 space-y-3\">\r\n {/* Paste textarea */}\r\n <textarea\r\n value={importCode}\r\n onChange={(e) => handleImportCodeChange(e.target.value)}\r\n placeholder={formatMessage({ id: 'theme.share.paste' })}\r\n rows={3}\r\n className=\"\r\n w-full px-3 py-2 rounded-lg text-sm font-mono\r\n bg-bg border-2 border-border text-text\r\n placeholder-text-tertiary resize-none\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:border-accent\r\n \"\r\n />\r\n\r\n {/* Error message */}\r\n {importError && (\r\n <div className=\"p-2 rounded-lg bg-error-light border border-error text-error-text text-xs\">\r\n {formatMessage({ id: getShareErrorMessageId(importError) })}\r\n </div>\r\n )}\r\n\r\n {/* Version warning */}\r\n {importWarning && !importError && (\r\n <div className=\"p-2 rounded-lg bg-warning-light border border-warning text-warning-text text-xs\">\r\n {formatMessage({ id: 'theme.share.versionWarning' })}\r\n </div>\r\n )}\r\n\r\n {/* Import Preview Card */}\r\n {importPreview && !importError && (\r\n <div className=\"p-3 rounded-lg bg-surface border border-border space-y-3\">\r\n <p className=\"text-xs font-medium text-text\">\r\n {formatMessage({ id: 'theme.share.preview' })}\r\n </p>\r\n\r\n {/* Preview swatches */}\r\n <div className=\"flex gap-3 items-end\">\r\n {(() => {\r\n const previewColors = getImportPreviewColors(importPreview);\r\n return (\r\n <>\r\n <div className=\"flex flex-col items-center gap-1\">\r\n <div\r\n className=\"w-10 h-10 rounded border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: previewColors.bg }}\r\n />\r\n <span className=\"text-[10px] text-text-tertiary\">\r\n {formatMessage({ id: 'theme.preview.background' })}\r\n </span>\r\n </div>\r\n <div className=\"flex flex-col items-center gap-1\">\r\n <div\r\n className=\"w-10 h-10 rounded border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: previewColors.surface }}\r\n />\r\n <span className=\"text-[10px] text-text-tertiary\">\r\n {formatMessage({ id: 'theme.preview.surface' })}\r\n </span>\r\n </div>\r\n <div className=\"flex flex-col items-center gap-1\">\r\n <div\r\n className=\"w-10 h-10 rounded border-2 border-border shadow-sm\"\r\n style={{ backgroundColor: previewColors.accent }}\r\n />\r\n <span className=\"text-[10px] text-text-tertiary\">\r\n {formatMessage({ id: 'theme.preview.accent' })}\r\n </span>\r\n </div>\r\n </>\r\n );\r\n })()}\r\n </div>\r\n\r\n {/* Settings summary */}\r\n <div className=\"text-xs text-text-secondary space-y-1\">\r\n <p>\r\n {formatMessage({ id: 'theme.styleTier.label' })}: {formatMessage({ id: `theme.styleTier.${importPreview.styleTier === 'high-contrast' ? 'highContrast' : importPreview.styleTier}` })}\r\n </p>\r\n <p>\r\n {formatMessage({ id: 'theme.gradient.title' })}: {formatMessage({ id: `theme.gradient.${importPreview.gradientLevel}` })}\r\n </p>\r\n {importPreview.customHue !== null && (\r\n <p>\r\n {formatMessage({ id: 'theme.hueValue' }, { value: importPreview.customHue })}\r\n </p>\r\n )}\r\n {importPreview.customHue === null && (\r\n <p>\r\n {formatMessage({ id: 'theme.title.colorScheme' })}: {formatMessage({ id: `theme.colorScheme.${importPreview.colorScheme}` })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Apply / Cancel buttons */}\r\n <div className=\"flex gap-2 pt-1\">\r\n <button\r\n onClick={handleApplyImport}\r\n className=\"\r\n flex-1 px-4 py-2 rounded-lg text-sm font-medium\r\n bg-accent text-white hover:bg-accent-hover\r\n transition-all duration-200\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n \"\r\n >\r\n {formatMessage({ id: 'theme.share.apply' })}\r\n </button>\r\n <button\r\n onClick={handleCloseImport}\r\n className=\"\r\n px-4 py-2 rounded-lg text-sm font-medium\r\n border-2 border-border bg-bg text-text\r\n hover:bg-surface transition-all duration-200\r\n focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2\r\n \"\r\n >\r\n {formatMessage({ id: 'theme.share.cancel' })}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <AlertDialog open={pendingDeleteSlot !== null} onOpenChange={handleCancelDelete}>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>Delete Theme Slot?</AlertDialogTitle>\r\n <AlertDialogDescription>\r\n This action cannot be undone. The theme slot will be permanently deleted.\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel onClick={handleCancelDelete}>Cancel</AlertDialogCancel>\r\n <AlertDialogAction onClick={handleConfirmDelete}>Delete</AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// Language Switcher Component\r\n// ========================================\r\n// Language selection dropdown with flag icons\r\n\r\nimport { Languages } from 'lucide-react';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport { useLocale } from '@/hooks/useLocale';\r\nimport { cn } from '@/lib/utils';\r\n\r\nexport interface LanguageSwitcherProps {\r\n /** Compact variant for header (smaller, icon-only trigger) */\r\n compact?: boolean;\r\n /** Additional CSS classes */\r\n className?: string;\r\n}\r\n\r\n// Language options with flag emojis and labels\r\nconst LANGUAGE_OPTIONS = [\r\n { value: 'en' as const, label: 'English', flag: '🇺🇸' },\r\n { value: 'zh' as const, label: '中文', flag: '🇨🇳' },\r\n] as const;\r\n\r\n/**\r\n * Language switcher component\r\n * Allows users to switch between English and Chinese\r\n */\r\nexport function LanguageSwitcher({ compact = false, className }: LanguageSwitcherProps) {\r\n const { locale, setLocale } = useLocale();\r\n\r\n return (\r\n <Select value={locale} onValueChange={setLocale}>\r\n <SelectTrigger\r\n className={cn(\r\n compact ? 'w-[110px]' : 'w-[160px]',\r\n 'gap-2',\r\n className\r\n )}\r\n aria-label=\"Select language\"\r\n >\r\n {compact ? (\r\n <>\r\n <Languages className=\"w-4 h-4\" />\r\n <SelectValue />\r\n </>\r\n ) : (\r\n <SelectValue />\r\n )}\r\n </SelectTrigger>\r\n <SelectContent>\r\n {LANGUAGE_OPTIONS.map((option) => (\r\n <SelectItem key={option.value} value={option.value}>\r\n <span className=\"flex items-center gap-2\">\r\n <span className=\"text-base\">{option.flag}</span>\r\n <span>{option.label}</span>\r\n </span>\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n );\r\n}\r\n\r\nexport default LanguageSwitcher;\r\n","// ========================================\r\n// Remote Notification Types (Frontend)\r\n// ========================================\r\n// Type definitions for remote notification system UI\r\n// Mirrors backend types with UI-specific additions\r\n\r\n/**\r\n * Supported notification platforms\r\n */\r\nexport type NotificationPlatform = 'discord' | 'telegram' | 'feishu' | 'dingtalk' | 'wecom' | 'email' | 'webhook';\r\n\r\n/**\r\n * Event types that can trigger notifications\r\n */\r\nexport type NotificationEventType =\r\n | 'ask-user-question'\r\n | 'session-start'\r\n | 'session-end'\r\n | 'task-completed'\r\n | 'task-failed';\r\n\r\n/**\r\n * Discord platform configuration\r\n */\r\nexport interface DiscordConfig {\r\n enabled: boolean;\r\n webhookUrl: string;\r\n username?: string;\r\n avatarUrl?: string;\r\n}\r\n\r\n/**\r\n * Telegram platform configuration\r\n */\r\nexport interface TelegramConfig {\r\n enabled: boolean;\r\n botToken: string;\r\n chatId: string;\r\n parseMode?: 'HTML' | 'Markdown' | 'MarkdownV2';\r\n}\r\n\r\n/**\r\n * Feishu (Lark) platform configuration\r\n */\r\nexport interface FeishuConfig {\r\n enabled: boolean;\r\n webhookUrl: string;\r\n useCard?: boolean;\r\n title?: string;\r\n}\r\n\r\n/**\r\n * DingTalk platform configuration\r\n */\r\nexport interface DingTalkConfig {\r\n enabled: boolean;\r\n webhookUrl: string;\r\n keywords?: string[];\r\n}\r\n\r\n/**\r\n * WeCom (WeChat Work) platform configuration\r\n */\r\nexport interface WeComConfig {\r\n enabled: boolean;\r\n webhookUrl: string;\r\n mentionedList?: string[];\r\n}\r\n\r\n/**\r\n * Email SMTP platform configuration\r\n */\r\nexport interface EmailConfig {\r\n enabled: boolean;\r\n host: string;\r\n port: number;\r\n secure?: boolean;\r\n username: string;\r\n password: string;\r\n from: string;\r\n to: string[];\r\n}\r\n\r\n/**\r\n * Generic Webhook platform configuration\r\n */\r\nexport interface WebhookConfig {\r\n enabled: boolean;\r\n url: string;\r\n method: 'POST' | 'PUT';\r\n headers?: Record<string, string>;\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Event configuration\r\n */\r\nexport interface EventConfig {\r\n event: NotificationEventType;\r\n platforms: NotificationPlatform[];\r\n enabled: boolean;\r\n}\r\n\r\n/**\r\n * Full remote notification configuration\r\n */\r\nexport interface RemoteNotificationConfig {\r\n enabled: boolean;\r\n platforms: {\r\n discord?: DiscordConfig;\r\n telegram?: TelegramConfig;\r\n feishu?: FeishuConfig;\r\n dingtalk?: DingTalkConfig;\r\n wecom?: WeComConfig;\r\n email?: EmailConfig;\r\n webhook?: WebhookConfig;\r\n };\r\n events: EventConfig[];\r\n timeout: number;\r\n}\r\n\r\n/**\r\n * Test notification request\r\n */\r\nexport interface TestNotificationRequest {\r\n platform: NotificationPlatform;\r\n config: DiscordConfig | TelegramConfig | FeishuConfig | DingTalkConfig | WeComConfig | EmailConfig | WebhookConfig;\r\n}\r\n\r\n/**\r\n * Test notification result\r\n */\r\nexport interface TestNotificationResult {\r\n success: boolean;\r\n error?: string;\r\n responseTime?: number;\r\n}\r\n\r\n/**\r\n * Platform display info\r\n */\r\nexport interface PlatformInfo {\r\n id: NotificationPlatform;\r\n name: string;\r\n icon: string;\r\n description: string;\r\n requiredFields: string[];\r\n}\r\n\r\n/**\r\n * Event display info\r\n */\r\nexport interface EventInfo {\r\n id: NotificationEventType;\r\n name: string;\r\n description: string;\r\n icon: string;\r\n}\r\n\r\n/**\r\n * Predefined platform information\r\n */\r\nexport const PLATFORM_INFO: Record<NotificationPlatform, PlatformInfo> = {\r\n discord: {\r\n id: 'discord',\r\n name: 'Discord',\r\n icon: 'message-circle',\r\n description: 'Send notifications to Discord channels via webhook',\r\n requiredFields: ['webhookUrl'],\r\n },\r\n telegram: {\r\n id: 'telegram',\r\n name: 'Telegram',\r\n icon: 'send',\r\n description: 'Send notifications to Telegram chats via bot',\r\n requiredFields: ['botToken', 'chatId'],\r\n },\r\n feishu: {\r\n id: 'feishu',\r\n name: 'Feishu',\r\n icon: 'message-square',\r\n description: 'Send notifications to Feishu (Lark) via webhook with rich card support',\r\n requiredFields: ['webhookUrl'],\r\n },\r\n dingtalk: {\r\n id: 'dingtalk',\r\n name: 'DingTalk',\r\n icon: 'bell',\r\n description: 'Send notifications to DingTalk via webhook',\r\n requiredFields: ['webhookUrl'],\r\n },\r\n wecom: {\r\n id: 'wecom',\r\n name: 'WeCom',\r\n icon: 'users',\r\n description: 'Send notifications to WeCom (WeChat Work) via webhook',\r\n requiredFields: ['webhookUrl'],\r\n },\r\n email: {\r\n id: 'email',\r\n name: 'Email',\r\n icon: 'mail',\r\n description: 'Send notifications via SMTP email',\r\n requiredFields: ['host', 'username', 'password', 'from', 'to'],\r\n },\r\n webhook: {\r\n id: 'webhook',\r\n name: 'Custom Webhook',\r\n icon: 'link',\r\n description: 'Send notifications to a custom HTTP endpoint',\r\n requiredFields: ['url'],\r\n },\r\n};\r\n\r\n/**\r\n * Predefined event information\r\n */\r\nexport const EVENT_INFO: Record<NotificationEventType, EventInfo> = {\r\n 'ask-user-question': {\r\n id: 'ask-user-question',\r\n name: 'Ask User Question',\r\n description: 'Notification when Claude asks a question via AskUserQuestion',\r\n icon: 'help-circle',\r\n },\r\n 'session-start': {\r\n id: 'session-start',\r\n name: 'Session Start',\r\n description: 'Notification when a CLI session starts',\r\n icon: 'play',\r\n },\r\n 'session-end': {\r\n id: 'session-end',\r\n name: 'Session End',\r\n description: 'Notification when a CLI session ends',\r\n icon: 'square',\r\n },\r\n 'task-completed': {\r\n id: 'task-completed',\r\n name: 'Task Completed',\r\n description: 'Notification when a task completes successfully',\r\n icon: 'check-circle',\r\n },\r\n 'task-failed': {\r\n id: 'task-failed',\r\n name: 'Task Failed',\r\n description: 'Notification when a task fails',\r\n icon: 'alert-circle',\r\n },\r\n};\r\n\r\n/**\r\n * Default configuration for UI initialization\r\n */\r\nexport function getDefaultConfig(): RemoteNotificationConfig {\r\n return {\r\n enabled: false,\r\n platforms: {},\r\n events: [\r\n { event: 'ask-user-question', platforms: ['discord', 'telegram'], enabled: true },\r\n { event: 'session-start', platforms: [], enabled: false },\r\n { event: 'session-end', platforms: [], enabled: false },\r\n { event: 'task-completed', platforms: [], enabled: false },\r\n { event: 'task-failed', platforms: ['discord', 'telegram'], enabled: true },\r\n ],\r\n timeout: 10000,\r\n };\r\n}\r\n","// ========================================\r\n// Platform Configuration Cards\r\n// ========================================\r\n// Individual configuration cards for each notification platform\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n MessageCircle,\r\n Send,\r\n Link,\r\n Check,\r\n X,\r\n ChevronDown,\r\n ChevronUp,\r\n TestTube,\r\n Eye,\r\n EyeOff,\r\n MessageSquare,\r\n Bell,\r\n Users,\r\n Mail,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type {\r\n RemoteNotificationConfig,\r\n NotificationPlatform,\r\n DiscordConfig,\r\n TelegramConfig,\r\n WebhookConfig,\r\n FeishuConfig,\r\n DingTalkConfig,\r\n WeComConfig,\r\n EmailConfig,\r\n} from '@/types/remote-notification';\r\nimport { PLATFORM_INFO } from '@/types/remote-notification';\r\n\r\ninterface PlatformConfigCardsProps {\r\n config: RemoteNotificationConfig;\r\n expandedPlatform: NotificationPlatform | null;\r\n testing: NotificationPlatform | null;\r\n onToggleExpand: (platform: NotificationPlatform | null) => void;\r\n onUpdateConfig: (\r\n platform: NotificationPlatform,\r\n updates: Partial<DiscordConfig | TelegramConfig | WebhookConfig | FeishuConfig | DingTalkConfig | WeComConfig | EmailConfig>\r\n ) => void;\r\n onTest: (\r\n platform: NotificationPlatform,\r\n config: DiscordConfig | TelegramConfig | WebhookConfig | FeishuConfig | DingTalkConfig | WeComConfig | EmailConfig\r\n ) => void;\r\n onSave: () => void;\r\n saving: boolean;\r\n}\r\n\r\nexport function PlatformConfigCards({\r\n config,\r\n expandedPlatform,\r\n testing,\r\n onToggleExpand,\r\n onUpdateConfig,\r\n onTest,\r\n onSave,\r\n saving,\r\n}: PlatformConfigCardsProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const platforms: NotificationPlatform[] = ['discord', 'telegram', 'feishu', 'dingtalk', 'wecom', 'email', 'webhook'];\r\n\r\n const getPlatformIcon = (platform: NotificationPlatform) => {\r\n switch (platform) {\r\n case 'discord':\r\n return <MessageCircle className=\"w-4 h-4\" />;\r\n case 'telegram':\r\n return <Send className=\"w-4 h-4\" />;\r\n case 'feishu':\r\n return <MessageSquare className=\"w-4 h-4\" />;\r\n case 'dingtalk':\r\n return <Bell className=\"w-4 h-4\" />;\r\n case 'wecom':\r\n return <Users className=\"w-4 h-4\" />;\r\n case 'email':\r\n return <Mail className=\"w-4 h-4\" />;\r\n case 'webhook':\r\n return <Link className=\"w-4 h-4\" />;\r\n }\r\n };\r\n\r\n const getPlatformConfig = (\r\n platform: NotificationPlatform\r\n ): DiscordConfig | TelegramConfig | WebhookConfig | FeishuConfig | DingTalkConfig | WeComConfig | EmailConfig => {\r\n switch (platform) {\r\n case 'discord':\r\n return config.platforms.discord || { enabled: false, webhookUrl: '' };\r\n case 'telegram':\r\n return config.platforms.telegram || { enabled: false, botToken: '', chatId: '' };\r\n case 'feishu':\r\n return config.platforms.feishu || { enabled: false, webhookUrl: '' };\r\n case 'dingtalk':\r\n return config.platforms.dingtalk || { enabled: false, webhookUrl: '' };\r\n case 'wecom':\r\n return config.platforms.wecom || { enabled: false, webhookUrl: '' };\r\n case 'email':\r\n return config.platforms.email || { enabled: false, host: '', port: 587, username: '', password: '', from: '', to: [] };\r\n case 'webhook':\r\n return config.platforms.webhook || { enabled: false, url: '', method: 'POST' };\r\n }\r\n };\r\n\r\n const isConfigured = (platform: NotificationPlatform): boolean => {\r\n const platformConfig = getPlatformConfig(platform);\r\n switch (platform) {\r\n case 'discord':\r\n return !!(platformConfig as DiscordConfig).webhookUrl;\r\n case 'telegram':\r\n return !!(platformConfig as TelegramConfig).botToken && !!(platformConfig as TelegramConfig).chatId;\r\n case 'feishu':\r\n return !!(platformConfig as FeishuConfig).webhookUrl;\r\n case 'dingtalk':\r\n return !!(platformConfig as DingTalkConfig).webhookUrl;\r\n case 'wecom':\r\n return !!(platformConfig as WeComConfig).webhookUrl;\r\n case 'email':\r\n const emailConfig = platformConfig as EmailConfig;\r\n return !!(emailConfig.host && emailConfig.username && emailConfig.password && emailConfig.from && emailConfig.to?.length > 0);\r\n case 'webhook':\r\n return !!(platformConfig as WebhookConfig).url;\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"grid gap-3\">\r\n {platforms.map((platform) => {\r\n const info = PLATFORM_INFO[platform];\r\n const platformConfig = getPlatformConfig(platform);\r\n const configured = isConfigured(platform);\r\n const expanded = expandedPlatform === platform;\r\n\r\n return (\r\n <Card key={platform} className=\"overflow-hidden\">\r\n {/* Header */}\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={() => onToggleExpand(expanded ? null : platform)}\r\n >\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n platformConfig.enabled && configured\r\n ? 'bg-primary/10 text-primary'\r\n : 'bg-muted text-muted-foreground'\r\n )}>\r\n {getPlatformIcon(platform)}\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium\">{info.name}</span>\r\n {configured && (\r\n <Badge variant=\"outline\" className=\"text-xs text-green-600 border-green-500/30\">\r\n <Check className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'settings.remoteNotifications.configured' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">{info.description}</p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant={platformConfig.enabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n onUpdateConfig(platform, { enabled: !platformConfig.enabled });\r\n }}\r\n >\r\n {platformConfig.enabled ? (\r\n <Check className=\"w-3.5 h-3.5\" />\r\n ) : (\r\n <X className=\"w-3.5 h-3.5\" />\r\n )}\r\n </Button>\r\n {expanded ? (\r\n <ChevronUp className=\"w-4 h-4 text-muted-foreground\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {expanded && (\r\n <div className=\"border-t border-border p-4 space-y-4 bg-muted/30\">\r\n {platform === 'discord' && (\r\n <DiscordConfigForm\r\n config={platformConfig as DiscordConfig}\r\n onUpdate={(updates) => onUpdateConfig('discord', updates)}\r\n />\r\n )}\r\n {platform === 'telegram' && (\r\n <TelegramConfigForm\r\n config={platformConfig as TelegramConfig}\r\n onUpdate={(updates) => onUpdateConfig('telegram', updates)}\r\n />\r\n )}\r\n {platform === 'feishu' && (\r\n <FeishuConfigForm\r\n config={platformConfig as FeishuConfig}\r\n onUpdate={(updates) => onUpdateConfig('feishu', updates)}\r\n />\r\n )}\r\n {platform === 'dingtalk' && (\r\n <DingTalkConfigForm\r\n config={platformConfig as DingTalkConfig}\r\n onUpdate={(updates) => onUpdateConfig('dingtalk', updates)}\r\n />\r\n )}\r\n {platform === 'wecom' && (\r\n <WeComConfigForm\r\n config={platformConfig as WeComConfig}\r\n onUpdate={(updates) => onUpdateConfig('wecom', updates)}\r\n />\r\n )}\r\n {platform === 'email' && (\r\n <EmailConfigForm\r\n config={platformConfig as EmailConfig}\r\n onUpdate={(updates) => onUpdateConfig('email', updates)}\r\n />\r\n )}\r\n {platform === 'webhook' && (\r\n <WebhookConfigForm\r\n config={platformConfig as WebhookConfig}\r\n onUpdate={(updates) => onUpdateConfig('webhook', updates)}\r\n />\r\n )}\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-2 pt-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => onTest(platform, platformConfig)}\r\n disabled={testing === platform || !configured}\r\n >\r\n <TestTube className={cn('w-3.5 h-3.5 mr-1', testing === platform && 'animate-pulse')} />\r\n {formatMessage({ id: 'settings.remoteNotifications.testConnection' })}\r\n </Button>\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={onSave}\r\n disabled={saving}\r\n >\r\n {formatMessage({ id: 'settings.remoteNotifications.save' })}\r\n </Button>\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Discord Config Form ==========\r\n\r\nfunction DiscordConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: DiscordConfig;\r\n onUpdate: (updates: Partial<DiscordConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const [showUrl, setShowUrl] = useState(false);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.discord.webhookUrl' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Input\r\n type={showUrl ? 'text' : 'password'}\r\n value={config.webhookUrl || ''}\r\n onChange={(e) => onUpdate({ webhookUrl: e.target.value })}\r\n placeholder=\"https://discord.com/api/webhooks/...\"\r\n className=\"flex-1\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0\"\r\n onClick={() => setShowUrl(!showUrl)}\r\n >\r\n {showUrl ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.discord.webhookUrlHint' })}\r\n </p>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.discord.username' })}\r\n </label>\r\n <Input\r\n value={config.username || ''}\r\n onChange={(e) => onUpdate({ username: e.target.value })}\r\n placeholder=\"CCW Notification\"\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Telegram Config Form ==========\r\n\r\nfunction TelegramConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: TelegramConfig;\r\n onUpdate: (updates: Partial<TelegramConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const [showToken, setShowToken] = useState(false);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.telegram.botToken' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Input\r\n type={showToken ? 'text' : 'password'}\r\n value={config.botToken || ''}\r\n onChange={(e) => onUpdate({ botToken: e.target.value })}\r\n placeholder=\"1234567890:ABCdefGHIjklMNOpqrsTUVwxyz\"\r\n className=\"flex-1\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0\"\r\n onClick={() => setShowToken(!showToken)}\r\n >\r\n {showToken ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.telegram.botTokenHint' })}\r\n </p>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.telegram.chatId' })}\r\n </label>\r\n <Input\r\n value={config.chatId || ''}\r\n onChange={(e) => onUpdate({ chatId: e.target.value })}\r\n placeholder=\"-1001234567890\"\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.telegram.chatIdHint' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Webhook Config Form ==========\r\n\r\nfunction WebhookConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: WebhookConfig;\r\n onUpdate: (updates: Partial<WebhookConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.webhook.url' })}\r\n </label>\r\n <Input\r\n value={config.url || ''}\r\n onChange={(e) => onUpdate({ url: e.target.value })}\r\n placeholder=\"https://your-server.com/webhook\"\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.webhook.method' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Button\r\n variant={config.method === 'POST' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => onUpdate({ method: 'POST' })}\r\n >\r\n POST\r\n </Button>\r\n <Button\r\n variant={config.method === 'PUT' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => onUpdate({ method: 'PUT' })}\r\n >\r\n PUT\r\n </Button>\r\n </div>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.webhook.headers' })}\r\n </label>\r\n <Input\r\n value={config.headers ? JSON.stringify(config.headers) : ''}\r\n onChange={(e) => {\r\n try {\r\n const headers = e.target.value ? JSON.parse(e.target.value) : undefined;\r\n onUpdate({ headers });\r\n } catch {\r\n // Invalid JSON, ignore\r\n }\r\n }}\r\n placeholder='{\"Authorization\": \"Bearer token\"}'\r\n className=\"mt-1 font-mono text-xs\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.webhook.headersHint' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Feishu Config Form ==========\r\n\r\nfunction FeishuConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: FeishuConfig;\r\n onUpdate: (updates: Partial<FeishuConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const [showUrl, setShowUrl] = useState(false);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.feishu.webhookUrl' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Input\r\n type={showUrl ? 'text' : 'password'}\r\n value={config.webhookUrl || ''}\r\n onChange={(e) => onUpdate({ webhookUrl: e.target.value })}\r\n placeholder=\"https://open.feishu.cn/open-apis/bot/v2/hook/...\"\r\n className=\"flex-1\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0\"\r\n onClick={() => setShowUrl(!showUrl)}\r\n >\r\n {showUrl ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.feishu.webhookUrlHint' })}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"feishu-useCard\"\r\n checked={config.useCard || false}\r\n onChange={(e) => onUpdate({ useCard: e.target.checked })}\r\n className=\"rounded border-border\"\r\n />\r\n <label htmlFor=\"feishu-useCard\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.feishu.useCard' })}\r\n </label>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground -mt-2\">\r\n {formatMessage({ id: 'settings.remoteNotifications.feishu.useCardHint' })}\r\n </p>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.feishu.title' })}\r\n </label>\r\n <Input\r\n value={config.title || ''}\r\n onChange={(e) => onUpdate({ title: e.target.value })}\r\n placeholder=\"CCW Notification\"\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== DingTalk Config Form ==========\r\n\r\nfunction DingTalkConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: DingTalkConfig;\r\n onUpdate: (updates: Partial<DingTalkConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const [showUrl, setShowUrl] = useState(false);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.dingtalk.webhookUrl' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Input\r\n type={showUrl ? 'text' : 'password'}\r\n value={config.webhookUrl || ''}\r\n onChange={(e) => onUpdate({ webhookUrl: e.target.value })}\r\n placeholder=\"https://oapi.dingtalk.com/robot/send?access_token=...\"\r\n className=\"flex-1\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0\"\r\n onClick={() => setShowUrl(!showUrl)}\r\n >\r\n {showUrl ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.dingtalk.webhookUrlHint' })}\r\n </p>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.dingtalk.keywords' })}\r\n </label>\r\n <Input\r\n value={config.keywords?.join(', ') || ''}\r\n onChange={(e) => onUpdate({ keywords: e.target.value.split(',').map(k => k.trim()).filter(Boolean) })}\r\n placeholder=\"keyword1, keyword2\"\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.dingtalk.keywordsHint' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== WeCom Config Form ==========\r\n\r\nfunction WeComConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: WeComConfig;\r\n onUpdate: (updates: Partial<WeComConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const [showUrl, setShowUrl] = useState(false);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.wecom.webhookUrl' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Input\r\n type={showUrl ? 'text' : 'password'}\r\n value={config.webhookUrl || ''}\r\n onChange={(e) => onUpdate({ webhookUrl: e.target.value })}\r\n placeholder=\"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...\"\r\n className=\"flex-1\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0\"\r\n onClick={() => setShowUrl(!showUrl)}\r\n >\r\n {showUrl ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.wecom.webhookUrlHint' })}\r\n </p>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.wecom.mentionedList' })}\r\n </label>\r\n <Input\r\n value={config.mentionedList?.join(', ') || ''}\r\n onChange={(e) => onUpdate({ mentionedList: e.target.value.split(',').map(m => m.trim()).filter(Boolean) })}\r\n placeholder=\"userid1, userid2, @all\"\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.wecom.mentionedListHint' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Email Config Form ==========\r\n\r\nfunction EmailConfigForm({\r\n config,\r\n onUpdate,\r\n}: {\r\n config: EmailConfig;\r\n onUpdate: (updates: Partial<EmailConfig>) => void;\r\n}) {\r\n const { formatMessage } = useIntl();\r\n const [showPassword, setShowPassword] = useState(false);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n <div className=\"grid grid-cols-2 gap-3\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.host' })}\r\n </label>\r\n <Input\r\n value={config.host || ''}\r\n onChange={(e) => onUpdate({ host: e.target.value })}\r\n placeholder=\"smtp.gmail.com\"\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.hostHint' })}\r\n </p>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.port' })}\r\n </label>\r\n <Input\r\n type=\"number\"\r\n value={config.port || 587}\r\n onChange={(e) => onUpdate({ port: parseInt(e.target.value, 10) || 587 })}\r\n placeholder=\"587\"\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"email-secure\"\r\n checked={config.secure || false}\r\n onChange={(e) => onUpdate({ secure: e.target.checked })}\r\n className=\"rounded border-border\"\r\n />\r\n <label htmlFor=\"email-secure\" className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.secure' })}\r\n </label>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.username' })}\r\n </label>\r\n <Input\r\n value={config.username || ''}\r\n onChange={(e) => onUpdate({ username: e.target.value })}\r\n placeholder=\"your-email@gmail.com\"\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.password' })}\r\n </label>\r\n <div className=\"flex gap-2 mt-1\">\r\n <Input\r\n type={showPassword ? 'text' : 'password'}\r\n value={config.password || ''}\r\n onChange={(e) => onUpdate({ password: e.target.value })}\r\n placeholder=\"********\"\r\n className=\"flex-1\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0\"\r\n onClick={() => setShowPassword(!showPassword)}\r\n >\r\n {showPassword ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </Button>\r\n </div>\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.from' })}\r\n </label>\r\n <Input\r\n value={config.from || ''}\r\n onChange={(e) => onUpdate({ from: e.target.value })}\r\n placeholder=\"noreply@example.com\"\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.to' })}\r\n </label>\r\n <Input\r\n value={config.to?.join(', ') || ''}\r\n onChange={(e) => onUpdate({ to: e.target.value.split(',').map(t => t.trim()).filter(Boolean) })}\r\n placeholder=\"user1@example.com, user2@example.com\"\r\n className=\"mt-1\"\r\n />\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.remoteNotifications.email.toHint' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default PlatformConfigCards;\r\n","// ========================================\r\n// Remote Notification Settings Section\r\n// ========================================\r\n// Configuration UI for remote notification platforms\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Bell,\r\n BellOff,\r\n RefreshCw,\r\n Check,\r\n X,\r\n Save,\r\n ChevronDown,\r\n ChevronUp,\r\n Plus,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport { toast } from 'sonner';\r\nimport type {\r\n RemoteNotificationConfig,\r\n NotificationPlatform,\r\n EventConfig,\r\n DiscordConfig,\r\n TelegramConfig,\r\n WebhookConfig,\r\n FeishuConfig,\r\n DingTalkConfig,\r\n WeComConfig,\r\n EmailConfig,\r\n} from '@/types/remote-notification';\r\nimport { PLATFORM_INFO, EVENT_INFO, getDefaultConfig } from '@/types/remote-notification';\r\nimport { PlatformConfigCards } from './PlatformConfigCards';\r\n\r\ninterface RemoteNotificationSectionProps {\r\n className?: string;\r\n}\r\n\r\nexport function RemoteNotificationSection({ className }: RemoteNotificationSectionProps) {\r\n const { formatMessage } = useIntl();\r\n const [config, setConfig] = useState<RemoteNotificationConfig | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [saving, setSaving] = useState(false);\r\n const [testing, setTesting] = useState<NotificationPlatform | null>(null);\r\n const [expandedPlatform, setExpandedPlatform] = useState<NotificationPlatform | null>(null);\r\n const [expandedEvent, setExpandedEvent] = useState<number | null>(null);\r\n\r\n // Load configuration\r\n const loadConfig = useCallback(async () => {\r\n setLoading(true);\r\n try {\r\n const response = await fetch('/api/notifications/remote/config');\r\n if (response.ok) {\r\n const data = await response.json();\r\n setConfig(data);\r\n } else {\r\n // Use default config if not found\r\n setConfig(getDefaultConfig());\r\n }\r\n } catch (error) {\r\n console.error('Failed to load remote notification config:', error);\r\n setConfig(getDefaultConfig());\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n loadConfig();\r\n }, [loadConfig]);\r\n\r\n // Save configuration\r\n const saveConfig = useCallback(async (newConfig: RemoteNotificationConfig) => {\r\n setSaving(true);\r\n try {\r\n const response = await fetch('/api/notifications/remote/config', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(newConfig),\r\n });\r\n\r\n if (response.ok) {\r\n const data = await response.json();\r\n setConfig(data.config);\r\n toast.success(formatMessage({ id: 'settings.remoteNotifications.saved' }));\r\n } else {\r\n throw new Error(`HTTP ${response.status}`);\r\n }\r\n } catch (error) {\r\n toast.error(formatMessage({ id: 'settings.remoteNotifications.saveError' }));\r\n } finally {\r\n setSaving(false);\r\n }\r\n }, [formatMessage]);\r\n\r\n // Test platform\r\n const testPlatform = useCallback(async (\r\n platform: NotificationPlatform,\r\n platformConfig: DiscordConfig | TelegramConfig | WebhookConfig | FeishuConfig | DingTalkConfig | WeComConfig | EmailConfig\r\n ) => {\r\n setTesting(platform);\r\n try {\r\n const response = await fetch('/api/notifications/remote/test', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ platform, config: platformConfig }),\r\n });\r\n\r\n const result = await response.json();\r\n\r\n if (result.success) {\r\n toast.success(\r\n formatMessage({ id: 'settings.remoteNotifications.testSuccess' }),\r\n { description: `${result.responseTime}ms` }\r\n );\r\n } else {\r\n toast.error(\r\n formatMessage({ id: 'settings.remoteNotifications.testFailed' }),\r\n { description: result.error }\r\n );\r\n }\r\n } catch (error) {\r\n toast.error(formatMessage({ id: 'settings.remoteNotifications.testError' }));\r\n } finally {\r\n setTesting(null);\r\n }\r\n }, [formatMessage]);\r\n\r\n // Toggle master switch\r\n const toggleEnabled = () => {\r\n if (!config) return;\r\n saveConfig({ ...config, enabled: !config.enabled });\r\n };\r\n\r\n // Update platform config\r\n const updatePlatformConfig = (\r\n platform: NotificationPlatform,\r\n updates: Partial<DiscordConfig | TelegramConfig | WebhookConfig | FeishuConfig | DingTalkConfig | WeComConfig | EmailConfig>\r\n ) => {\r\n if (!config) return;\r\n const newConfig = {\r\n ...config,\r\n platforms: {\r\n ...config.platforms,\r\n [platform]: {\r\n ...config.platforms[platform as keyof typeof config.platforms],\r\n ...updates,\r\n },\r\n },\r\n };\r\n setConfig(newConfig);\r\n };\r\n\r\n // Update event config\r\n const updateEventConfig = (eventIndex: number, updates: Partial<EventConfig>) => {\r\n if (!config) return;\r\n const newEvents = [...config.events];\r\n newEvents[eventIndex] = { ...newEvents[eventIndex], ...updates };\r\n setConfig({ ...config, events: newEvents });\r\n };\r\n\r\n // Toggle platform for event\r\n const toggleEventPlatform = (eventIndex: number, platform: NotificationPlatform) => {\r\n if (!config) return;\r\n const eventConfig = config.events[eventIndex];\r\n const platforms = eventConfig.platforms.includes(platform)\r\n ? eventConfig.platforms.filter((p) => p !== platform)\r\n : [...eventConfig.platforms, platform];\r\n updateEventConfig(eventIndex, { platforms });\r\n };\r\n\r\n // All available platforms\r\n const allPlatforms: NotificationPlatform[] = ['discord', 'telegram', 'feishu', 'dingtalk', 'wecom', 'email', 'webhook'];\r\n\r\n // Reset to defaults\r\n const resetConfig = async () => {\r\n if (!confirm(formatMessage({ id: 'settings.remoteNotifications.resetConfirm' }))) {\r\n return;\r\n }\r\n try {\r\n const response = await fetch('/api/notifications/remote/reset', {\r\n method: 'POST',\r\n });\r\n if (response.ok) {\r\n const data = await response.json();\r\n setConfig(data.config);\r\n toast.success(formatMessage({ id: 'settings.remoteNotifications.resetSuccess' }));\r\n }\r\n } catch {\r\n toast.error(formatMessage({ id: 'settings.remoteNotifications.resetError' }));\r\n }\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <Card className={cn('p-6', className)}>\r\n <div className=\"flex items-center justify-center py-8\">\r\n <RefreshCw className=\"w-5 h-5 animate-spin text-muted-foreground\" />\r\n </div>\r\n </Card>\r\n );\r\n }\r\n\r\n if (!config) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Card className={cn('p-6', className)}>\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between mb-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2\">\r\n {config.enabled ? (\r\n <Bell className=\"w-5 h-5 text-primary\" />\r\n ) : (\r\n <BellOff className=\"w-5 h-5 text-muted-foreground\" />\r\n )}\r\n {formatMessage({ id: 'settings.remoteNotifications.title' })}\r\n </h2>\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => loadConfig()}\r\n disabled={loading}\r\n >\r\n <RefreshCw className={cn('w-3.5 h-3.5', loading && 'animate-spin')} />\r\n </Button>\r\n <Button\r\n variant={config.enabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={toggleEnabled}\r\n >\r\n {config.enabled ? (\r\n <>\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.remoteNotifications.enabled' })}\r\n </>\r\n ) : (\r\n <>\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.remoteNotifications.disabled' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-sm text-muted-foreground mb-6\">\r\n {formatMessage({ id: 'settings.remoteNotifications.description' })}\r\n </p>\r\n\r\n {config.enabled && (\r\n <>\r\n {/* Platform Configuration */}\r\n <div className=\"space-y-4 mb-6\">\r\n <h3 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.platforms' })}\r\n </h3>\r\n <PlatformConfigCards\r\n config={config}\r\n expandedPlatform={expandedPlatform}\r\n testing={testing}\r\n onToggleExpand={setExpandedPlatform}\r\n onUpdateConfig={updatePlatformConfig}\r\n onTest={testPlatform}\r\n onSave={() => saveConfig(config)}\r\n saving={saving}\r\n />\r\n </div>\r\n\r\n {/* Event Configuration */}\r\n <div className=\"space-y-4\">\r\n <h3 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.events' })}\r\n </h3>\r\n <div className=\"grid gap-3\">\r\n {config.events.map((eventConfig, index) => {\r\n const info = EVENT_INFO[eventConfig.event];\r\n const isExpanded = expandedEvent === index;\r\n return (\r\n <div\r\n key={eventConfig.event}\r\n className=\"rounded-lg border border-border bg-muted/30 overflow-hidden\"\r\n >\r\n {/* Event Header */}\r\n <div\r\n className=\"flex items-center justify-between p-3 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={() => setExpandedEvent(isExpanded ? null : index)}\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n eventConfig.enabled ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground'\r\n )}>\r\n <span className=\"text-sm\">{info.icon}</span>\r\n </div>\r\n <div>\r\n <p className=\"text-sm font-medium\">{info.name}</p>\r\n <p className=\"text-xs text-muted-foreground\">{info.description}</p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n {/* Platform badges */}\r\n <div className=\"flex gap-1 flex-wrap max-w-xs\">\r\n {eventConfig.platforms.slice(0, 3).map((platform) => (\r\n <Badge key={platform} variant=\"secondary\" className=\"text-xs\">\r\n {PLATFORM_INFO[platform].name}\r\n </Badge>\r\n ))}\r\n {eventConfig.platforms.length > 3 && (\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n +{eventConfig.platforms.length - 3}\r\n </Badge>\r\n )}\r\n {eventConfig.platforms.length === 0 && (\r\n <Badge variant=\"outline\" className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.noPlatforms' })}\r\n </Badge>\r\n )}\r\n </div>\r\n {/* Toggle */}\r\n <Button\r\n variant={eventConfig.enabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n updateEventConfig(index, { enabled: !eventConfig.enabled });\r\n }}\r\n >\r\n {eventConfig.enabled ? (\r\n <Check className=\"w-3.5 h-3.5\" />\r\n ) : (\r\n <X className=\"w-3.5 h-3.5\" />\r\n )}\r\n </Button>\r\n {/* Expand icon */}\r\n {isExpanded ? (\r\n <ChevronUp className=\"w-4 h-4 text-muted-foreground\" />\r\n ) : (\r\n <ChevronDown className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content - Platform Selection */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border p-4 space-y-3 bg-muted/20\">\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.remoteNotifications.selectPlatforms' })}\r\n </p>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {allPlatforms.map((platform) => {\r\n const isSelected = eventConfig.platforms.includes(platform);\r\n const platformInfo = PLATFORM_INFO[platform];\r\n const platformConfig = config.platforms[platform];\r\n const isConfigured = platformConfig?.enabled;\r\n return (\r\n <Button\r\n key={platform}\r\n variant={isSelected ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className={cn(\r\n 'h-8',\r\n !isConfigured && !isSelected && 'opacity-50'\r\n )}\r\n onClick={() => toggleEventPlatform(index, platform)}\r\n >\r\n {isSelected && <Check className=\"w-3 h-3 mr-1\" />}\r\n {platformInfo.name}\r\n {!isConfigured && !isSelected && (\r\n <Plus className=\"w-3 h-3 ml-1 opacity-50\" />\r\n )}\r\n </Button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center justify-between mt-6 pt-4 border-t border-border\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={resetConfig}\r\n >\r\n {formatMessage({ id: 'settings.remoteNotifications.reset' })}\r\n </Button>\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={() => saveConfig(config)}\r\n disabled={saving}\r\n >\r\n <Save className=\"w-4 h-4 mr-1\" />\r\n {saving\r\n ? formatMessage({ id: 'settings.remoteNotifications.saving' })\r\n : formatMessage({ id: 'settings.remoteNotifications.save' })}\r\n </Button>\r\n </div>\r\n </>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\nexport default RemoteNotificationSection;\r\n","// ========================================\n// A2UI Preferences Section\n// ========================================\n// Settings section for A2UI dialog style preferences\n\nimport { useIntl } from 'react-intl';\nimport { MessageSquare, Clock, Volume2, LayoutPanelLeft, Sparkles } from 'lucide-react';\nimport { Card } from '@/components/ui/Card';\nimport { Button } from '@/components/ui/Button';\nimport { Label } from '@/components/ui/Label';\nimport { cn } from '@/lib/utils';\nimport { useDialogStyleContext, type DialogStyle } from '@/contexts/DialogStyleContext';\n\n// ========== Style Option Button ==========\n\ninterface StyleOptionProps {\n value: DialogStyle;\n label: string;\n description: string;\n selected: boolean;\n onClick: () => void;\n}\n\nfunction StyleOption({ value, label, description, selected, onClick }: StyleOptionProps) {\n const icons: Record<DialogStyle, React.ReactNode> = {\n modal: (\n <div className=\"w-8 h-8 border-2 border-current rounded-lg flex items-center justify-center\">\n <div className=\"w-4 h-3 border border-current rounded-sm\" />\n </div>\n ),\n drawer: (\n <div className=\"w-8 h-8 border-2 border-current rounded-lg flex items-end justify-end p-0.5\">\n <div className=\"w-2 h-6 border border-current rounded-sm\" />\n </div>\n ),\n sheet: (\n <div className=\"w-8 h-8 border-2 border-current rounded-lg flex items-end justify-center p-0.5\">\n <div className=\"w-6 h-2 border border-current rounded-sm\" />\n </div>\n ),\n fullscreen: (\n <div className=\"w-8 h-8 border-2 border-current rounded-lg flex items-center justify-center\">\n <div className=\"w-5 h-4 border border-current rounded-sm\" />\n </div>\n ),\n };\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n 'flex flex-col items-center gap-2 p-3 rounded-lg border-2 transition-all',\n 'hover:bg-accent/50',\n selected\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border text-muted-foreground'\n )}\n >\n {icons[value]}\n <div className=\"text-center\">\n <div className={cn('text-sm font-medium', selected && 'text-primary')}>{label}</div>\n <div className=\"text-xs text-muted-foreground\">{description}</div>\n </div>\n </button>\n );\n}\n\n// ========== Duration Slider ==========\n\ninterface DurationSliderProps {\n value: number;\n onChange: (value: number) => void;\n disabled?: boolean;\n}\n\nfunction DurationSlider({ value, onChange, disabled }: DurationSliderProps) {\n const presets = [10, 20, 30, 45, 60, 90, 120];\n\n return (\n <div className=\"flex flex-wrap gap-2\">\n {presets.map((seconds) => (\n <Button\n key={seconds}\n type=\"button\"\n variant={value === seconds ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange(seconds)}\n >\n {seconds}s\n </Button>\n ))}\n </div>\n );\n}\n\n// ========== Main Component ==========\n\nexport function A2UIPreferencesSection() {\n const { formatMessage } = useIntl();\n const { preferences, updatePreference, resetPreferences } = useDialogStyleContext();\n\n const styleOptions: Array<{ value: DialogStyle; label: string; description: string }> = [\n {\n value: 'modal',\n label: formatMessage({ id: 'settings.a2ui.styleModal', defaultMessage: 'Modal' }),\n description: formatMessage({ id: 'settings.a2ui.styleModalDesc', defaultMessage: 'Centered' }),\n },\n {\n value: 'drawer',\n label: formatMessage({ id: 'settings.a2ui.styleDrawer', defaultMessage: 'Drawer' }),\n description: formatMessage({ id: 'settings.a2ui.styleDrawerDesc', defaultMessage: 'Side panel' }),\n },\n {\n value: 'sheet',\n label: formatMessage({ id: 'settings.a2ui.styleSheet', defaultMessage: 'Sheet' }),\n description: formatMessage({ id: 'settings.a2ui.styleSheetDesc', defaultMessage: 'Bottom' }),\n },\n {\n value: 'fullscreen',\n label: formatMessage({ id: 'settings.a2ui.styleFullscreen', defaultMessage: 'Fullscreen' }),\n description: formatMessage({ id: 'settings.a2ui.styleFullscreenDesc', defaultMessage: 'Full screen' }),\n },\n ];\n\n return (\n <Card className=\"p-6\">\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\n <MessageSquare className=\"w-5 h-5\" />\n {formatMessage({ id: 'settings.sections.a2ui', defaultMessage: 'A2UI Preferences' })}\n </h2>\n\n <div className=\"space-y-6\">\n {/* Dialog Style Selection */}\n <div className=\"space-y-3\">\n <Label className=\"text-sm font-medium flex items-center gap-2\">\n <LayoutPanelLeft className=\"w-4 h-4\" />\n {formatMessage({ id: 'settings.a2ui.dialogStyle', defaultMessage: 'Dialog Style' })}\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({\n id: 'settings.a2ui.dialogStyleDesc',\n defaultMessage: 'Choose how A2UI dialogs are displayed',\n })}\n </p>\n <div className=\"grid grid-cols-4 gap-2\">\n {styleOptions.map((option) => (\n <StyleOption\n key={option.value}\n value={option.value}\n label={option.label}\n description={option.description}\n selected={preferences.dialogStyle === option.value}\n onClick={() => updatePreference('dialogStyle', option.value)}\n />\n ))}\n </div>\n </div>\n\n {/* Smart Mode */}\n <div className=\"flex items-center justify-between py-2 border-t border-border\">\n <div className=\"flex items-center gap-2\">\n <Sparkles className=\"w-4 h-4 text-muted-foreground\" />\n <div>\n <p className=\"text-sm font-medium\">\n {formatMessage({ id: 'settings.a2ui.smartMode', defaultMessage: 'Smart Mode' })}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({\n id: 'settings.a2ui.smartModeDesc',\n defaultMessage: 'Auto-select style based on question type',\n })}\n </p>\n </div>\n </div>\n <Button\n variant={preferences.smartModeEnabled ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => updatePreference('smartModeEnabled', !preferences.smartModeEnabled)}\n >\n {preferences.smartModeEnabled\n ? formatMessage({ id: 'common.enabled', defaultMessage: 'Enabled' })\n : formatMessage({ id: 'common.disabled', defaultMessage: 'Disabled' })}\n </Button>\n </div>\n\n {/* Auto Selection Duration */}\n <div className=\"space-y-3 py-2 border-t border-border\">\n <div className=\"flex items-center gap-2\">\n <Clock className=\"w-4 h-4 text-muted-foreground\" />\n <Label className=\"text-sm font-medium\">\n {formatMessage({ id: 'settings.a2ui.autoSelectionDuration', defaultMessage: 'Auto-Selection Duration' })}\n </Label>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({\n id: 'settings.a2ui.autoSelectionDurationDesc',\n defaultMessage: 'Countdown before auto-selecting default option',\n })}\n </p>\n <DurationSlider\n value={preferences.autoSelectionDuration}\n onChange={(v) => updatePreference('autoSelectionDuration', v)}\n />\n </div>\n\n {/* Pause on Interaction */}\n <div className=\"flex items-center justify-between py-2 border-t border-border\">\n <div>\n <p className=\"text-sm font-medium\">\n {formatMessage({ id: 'settings.a2ui.pauseOnInteraction', defaultMessage: 'Pause on Interaction' })}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({\n id: 'settings.a2ui.pauseOnInteractionDesc',\n defaultMessage: 'Pause countdown when you interact with the dialog',\n })}\n </p>\n </div>\n <Button\n variant={preferences.pauseOnInteraction ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => updatePreference('pauseOnInteraction', !preferences.pauseOnInteraction)}\n >\n {preferences.pauseOnInteraction\n ? formatMessage({ id: 'common.enabled', defaultMessage: 'Enabled' })\n : formatMessage({ id: 'common.disabled', defaultMessage: 'Disabled' })}\n </Button>\n </div>\n\n {/* Sound Notification */}\n <div className=\"flex items-center justify-between py-2 border-t border-border\">\n <div className=\"flex items-center gap-2\">\n <Volume2 className=\"w-4 h-4 text-muted-foreground\" />\n <div>\n <p className=\"text-sm font-medium\">\n {formatMessage({ id: 'settings.a2ui.soundNotification', defaultMessage: 'Sound Notification' })}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({\n id: 'settings.a2ui.soundNotificationDesc',\n defaultMessage: 'Play sound before auto-submit (3 seconds before)',\n })}\n </p>\n </div>\n </div>\n <Button\n variant={preferences.autoSelectionSoundEnabled ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => updatePreference('autoSelectionSoundEnabled', !preferences.autoSelectionSoundEnabled)}\n >\n {preferences.autoSelectionSoundEnabled\n ? formatMessage({ id: 'common.enabled', defaultMessage: 'Enabled' })\n : formatMessage({ id: 'common.disabled', defaultMessage: 'Disabled' })}\n </Button>\n </div>\n\n {/* Show A2UI Button in Toolbar */}\n <div className=\"flex items-center justify-between py-2 border-t border-border\">\n <div>\n <p className=\"text-sm font-medium\">\n {formatMessage({ id: 'settings.a2ui.showToolbarButton', defaultMessage: 'Show Toolbar Button' })}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatMessage({\n id: 'settings.a2ui.showToolbarButtonDesc',\n defaultMessage: 'Show A2UI quick action button in the toolbar',\n })}\n </p>\n </div>\n <Button\n variant={preferences.showA2UIButtonInToolbar ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => updatePreference('showA2UIButtonInToolbar', !preferences.showA2UIButtonInToolbar)}\n >\n {preferences.showA2UIButtonInToolbar\n ? formatMessage({ id: 'common.enabled', defaultMessage: 'Enabled' })\n : formatMessage({ id: 'common.disabled', defaultMessage: 'Disabled' })}\n </Button>\n </div>\n\n {/* Reset Button */}\n <div className=\"flex justify-end pt-4 border-t border-border\">\n <Button variant=\"outline\" size=\"sm\" onClick={resetPreferences}>\n {formatMessage({ id: 'common.resetToDefaults', defaultMessage: 'Reset to Defaults' })}\n </Button>\n </div>\n </div>\n </Card>\n );\n}\n\nexport default A2UIPreferencesSection;\n","// ========================================\n// Agent Definitions Section\n// ========================================\n// Settings section for viewing and editing Codex/Claude agent model and effort fields\n// Claude agents support advanced frontmatter config: MCP servers, hooks, permissions, etc.\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { Bot, ChevronDown, ChevronRight, Save, RefreshCw, Settings2, Plus, X } from 'lucide-react';\nimport { Card } from '@/components/ui/Card';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Badge } from '@/components/ui/Badge';\nimport { Checkbox } from '@/components/ui/Checkbox';\nimport { cn } from '@/lib/utils';\nimport { toast } from 'sonner';\nimport {\n fetchAgentDefinitions,\n updateAgentDefinition,\n batchUpdateAgentDefinitions,\n fetchMcpConfig,\n type AgentDefinition,\n} from '@/lib/api';\n\n// ========== Constants ==========\n\nconst CODEX_EFFORTS = ['', 'low', 'medium', 'high'];\nconst CLAUDE_EFFORTS = ['', 'low', 'medium', 'high', 'max'];\nconst CLAUDE_MODEL_PRESETS = ['sonnet', 'opus', 'haiku', 'inherit'];\nconst PERMISSION_MODES = ['', 'default', 'acceptEdits', 'dontAsk', 'bypassPermissions', 'plan'];\nconst MEMORY_OPTIONS = ['', 'user', 'project', 'local'];\nconst ISOLATION_OPTIONS = ['', 'worktree'];\nconst COLOR_OPTIONS = ['', 'purple', 'blue', 'yellow', 'green', 'red'];\nconst HOOK_EVENTS = ['PreToolUse', 'PostToolUse', 'Stop'];\n\nconst selectClass = 'h-7 text-xs rounded border border-input bg-background px-2';\nconst labelClass = 'text-xs text-muted-foreground shrink-0';\n\n// ========== YAML helpers ==========\n\nfunction parseMcpServersYaml(yaml: string): string[] {\n if (!yaml) return [];\n const servers: string[] = [];\n const lines = yaml.split('\\n');\n for (const line of lines) {\n const match = line.match(/^\\s+-\\s+(.+)$/);\n if (match) servers.push(match[1].trim());\n }\n return servers;\n}\n\nfunction serializeMcpServersYaml(servers: string[]): string {\n if (servers.length === 0) return '';\n return `mcpServers:\\n${servers.map(s => ` - ${s}`).join('\\n')}`;\n}\n\ninterface HookEntry {\n matcher: string;\n command: string;\n}\n\ninterface ParsedHooks {\n PreToolUse: HookEntry[];\n PostToolUse: HookEntry[];\n Stop: HookEntry[];\n}\n\nfunction parseHooksYaml(yaml: string): ParsedHooks {\n const result: ParsedHooks = { PreToolUse: [], PostToolUse: [], Stop: [] };\n if (!yaml) return result;\n\n let currentEvent: string | null = null;\n let currentMatcher: string | null = null;\n const lines = yaml.split('\\n');\n\n for (const line of lines) {\n // Top-level event: \" PreToolUse:\"\n const eventMatch = line.match(/^\\s{2,4}(\\w+):$/);\n if (eventMatch && (eventMatch[1] in result)) {\n currentEvent = eventMatch[1];\n currentMatcher = null;\n continue;\n }\n // Matcher line: \" - matcher: \"Bash\"\"\n const matcherMatch = line.match(/^\\s+-\\s+matcher:\\s*[\"']?([^\"'\\n]+)[\"']?$/);\n if (matcherMatch && currentEvent) {\n currentMatcher = matcherMatch[1].trim();\n continue;\n }\n // Command line: \" command: \"./scripts/validate.sh\"\n const commandMatch = line.match(/^\\s+command:\\s*[\"']?([^\"'\\n]+)[\"']?$/);\n if (commandMatch && currentEvent && currentMatcher !== null) {\n result[currentEvent as keyof ParsedHooks].push({\n matcher: currentMatcher,\n command: commandMatch[1].trim(),\n });\n currentMatcher = null;\n continue;\n }\n // type: command line — skip, we only support command type\n }\n return result;\n}\n\nfunction serializeHooksYaml(hooks: ParsedHooks): string {\n const parts: string[] = [];\n for (const event of HOOK_EVENTS) {\n const entries = hooks[event as keyof ParsedHooks];\n if (entries.length === 0) continue;\n parts.push(` ${event}:`);\n for (const entry of entries) {\n parts.push(` - matcher: \"${entry.matcher}\"`);\n parts.push(` hooks:`);\n parts.push(` - type: command`);\n parts.push(` command: \"${entry.command}\"`);\n }\n }\n if (parts.length === 0) return '';\n return `hooks:\\n${parts.join('\\n')}`;\n}\n\n// ========== Advanced Settings (Claude only) ==========\n\ninterface AdvancedSettingsProps {\n agent: AgentDefinition;\n onSaved: () => void;\n}\n\nfunction AdvancedSettings({ agent, onSaved }: AdvancedSettingsProps) {\n // Quick settings\n const [color, setColor] = useState(agent.color);\n const [permissionMode, setPermissionMode] = useState(agent.permissionMode);\n const [memory, setMemory] = useState(agent.memory);\n const [maxTurns, setMaxTurns] = useState(agent.maxTurns);\n const [background, setBackground] = useState(agent.background === 'true');\n const [isolation, setIsolation] = useState(agent.isolation);\n\n // Tools\n const [tools, setTools] = useState(agent.tools);\n const [disallowedTools, setDisallowedTools] = useState(agent.disallowedTools);\n const [skills, setSkills] = useState(agent.skills);\n\n // MCP Servers\n const [installedServers, setInstalledServers] = useState<string[]>([]);\n const [selectedServers, setSelectedServers] = useState<string[]>(() => parseMcpServersYaml(agent.mcpServers));\n const [mcpLoading, setMcpLoading] = useState(false);\n const [customServer, setCustomServer] = useState('');\n\n // Hooks\n const [hooks, setHooks] = useState<ParsedHooks>(() => parseHooksYaml(agent.hooks));\n const [newHookEvent, setNewHookEvent] = useState('PreToolUse');\n\n const [saving, setSaving] = useState(false);\n\n // Load installed MCP servers\n useEffect(() => {\n let cancelled = false;\n setMcpLoading(true);\n fetchMcpConfig()\n .then((config) => {\n if (cancelled) return;\n const names = new Set<string>();\n // Collect from all sources\n if (config.userServers) Object.keys(config.userServers).forEach(n => names.add(n));\n if (config.globalServers) Object.keys(config.globalServers).forEach(n => names.add(n));\n if (config.projects) {\n Object.values(config.projects).forEach((proj: any) => {\n if (proj?.mcpServers) Object.keys(proj.mcpServers).forEach(n => names.add(n));\n });\n }\n setInstalledServers(Array.from(names).sort());\n })\n .catch(() => {})\n .finally(() => { if (!cancelled) setMcpLoading(false); });\n return () => { cancelled = true; };\n }, []);\n\n // Sync state on agent prop change\n useEffect(() => {\n setColor(agent.color);\n setPermissionMode(agent.permissionMode);\n setMemory(agent.memory);\n setMaxTurns(agent.maxTurns);\n setBackground(agent.background === 'true');\n setIsolation(agent.isolation);\n setTools(agent.tools);\n setDisallowedTools(agent.disallowedTools);\n setSkills(agent.skills);\n setSelectedServers(parseMcpServersYaml(agent.mcpServers));\n setHooks(parseHooksYaml(agent.hooks));\n }, [agent]);\n\n const handleSave = useCallback(async () => {\n setSaving(true);\n try {\n const body: { filePath: string; [key: string]: string | undefined } = { filePath: agent.filePath };\n\n // Only send changed fields\n if (color !== agent.color) body.color = color;\n if (permissionMode !== agent.permissionMode) body.permissionMode = permissionMode;\n if (memory !== agent.memory) body.memory = memory;\n if (maxTurns !== agent.maxTurns) body.maxTurns = maxTurns;\n const bgStr = background ? 'true' : '';\n if (bgStr !== agent.background) body.background = bgStr;\n if (isolation !== agent.isolation) body.isolation = isolation;\n if (tools !== agent.tools) body.tools = tools;\n if (disallowedTools !== agent.disallowedTools) body.disallowedTools = disallowedTools;\n if (skills !== agent.skills) body.skills = skills;\n\n // MCP servers\n const newMcpYaml = serializeMcpServersYaml(selectedServers);\n if (newMcpYaml !== agent.mcpServers) body.mcpServers = newMcpYaml;\n\n // Hooks\n const newHooksYaml = serializeHooksYaml(hooks);\n if (newHooksYaml !== agent.hooks) body.hooks = newHooksYaml;\n\n // Only save if something changed\n const changedKeys = Object.keys(body).filter(k => k !== 'filePath');\n if (changedKeys.length === 0) {\n toast.info('No changes to save');\n return;\n }\n\n await updateAgentDefinition(agent.type, agent.name, body);\n toast.success(`Updated ${agent.name} advanced settings`);\n onSaved();\n } catch (err) {\n toast.error(`Failed: ${(err as Error).message}`);\n } finally {\n setSaving(false);\n }\n }, [agent, color, permissionMode, memory, maxTurns, background, isolation, tools, disallowedTools, skills, selectedServers, hooks, onSaved]);\n\n const toggleServer = (name: string) => {\n setSelectedServers(prev =>\n prev.includes(name) ? prev.filter(s => s !== name) : [...prev, name]\n );\n };\n\n const addCustomServer = () => {\n const name = customServer.trim();\n if (name && !selectedServers.includes(name)) {\n setSelectedServers(prev => [...prev, name]);\n setCustomServer('');\n }\n };\n\n const addHook = () => {\n setHooks(prev => ({\n ...prev,\n [newHookEvent]: [...prev[newHookEvent as keyof ParsedHooks], { matcher: '', command: '' }],\n }));\n };\n\n const removeHook = (event: string, idx: number) => {\n setHooks(prev => ({\n ...prev,\n [event]: prev[event as keyof ParsedHooks].filter((_, i) => i !== idx),\n }));\n };\n\n const updateHook = (event: string, idx: number, field: 'matcher' | 'command', value: string) => {\n setHooks(prev => ({\n ...prev,\n [event]: prev[event as keyof ParsedHooks].map((h, i) => i === idx ? { ...h, [field]: value } : h),\n }));\n };\n\n return (\n <div className=\"mt-2 ml-6 p-3 rounded-md border border-border bg-muted/20 space-y-4\">\n {/* Quick Settings Row 1 */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Color:</span>\n <select className={selectClass} value={color} onChange={e => setColor(e.target.value)}>\n {COLOR_OPTIONS.map(c => <option key={c} value={c}>{c || '—'}</option>)}\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Permission:</span>\n <select className={selectClass} value={permissionMode} onChange={e => setPermissionMode(e.target.value)}>\n {PERMISSION_MODES.map(p => <option key={p} value={p}>{p || '—'}</option>)}\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Memory:</span>\n <select className={selectClass} value={memory} onChange={e => setMemory(e.target.value)}>\n {MEMORY_OPTIONS.map(m => <option key={m} value={m}>{m || '—'}</option>)}\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>MaxTurns:</span>\n <Input\n className=\"h-7 text-xs w-[60px]\"\n type=\"number\"\n value={maxTurns}\n onChange={e => setMaxTurns(e.target.value)}\n placeholder=\"—\"\n />\n </div>\n <div className=\"flex items-center gap-1.5\">\n <Checkbox\n checked={background}\n onCheckedChange={(v) => setBackground(v === true)}\n />\n <span className={labelClass}>Background</span>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Isolation:</span>\n <select className={selectClass} value={isolation} onChange={e => setIsolation(e.target.value)}>\n {ISOLATION_OPTIONS.map(i => <option key={i} value={i}>{i || '—'}</option>)}\n </select>\n </div>\n </div>\n\n {/* Tools Row */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className={labelClass}>Tools:</span>\n <Input\n className=\"h-7 text-xs flex-1\"\n value={tools}\n onChange={e => setTools(e.target.value)}\n placeholder=\"Read, Write, Bash, Glob, Grep\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className={labelClass}>Disallowed:</span>\n <Input\n className=\"h-7 text-xs flex-1\"\n value={disallowedTools}\n onChange={e => setDisallowedTools(e.target.value)}\n placeholder=\"e.g. Edit\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className={labelClass}>Skills:</span>\n <Input\n className=\"h-7 text-xs flex-1\"\n value={skills}\n onChange={e => setSkills(e.target.value)}\n placeholder=\"e.g. api-conventions, error-handling\"\n />\n </div>\n </div>\n\n {/* MCP Servers Picker */}\n <div className=\"space-y-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">MCP Servers:</span>\n {mcpLoading ? (\n <span className=\"text-xs text-muted-foreground ml-2\">Loading...</span>\n ) : (\n <div className=\"flex flex-wrap gap-3 ml-1\">\n {installedServers.map(name => (\n <label key={name} className=\"flex items-center gap-1.5 text-xs cursor-pointer\">\n <Checkbox\n checked={selectedServers.includes(name)}\n onCheckedChange={() => toggleServer(name)}\n />\n <span className=\"text-foreground\">{name}</span>\n </label>\n ))}\n {/* Show selected servers not in installed list */}\n {selectedServers.filter(s => !installedServers.includes(s)).map(name => (\n <label key={name} className=\"flex items-center gap-1.5 text-xs cursor-pointer\">\n <Checkbox checked onCheckedChange={() => toggleServer(name)} />\n <span className=\"text-foreground italic\">{name}</span>\n </label>\n ))}\n <div className=\"flex items-center gap-1\">\n <Input\n className=\"h-6 text-xs w-[120px]\"\n value={customServer}\n onChange={e => setCustomServer(e.target.value)}\n placeholder=\"+ Custom\"\n onKeyDown={e => { if (e.key === 'Enter') addCustomServer(); }}\n />\n <Button variant=\"ghost\" size=\"sm\" className=\"h-6 px-1\" onClick={addCustomServer} disabled={!customServer.trim()}>\n <Plus className=\"w-3 h-3\" />\n </Button>\n </div>\n </div>\n )}\n </div>\n\n {/* Hooks Editor */}\n <div className=\"space-y-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">Hooks:</span>\n {HOOK_EVENTS.map(event => {\n const entries = hooks[event as keyof ParsedHooks];\n if (entries.length === 0) return null;\n return (\n <div key={event} className=\"ml-1 space-y-1\">\n <span className=\"text-xs text-muted-foreground font-medium\">{event}:</span>\n {entries.map((entry, idx) => (\n <div key={idx} className=\"flex items-center gap-2 ml-3\">\n <Input\n className=\"h-6 text-xs w-[100px]\"\n value={entry.matcher}\n onChange={e => updateHook(event, idx, 'matcher', e.target.value)}\n placeholder=\"matcher (e.g. Bash)\"\n />\n <span className=\"text-xs text-muted-foreground\">&rarr;</span>\n <Input\n className=\"h-6 text-xs flex-1\"\n value={entry.command}\n onChange={e => updateHook(event, idx, 'command', e.target.value)}\n placeholder=\"command\"\n />\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-destructive transition-colors\"\n onClick={() => removeHook(event, idx)}\n >\n <X className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n );\n })}\n <div className=\"flex items-center gap-2 ml-1\">\n <select className={selectClass} value={newHookEvent} onChange={e => setNewHookEvent(e.target.value)}>\n {HOOK_EVENTS.map(e => <option key={e} value={e}>{e}</option>)}\n </select>\n <Button variant=\"outline\" size=\"sm\" className=\"h-6 px-2 text-xs\" onClick={addHook}>\n <Plus className=\"w-3 h-3 mr-1\" />\n Add Hook\n </Button>\n </div>\n </div>\n\n {/* Save Button */}\n <div className=\"flex justify-end\">\n <Button variant=\"default\" size=\"sm\" className=\"h-7\" disabled={saving} onClick={handleSave}>\n <Save className=\"w-3 h-3 mr-1\" />\n {saving ? 'Saving...' : 'Save Advanced'}\n </Button>\n </div>\n </div>\n );\n}\n\n// ========== Agent Card ==========\n\ninterface AgentCardProps {\n agent: AgentDefinition;\n onSaved: () => void;\n}\n\nfunction AgentCard({ agent, onSaved }: AgentCardProps) {\n const [model, setModel] = useState(agent.model);\n const [effort, setEffort] = useState(agent.effort);\n const [saving, setSaving] = useState(false);\n const [showAdvanced, setShowAdvanced] = useState(false);\n\n const isDirty = model !== agent.model || effort !== agent.effort;\n const effortOptions = agent.type === 'codex' ? CODEX_EFFORTS : CLAUDE_EFFORTS;\n\n const handleSave = useCallback(async () => {\n setSaving(true);\n try {\n const body: { filePath: string; [key: string]: string | undefined } = { filePath: agent.filePath };\n if (model !== agent.model) body.model = model;\n if (effort !== agent.effort) body.effort = effort;\n await updateAgentDefinition(agent.type, agent.name, body);\n toast.success(`Updated ${agent.name}`);\n onSaved();\n } catch (err) {\n toast.error(`Failed to update ${agent.name}: ${(err as Error).message}`);\n } finally {\n setSaving(false);\n }\n }, [agent, model, effort, onSaved]);\n\n // Sync local state when agent prop changes (after refetch)\n useEffect(() => {\n setModel(agent.model);\n setEffort(agent.effort);\n }, [agent.model, agent.effort]);\n\n return (\n <div>\n <div className=\"flex items-center gap-3 py-2 px-3 rounded-md border border-border bg-card hover:bg-accent/30 transition-colors\">\n <Badge variant={agent.type === 'codex' ? 'default' : 'secondary'} className=\"text-xs shrink-0\">\n {agent.type}\n </Badge>\n <span className=\"text-sm font-medium text-foreground min-w-[140px] truncate\" title={agent.name}>\n {agent.name}\n </span>\n\n {/* Model input */}\n <div className=\"flex items-center gap-1 flex-1 min-w-0\">\n <span className=\"text-xs text-muted-foreground shrink-0\">Model:</span>\n {agent.type === 'claude' ? (\n <div className=\"flex gap-1 flex-1 min-w-0\">\n <select\n className=\"h-7 text-xs rounded border border-input bg-background px-2 shrink-0\"\n value={CLAUDE_MODEL_PRESETS.includes(model) ? model : '__custom__'}\n onChange={(e) => {\n if (e.target.value === '__custom__') return;\n setModel(e.target.value);\n }}\n >\n {CLAUDE_MODEL_PRESETS.map(m => (\n <option key={m} value={m}>{m || '(none)'}</option>\n ))}\n {!CLAUDE_MODEL_PRESETS.includes(model) && (\n <option value=\"__custom__\">custom</option>\n )}\n </select>\n {!CLAUDE_MODEL_PRESETS.includes(model) && (\n <Input\n className=\"h-7 text-xs flex-1 min-w-[100px]\"\n value={model}\n onChange={(e) => setModel(e.target.value)}\n placeholder=\"model id\"\n />\n )}\n </div>\n ) : (\n <Input\n className=\"h-7 text-xs flex-1 min-w-[100px]\"\n value={model}\n onChange={(e) => setModel(e.target.value)}\n placeholder=\"model id\"\n />\n )}\n </div>\n\n {/* Effort select */}\n <div className=\"flex items-center gap-1 shrink-0\">\n <span className=\"text-xs text-muted-foreground\">Effort:</span>\n <select\n className=\"h-7 text-xs rounded border border-input bg-background px-2\"\n value={effort}\n onChange={(e) => setEffort(e.target.value)}\n >\n {effortOptions.map(e => (\n <option key={e} value={e}>{e || '—'}</option>\n ))}\n </select>\n </div>\n\n {/* Save button */}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 px-2 shrink-0\"\n disabled={!isDirty || saving}\n onClick={handleSave}\n >\n <Save className=\"w-3 h-3 mr-1\" />\n {saving ? '...' : 'Save'}\n </Button>\n\n {/* Advanced toggle (claude only) */}\n {agent.type === 'claude' && (\n <button\n type=\"button\"\n className={cn(\n 'p-1 rounded hover:bg-accent transition-colors',\n showAdvanced && 'text-primary'\n )}\n onClick={() => setShowAdvanced(!showAdvanced)}\n title=\"Advanced Settings\"\n >\n <Settings2 className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n\n {/* Advanced Settings Panel */}\n {showAdvanced && agent.type === 'claude' && (\n <AdvancedSettings agent={agent} onSaved={onSaved} />\n )}\n </div>\n );\n}\n\n// ========== Installation Group ==========\n\ninterface InstallationGroupProps {\n installationPath: string;\n agents: AgentDefinition[];\n onSaved: () => void;\n}\n\nfunction InstallationGroup({ installationPath, agents, onSaved }: InstallationGroupProps) {\n const [expanded, setExpanded] = useState(true);\n\n return (\n <div className=\"space-y-2\">\n <button\n type=\"button\"\n className=\"flex items-center gap-2 w-full text-left py-1 hover:text-primary transition-colors\"\n onClick={() => setExpanded(!expanded)}\n >\n {expanded ? <ChevronDown className=\"w-4 h-4\" /> : <ChevronRight className=\"w-4 h-4\" />}\n <span className=\"text-sm font-medium text-foreground truncate\" title={installationPath}>\n {installationPath}\n </span>\n <Badge variant=\"outline\" className=\"text-xs ml-auto shrink-0\">\n {agents.length} agents\n </Badge>\n </button>\n {expanded && (\n <div className=\"space-y-1 ml-6\">\n {agents.map((agent) => (\n <AgentCard key={agent.filePath} agent={agent} onSaved={onSaved} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ========== Main Component ==========\n\nexport function AgentDefinitionsSection() {\n const [agents, setAgents] = useState<AgentDefinition[]>([]);\n const [loading, setLoading] = useState(true);\n const [batchModel, setBatchModel] = useState('');\n const [batchEffort, setBatchEffort] = useState('');\n const [batchType, setBatchType] = useState<'all' | 'codex' | 'claude'>('all');\n const [batchColor, setBatchColor] = useState('');\n const [batchPermission, setBatchPermission] = useState('');\n const [batchMemory, setBatchMemory] = useState('');\n const [batchMaxTurns, setBatchMaxTurns] = useState('');\n const [batchBackground, setBatchBackground] = useState<'' | 'true' | 'false'>('');\n const [batchIsolation, setBatchIsolation] = useState('');\n const [batchTools, setBatchTools] = useState('');\n const [batchDisallowedTools, setBatchDisallowedTools] = useState('');\n const [batchSkills, setBatchSkills] = useState('');\n const [batchShowAdvanced, setBatchShowAdvanced] = useState(false);\n const [batchSaving, setBatchSaving] = useState(false);\n\n const loadAgents = useCallback(async () => {\n try {\n setLoading(true);\n const data = await fetchAgentDefinitions();\n setAgents(data.agents);\n } catch (err) {\n toast.error(`Failed to load agents: ${(err as Error).message}`);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => { loadAgents(); }, [loadAgents]);\n\n // Group agents by installation path\n const grouped = agents.reduce<Record<string, AgentDefinition[]>>((acc, agent) => {\n const key = agent.installationPath;\n if (!acc[key]) acc[key] = [];\n acc[key].push(agent);\n return acc;\n }, {});\n\n const batchTargets = agents.filter(a => batchType === 'all' || a.type === batchType);\n const batchHasClaudeTargets = batchTargets.some(a => a.type === 'claude');\n const batchEffortOptions = batchType === 'codex'\n ? CODEX_EFFORTS\n : batchType === 'claude'\n ? CLAUDE_EFFORTS\n : ['', 'low', 'medium', 'high', 'max (claude only)'];\n\n // Collect all claude-only batch values into a single object for easier checking\n const claudeBatchFields: Record<string, string> = {};\n if (batchColor) claudeBatchFields.color = batchColor;\n if (batchPermission) claudeBatchFields.permissionMode = batchPermission;\n if (batchMemory) claudeBatchFields.memory = batchMemory;\n if (batchMaxTurns) claudeBatchFields.maxTurns = batchMaxTurns;\n if (batchBackground) claudeBatchFields.background = batchBackground;\n if (batchIsolation) claudeBatchFields.isolation = batchIsolation;\n if (batchTools) claudeBatchFields.tools = batchTools;\n if (batchDisallowedTools) claudeBatchFields.disallowedTools = batchDisallowedTools;\n if (batchSkills) claudeBatchFields.skills = batchSkills;\n const hasClaudeBatchFields = Object.keys(claudeBatchFields).length > 0;\n\n const handleBatchApply = useCallback(async () => {\n const hasAnyValue = batchModel || batchEffort || hasClaudeBatchFields;\n if (!hasAnyValue) {\n toast.error('Set at least one value first');\n return;\n }\n if (batchTargets.length === 0) {\n toast.error('No agents match the selected type');\n return;\n }\n\n setBatchSaving(true);\n try {\n // For model/effort, use the batch endpoint (works for both codex and claude)\n if (batchModel || batchEffort) {\n const targets = batchTargets.map(a => ({ filePath: a.filePath, type: a.type }));\n const result = await batchUpdateAgentDefinitions({\n targets,\n model: batchModel || undefined,\n effort: batchEffort || undefined,\n });\n toast.success(`Updated model/effort: ${result.updated}/${result.total} agents`);\n }\n\n // For claude-only fields, update each claude agent individually\n if (hasClaudeBatchFields && batchHasClaudeTargets) {\n const claudeTargets = batchTargets.filter(a => a.type === 'claude');\n let updated = 0;\n for (const agent of claudeTargets) {\n try {\n const body: { filePath: string; [key: string]: string | undefined } = {\n filePath: agent.filePath,\n ...claudeBatchFields,\n };\n await updateAgentDefinition(agent.type, agent.name, body);\n updated++;\n } catch { /* skip failed */ }\n }\n toast.success(`Updated claude fields: ${updated}/${claudeTargets.length} agents`);\n }\n\n loadAgents();\n } catch (err) {\n toast.error(`Batch update failed: ${(err as Error).message}`);\n } finally {\n setBatchSaving(false);\n }\n }, [batchTargets, batchHasClaudeTargets, batchModel, batchEffort, hasClaudeBatchFields, claudeBatchFields, loadAgents]);\n\n return (\n <Card className=\"p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2\">\n <Bot className=\"w-5 h-5\" />\n Agent Definitions\n </h2>\n <Button variant=\"ghost\" size=\"sm\" onClick={loadAgents} disabled={loading}>\n <RefreshCw className={cn('w-4 h-4 mr-1', loading && 'animate-spin')} />\n Refresh\n </Button>\n </div>\n\n {/* Batch Controls */}\n <div className=\"p-3 mb-4 rounded-md border border-border bg-muted/30 space-y-2\">\n {/* Row 1: shared fields (all agent types) */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-xs font-medium text-muted-foreground shrink-0\">Batch:</span>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Target:</span>\n <select\n className={selectClass}\n value={batchType}\n onChange={(e) => setBatchType(e.target.value as 'all' | 'codex' | 'claude')}\n >\n <option value=\"all\">All ({agents.length})</option>\n <option value=\"codex\">Codex ({agents.filter(a => a.type === 'codex').length})</option>\n <option value=\"claude\">Claude ({agents.filter(a => a.type === 'claude').length})</option>\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Model:</span>\n <Input\n className=\"h-7 text-xs w-[140px]\"\n value={batchModel}\n onChange={(e) => setBatchModel(e.target.value)}\n placeholder=\"model\"\n />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Effort:</span>\n <select\n className={selectClass}\n value={batchEffort}\n onChange={(e) => setBatchEffort(e.target.value)}\n >\n {batchEffortOptions.map(e => {\n const val = e.startsWith('max') ? 'max' : e;\n return <option key={e} value={val}>{e || '—'}</option>;\n })}\n </select>\n </div>\n {/* Advanced toggle (claude targets only) */}\n {batchType !== 'codex' && (\n <button\n type=\"button\"\n className={cn(\n 'p-1 rounded hover:bg-accent transition-colors',\n batchShowAdvanced && 'text-primary'\n )}\n onClick={() => setBatchShowAdvanced(!batchShowAdvanced)}\n title=\"Claude Advanced Batch Settings\"\n >\n <Settings2 className=\"w-4 h-4\" />\n </button>\n )}\n <Button\n variant=\"default\"\n size=\"sm\"\n className=\"h-7\"\n disabled={batchSaving || (!batchModel && !batchEffort && !hasClaudeBatchFields)}\n onClick={handleBatchApply}\n >\n {batchSaving ? 'Applying...' : `Apply to ${batchType === 'all' ? 'All' : batchType} (${batchTargets.length})`}\n </Button>\n </div>\n\n {/* Row 2: Claude-only advanced batch fields */}\n {batchShowAdvanced && batchType !== 'codex' && (\n <div className=\"pt-2 border-t border-border space-y-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">Claude-only fields {batchType === 'all' && '(applied to claude agents only)'}:</span>\n {/* Quick settings */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Color:</span>\n <select className={selectClass} value={batchColor} onChange={e => setBatchColor(e.target.value)}>\n {COLOR_OPTIONS.map(c => <option key={c} value={c}>{c || '—'}</option>)}\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Permission:</span>\n <select className={selectClass} value={batchPermission} onChange={e => setBatchPermission(e.target.value)}>\n {PERMISSION_MODES.map(p => <option key={p} value={p}>{p || '—'}</option>)}\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Memory:</span>\n <select className={selectClass} value={batchMemory} onChange={e => setBatchMemory(e.target.value)}>\n {MEMORY_OPTIONS.map(m => <option key={m} value={m}>{m || '—'}</option>)}\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>MaxTurns:</span>\n <Input\n className=\"h-7 text-xs w-[60px]\"\n type=\"number\"\n value={batchMaxTurns}\n onChange={e => setBatchMaxTurns(e.target.value)}\n placeholder=\"—\"\n />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Background:</span>\n <select className={selectClass} value={batchBackground} onChange={e => setBatchBackground(e.target.value as '' | 'true' | 'false')}>\n <option value=\"\">—</option>\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className={labelClass}>Isolation:</span>\n <select className={selectClass} value={batchIsolation} onChange={e => setBatchIsolation(e.target.value)}>\n {ISOLATION_OPTIONS.map(i => <option key={i} value={i}>{i || '—'}</option>)}\n </select>\n </div>\n </div>\n {/* Tools row */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-1 flex-1 min-w-[200px]\">\n <span className={labelClass}>Tools:</span>\n <Input\n className=\"h-7 text-xs flex-1\"\n value={batchTools}\n onChange={e => setBatchTools(e.target.value)}\n placeholder=\"Read, Write, Bash, Glob, Grep\"\n />\n </div>\n <div className=\"flex items-center gap-1 flex-1 min-w-[200px]\">\n <span className={labelClass}>Disallowed:</span>\n <Input\n className=\"h-7 text-xs flex-1\"\n value={batchDisallowedTools}\n onChange={e => setBatchDisallowedTools(e.target.value)}\n placeholder=\"e.g. Edit\"\n />\n </div>\n <div className=\"flex items-center gap-1 flex-1 min-w-[200px]\">\n <span className={labelClass}>Skills:</span>\n <Input\n className=\"h-7 text-xs flex-1\"\n value={batchSkills}\n onChange={e => setBatchSkills(e.target.value)}\n placeholder=\"e.g. api-conventions\"\n />\n </div>\n </div>\n </div>\n )}\n </div>\n\n {/* Agent list */}\n {loading ? (\n <div className=\"text-center text-sm text-muted-foreground py-8\">Loading agents...</div>\n ) : agents.length === 0 ? (\n <div className=\"text-center text-sm text-muted-foreground py-8\">\n No agent definitions found. Install CCW to a project first.\n </div>\n ) : (\n <div className=\"space-y-4\">\n {Object.entries(grouped).map(([path, groupAgents]) => (\n <InstallationGroup\n key={path}\n installationPath={path}\n agents={groupAgents}\n onSaved={loadAgents}\n />\n ))}\n </div>\n )}\n </Card>\n );\n}\n\nexport default AgentDefinitionsSection;\n","// ========================================\r\n// Settings Page\r\n// ========================================\r\n// Application settings and configuration with CLI tools management\r\n\r\nimport { useState, useCallback, useEffect, useRef } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Settings,\r\n Moon,\r\n Bell,\r\n Cpu,\r\n RefreshCw,\r\n RotateCcw,\r\n Check,\r\n X,\r\n ChevronDown,\r\n ChevronUp,\r\n Languages,\r\n Plus,\r\n MessageSquareText,\r\n Monitor,\r\n Terminal,\r\n AlertTriangle,\r\n Package,\r\n Home,\r\n Folder,\r\n FolderOpen,\r\n Calendar,\r\n File,\r\n ArrowUpCircle,\r\n Save,\r\n Download,\r\n Upload,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { ThemeSelector } from '@/components/shared/ThemeSelector';\r\nimport { useTheme } from '@/hooks';\r\nimport { toast } from 'sonner';\r\nimport { useConfigStore, selectCliTools, selectDefaultCliTool, selectUserPreferences } from '@/stores/configStore';\r\nimport type { CliToolConfig, UserPreferences } from '@/types/store';\r\nimport { cn } from '@/lib/utils';\r\nimport { LanguageSwitcher } from '@/components/layout/LanguageSwitcher';\r\nimport {\r\n useChineseResponseStatus,\r\n useToggleChineseResponse,\r\n useWindowsPlatformStatus,\r\n useToggleWindowsPlatform,\r\n useCodexCliEnhancementStatus,\r\n useToggleCodexCliEnhancement,\r\n useRefreshCodexCliEnhancement,\r\n useCcwInstallStatus,\r\n useCliToolStatus,\r\n useCcwInstallations,\r\n useUpgradeCcwInstallation,\r\n useExportSettings,\r\n useImportSettings,\r\n} from '@/hooks/useSystemSettings';\r\nimport type { ExportedSettings } from '@/lib/api';\r\nimport { RemoteNotificationSection } from '@/components/settings/RemoteNotificationSection';\r\nimport { A2UIPreferencesSection } from '@/components/settings/A2UIPreferencesSection';\r\nimport { AgentDefinitionsSection } from '@/components/settings/AgentDefinitionsSection';\r\n\r\n// ========== CSRF Token Helper ==========\r\nfunction getCsrfToken(): string | null {\r\n const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);\r\n return match ? decodeURIComponent(match[1]) : null;\r\n}\r\n\r\n// ========== File Path Input with Native File Picker ==========\r\n\r\nimport { useDebounce } from '@/hooks/useDebounce';\r\nimport { Loader2 } from 'lucide-react';\r\n\r\n// ...\r\n\r\ninterface FilePathInputProps {\r\n value: string;\r\n onChange: (value: string) => void;\r\n placeholder: string;\r\n}\r\n\r\nfunction FilePathInput({ value, onChange, placeholder }: FilePathInputProps) {\r\n const [isValidating, setIsValidating] = useState(false);\r\n const [pathError, setPathError] = useState<string | null>(null);\r\n const debouncedValue = useDebounce(value, 500);\r\n\r\n useEffect(() => {\r\n if (debouncedValue) {\r\n setIsValidating(true);\r\n setPathError(null);\r\n // Simulate async validation\r\n const timeoutId = setTimeout(() => {\r\n // Simple validation: check if path is not empty.\r\n // In a real scenario, this would check for path existence.\r\n if (debouncedValue.trim().length > 0) {\r\n setPathError(null);\r\n } else {\r\n setPathError('Path cannot be empty.');\r\n }\r\n setIsValidating(false);\r\n }, 1000);\r\n\r\n return () => clearTimeout(timeoutId);\r\n } else {\r\n setPathError(null);\r\n setIsValidating(false);\r\n }\r\n }, [debouncedValue]);\r\n\r\n const handleBrowse = async () => {\r\n const { selectFile } = await import('@/lib/nativeDialog');\r\n const initialDir = value ? value.replace(/[/\\\\][^/\\\\]*$/, '') : undefined;\r\n const result = await selectFile(initialDir);\r\n if (result.path && !result.cancelled && !result.error) {\r\n onChange(result.path);\r\n }\r\n };\r\n\r\n return (\r\n <div>\r\n <div className=\"flex gap-2 items-center\">\r\n <div className=\"relative flex-1\">\r\n <Input\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={placeholder}\r\n className={cn(\r\n \"flex-1\",\r\n pathError && \"border-destructive\"\r\n )}\r\n />\r\n {isValidating && (\r\n <div className=\"absolute inset-y-0 right-0 flex items-center pr-3\">\r\n <Loader2 className=\"h-4 w-4 animate-spin text-muted-foreground\" />\r\n </div>\r\n )}\r\n </div>\r\n <Button\r\n type=\"button\"\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"shrink-0 h-9\"\r\n onClick={handleBrowse}\r\n title=\"Browse\"\r\n >\r\n <FolderOpen className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n {pathError && (\r\n <p className=\"text-xs text-destructive mt-1\">{pathError}</p>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Tool Config File Helpers ==========\r\n\r\n/** Tools that use .env file for environment variables */\r\nconst ENV_FILE_TOOLS = new Set(['gemini', 'qwen', 'opencode']);\r\n/** Tools that use --settings for Claude CLI settings file */\r\nconst SETTINGS_FILE_TOOLS = new Set(['claude']);\r\nfunction getConfigFileType(toolId: string): 'envFile' | 'settingsFile' | 'none' {\r\n if (ENV_FILE_TOOLS.has(toolId)) return 'envFile';\r\n if (SETTINGS_FILE_TOOLS.has(toolId)) return 'settingsFile';\r\n return 'none';\r\n}\r\n\r\n// ========== CLI Tool Card Component ==========\r\n\r\ninterface CliToolCardProps {\r\n toolId: string;\r\n config: CliToolConfig;\r\n isDefault: boolean;\r\n isExpanded: boolean;\r\n toolAvailable?: boolean;\r\n isSaving?: boolean;\r\n onToggleExpand: () => void;\r\n onToggleEnabled: () => void;\r\n onSetDefault: () => void;\r\n onUpdateModel: (field: 'primaryModel' | 'secondaryModel', value: string) => void;\r\n onUpdateTags: (tags: string[]) => void;\r\n onUpdateAvailableModels: (models: string[]) => void;\r\n onUpdateEnvFile: (envFile: string | undefined) => void;\r\n onUpdateSettingsFile: (settingsFile: string | undefined) => void;\r\n onUpdateEffort: (effort: string | undefined) => void;\r\n onSaveToBackend: () => void;\r\n}\r\n\r\nfunction CliToolCard({\r\n toolId,\r\n config,\r\n isDefault,\r\n isExpanded,\r\n toolAvailable,\r\n isSaving,\r\n onToggleExpand,\r\n onToggleEnabled,\r\n onSetDefault,\r\n onUpdateModel,\r\n onUpdateTags,\r\n onUpdateAvailableModels,\r\n onUpdateEnvFile,\r\n onUpdateSettingsFile,\r\n onUpdateEffort,\r\n onSaveToBackend,\r\n}: CliToolCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // Local state for tag and model input\r\n const [tagInput, setTagInput] = useState('');\r\n const [modelInput, setModelInput] = useState('');\r\n\r\n // Handler for adding tags\r\n const handleAddTag = () => {\r\n const newTag = tagInput.trim();\r\n if (newTag && !config.tags.includes(newTag)) {\r\n onUpdateTags([...config.tags, newTag]);\r\n setTagInput('');\r\n }\r\n };\r\n\r\n // Handler for removing tags\r\n const handleRemoveTag = (tagToRemove: string) => {\r\n onUpdateTags(config.tags.filter((t) => t !== tagToRemove));\r\n };\r\n\r\n // Handler for adding available models\r\n const handleAddModel = () => {\r\n const newModel = modelInput.trim();\r\n const currentModels = config.availableModels || [];\r\n if (newModel && !currentModels.includes(newModel)) {\r\n onUpdateAvailableModels([...currentModels, newModel]);\r\n setModelInput('');\r\n }\r\n };\r\n\r\n // Handler for removing available models\r\n const handleRemoveModel = (modelToRemove: string) => {\r\n const currentModels = config.availableModels || [];\r\n onUpdateAvailableModels(currentModels.filter((m) => m !== modelToRemove));\r\n };\r\n\r\n // Predefined tags\r\n const predefinedTags = ['分析', 'Debug', 'implementation', 'refactoring', 'testing'];\r\n\r\n const configFileType = getConfigFileType(toolId);\r\n\r\n return (\r\n <Card className={cn('overflow-hidden', !config.enabled && 'opacity-60')}>\r\n {/* Header */}\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={onToggleExpand}\r\n >\r\n <div className=\"flex items-center justify-between gap-2\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n config.enabled ? 'bg-primary/10' : 'bg-muted'\r\n )}>\r\n <Cpu className={cn(\r\n 'w-5 h-5',\r\n config.enabled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground capitalize\">\r\n {toolId}\r\n </span>\r\n {isDefault && (\r\n <Badge variant=\"default\" className=\"text-xs\">{formatMessage({ id: 'settings.cliTools.default' })}</Badge>\r\n )}\r\n <Badge variant=\"outline\" className=\"text-xs\">{config.type}</Badge>\r\n {toolAvailable !== undefined && (\r\n <span className={cn(\r\n 'inline-block w-2 h-2 rounded-full',\r\n toolAvailable ? 'bg-green-500' : 'bg-red-400'\r\n )} title={toolAvailable ? 'Available' : 'Unavailable'} />\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n {config.primaryModel}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant={config.enabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-8\"\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n onToggleEnabled();\r\n }}\r\n >\r\n {config.enabled ? (\r\n <>\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.cliTools.enabled' })}\r\n </>\r\n ) : (\r\n <>\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.cliTools.disabled' })}\r\n </>\r\n )}\r\n </Button>\r\n {isExpanded ? (\r\n <ChevronUp className=\"w-5 h-5 text-muted-foreground\" />\r\n ) : (\r\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Tags */}\r\n {config.tags && config.tags.length > 0 && (\r\n <div className=\"flex flex-wrap gap-1 mt-2\">\r\n {config.tags.map((tag) => (\r\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\r\n {tag}\r\n </Badge>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border p-4 space-y-4 bg-muted/30\">\r\n <div className=\"grid gap-4 md:grid-cols-2\">\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">{formatMessage({ id: 'settings.cliTools.primaryModel' })}</label>\r\n <Input\r\n value={config.primaryModel}\r\n onChange={(e) => onUpdateModel('primaryModel', e.target.value)}\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n <div>\r\n <label className=\"text-sm font-medium text-foreground\">{formatMessage({ id: 'settings.cliTools.secondaryModel' })}</label>\r\n <Input\r\n value={config.secondaryModel}\r\n onChange={(e) => onUpdateModel('secondaryModel', e.target.value)}\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Tags Section */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.tags' })}\r\n </label>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.tagsDescription' })}\r\n </p>\r\n <div className=\"flex gap-2\">\r\n <div className=\"flex-1 flex flex-wrap gap-1.5 p-2 border border-input bg-background rounded-md min-h-[38px] focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2\">\r\n {config.tags.map((tag) => (\r\n <span\r\n key={tag}\r\n className=\"inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded text-xs h-6\"\r\n >\r\n {tag}\r\n <button\r\n type=\"button\"\r\n onClick={() => handleRemoveTag(tag)}\r\n className=\"hover:text-destructive transition-colors\"\r\n aria-label={formatMessage({ id: 'apiSettings.cliSettings.removeTag' })}\r\n >\r\n <X className=\"w-3 h-3\" />\r\n </button>\r\n </span>\r\n ))}\r\n <input\r\n type=\"text\"\r\n value={tagInput}\r\n onChange={(e) => setTagInput(e.target.value)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n e.preventDefault();\r\n handleAddTag();\r\n }\r\n }}\r\n placeholder={config.tags.length === 0 ? formatMessage({ id: 'apiSettings.cliSettings.tagInputPlaceholder' }) : ''}\r\n className=\"flex-1 min-w-[120px] bg-transparent border-0 outline-none text-sm placeholder:text-muted-foreground\"\r\n />\r\n </div>\r\n <Button\r\n type=\"button\"\r\n size=\"sm\"\r\n onClick={handleAddTag}\r\n variant=\"outline\"\r\n className=\"shrink-0\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n {/* Predefined Tags */}\r\n <div className=\"flex flex-wrap gap-1\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.predefinedTags' })}:\r\n </span>\r\n {predefinedTags.map((predefinedTag) => (\r\n <button\r\n key={predefinedTag}\r\n type=\"button\"\r\n onClick={() => {\r\n if (!config.tags.includes(predefinedTag)) {\r\n onUpdateTags([...config.tags, predefinedTag]);\r\n }\r\n }}\r\n disabled={config.tags.includes(predefinedTag)}\r\n className=\"text-xs px-2 py-0.5 rounded border border-border hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n {predefinedTag}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Available Models Section */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.availableModels' })}\r\n </label>\r\n <div className=\"flex gap-2\">\r\n <div className=\"flex-1 flex flex-wrap gap-1.5 p-2 border border-input bg-background rounded-md min-h-[38px] focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2\">\r\n {(config.availableModels || []).map((model) => (\r\n <span\r\n key={model}\r\n className=\"inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded text-xs h-6\"\r\n >\r\n {model}\r\n <button\r\n type=\"button\"\r\n onClick={() => handleRemoveModel(model)}\r\n className=\"hover:text-destructive transition-colors\"\r\n >\r\n <X className=\"w-3 h-3\" />\r\n </button>\r\n </span>\r\n ))}\r\n <input\r\n type=\"text\"\r\n value={modelInput}\r\n onChange={(e) => setModelInput(e.target.value)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n e.preventDefault();\r\n handleAddModel();\r\n }\r\n }}\r\n placeholder={(config.availableModels || []).length === 0 ? formatMessage({ id: 'apiSettings.cliSettings.availableModelsPlaceholder' }) : ''}\r\n className=\"flex-1 min-w-[120px] bg-transparent border-0 outline-none text-sm placeholder:text-muted-foreground\"\r\n />\r\n </div>\r\n <Button\r\n type=\"button\"\r\n size=\"sm\"\r\n onClick={handleAddModel}\r\n variant=\"outline\"\r\n className=\"shrink-0\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.availableModelsHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Env File - for gemini/qwen/opencode */}\r\n {configFileType === 'envFile' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.cliTools.envFile' })}\r\n </label>\r\n <FilePathInput\r\n value={config.envFile || ''}\r\n onChange={(v) => onUpdateEnvFile(v || undefined)}\r\n placeholder={formatMessage({ id: 'settings.cliTools.envFilePlaceholder' })}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.cliTools.envFileHint' })}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Settings File - for claude only */}\r\n {configFileType === 'settingsFile' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.settingsFile' })}\r\n </label>\r\n <FilePathInput\r\n value={config.settingsFile || ''}\r\n onChange={(v) => onUpdateSettingsFile(v || undefined)}\r\n placeholder={formatMessage({ id: 'apiSettings.cliSettings.settingsFilePlaceholder' })}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'apiSettings.cliSettings.settingsFileHint' })}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Effort Level - for claude only */}\r\n {configFileType === 'settingsFile' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'settings.cliTools.effort' })}\r\n </label>\r\n <div className=\"flex gap-2\">\r\n {(['low', 'medium', 'high'] as const).map((level) => {\r\n const effectiveEffort = config.effort || 'high';\r\n const labelId = `settings.cliTools.effort${level.charAt(0).toUpperCase() + level.slice(1)}` as const;\r\n return (\r\n <button\r\n key={level}\r\n type=\"button\"\r\n onClick={() => onUpdateEffort(level === 'high' && !config.effort ? undefined : level)}\r\n className={cn(\r\n 'px-3 py-1.5 rounded-md text-sm border transition-colors',\r\n effectiveEffort === level\r\n ? 'bg-primary text-primary-foreground border-primary'\r\n : 'border-border hover:bg-muted'\r\n )}\r\n >\r\n {formatMessage({ id: labelId })}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.cliTools.effortHint' })}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n {!isDefault && config.enabled && (\r\n <Button variant=\"outline\" size=\"sm\" onClick={onSetDefault}>\r\n {formatMessage({ id: 'settings.cliTools.setDefault' })}\r\n </Button>\r\n )}\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={onSaveToBackend}\r\n disabled={isSaving}\r\n >\r\n <Save className=\"w-4 h-4 mr-1\" />\r\n {isSaving\r\n ? formatMessage({ id: 'settings.cliTools.saving' })\r\n : formatMessage({ id: 'settings.cliTools.saveToConfig' })}\r\n </Button>\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Response Language Section ==========\r\n\r\nfunction ResponseLanguageSection() {\r\n const { formatMessage } = useIntl();\r\n const { data: chineseStatus, isLoading: chineseLoading } = useChineseResponseStatus();\r\n const { toggle: toggleChinese, isPending: chineseToggling } = useToggleChineseResponse();\r\n const { data: windowsStatus, isLoading: windowsLoading } = useWindowsPlatformStatus();\r\n const { toggle: toggleWindows, isPending: windowsToggling } = useToggleWindowsPlatform();\r\n const { data: cliEnhStatus, isLoading: cliEnhLoading } = useCodexCliEnhancementStatus();\r\n const { toggle: toggleCliEnh, isPending: cliEnhToggling } = useToggleCodexCliEnhancement();\r\n const { refresh: refreshCliEnh, isPending: refreshing } = useRefreshCodexCliEnhancement();\r\n const { exportSettings: doExport, isPending: exporting } = useExportSettings();\r\n const { importSettings: doImport, isPending: importing } = useImportSettings();\r\n const fileInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const handleExport = useCallback(async () => {\r\n try {\r\n const data = await doExport();\r\n const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement('a');\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\r\n a.href = url;\r\n a.download = `ccw-settings-${timestamp}.json`;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n toast.success(formatMessage({ id: 'settings.responseLanguage.exportSuccess' }));\r\n } catch (error) {\r\n toast.error(formatMessage({ id: 'settings.responseLanguage.exportError' }));\r\n }\r\n }, [doExport, formatMessage]);\r\n\r\n const handleFileImport = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const file = e.target.files?.[0];\r\n if (!file) return;\r\n\r\n // Reset file input so the same file can be re-selected\r\n e.target.value = '';\r\n\r\n // Validate file type\r\n if (!file.name.endsWith('.json') && file.type !== 'application/json') {\r\n toast.error(formatMessage({ id: 'settings.responseLanguage.importInvalidFile' }));\r\n return;\r\n }\r\n\r\n try {\r\n const text = await file.text();\r\n const data = JSON.parse(text) as ExportedSettings;\r\n\r\n // Validate basic structure\r\n if (!data.version || !data.endpoints) {\r\n toast.error(formatMessage({ id: 'settings.responseLanguage.importInvalidStructure' }));\r\n return;\r\n }\r\n\r\n const result = await doImport(data);\r\n\r\n if (result.success) {\r\n toast.success(\r\n formatMessage(\r\n { id: 'settings.responseLanguage.importSuccess' },\r\n { imported: result.imported, skipped: result.skipped }\r\n )\r\n );\r\n } else {\r\n toast.error(formatMessage({ id: 'settings.responseLanguage.importError' }));\r\n }\r\n } catch (error) {\r\n if (error instanceof SyntaxError) {\r\n toast.error(formatMessage({ id: 'settings.responseLanguage.importInvalidJson' }));\r\n } else {\r\n toast.error(formatMessage({ id: 'settings.responseLanguage.importError' }));\r\n }\r\n }\r\n }, [doImport, formatMessage]);\r\n\r\n return (\r\n <Card className=\"p-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <MessageSquareText className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.sections.responseLanguage' })}\r\n </h2>\r\n <div className=\"grid gap-4 md:grid-cols-2\">\r\n {/* Chinese Response - Claude */}\r\n <div className=\"rounded-lg border border-border p-4 space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'settings.responseLanguage.chineseClaude' })}</span>\r\n <Badge variant=\"default\" className=\"text-xs\">Claude</Badge>\r\n </div>\r\n <Button\r\n variant={chineseStatus?.claudeEnabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={chineseLoading || chineseToggling}\r\n onClick={() => toggleChinese(!chineseStatus?.claudeEnabled, 'claude')}\r\n >\r\n {chineseStatus?.claudeEnabled ? (\r\n <>\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.enabled' })}\r\n </>\r\n ) : (\r\n <>\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.disabled' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.responseLanguage.chineseClaudeDesc' })}\r\n </p>\r\n </div>\r\n\r\n {/* Chinese Response - Codex */}\r\n <div className=\"rounded-lg border border-border p-4 space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'settings.responseLanguage.chineseCodex' })}</span>\r\n <Badge variant=\"secondary\" className=\"text-xs\">Codex</Badge>\r\n </div>\r\n <Button\r\n variant={chineseStatus?.codexEnabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={chineseLoading || chineseToggling}\r\n onClick={() => toggleChinese(!chineseStatus?.codexEnabled, 'codex')}\r\n >\r\n {chineseStatus?.codexEnabled ? (\r\n <>\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.enabled' })}\r\n </>\r\n ) : (\r\n <>\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.disabled' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.responseLanguage.chineseCodexDesc' })}\r\n </p>\r\n {chineseStatus?.codexNeedsMigration && (\r\n <p className=\"text-xs text-yellow-500\">\r\n <AlertTriangle className=\"w-3 h-3 inline mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.migrationWarning' })}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Windows Platform */}\r\n <div className=\"rounded-lg border border-border p-4 space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Monitor className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'settings.responseLanguage.windowsPlatform' })}</span>\r\n </div>\r\n <Button\r\n variant={windowsStatus?.enabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={windowsLoading || windowsToggling}\r\n onClick={() => toggleWindows(!windowsStatus?.enabled)}\r\n >\r\n {windowsStatus?.enabled ? (\r\n <>\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.enabled' })}\r\n </>\r\n ) : (\r\n <>\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.disabled' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.responseLanguage.windowsPlatformDesc' })}\r\n </p>\r\n </div>\r\n\r\n {/* CLI Enhancement - Codex */}\r\n <div className=\"rounded-lg border border-border p-4 space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Terminal className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'settings.responseLanguage.cliEnhancement' })}</span>\r\n <Badge variant=\"secondary\" className=\"text-xs\">Codex</Badge>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n {cliEnhStatus?.enabled && (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-7 w-7 p-0\"\r\n disabled={cliEnhLoading || refreshing}\r\n onClick={() => refreshCliEnh()}\r\n title={formatMessage({ id: 'settings.responseLanguage.refreshConfig' })}\r\n >\r\n <RefreshCw className={cn('w-3.5 h-3.5', refreshing && 'animate-spin')} />\r\n </Button>\r\n )}\r\n <Button\r\n variant={cliEnhStatus?.enabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={cliEnhLoading || cliEnhToggling}\r\n onClick={() => toggleCliEnh(!cliEnhStatus?.enabled)}\r\n >\r\n {cliEnhStatus?.enabled ? (\r\n <>\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.enabled' })}\r\n </>\r\n ) : (\r\n <>\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.disabled' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.responseLanguage.cliEnhancementDesc' })}\r\n </p>\r\n {cliEnhStatus?.enabled && (\r\n <p className=\"text-xs text-muted-foreground/70\">\r\n {formatMessage({ id: 'settings.responseLanguage.cliEnhancementHint' })}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Export/Import Actions */}\r\n <div className=\"mt-4 pt-4 border-t border-border\">\r\n <div className=\"flex items-center justify-between\">\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.responseLanguage.exportImportHint' })}\r\n </p>\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n ref={fileInputRef}\r\n type=\"file\"\r\n accept=\".json,application/json\"\r\n onChange={handleFileImport}\r\n className=\"hidden\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={importing}\r\n onClick={() => fileInputRef.current?.click()}\r\n >\r\n {importing ? (\r\n <>\r\n <div className=\"w-3.5 h-3.5 border-2 border-border border-t-accent rounded-full animate-spin mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.importing' })}\r\n </>\r\n ) : (\r\n <>\r\n <Upload className=\"w-3.5 h-3.5 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.import' })}\r\n </>\r\n )}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={exporting}\r\n onClick={handleExport}\r\n >\r\n {exporting ? (\r\n <>\r\n <div className=\"w-3.5 h-3.5 border-2 border-border border-t-accent rounded-full animate-spin mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.exporting' })}\r\n </>\r\n ) : (\r\n <>\r\n <Download className=\"w-3.5 h-3.5 mr-1\" />\r\n {formatMessage({ id: 'settings.responseLanguage.export' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Version Check Section ==========\r\n\r\ninterface VersionData {\r\n currentVersion: string;\r\n latestVersion: string;\r\n hasUpdate: boolean;\r\n packageName: string;\r\n updateCommand: string;\r\n checkedAt: string;\r\n}\r\n\r\nfunction VersionCheckSection() {\r\n const { formatMessage } = useIntl();\r\n const [versionData, setVersionData] = useState<VersionData | null>(null);\r\n const [checking, setChecking] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [lastChecked, setLastChecked] = useState<Date | null>(null);\r\n const [autoCheck, setAutoCheck] = useState(() => {\r\n try {\r\n const saved = localStorage.getItem('ccw.autoUpdate');\r\n return saved === null ? true : JSON.parse(saved);\r\n } catch {\r\n return true;\r\n }\r\n });\r\n\r\n const checkVersion = async (silent = false) => {\r\n if (!silent) setChecking(true);\r\n setError(null);\r\n try {\r\n const response = await fetch('/api/version-check');\r\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\r\n\r\n const data: VersionData = await response.json();\r\n if (!data.currentVersion) throw new Error('Invalid response');\r\n\r\n setVersionData(data);\r\n setLastChecked(new Date());\r\n } catch (err) {\r\n if (!silent) setError(err instanceof Error ? err.message : 'Unknown error');\r\n } finally {\r\n setChecking(false);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n // Initial check\r\n checkVersion(true);\r\n\r\n if (!autoCheck) return;\r\n const interval = setInterval(() => checkVersion(true), 60 * 60 * 1000);\r\n return () => clearInterval(interval);\r\n }, [autoCheck]);\r\n\r\n const toggleAutoCheck = (enabled: boolean) => {\r\n setAutoCheck(enabled);\r\n localStorage.setItem('ccw.autoUpdate', JSON.stringify(enabled));\r\n };\r\n\r\n return (\r\n <Card className=\"p-6\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2\">\r\n <ArrowUpCircle className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.versionCheck.title' })}\r\n </h2>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n disabled={checking}\r\n onClick={() => checkVersion()}\r\n >\r\n <RefreshCw className={cn('w-3.5 h-3.5 mr-1.5', checking && 'animate-spin')} />\r\n {checking\r\n ? formatMessage({ id: 'settings.versionCheck.checking' })\r\n : formatMessage({ id: 'settings.versionCheck.checkNow' })}\r\n </Button>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n {/* Version info */}\r\n <div className=\"rounded-lg border border-border p-4 space-y-3\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.versionCheck.currentVersion' })}\r\n </span>\r\n <Badge variant=\"secondary\" className=\"font-mono text-xs\">\r\n {versionData?.currentVersion ?? '...'}\r\n </Badge>\r\n </div>\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.versionCheck.latestVersion' })}\r\n </span>\r\n <Badge\r\n variant={versionData?.hasUpdate ? 'default' : 'secondary'}\r\n className=\"font-mono text-xs\"\r\n >\r\n {versionData?.latestVersion ?? '...'}\r\n </Badge>\r\n </div>\r\n\r\n {/* Status */}\r\n {versionData && (\r\n <div className=\"flex items-center justify-between pt-2 border-t border-border\">\r\n <span className=\"text-sm font-medium\">\r\n {versionData.hasUpdate\r\n ? formatMessage({ id: 'settings.versionCheck.updateAvailable' })\r\n : formatMessage({ id: 'settings.versionCheck.upToDate' })}\r\n </span>\r\n <span className={cn(\r\n 'inline-block w-2.5 h-2.5 rounded-full',\r\n versionData.hasUpdate ? 'bg-orange-500' : 'bg-green-500'\r\n )} />\r\n </div>\r\n )}\r\n\r\n {error && (\r\n <div className=\"flex items-center gap-2 pt-2 border-t border-border\">\r\n <AlertTriangle className=\"w-4 h-4 text-destructive flex-shrink-0\" />\r\n <span className=\"text-sm text-destructive\">\r\n {formatMessage({ id: 'settings.versionCheck.checkFailed' })}: {error}\r\n </span>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Update action */}\r\n {versionData?.hasUpdate && (\r\n <div className=\"rounded-lg border border-orange-500/30 bg-orange-500/5 p-4 space-y-3\">\r\n <div>\r\n <p className=\"text-sm font-medium text-foreground mb-1\">\r\n {formatMessage({ id: 'settings.versionCheck.updateCommand' })}\r\n </p>\r\n <code className=\"text-xs font-mono bg-muted px-3 py-1.5 rounded block\">\r\n {versionData.updateCommand}\r\n </code>\r\n </div>\r\n <Button variant=\"outline\" size=\"sm\" asChild>\r\n <a\r\n href=\"https://github.com/dyw0830/ccw/releases\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"inline-flex items-center gap-1.5\"\r\n >\r\n {formatMessage({ id: 'settings.versionCheck.viewRelease' })}\r\n </a>\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Auto check toggle + last checked */}\r\n <div className=\"flex items-center justify-between\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"checkbox\"\r\n checked={autoCheck}\r\n onChange={(e) => toggleAutoCheck(e.target.checked)}\r\n className=\"rounded border-input\"\r\n />\r\n <div>\r\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'settings.versionCheck.autoCheck' })}</span>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'settings.versionCheck.autoCheckDesc' })}</p>\r\n </div>\r\n </label>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'settings.versionCheck.lastChecked' })}:{' '}\r\n {lastChecked ? lastChecked.toLocaleTimeString() : formatMessage({ id: 'settings.versionCheck.never' })}\r\n </span>\r\n </div>\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== System Status Section ==========\r\n\r\nfunction SystemStatusSection() {\r\n const { formatMessage } = useIntl();\r\n const { installations, isLoading, refetch } = useCcwInstallations();\r\n const { upgrade, isPending: upgrading } = useUpgradeCcwInstallation();\r\n const { data: ccwInstall } = useCcwInstallStatus();\r\n\r\n return (\r\n <Card className=\"p-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2\">\r\n <Package className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.systemStatus.title' })}\r\n {!isLoading && (\r\n <span className=\"text-sm font-normal text-muted-foreground\">\r\n {installations.length} {formatMessage({ id: 'settings.systemStatus.installations' })}\r\n </span>\r\n )}\r\n </h2>\r\n <div className=\"flex items-center gap-1\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-7 w-7 p-0\"\r\n onClick={() => refetch()}\r\n title={formatMessage({ id: 'settings.systemStatus.refresh' })}\r\n >\r\n <RefreshCw className={cn('w-3.5 h-3.5', isLoading && 'animate-spin')} />\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Installation cards */}\r\n {isLoading ? (\r\n <div className=\"text-sm text-muted-foreground py-4 text-center\">\r\n {formatMessage({ id: 'settings.systemStatus.checking' })}\r\n </div>\r\n ) : installations.length === 0 ? (\r\n <div className=\"text-center py-6 space-y-2\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.systemStatus.noInstallations' })}\r\n </p>\r\n <div className=\"bg-muted/50 rounded-md p-3 inline-block\">\r\n <code className=\"text-xs font-mono\">ccw install</code>\r\n </div>\r\n </div>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {installations.map((inst) => {\r\n const isGlobal = inst.installation_mode === 'Global';\r\n const installDate = new Date(inst.installation_date).toLocaleDateString();\r\n const version = inst.application_version !== 'unknown' ? inst.application_version : inst.installer_version;\r\n\r\n return (\r\n <div\r\n key={inst.manifest_id}\r\n className=\"rounded-lg border border-border p-4 space-y-2\"\r\n >\r\n {/* Mode + Version + Upgrade */}\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className={cn(\r\n 'inline-flex items-center justify-center w-8 h-8 rounded-lg',\r\n isGlobal ? 'bg-primary/10 text-primary' : 'bg-orange-500/10 text-orange-500'\r\n )}>\r\n {isGlobal ? <Home className=\"w-4 h-4\" /> : <Folder className=\"w-4 h-4\" />}\r\n </span>\r\n <span className=\"text-sm font-medium\">\r\n {isGlobal\r\n ? formatMessage({ id: 'settings.systemStatus.global' })\r\n : formatMessage({ id: 'settings.systemStatus.path' })}\r\n </span>\r\n <Badge variant=\"secondary\" className=\"text-xs font-mono\">\r\n v{version}\r\n </Badge>\r\n </div>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-7\"\r\n disabled={upgrading}\r\n onClick={() => upgrade(inst.installation_path)}\r\n >\r\n <ArrowUpCircle className={cn('w-3.5 h-3.5 mr-1', upgrading && 'animate-spin')} />\r\n {upgrading\r\n ? formatMessage({ id: 'settings.systemStatus.upgrading' })\r\n : formatMessage({ id: 'settings.systemStatus.upgrade' })}\r\n </Button>\r\n </div>\r\n\r\n {/* Path */}\r\n <div className=\"text-xs text-muted-foreground bg-muted/50 rounded px-2 py-1 font-mono truncate\" title={inst.installation_path}>\r\n {inst.installation_path}\r\n </div>\r\n\r\n {/* Date + Files */}\r\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\r\n <span className=\"inline-flex items-center gap-1\">\r\n <Calendar className=\"w-3 h-3\" />\r\n {installDate}\r\n </span>\r\n <span className=\"inline-flex items-center gap-1\">\r\n <File className=\"w-3 h-3\" />\r\n {inst.files_count} {formatMessage({ id: 'settings.systemStatus.files' })}\r\n </span>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n\r\n {/* Missing files warning */}\r\n {ccwInstall && !ccwInstall.installed && ccwInstall.missingFiles.length > 0 && (\r\n <div className=\"rounded-lg border border-yellow-500/50 bg-yellow-500/5 p-4 space-y-2\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-yellow-600 dark:text-yellow-500\">\r\n <AlertTriangle className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'settings.systemStatus.incomplete' })} &mdash; {ccwInstall.missingFiles.length} {formatMessage({ id: 'settings.systemStatus.missingFiles' }).toLowerCase()}\r\n </div>\r\n <ul className=\"text-xs text-muted-foreground list-disc list-inside\">\r\n {ccwInstall.missingFiles.slice(0, 4).map((f) => (\r\n <li key={f}>{f}</li>\r\n ))}\r\n {ccwInstall.missingFiles.length > 4 && (\r\n <li>+{ccwInstall.missingFiles.length - 4} more...</li>\r\n )}\r\n </ul>\r\n <div className=\"bg-muted/50 rounded-md p-2\">\r\n <p className=\"text-xs font-medium mb-1\">{formatMessage({ id: 'settings.systemStatus.runToFix' })}:</p>\r\n <code className=\"text-xs font-mono bg-background px-2 py-1 rounded block\">ccw install</code>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== CLI Tools with Status Enhancement ==========\r\n\r\ninterface CliToolsWithStatusProps {\r\n cliTools: Record<string, CliToolConfig>;\r\n defaultCliTool: string;\r\n expandedTools: Set<string>;\r\n savingTools: Set<string>;\r\n onToggleExpand: (toolId: string) => void;\r\n onToggleEnabled: (toolId: string) => void;\r\n onSetDefault: (toolId: string) => void;\r\n onUpdateModel: (toolId: string, field: 'primaryModel' | 'secondaryModel', value: string) => void;\r\n onUpdateTags: (toolId: string, tags: string[]) => void;\r\n onUpdateAvailableModels: (toolId: string, models: string[]) => void;\r\n onUpdateEnvFile: (toolId: string, envFile: string | undefined) => void;\r\n onUpdateSettingsFile: (toolId: string, settingsFile: string | undefined) => void;\r\n onUpdateEffort: (toolId: string, effort: string | undefined) => void;\r\n onSaveToBackend: (toolId: string) => void;\r\n formatMessage: ReturnType<typeof useIntl>['formatMessage'];\r\n}\r\n\r\nfunction CliToolsWithStatus({\r\n cliTools,\r\n defaultCliTool,\r\n expandedTools,\r\n savingTools,\r\n onToggleExpand,\r\n onToggleEnabled,\r\n onSetDefault,\r\n onUpdateModel,\r\n onUpdateTags,\r\n onUpdateAvailableModels,\r\n onUpdateEnvFile,\r\n onUpdateSettingsFile,\r\n onUpdateEffort,\r\n onSaveToBackend,\r\n formatMessage,\r\n}: CliToolsWithStatusProps) {\r\n const { data: toolStatus } = useCliToolStatus();\r\n\r\n return (\r\n <>\r\n <p className=\"text-sm text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'settings.cliTools.description' })} <strong className=\"text-foreground\">{defaultCliTool}</strong>\r\n </p>\r\n <div className=\"space-y-3\">\r\n {Object.entries(cliTools).map(([toolId, config]) => {\r\n const status = toolStatus?.[toolId];\r\n return (\r\n <CliToolCard\r\n key={toolId}\r\n toolId={toolId}\r\n config={config}\r\n isDefault={toolId === defaultCliTool}\r\n isExpanded={expandedTools.has(toolId)}\r\n toolAvailable={status?.available}\r\n isSaving={savingTools.has(toolId)}\r\n onToggleExpand={() => onToggleExpand(toolId)}\r\n onToggleEnabled={() => onToggleEnabled(toolId)}\r\n onSetDefault={() => onSetDefault(toolId)}\r\n onUpdateModel={(field, value) => onUpdateModel(toolId, field, value)}\r\n onUpdateTags={(tags) => onUpdateTags(toolId, tags)}\r\n onUpdateAvailableModels={(models) => onUpdateAvailableModels(toolId, models)}\r\n onUpdateEnvFile={(envFile) => onUpdateEnvFile(toolId, envFile)}\r\n onUpdateSettingsFile={(settingsFile) => onUpdateSettingsFile(toolId, settingsFile)}\r\n onUpdateEffort={(effort) => onUpdateEffort(toolId, effort)}\r\n onSaveToBackend={() => onSaveToBackend(toolId)}\r\n />\r\n );\r\n })}\r\n </div>\r\n </>\r\n );\r\n}\r\n\r\n// ========== Main Page Component ==========\r\n\r\nexport function SettingsPage() {\r\n const { formatMessage } = useIntl();\r\n const { theme, setTheme } = useTheme();\r\n const cliTools = useConfigStore(selectCliTools);\r\n const defaultCliTool = useConfigStore(selectDefaultCliTool);\r\n const userPreferences = useConfigStore(selectUserPreferences);\r\n const { updateCliTool, setDefaultCliTool, setUserPreferences, resetUserPreferences } = useConfigStore();\r\n\r\n const [expandedTools, setExpandedTools] = useState<Set<string>>(new Set());\r\n const [savingTools, setSavingTools] = useState<Set<string>>(new Set());\r\n\r\n const toggleToolExpand = (toolId: string) => {\r\n setExpandedTools((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(toolId)) {\r\n next.delete(toolId);\r\n } else {\r\n next.add(toolId);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const handleToggleToolEnabled = (toolId: string) => {\r\n updateCliTool(toolId, { enabled: !cliTools[toolId].enabled });\r\n };\r\n\r\n const handleSetDefaultTool = (toolId: string) => {\r\n setDefaultCliTool(toolId);\r\n };\r\n\r\n const handleUpdateModel = (toolId: string, field: 'primaryModel' | 'secondaryModel', value: string) => {\r\n updateCliTool(toolId, { [field]: value });\r\n };\r\n\r\n const handleUpdateTags = (toolId: string, tags: string[]) => {\r\n updateCliTool(toolId, { tags });\r\n };\r\n\r\n const handleUpdateAvailableModels = (toolId: string, availableModels: string[]) => {\r\n updateCliTool(toolId, { availableModels });\r\n };\r\n\r\n const handleUpdateEnvFile = (toolId: string, envFile: string | undefined) => {\r\n updateCliTool(toolId, { envFile });\r\n };\r\n\r\n const handleUpdateSettingsFile = (toolId: string, settingsFile: string | undefined) => {\r\n updateCliTool(toolId, { settingsFile });\r\n };\r\n\r\n const handleUpdateEffort = (toolId: string, effort: string | undefined) => {\r\n updateCliTool(toolId, { effort });\r\n };\r\n\r\n // Save tool config to backend (~/.claude/cli-tools.json)\r\n const handleSaveToBackend = useCallback(async (toolId: string) => {\r\n const config = cliTools[toolId];\r\n if (!config) return;\r\n\r\n setSavingTools((prev) => new Set(prev).add(toolId));\r\n try {\r\n const body: Record<string, unknown> = {\r\n enabled: config.enabled,\r\n primaryModel: config.primaryModel,\r\n secondaryModel: config.secondaryModel,\r\n tags: config.tags,\r\n availableModels: config.availableModels,\r\n };\r\n\r\n // Only include the relevant config file field\r\n const configFileType = getConfigFileType(toolId);\r\n if (configFileType === 'envFile') {\r\n body.envFile = config.envFile || null;\r\n } else if (configFileType === 'settingsFile') {\r\n body.settingsFile = config.settingsFile || null;\r\n body.effort = config.effort || null;\r\n }\r\n\r\n const csrfToken = getCsrfToken();\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (csrfToken) {\r\n headers['X-CSRF-Token'] = csrfToken;\r\n }\r\n\r\n const res = await fetch(`/api/cli/config/${toolId}`, {\r\n method: 'PUT',\r\n headers,\r\n body: JSON.stringify(body),\r\n credentials: 'same-origin',\r\n });\r\n\r\n if (!res.ok) {\r\n throw new Error(`HTTP ${res.status}`);\r\n }\r\n\r\n toast.success(formatMessage({ id: 'settings.cliTools.configSaved' }), {\r\n description: toolId,\r\n });\r\n } catch {\r\n toast.error(formatMessage({ id: 'settings.cliTools.configSaveError' }), {\r\n description: toolId,\r\n });\r\n } finally {\r\n setSavingTools((prev) => {\r\n const next = new Set(prev);\r\n next.delete(toolId);\r\n return next;\r\n });\r\n }\r\n }, [cliTools, formatMessage]);\r\n\r\n const handlePreferenceChange = (key: keyof UserPreferences, value: unknown) => {\r\n setUserPreferences({ [key]: value });\r\n };\r\n\r\n return (\r\n <div className=\"max-w-4xl mx-auto space-y-8\">\r\n {/* Page Header */}\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\r\n <Settings className=\"w-6 h-6 text-primary\" />\r\n {formatMessage({ id: 'settings.title' })}\r\n </h1>\r\n <p className=\"text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'settings.description' })}\r\n </p>\r\n </div>\r\n\r\n {/* Appearance Settings */}\r\n <Card className=\"p-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <Moon className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.sections.appearance' })}\r\n </h2>\r\n <div className=\"space-y-6\">\r\n {/* Multi-Theme Selector */}\r\n <div>\r\n <p className=\"font-medium text-foreground mb-1\">\r\n {formatMessage({ id: 'settings.appearance.theme' })}\r\n </p>\r\n <p className=\"text-sm text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'settings.appearance.description' })}\r\n </p>\r\n <ThemeSelector />\r\n </div>\r\n\r\n {/* System Theme Toggle (Backward Compatibility) */}\r\n <div className=\"flex items-center justify-between pt-4 border-t border-border\">\r\n <div>\r\n <p className=\"font-medium text-foreground\">{formatMessage({ id: 'settings.appearance.systemFollow' })}</p>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.appearance.systemFollowDesc' })}\r\n </p>\r\n </div>\r\n <Button\r\n variant={theme === 'system' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setTheme('system')}\r\n >\r\n {formatMessage({ id: 'settings.appearance.themeOptions.system' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Language Settings */}\r\n <Card className=\"p-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <Languages className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.sections.language' })}\r\n </h2>\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-foreground\">{formatMessage({ id: 'settings.language.displayLanguage' })}</p>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.language.chooseLanguage' })}\r\n </p>\r\n </div>\r\n <LanguageSwitcher />\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Response Language Settings */}\r\n <ResponseLanguageSection />\r\n\r\n {/* A2UI Preferences */}\r\n <A2UIPreferencesSection />\r\n\r\n {/* System Status */}\r\n <SystemStatusSection />\r\n\r\n {/* Version Check */}\r\n <VersionCheckSection />\r\n\r\n {/* CLI Tools Configuration */}\r\n <Card className=\"p-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <Cpu className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.sections.cliTools' })}\r\n </h2>\r\n <CliToolsWithStatus\r\n cliTools={cliTools}\r\n defaultCliTool={defaultCliTool}\r\n expandedTools={expandedTools}\r\n savingTools={savingTools}\r\n onToggleExpand={toggleToolExpand}\r\n onToggleEnabled={handleToggleToolEnabled}\r\n onSetDefault={handleSetDefaultTool}\r\n onUpdateModel={handleUpdateModel}\r\n onUpdateTags={handleUpdateTags}\r\n onUpdateAvailableModels={handleUpdateAvailableModels}\r\n onUpdateEnvFile={handleUpdateEnvFile}\r\n onUpdateSettingsFile={handleUpdateSettingsFile}\r\n onUpdateEffort={handleUpdateEffort}\r\n onSaveToBackend={handleSaveToBackend}\r\n formatMessage={formatMessage}\r\n />\r\n </Card>\r\n\r\n {/* Agent Definitions */}\r\n <AgentDefinitionsSection />\r\n\r\n {/* Data Refresh Settings */}\r\n <Card className=\"p-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <RefreshCw className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.dataRefresh.title' })}\r\n </h2>\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-foreground\">{formatMessage({ id: 'settings.dataRefresh.autoRefresh' })}</p>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.dataRefresh.autoRefreshDesc' })}\r\n </p>\r\n </div>\r\n <Button\r\n variant={userPreferences.autoRefresh ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => handlePreferenceChange('autoRefresh', !userPreferences.autoRefresh)}\r\n >\r\n {userPreferences.autoRefresh ? formatMessage({ id: 'settings.dataRefresh.enabled' }) : formatMessage({ id: 'settings.dataRefresh.disabled' })}\r\n </Button>\r\n </div>\r\n\r\n {userPreferences.autoRefresh && (\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-foreground\">{formatMessage({ id: 'settings.dataRefresh.refreshInterval' })}</p>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.dataRefresh.refreshIntervalDesc' })}\r\n </p>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n {[15000, 30000, 60000, 120000].map((interval) => (\r\n <Button\r\n key={interval}\r\n variant={userPreferences.refreshInterval === interval ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => handlePreferenceChange('refreshInterval', interval)}\r\n >\r\n {interval / 1000}s\r\n </Button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </Card>\r\n\r\n {/* Notifications */}\r\n <Card className=\"p-6\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <Bell className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'settings.notifications.title' })}\r\n </h2>\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-foreground\">{formatMessage({ id: 'settings.notifications.enableNotifications' })}</p>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.notifications.enableNotificationsDesc' })}\r\n </p>\r\n </div>\r\n <Button\r\n variant={userPreferences.notificationsEnabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => handlePreferenceChange('notificationsEnabled', !userPreferences.notificationsEnabled)}\r\n >\r\n {userPreferences.notificationsEnabled ? formatMessage({ id: 'settings.dataRefresh.enabled' }) : formatMessage({ id: 'settings.dataRefresh.disabled' })}\r\n </Button>\r\n </div>\r\n\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <p className=\"font-medium text-foreground\">{formatMessage({ id: 'settings.notifications.soundEffects' })}</p>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'settings.notifications.soundEffectsDesc' })}\r\n </p>\r\n </div>\r\n <Button\r\n variant={userPreferences.soundEnabled ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => handlePreferenceChange('soundEnabled', !userPreferences.soundEnabled)}\r\n >\r\n {userPreferences.soundEnabled ? formatMessage({ id: 'settings.notifications.on' }) : formatMessage({ id: 'settings.notifications.off' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Remote Notifications */}\r\n <RemoteNotificationSection />\r\n\r\n {/* Reset Settings */}\r\n <Card className=\"p-6 border-destructive/50\">\r\n <h2 className=\"text-lg font-semibold text-foreground flex items-center gap-2 mb-4\">\r\n <RotateCcw className=\"w-5 h-5\" />\r\n {formatMessage({ id: 'common.actions.reset' })}\r\n </h2>\r\n <p className=\"text-sm text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'settings.reset.description' })}\r\n </p>\r\n <Button\r\n variant=\"destructive\"\r\n onClick={() => {\r\n if (confirm(formatMessage({ id: 'settings.reset.confirm' }))) {\r\n resetUserPreferences();\r\n }\r\n }}\r\n >\r\n <RotateCcw className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'common.actions.resetToDefaults' })}\r\n </Button>\r\n </Card>\r\n </div>\r\n );\r\n}\r\n\r\nexport default SettingsPage;\r\n"],"file":"assets/SettingsPage-BPDbXPSM.js"}