@pennyfarthing/core 11.2.0 → 11.2.1

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 (403) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -1
  3. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
  4. package/packages/core/dist/cli/commands/doctor.js +381 -66
  5. package/packages/core/dist/cli/commands/doctor.js.map +1 -1
  6. package/packages/core/dist/cli/commands/init.js +4 -4
  7. package/packages/core/dist/cli/commands/init.js.map +1 -1
  8. package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
  9. package/packages/core/dist/cli/commands/update.js +4 -5
  10. package/packages/core/dist/cli/commands/update.js.map +1 -1
  11. package/packages/core/dist/cli/utils/constants.d.ts +3 -8
  12. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
  13. package/packages/core/dist/cli/utils/constants.js +3 -4
  14. package/packages/core/dist/cli/utils/constants.js.map +1 -1
  15. package/packages/core/dist/cli/utils/settings.d.ts +11 -0
  16. package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
  17. package/packages/core/dist/cli/utils/settings.js +65 -29
  18. package/packages/core/dist/cli/utils/settings.js.map +1 -1
  19. package/packages/core/dist/cli/utils/symlinks.js +16 -16
  20. package/packages/core/dist/cli/utils/symlinks.js.map +1 -1
  21. package/packages/core/dist/consultation/tandem-metrics.d.ts +91 -0
  22. package/packages/core/dist/consultation/tandem-metrics.d.ts.map +1 -0
  23. package/packages/core/dist/consultation/tandem-metrics.js +131 -0
  24. package/packages/core/dist/consultation/tandem-metrics.js.map +1 -0
  25. package/packages/core/dist/consultation/tandem-metrics.test.d.ts +18 -0
  26. package/packages/core/dist/consultation/tandem-metrics.test.d.ts.map +1 -0
  27. package/packages/core/dist/consultation/tandem-metrics.test.js +457 -0
  28. package/packages/core/dist/consultation/tandem-metrics.test.js.map +1 -0
  29. package/packages/core/dist/public/js/react/react.js +14 -14
  30. package/packages/core/dist/scripts/benchmark-integration.d.ts +182 -0
  31. package/packages/core/dist/scripts/benchmark-integration.d.ts.map +1 -0
  32. package/packages/core/dist/scripts/benchmark-integration.js +691 -0
  33. package/packages/core/dist/scripts/benchmark-integration.js.map +1 -0
  34. package/packages/core/dist/scripts/job-fair-aggregator.d.ts +150 -0
  35. package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +1 -0
  36. package/packages/core/dist/scripts/job-fair-aggregator.js +547 -0
  37. package/packages/core/dist/scripts/job-fair-aggregator.js.map +1 -0
  38. package/packages/core/dist/server/api/agent-load.js +1 -1
  39. package/packages/core/dist/server/api/agent-load.js.map +1 -1
  40. package/packages/core/dist/server/server.d.ts +0 -3
  41. package/packages/core/dist/server/server.d.ts.map +1 -1
  42. package/packages/core/dist/server/server.js +3 -37
  43. package/packages/core/dist/server/server.js.map +1 -1
  44. package/packages/core/dist/server/server.test.d.ts +1 -1
  45. package/packages/core/dist/server/server.test.js +12 -23
  46. package/packages/core/dist/server/server.test.js.map +1 -1
  47. package/packages/core/dist/shared/capabilities.d.ts +88 -0
  48. package/packages/core/dist/shared/capabilities.d.ts.map +1 -0
  49. package/packages/core/dist/shared/capabilities.js +133 -0
  50. package/packages/core/dist/shared/capabilities.js.map +1 -0
  51. package/packages/core/dist/shared/capabilities.test.d.ts +2 -0
  52. package/packages/core/dist/shared/capabilities.test.d.ts.map +1 -0
  53. package/packages/core/dist/shared/capabilities.test.js +217 -0
  54. package/packages/core/dist/shared/capabilities.test.js.map +1 -0
  55. package/packages/core/dist/shared/spawn-prompt.d.ts +47 -0
  56. package/packages/core/dist/shared/spawn-prompt.d.ts.map +1 -0
  57. package/packages/core/dist/shared/spawn-prompt.js +82 -0
  58. package/packages/core/dist/shared/spawn-prompt.js.map +1 -0
  59. package/packages/core/dist/shared/spawn-prompt.test.d.ts +2 -0
  60. package/packages/core/dist/shared/spawn-prompt.test.d.ts.map +1 -0
  61. package/packages/core/dist/shared/spawn-prompt.test.js +251 -0
  62. package/packages/core/dist/shared/spawn-prompt.test.js.map +1 -0
  63. package/packages/core/dist/workflow/tandem-workflow-templates.test.d.ts +18 -0
  64. package/packages/core/dist/workflow/tandem-workflow-templates.test.d.ts.map +1 -0
  65. package/packages/core/dist/workflow/tandem-workflow-templates.test.js +434 -0
  66. package/packages/core/dist/workflow/tandem-workflow-templates.test.js.map +1 -0
  67. package/packages/core/dist/workflow/workflow-schema.d.ts +32 -0
  68. package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
  69. package/packages/core/dist/workflow/workflow-schema.js +120 -0
  70. package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
  71. package/packages/core/dist/workflow/workflow-schema.test.d.ts.map +1 -1
  72. package/packages/core/dist/workflow/workflow-schema.test.js +570 -1
  73. package/packages/core/dist/workflow/workflow-schema.test.js.map +1 -1
  74. package/pennyfarthing-dist/agents/dev.md +6 -10
  75. package/pennyfarthing-dist/agents/reviewer.md +8 -2
  76. package/pennyfarthing-dist/agents/sm-finish.md +18 -1
  77. package/pennyfarthing-dist/commands/pf-git.md +4 -2
  78. package/pennyfarthing-dist/gates/approval.md +63 -0
  79. package/pennyfarthing-dist/gates/confidence-sm.md +71 -0
  80. package/pennyfarthing-dist/gates/context-ok.md +56 -0
  81. package/pennyfarthing-dist/gates/evaluations/confidence-sm.md +54 -0
  82. package/pennyfarthing-dist/gates/quality-pass.md +67 -0
  83. package/pennyfarthing-dist/gates/tests-fail.md +84 -0
  84. package/pennyfarthing-dist/gates/tests-pass.md +79 -0
  85. package/pennyfarthing-dist/guides/agent-behavior.md +23 -19
  86. package/pennyfarthing-dist/guides/bell-mode.md +1 -1
  87. package/pennyfarthing-dist/guides/hooks.md +28 -28
  88. package/pennyfarthing-dist/guides/reflector.md +1 -1
  89. package/pennyfarthing-dist/guides/tandem-protocol.md +3 -3
  90. package/pennyfarthing-dist/scripts/core/check-context.sh +2 -0
  91. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +5 -87
  92. package/pennyfarthing-dist/scripts/hooks/README.md +5 -5
  93. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  94. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +4 -183
  95. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +4 -95
  96. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +4 -65
  97. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +3 -31
  98. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +27 -33
  99. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +4 -71
  100. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +3 -19
  101. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +4 -30
  102. package/pennyfarthing-dist/scripts/hooks/session-start.sh +3 -32
  103. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +4 -65
  104. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +4 -78
  105. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +4 -93
  106. package/pennyfarthing-dist/scripts/misc/README.md +1 -1
  107. package/pennyfarthing-dist/scripts/misc/statusline.sh +4 -301
  108. package/pennyfarthing-dist/templates/settings.local.json.template +19 -10
  109. package/pennyfarthing-dist/workflows/tdd.yaml +11 -2
  110. package/pennyfarthing_scripts/CLAUDE.md +19 -10
  111. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  112. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  113. package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
  114. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  115. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  116. package/pennyfarthing_scripts/__pycache__/context.cpython-314.pyc +0 -0
  117. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  118. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  119. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  120. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  121. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  122. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  123. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  124. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  125. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  126. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  127. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  128. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  129. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  130. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  131. package/pennyfarthing_scripts/bc/__pycache__/__init__.cpython-314.pyc +0 -0
  132. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  133. package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
  134. package/pennyfarthing_scripts/bellmode_hook.py +12 -296
  135. package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
  136. package/pennyfarthing_scripts/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
  137. package/pennyfarthing_scripts/bikerack/__pycache__/audit_log_panel.cpython-314.pyc +0 -0
  138. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  139. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  140. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  141. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  142. package/pennyfarthing_scripts/bikerack/__pycache__/context_meter_footer.cpython-314.pyc +0 -0
  143. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  144. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  145. package/pennyfarthing_scripts/bikerack/__pycache__/events.cpython-314.pyc +0 -0
  146. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  147. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  148. package/pennyfarthing_scripts/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
  149. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  150. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  151. package/pennyfarthing_scripts/bikerack/__pycache__/story_detail_data.cpython-314.pyc +0 -0
  152. package/pennyfarthing_scripts/bikerack/__pycache__/story_detail_screen.cpython-314.pyc +0 -0
  153. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  154. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  155. package/pennyfarthing_scripts/bikerack/audit_log_panel.py +119 -0
  156. package/pennyfarthing_scripts/bikerack/base_panel.py +27 -4
  157. package/pennyfarthing_scripts/bikerack/changed_panel.py +96 -4
  158. package/pennyfarthing_scripts/bikerack/context_meter_footer.py +88 -0
  159. package/pennyfarthing_scripts/bikerack/debug_panel.py +1 -1
  160. package/pennyfarthing_scripts/bikerack/diffs_panel.py +30 -0
  161. package/pennyfarthing_scripts/bikerack/events.py +28 -0
  162. package/pennyfarthing_scripts/bikerack/portrait_resolver.py +139 -0
  163. package/pennyfarthing_scripts/bikerack/sprint_panel.py +373 -142
  164. package/pennyfarthing_scripts/bikerack/story_detail_data.py +244 -0
  165. package/pennyfarthing_scripts/bikerack/story_detail_screen.py +176 -0
  166. package/pennyfarthing_scripts/bikerack/tui.py +293 -61
  167. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  171. package/pennyfarthing_scripts/cli.py +5 -0
  172. package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  173. package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
  174. package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  181. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  182. package/pennyfarthing_scripts/common/pr_config.py +38 -0
  183. package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  184. package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
  185. package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  186. package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
  187. package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
  188. package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
  189. package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  190. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  191. package/pennyfarthing_scripts/consultation/__pycache__/dialogue_manager.cpython-314.pyc +0 -0
  192. package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  193. package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
  194. package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  195. package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  196. package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
  197. package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  198. package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
  200. package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  201. package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
  202. package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
  203. package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
  206. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  209. package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  210. package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  211. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  212. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  213. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  214. package/pennyfarthing_scripts/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
  215. package/pennyfarthing_scripts/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
  216. package/pennyfarthing_scripts/handoff/__pycache__/marker.cpython-314.pyc +0 -0
  217. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  218. package/pennyfarthing_scripts/handoff/cli.py +33 -1
  219. package/pennyfarthing_scripts/handoff/complete_phase.py +28 -0
  220. package/pennyfarthing_scripts/handoff/marker.py +15 -15
  221. package/pennyfarthing_scripts/handoff/phase_check.py +96 -0
  222. package/pennyfarthing_scripts/handoff/resolve_gate.py +13 -1
  223. package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  224. package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  225. package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  226. package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  227. package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  228. package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  229. package/pennyfarthing_scripts/hooks/__init__.py +437 -0
  230. package/pennyfarthing_scripts/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  231. package/pennyfarthing_scripts/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
  232. package/pennyfarthing_scripts/hooks/__pycache__/cli.cpython-314.pyc +0 -0
  233. package/pennyfarthing_scripts/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
  235. package/pennyfarthing_scripts/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
  237. package/pennyfarthing_scripts/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
  238. package/pennyfarthing_scripts/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
  239. package/pennyfarthing_scripts/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
  240. package/pennyfarthing_scripts/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
  241. package/pennyfarthing_scripts/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
  242. package/pennyfarthing_scripts/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
  243. package/pennyfarthing_scripts/hooks/bell_mode.py +215 -0
  244. package/pennyfarthing_scripts/hooks/cli.py +96 -0
  245. package/pennyfarthing_scripts/hooks/context_breaker.py +104 -0
  246. package/pennyfarthing_scripts/hooks/context_warning.py +66 -0
  247. package/pennyfarthing_scripts/hooks/cyclist_pretooluse.py +129 -0
  248. package/pennyfarthing_scripts/hooks/pre_edit_check.py +78 -0
  249. package/pennyfarthing_scripts/hooks/reflector_check.py +271 -0
  250. package/pennyfarthing_scripts/hooks/schema_validation.py +203 -0
  251. package/pennyfarthing_scripts/hooks/session_start.py +296 -0
  252. package/pennyfarthing_scripts/hooks/session_stop.py +111 -0
  253. package/pennyfarthing_scripts/hooks/sprint_yaml_validation.py +97 -0
  254. package/pennyfarthing_scripts/hooks/statusline.py +420 -0
  255. package/pennyfarthing_scripts/hooks.py +27 -432
  256. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  257. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  258. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  259. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  260. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  261. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  262. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  263. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  264. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  265. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  266. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  267. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  268. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  269. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  270. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  271. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  272. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  273. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  274. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  275. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  276. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  277. package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-314.pyc +0 -0
  278. package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-314.pyc +0 -0
  279. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  280. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  281. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  282. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  283. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  284. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  285. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  286. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  287. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  288. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  289. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  290. package/pennyfarthing_scripts/pretooluse_hook.py +3 -185
  291. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  292. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  293. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  294. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  295. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  296. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  297. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  298. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  299. package/pennyfarthing_scripts/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
  300. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  301. package/pennyfarthing_scripts/prime/workflow.py +2 -1
  302. package/pennyfarthing_scripts/schema_validation_hook.py +3 -298
  303. package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
  304. package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
  305. package/pennyfarthing_scripts/session_start_hook.py +4 -186
  306. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  307. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  308. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  309. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  310. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  311. package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  312. package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
  313. package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
  314. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  315. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  316. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  317. package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  318. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  319. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  320. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  321. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  322. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  323. package/pennyfarthing_scripts/sprint/story_update.py +19 -0
  324. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  325. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  326. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  327. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  328. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  329. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  330. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  331. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  332. package/pennyfarthing_scripts/tests/__pycache__/test_108_1_gate_migration.cpython-314-pytest-9.0.2.pyc +0 -0
  333. package/pennyfarthing_scripts/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
  334. package/pennyfarthing_scripts/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
  335. package/pennyfarthing_scripts/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
  336. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  337. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  338. package/pennyfarthing_scripts/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
  339. package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
  340. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  341. package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_evaluation.cpython-314-pytest-9.0.2.pyc +0 -0
  342. package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_gate.cpython-314-pytest-9.0.2.pyc +0 -0
  343. package/pennyfarthing_scripts/tests/__pycache__/test_dialogue_manager.cpython-314-pytest-9.0.2.pyc +0 -0
  344. package/pennyfarthing_scripts/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
  345. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  346. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  347. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  348. package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
  349. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  350. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  351. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  352. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  353. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  354. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
  355. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  356. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  357. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  358. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  359. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  360. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  361. package/pennyfarthing_scripts/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
  362. package/pennyfarthing_scripts/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
  363. package/pennyfarthing_scripts/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
  364. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  365. package/pennyfarthing_scripts/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
  366. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  367. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  368. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  369. package/pennyfarthing_scripts/tests/test_sprint_panel.py +344 -265
  370. package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  371. package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
  372. package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  373. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  374. package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  375. package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
  376. package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
  377. package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
  378. package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
  379. package/pennyfarthing_scripts/validate/adapters/__pycache__/tandem_awareness.cpython-314.pyc +0 -0
  380. package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
  381. package/pennyfarthing_scripts/validate/adapters/workflow.py +19 -0
  382. package/pennyfarthing_scripts/welcome_hook.py +3 -149
  383. package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  384. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  385. package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  386. package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  387. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
  388. package/pennyfarthing_scripts/workflow/cli.py +7 -6
  389. package/pennyfarthing_scripts/workflow/team_lifecycle.py +257 -0
  390. package/packages/core/dist/scripts/theme-detail.test.d.ts +0 -10
  391. package/packages/core/dist/scripts/theme-detail.test.js +0 -199
  392. package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
  393. package/pennyfarthing_scripts/gate/__pycache__/__init__.cpython-314.pyc +0 -0
  394. package/pennyfarthing_scripts/gate/__pycache__/cli.cpython-314.pyc +0 -0
  395. package/pennyfarthing_scripts/gate/__pycache__/validate.cpython-314.pyc +0 -0
  396. package/pennyfarthing_scripts/git/__pycache__/hooks_installer.cpython-314.pyc +0 -0
  397. package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
  398. package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
  399. package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
  400. package/pennyfarthing_scripts/tests/__pycache__/test_108_2_remove_handoff_fallback.cpython-314-pytest-9.0.2.pyc +0 -0
  401. package/pennyfarthing_scripts/tests/__pycache__/test_gate_file_resolution.cpython-314-pytest-9.0.2.pyc +0 -0
  402. package/pennyfarthing_scripts/tests/__pycache__/test_gate_runner.cpython-314-pytest-9.0.2.pyc +0 -0
  403. package/pennyfarthing_scripts/tests/__pycache__/test_resolve_gate_file_field.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -0,0 +1,457 @@
1
+ /**
2
+ * Tests for Story 86-6: Tandem Metrics and Token Tracking
3
+ *
4
+ * RED state tests for consultation token usage, frequency, and outcome metrics.
5
+ * These metrics are tracked separately from leader session tokens and written
6
+ * to the dialogue file summary section.
7
+ *
8
+ * ACs covered:
9
+ * AC1: Consultation tokens logged separately from leader session tokens
10
+ * AC2: Metrics captured: count, total tokens, avg response time, outcome distribution
11
+ * AC3: Metrics written to dialogue file summary section
12
+ * AC4: Session summary includes tandem overhead percentage
13
+ * AC5: Target: consultation overhead < 25% of baseline story token cost
14
+ *
15
+ * Run with: npm test
16
+ */
17
+ import { describe, it } from 'node:test';
18
+ import assert from 'node:assert';
19
+ import { aggregateMetrics, calculateOverheadPercent, isWithinBudget, formatMetricsSummary, parseMetricsFromSummary, } from './tandem-metrics.js';
20
+ // =============================================================================
21
+ // Test Fixtures
22
+ // =============================================================================
23
+ const EXCHANGE_WITH_METRICS = {
24
+ number: 1,
25
+ timestamp: '10:05',
26
+ leader: 'dev',
27
+ partner: 'architect',
28
+ question: 'Should we use a class or functional approach?',
29
+ recommendation: 'Use pure functions',
30
+ confidence: 'high',
31
+ outcome: 'applied',
32
+ outcomeNote: 'Adopted functional approach',
33
+ metrics: {
34
+ inputTokens: 150,
35
+ outputTokens: 85,
36
+ responseTimeMs: 2300,
37
+ },
38
+ };
39
+ const SECOND_EXCHANGE_WITH_METRICS = {
40
+ number: 2,
41
+ timestamp: '10:20',
42
+ leader: 'dev',
43
+ partner: 'architect',
44
+ question: 'Shell wrapper: Node.js or pure bash?',
45
+ recommendation: 'Pure bash for dependency-free scripts',
46
+ confidence: 'medium',
47
+ outcome: 'deferred',
48
+ outcomeNote: 'Revisit after prototype',
49
+ metrics: {
50
+ inputTokens: 200,
51
+ outputTokens: 120,
52
+ responseTimeMs: 3100,
53
+ },
54
+ };
55
+ const THIRD_EXCHANGE_WITH_METRICS = {
56
+ number: 3,
57
+ timestamp: '10:35',
58
+ leader: 'dev',
59
+ partner: 'architect',
60
+ question: 'Error handling: result objects or exceptions?',
61
+ recommendation: 'Result objects per framework convention',
62
+ confidence: 'high',
63
+ outcome: 'applied',
64
+ outcomeNote: 'Used {success, data?, error?} pattern',
65
+ metrics: {
66
+ inputTokens: 180,
67
+ outputTokens: 95,
68
+ responseTimeMs: 1800,
69
+ },
70
+ };
71
+ const EXCHANGE_NO_METRICS = {
72
+ number: 4,
73
+ timestamp: '10:50',
74
+ leader: 'dev',
75
+ partner: 'architect',
76
+ question: 'Legacy exchange without tracking',
77
+ recommendation: 'N/A',
78
+ confidence: 'low',
79
+ };
80
+ const EXCHANGE_REJECTED = {
81
+ number: 5,
82
+ timestamp: '11:00',
83
+ leader: 'dev',
84
+ partner: 'tea',
85
+ question: 'Should we add integration tests here?',
86
+ recommendation: 'Yes, add container-based tests',
87
+ confidence: 'high',
88
+ outcome: 'rejected',
89
+ outcomeNote: 'Unit tests sufficient for this scope',
90
+ metrics: {
91
+ inputTokens: 130,
92
+ outputTokens: 70,
93
+ responseTimeMs: 1500,
94
+ },
95
+ };
96
+ const EXCHANGE_PENDING = {
97
+ number: 6,
98
+ timestamp: '11:10',
99
+ leader: 'dev',
100
+ partner: 'architect',
101
+ question: 'Pending decision',
102
+ recommendation: 'Still thinking',
103
+ confidence: 'low',
104
+ metrics: {
105
+ inputTokens: 100,
106
+ outputTokens: 50,
107
+ responseTimeMs: 900,
108
+ },
109
+ };
110
+ // =============================================================================
111
+ // AC1: Consultation tokens logged separately from leader session tokens
112
+ // =============================================================================
113
+ describe('86-6: Tandem Metrics and Token Tracking', () => {
114
+ describe('AC1: Consultation tokens tracked per exchange', () => {
115
+ it('should track input and output tokens separately per exchange', () => {
116
+ const exchanges = [EXCHANGE_WITH_METRICS];
117
+ const metrics = aggregateMetrics(exchanges);
118
+ assert.strictEqual(metrics.totalInputTokens, 150, 'Must track input tokens from consultation request');
119
+ assert.strictEqual(metrics.totalOutputTokens, 85, 'Must track output tokens from consultation response');
120
+ });
121
+ it('should sum tokens across multiple exchanges', () => {
122
+ const exchanges = [EXCHANGE_WITH_METRICS, SECOND_EXCHANGE_WITH_METRICS];
123
+ const metrics = aggregateMetrics(exchanges);
124
+ assert.strictEqual(metrics.totalInputTokens, 350, 'Must sum input tokens: 150 + 200');
125
+ assert.strictEqual(metrics.totalOutputTokens, 205, 'Must sum output tokens: 85 + 120');
126
+ assert.strictEqual(metrics.totalTokens, 555, 'Must sum total tokens: 350 + 205');
127
+ });
128
+ it('should exclude exchanges without metrics from token totals', () => {
129
+ const exchanges = [EXCHANGE_WITH_METRICS, EXCHANGE_NO_METRICS];
130
+ const metrics = aggregateMetrics(exchanges);
131
+ assert.strictEqual(metrics.totalInputTokens, 150, 'Must only count exchanges with metrics');
132
+ assert.strictEqual(metrics.totalOutputTokens, 85, 'Must only count exchanges with metrics');
133
+ });
134
+ it('should still count exchanges without metrics in consultationCount', () => {
135
+ const exchanges = [EXCHANGE_WITH_METRICS, EXCHANGE_NO_METRICS];
136
+ const metrics = aggregateMetrics(exchanges);
137
+ assert.strictEqual(metrics.consultationCount, 2, 'All exchanges count toward consultation count regardless of metrics');
138
+ });
139
+ it('should handle empty exchange list', () => {
140
+ const metrics = aggregateMetrics([]);
141
+ assert.strictEqual(metrics.consultationCount, 0);
142
+ assert.strictEqual(metrics.totalInputTokens, 0);
143
+ assert.strictEqual(metrics.totalOutputTokens, 0);
144
+ assert.strictEqual(metrics.totalTokens, 0);
145
+ });
146
+ });
147
+ // =============================================================================
148
+ // AC2: Metrics captured: count, total tokens, avg response time, outcome dist
149
+ // =============================================================================
150
+ describe('AC2: Aggregate metrics calculation', () => {
151
+ it('should calculate average response time across exchanges', () => {
152
+ const exchanges = [EXCHANGE_WITH_METRICS, SECOND_EXCHANGE_WITH_METRICS];
153
+ const metrics = aggregateMetrics(exchanges);
154
+ // (2300 + 3100) / 2 = 2700
155
+ assert.strictEqual(metrics.avgResponseTimeMs, 2700, 'Must calculate average response time from exchanges with metrics');
156
+ });
157
+ it('should exclude exchanges without metrics from response time average', () => {
158
+ const exchanges = [EXCHANGE_WITH_METRICS, EXCHANGE_NO_METRICS];
159
+ const metrics = aggregateMetrics(exchanges);
160
+ assert.strictEqual(metrics.avgResponseTimeMs, 2300, 'Average must only consider exchanges with metrics data');
161
+ });
162
+ it('should return 0 avg response time for no metrics', () => {
163
+ const exchanges = [EXCHANGE_NO_METRICS];
164
+ const metrics = aggregateMetrics(exchanges);
165
+ assert.strictEqual(metrics.avgResponseTimeMs, 0, 'No metrics data means 0 average response time');
166
+ });
167
+ it('should calculate outcome distribution', () => {
168
+ const exchanges = [
169
+ EXCHANGE_WITH_METRICS, // applied
170
+ SECOND_EXCHANGE_WITH_METRICS, // deferred
171
+ THIRD_EXCHANGE_WITH_METRICS, // applied
172
+ EXCHANGE_REJECTED, // rejected
173
+ EXCHANGE_PENDING, // pending (no outcome)
174
+ ];
175
+ const metrics = aggregateMetrics(exchanges);
176
+ assert.strictEqual(metrics.outcomeDistribution['applied'], 2, 'Must count applied outcomes');
177
+ assert.strictEqual(metrics.outcomeDistribution['deferred'], 1, 'Must count deferred outcomes');
178
+ assert.strictEqual(metrics.outcomeDistribution['rejected'], 1, 'Must count rejected outcomes');
179
+ assert.strictEqual(metrics.outcomeDistribution['pending'], 1, 'Must count exchanges with no outcome as pending');
180
+ });
181
+ it('should include all outcome types even when count is zero', () => {
182
+ const exchanges = [EXCHANGE_WITH_METRICS]; // only applied
183
+ const metrics = aggregateMetrics(exchanges);
184
+ assert.strictEqual(metrics.outcomeDistribution['applied'], 1);
185
+ assert.strictEqual(metrics.outcomeDistribution['deferred'], 0, 'Must include deferred even when zero');
186
+ assert.strictEqual(metrics.outcomeDistribution['rejected'], 0, 'Must include rejected even when zero');
187
+ assert.strictEqual(metrics.outcomeDistribution['pending'], 0, 'Must include pending even when zero');
188
+ });
189
+ it('should handle all-pending exchanges', () => {
190
+ const exchanges = [EXCHANGE_PENDING, EXCHANGE_NO_METRICS];
191
+ const metrics = aggregateMetrics(exchanges);
192
+ assert.strictEqual(metrics.outcomeDistribution['pending'], 2);
193
+ assert.strictEqual(metrics.outcomeDistribution['applied'], 0);
194
+ });
195
+ it('should calculate metrics across three exchanges correctly', () => {
196
+ const exchanges = [
197
+ EXCHANGE_WITH_METRICS,
198
+ SECOND_EXCHANGE_WITH_METRICS,
199
+ THIRD_EXCHANGE_WITH_METRICS,
200
+ ];
201
+ const metrics = aggregateMetrics(exchanges);
202
+ assert.strictEqual(metrics.consultationCount, 3);
203
+ assert.strictEqual(metrics.totalInputTokens, 530, 'Must sum: 150 + 200 + 180');
204
+ assert.strictEqual(metrics.totalOutputTokens, 300, 'Must sum: 85 + 120 + 95');
205
+ assert.strictEqual(metrics.totalTokens, 830);
206
+ // (2300 + 3100 + 1800) / 3 = 2400
207
+ assert.strictEqual(metrics.avgResponseTimeMs, 2400);
208
+ });
209
+ });
210
+ // =============================================================================
211
+ // AC3: Metrics written to dialogue file summary section
212
+ // =============================================================================
213
+ describe('AC3: Metrics formatted for dialogue summary', () => {
214
+ it('should format consultation token totals', () => {
215
+ const metrics = {
216
+ consultationCount: 3,
217
+ totalInputTokens: 530,
218
+ totalOutputTokens: 300,
219
+ totalTokens: 830,
220
+ avgResponseTimeMs: 2400,
221
+ outcomeDistribution: { applied: 2, deferred: 1, rejected: 0, pending: 0 },
222
+ overheadPercent: null,
223
+ };
224
+ const lines = formatMetricsSummary(metrics);
225
+ const text = lines.join('\n');
226
+ assert.ok(text.includes('830'), 'Must include total token count');
227
+ assert.ok(text.includes('530') || text.includes('input'), 'Must include input token breakdown');
228
+ assert.ok(text.includes('300') || text.includes('output'), 'Must include output token breakdown');
229
+ });
230
+ it('should format average response time', () => {
231
+ const metrics = {
232
+ consultationCount: 2,
233
+ totalInputTokens: 350,
234
+ totalOutputTokens: 205,
235
+ totalTokens: 555,
236
+ avgResponseTimeMs: 2700,
237
+ outcomeDistribution: { applied: 1, deferred: 1, rejected: 0, pending: 0 },
238
+ overheadPercent: null,
239
+ };
240
+ const lines = formatMetricsSummary(metrics);
241
+ const text = lines.join('\n');
242
+ assert.ok(text.includes('2700') || text.includes('2,700'), 'Must include average response time in ms');
243
+ });
244
+ it('should format outcome distribution', () => {
245
+ const metrics = {
246
+ consultationCount: 5,
247
+ totalInputTokens: 760,
248
+ totalOutputTokens: 420,
249
+ totalTokens: 1180,
250
+ avgResponseTimeMs: 1920,
251
+ outcomeDistribution: { applied: 2, deferred: 1, rejected: 1, pending: 1 },
252
+ overheadPercent: 15.0,
253
+ };
254
+ const lines = formatMetricsSummary(metrics);
255
+ const text = lines.join('\n');
256
+ assert.ok(text.includes('applied'), 'Must include applied in distribution');
257
+ assert.ok(text.includes('deferred'), 'Must include deferred in distribution');
258
+ assert.ok(text.includes('rejected'), 'Must include rejected in distribution');
259
+ });
260
+ it('should format overhead percentage when present', () => {
261
+ const metrics = {
262
+ consultationCount: 3,
263
+ totalInputTokens: 530,
264
+ totalOutputTokens: 300,
265
+ totalTokens: 830,
266
+ avgResponseTimeMs: 2400,
267
+ outcomeDistribution: { applied: 2, deferred: 1, rejected: 0, pending: 0 },
268
+ overheadPercent: 12.5,
269
+ };
270
+ const lines = formatMetricsSummary(metrics);
271
+ const text = lines.join('\n');
272
+ assert.ok(text.includes('12.5%') || text.includes('12.5'), 'Must include overhead percentage');
273
+ });
274
+ it('should handle null overhead percentage gracefully', () => {
275
+ const metrics = {
276
+ consultationCount: 1,
277
+ totalInputTokens: 150,
278
+ totalOutputTokens: 85,
279
+ totalTokens: 235,
280
+ avgResponseTimeMs: 2300,
281
+ outcomeDistribution: { applied: 1, deferred: 0, rejected: 0, pending: 0 },
282
+ overheadPercent: null,
283
+ };
284
+ const lines = formatMetricsSummary(metrics);
285
+ const text = lines.join('\n');
286
+ // Should either show "N/A" or omit the overhead line — not crash
287
+ assert.ok(typeof text === 'string', 'Must format without crashing on null overhead');
288
+ assert.ok(!text.includes('null'), 'Must not display literal "null" in summary');
289
+ });
290
+ it('should return an array of markdown bullet lines', () => {
291
+ const metrics = {
292
+ consultationCount: 2,
293
+ totalInputTokens: 350,
294
+ totalOutputTokens: 205,
295
+ totalTokens: 555,
296
+ avgResponseTimeMs: 2700,
297
+ outcomeDistribution: { applied: 1, deferred: 1, rejected: 0, pending: 0 },
298
+ overheadPercent: 10.0,
299
+ };
300
+ const lines = formatMetricsSummary(metrics);
301
+ assert.ok(Array.isArray(lines), 'Must return an array');
302
+ assert.ok(lines.length > 0, 'Must return at least one line');
303
+ for (const line of lines) {
304
+ assert.ok(line.startsWith('- '), `Each line must be a markdown bullet: "${line}"`);
305
+ }
306
+ });
307
+ it('should include consultation count in summary', () => {
308
+ const metrics = {
309
+ consultationCount: 4,
310
+ totalInputTokens: 600,
311
+ totalOutputTokens: 400,
312
+ totalTokens: 1000,
313
+ avgResponseTimeMs: 2000,
314
+ outcomeDistribution: { applied: 2, deferred: 1, rejected: 0, pending: 1 },
315
+ overheadPercent: null,
316
+ };
317
+ const lines = formatMetricsSummary(metrics);
318
+ const text = lines.join('\n');
319
+ assert.ok(text.includes('4'), 'Must include consultation count');
320
+ });
321
+ });
322
+ // =============================================================================
323
+ // AC3 (continued): Parse metrics back from summary
324
+ // =============================================================================
325
+ describe('AC3: Parse metrics from summary', () => {
326
+ it('should round-trip metrics through format and parse', () => {
327
+ const original = {
328
+ consultationCount: 3,
329
+ totalInputTokens: 530,
330
+ totalOutputTokens: 300,
331
+ totalTokens: 830,
332
+ avgResponseTimeMs: 2400,
333
+ outcomeDistribution: { applied: 2, deferred: 1, rejected: 0, pending: 0 },
334
+ overheadPercent: 12.5,
335
+ };
336
+ const formatted = formatMetricsSummary(original);
337
+ const parsed = parseMetricsFromSummary(formatted.join('\n'));
338
+ assert.ok(parsed, 'Must parse formatted metrics');
339
+ assert.strictEqual(parsed.consultationCount, 3);
340
+ assert.strictEqual(parsed.totalTokens, 830);
341
+ assert.strictEqual(parsed.avgResponseTimeMs, 2400);
342
+ });
343
+ it('should return null for summary without metrics', () => {
344
+ const plainSummary = `- **Total exchanges:** 2
345
+ - **Key decisions:** None
346
+ - **Time in tandem:** 15m`;
347
+ const parsed = parseMetricsFromSummary(plainSummary);
348
+ assert.strictEqual(parsed, null, 'Must return null when no metrics fields are present');
349
+ });
350
+ });
351
+ // =============================================================================
352
+ // AC4: Session summary includes tandem overhead percentage
353
+ // =============================================================================
354
+ describe('AC4: Overhead percentage calculation', () => {
355
+ it('should calculate overhead as percentage of baseline', () => {
356
+ // 830 tandem tokens, 10000 baseline = 8.3%
357
+ const result = calculateOverheadPercent(830, 10000);
358
+ assert.strictEqual(result, 8.3, 'Must calculate: (830 / 10000) * 100 = 8.3');
359
+ });
360
+ it('should return null when baseline is zero', () => {
361
+ const result = calculateOverheadPercent(500, 0);
362
+ assert.strictEqual(result, null, 'Must return null for zero baseline (cannot divide by zero)');
363
+ });
364
+ it('should handle zero tandem tokens', () => {
365
+ const result = calculateOverheadPercent(0, 10000);
366
+ assert.strictEqual(result, 0, 'Zero tandem tokens means 0% overhead');
367
+ });
368
+ it('should round to one decimal place', () => {
369
+ // 333 / 10000 = 3.33 → 3.3
370
+ const result = calculateOverheadPercent(333, 10000);
371
+ assert.strictEqual(result, 3.3, 'Must round to one decimal place');
372
+ });
373
+ it('should handle large overhead values', () => {
374
+ // 5000 / 10000 = 50%
375
+ const result = calculateOverheadPercent(5000, 10000);
376
+ assert.strictEqual(result, 50.0, 'Must handle overhead > 25% target');
377
+ });
378
+ it('should handle very small overhead values', () => {
379
+ // 1 / 100000 = 0.001 → 0.0
380
+ const result = calculateOverheadPercent(1, 100000);
381
+ assert.strictEqual(result, 0.0, 'Must handle very small percentages');
382
+ });
383
+ it('should include overhead in aggregated metrics when baseline provided', () => {
384
+ const exchanges = [EXCHANGE_WITH_METRICS, SECOND_EXCHANGE_WITH_METRICS];
385
+ const metrics = aggregateMetrics(exchanges);
386
+ // totalTokens = 555, test with baseline of 5000
387
+ const overhead = calculateOverheadPercent(metrics.totalTokens, 5000);
388
+ assert.strictEqual(overhead, 11.1, 'Must calculate: (555 / 5000) * 100 = 11.1');
389
+ });
390
+ });
391
+ // =============================================================================
392
+ // AC5: Target: consultation overhead < 25% of baseline story token cost
393
+ // =============================================================================
394
+ describe('AC5: Budget threshold validation', () => {
395
+ it('should pass when overhead is below 25% threshold', () => {
396
+ const result = isWithinBudget(12.5);
397
+ assert.strictEqual(result, true, '12.5% is below 25% threshold');
398
+ });
399
+ it('should fail when overhead exceeds 25% threshold', () => {
400
+ const result = isWithinBudget(30.0);
401
+ assert.strictEqual(result, false, '30% exceeds 25% threshold');
402
+ });
403
+ it('should fail when overhead exactly equals 25%', () => {
404
+ const result = isWithinBudget(25.0);
405
+ assert.strictEqual(result, false, '25% is not strictly less than 25% — must be under');
406
+ });
407
+ it('should pass when overhead is zero', () => {
408
+ const result = isWithinBudget(0);
409
+ assert.strictEqual(result, true, '0% overhead is within any threshold');
410
+ });
411
+ it('should pass when overhead is null (no baseline available)', () => {
412
+ const result = isWithinBudget(null);
413
+ assert.strictEqual(result, true, 'Null overhead (no baseline) should not block — pass by default');
414
+ });
415
+ it('should use custom threshold when provided', () => {
416
+ assert.strictEqual(isWithinBudget(15.0, 10), false, '15% exceeds custom 10% threshold');
417
+ assert.strictEqual(isWithinBudget(8.0, 10), true, '8% is within custom 10% threshold');
418
+ });
419
+ it('should default to 25% when no threshold specified', () => {
420
+ assert.strictEqual(isWithinBudget(24.9), true, '24.9% is just under default 25%');
421
+ assert.strictEqual(isWithinBudget(25.1), false, '25.1% is over default 25%');
422
+ });
423
+ });
424
+ // =============================================================================
425
+ // Result format compliance (framework pattern)
426
+ // =============================================================================
427
+ describe('Result format compliance', () => {
428
+ it('should return TandemMetricsSummary with all required fields', () => {
429
+ const exchanges = [EXCHANGE_WITH_METRICS];
430
+ const metrics = aggregateMetrics(exchanges);
431
+ assert.ok('consultationCount' in metrics, 'Must have consultationCount');
432
+ assert.ok('totalInputTokens' in metrics, 'Must have totalInputTokens');
433
+ assert.ok('totalOutputTokens' in metrics, 'Must have totalOutputTokens');
434
+ assert.ok('totalTokens' in metrics, 'Must have totalTokens');
435
+ assert.ok('avgResponseTimeMs' in metrics, 'Must have avgResponseTimeMs');
436
+ assert.ok('outcomeDistribution' in metrics, 'Must have outcomeDistribution');
437
+ assert.ok('overheadPercent' in metrics, 'Must have overheadPercent');
438
+ });
439
+ it('should return formatMetricsSummary as string array', () => {
440
+ const metrics = {
441
+ consultationCount: 1,
442
+ totalInputTokens: 150,
443
+ totalOutputTokens: 85,
444
+ totalTokens: 235,
445
+ avgResponseTimeMs: 2300,
446
+ outcomeDistribution: { applied: 1, deferred: 0, rejected: 0, pending: 0 },
447
+ overheadPercent: 5.0,
448
+ };
449
+ const result = formatMetricsSummary(metrics);
450
+ assert.ok(Array.isArray(result), 'Must return array');
451
+ for (const line of result) {
452
+ assert.strictEqual(typeof line, 'string', 'Each element must be a string');
453
+ }
454
+ });
455
+ });
456
+ });
457
+ //# sourceMappingURL=tandem-metrics.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tandem-metrics.test.js","sourceRoot":"","sources":["../../src/consultation/tandem-metrics.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAQ7B,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,MAAM,qBAAqB,GAAoB;IAC7C,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,+CAA+C;IACzD,cAAc,EAAE,oBAAoB;IACpC,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,6BAA6B;IAC1C,OAAO,EAAE;QACP,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC;AAEF,MAAM,4BAA4B,GAAoB;IACpD,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,sCAAsC;IAChD,cAAc,EAAE,uCAAuC;IACvD,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,UAAU;IACnB,WAAW,EAAE,yBAAyB;IACtC,OAAO,EAAE;QACP,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,GAAG;QACjB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC;AAEF,MAAM,2BAA2B,GAAoB;IACnD,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,+CAA+C;IACzD,cAAc,EAAE,yCAAyC;IACzD,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,uCAAuC;IACpD,OAAO,EAAE;QACP,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC;AAEF,MAAM,mBAAmB,GAAoB;IAC3C,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,kCAAkC;IAC5C,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,MAAM,iBAAiB,GAAoB;IACzC,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,uCAAuC;IACjD,cAAc,EAAE,gCAAgC;IAChD,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,UAAU;IACnB,WAAW,EAAE,sCAAsC;IACnD,OAAO,EAAE;QACP,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC;AAEF,MAAM,gBAAgB,GAAoB;IACxC,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,kBAAkB;IAC5B,cAAc,EAAE,gBAAgB;IAChC,UAAU,EAAE,KAAK;IACjB,OAAO,EAAE;QACP,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,GAAG;KACpB;CACF,CAAC;AAEF,gFAAgF;AAChF,wEAAwE;AACxE,gFAAgF;AAEhF,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IAEvD,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;QAE7D,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;YACtE,MAAM,SAAS,GAAG,CAAC,qBAAqB,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAC9C,mDAAmD,CAAC,CAAC;YACvD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,EAC9C,qDAAqD,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,SAAS,GAAG,CAAC,qBAAqB,EAAE,4BAA4B,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAC9C,kCAAkC,CAAC,CAAC;YACtC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,EAC/C,kCAAkC,CAAC,CAAC;YACtC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EACzC,kCAAkC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,SAAS,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAC9C,wCAAwC,CAAC,CAAC;YAC5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,EAC9C,wCAAwC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;YAC3E,MAAM,SAAS,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,EAC7C,qEAAqE,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,OAAO,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAErC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,8EAA8E;IAC9E,gFAAgF;IAEhF,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAElD,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,SAAS,GAAG,CAAC,qBAAqB,EAAE,4BAA4B,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,2BAA2B;YAC3B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,EAChD,kEAAkE,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,SAAS,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,EAChD,wDAAwD,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,SAAS,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,EAC7C,+CAA+C,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,SAAS,GAAG;gBAChB,qBAAqB,EAAS,UAAU;gBACxC,4BAA4B,EAAE,WAAW;gBACzC,2BAA2B,EAAG,UAAU;gBACxC,iBAAiB,EAAa,WAAW;gBACzC,gBAAgB,EAAc,uBAAuB;aACtD,CAAC;YACF,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,EAC1D,6BAA6B,CAAC,CAAC;YACjC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,EAC3D,8BAA8B,CAAC,CAAC;YAClC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,EAC3D,8BAA8B,CAAC,CAAC;YAClC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,EAC1D,iDAAiD,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,SAAS,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe;YAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9D,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,EAC3D,sCAAsC,CAAC,CAAC;YAC1C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,EAC3D,sCAAsC,CAAC,CAAC;YAC1C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,EAC1D,qCAAqC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,SAAS,GAAG,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9D,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,SAAS,GAAG;gBAChB,qBAAqB;gBACrB,4BAA4B;gBAC5B,2BAA2B;aAC5B,CAAC;YACF,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAC9C,2BAA2B,CAAC,CAAC;YAC/B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,EAC/C,yBAAyB,CAAC,CAAC;YAC7B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YAC7C,kCAAkC;YAClC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,wDAAwD;IACxD,gFAAgF;IAEhF,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;QAE3D,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC5B,gCAAgC,CAAC,CAAC;YACpC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EACtD,oCAAoC,CAAC,CAAC;YACxC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACvD,qCAAqC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EACvD,0CAA0C,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,IAAI;gBACjB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAChC,sCAAsC,CAAC,CAAC;YAC1C,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EACjC,uCAAuC,CAAC,CAAC;YAC3C,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EACjC,uCAAuC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EACvD,kCAAkC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,EAAE;gBACrB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,iEAAiE;YACjE,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,EAChC,+CAA+C,CAAC,CAAC;YACnD,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC9B,4CAA4C,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAE5C,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAC;YACxD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,+BAA+B,CAAC,CAAC;YAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAC7B,yCAAyC,IAAI,GAAG,CAAC,CAAC;YACtD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,IAAI;gBACjB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC1B,iCAAiC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,mDAAmD;IACnD,gFAAgF;IAEhF,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAE/C,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,QAAQ,GAAyB;gBACrC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,GAAG;gBACtB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,IAAI;aACtB,CAAC;YAEF,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAE7D,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAC;YAClD,MAAM,CAAC,WAAW,CAAC,MAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,WAAW,CAAC,MAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YAC7C,MAAM,CAAC,WAAW,CAAC,MAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,YAAY,GAAG;;0BAED,CAAC;YAErB,MAAM,MAAM,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAC;YAErD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAC7B,qDAAqD,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,2DAA2D;IAC3D,gFAAgF;IAEhF,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAEpD,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,2CAA2C;YAC3C,MAAM,MAAM,GAAG,wBAAwB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAEpD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAC5B,2CAA2C,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,MAAM,GAAG,wBAAwB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAEhD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAC7B,4DAA4D,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,MAAM,GAAG,wBAAwB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAElD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAC1B,sCAAsC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,2BAA2B;YAC3B,MAAM,MAAM,GAAG,wBAAwB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAEpD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAC5B,iCAAiC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,qBAAqB;YACrB,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAErD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAC7B,mCAAmC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,2BAA2B;YAC3B,MAAM,MAAM,GAAG,wBAAwB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAEnD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAC5B,oCAAoC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,MAAM,SAAS,GAAG,CAAC,qBAAqB,EAAE,4BAA4B,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,gDAAgD;YAChD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YAErE,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,EAC/B,2CAA2C,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,wEAAwE;IACxE,gFAAgF;IAEhF,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAEhD,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAC7B,8BAA8B,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAC9B,2BAA2B,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAC9B,mDAAmD,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAC7B,qCAAqC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAC7B,gEAAgE,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,EAChD,kCAAkC,CAAC,CAAC;YACtC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,EAC9C,mCAAmC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAC3C,iCAAiC,CAAC,CAAC;YACrC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAC5C,2BAA2B,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,+CAA+C;IAC/C,gFAAgF;IAEhF,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAExC,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;YACrE,MAAM,SAAS,GAAG,CAAC,qBAAqB,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAE5C,MAAM,CAAC,EAAE,CAAC,mBAAmB,IAAI,OAAO,EAAE,6BAA6B,CAAC,CAAC;YACzE,MAAM,CAAC,EAAE,CAAC,kBAAkB,IAAI,OAAO,EAAE,4BAA4B,CAAC,CAAC;YACvE,MAAM,CAAC,EAAE,CAAC,mBAAmB,IAAI,OAAO,EAAE,6BAA6B,CAAC,CAAC;YACzE,MAAM,CAAC,EAAE,CAAC,aAAa,IAAI,OAAO,EAAE,uBAAuB,CAAC,CAAC;YAC7D,MAAM,CAAC,EAAE,CAAC,mBAAmB,IAAI,OAAO,EAAE,6BAA6B,CAAC,CAAC;YACzE,MAAM,CAAC,EAAE,CAAC,qBAAqB,IAAI,OAAO,EAAE,+BAA+B,CAAC,CAAC;YAC7E,MAAM,CAAC,EAAE,CAAC,iBAAiB,IAAI,OAAO,EAAE,2BAA2B,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,OAAO,GAAyB;gBACpC,iBAAiB,EAAE,CAAC;gBACpB,gBAAgB,EAAE,GAAG;gBACrB,iBAAiB,EAAE,EAAE;gBACrB,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;gBACzE,eAAe,EAAE,GAAG;aACrB,CAAC;YAEF,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC;YACtD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;gBAC1B,MAAM,CAAC,WAAW,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}