@knpkv/control-center 0.7.0 → 0.8.0

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 (162) hide show
  1. package/dist/client/.vite/manifest.json +312 -255
  2. package/dist/client/assets/ActiveWorkPage-C6lIQfjL.js +2 -0
  3. package/dist/client/assets/{ActiveWorkPage-BsaIr8ah.js.map → ActiveWorkPage-C6lIQfjL.js.map} +1 -1
  4. package/dist/client/assets/AgentPage-DqB5BilE.js +6 -0
  5. package/dist/client/assets/{AgentPage-Cybynsnc.js.map → AgentPage-DqB5BilE.js.map} +1 -1
  6. package/dist/client/assets/{AtlassianOAuthCallbackPage-Du3pHuS9.js → AtlassianOAuthCallbackPage-DzTO6SqN.js} +2 -2
  7. package/dist/client/assets/{AtlassianOAuthCallbackPage-Du3pHuS9.js.map → AtlassianOAuthCallbackPage-DzTO6SqN.js.map} +1 -1
  8. package/dist/client/assets/AuthorizedSharePage-V_E5giT7.js +2 -0
  9. package/dist/client/assets/{AuthorizedSharePage-tfTdXNjt.js.map → AuthorizedSharePage-V_E5giT7.js.map} +1 -1
  10. package/dist/client/assets/BrowserCrypto-CoBR2WBd.js +2 -0
  11. package/dist/client/assets/{BrowserCrypto-DVxU0-Oc.js.map → BrowserCrypto-CoBR2WBd.js.map} +1 -1
  12. package/dist/client/assets/BrowserSessionHydrator-CEypgMkR.js +2 -0
  13. package/dist/client/assets/{BrowserSessionHydrator-CvtvZstV.js.map → BrowserSessionHydrator-CEypgMkR.js.map} +1 -1
  14. package/dist/client/assets/CommandSearch-syQMt_rx.js +2 -0
  15. package/dist/client/assets/{CommandSearch-Bf_oW_kD.js.map → CommandSearch-syQMt_rx.js.map} +1 -1
  16. package/dist/client/assets/Dialog-DSwimdwG-BeHnBpPp.js +42 -0
  17. package/dist/client/assets/Dialog-DSwimdwG-BeHnBpPp.js.map +1 -0
  18. package/dist/client/assets/Domain-cJ5aJFpE.js +2 -0
  19. package/dist/client/assets/Domain-cJ5aJFpE.js.map +1 -0
  20. package/dist/client/assets/ItemsPage-Cr3--iJc.js +2 -0
  21. package/dist/client/assets/{ItemsPage-BmWEHinz.js.map → ItemsPage-Cr3--iJc.js.map} +1 -1
  22. package/dist/client/assets/OpenPullRequestPage-BYoRmtui.js +2 -0
  23. package/dist/client/assets/OpenPullRequestPage-BYoRmtui.js.map +1 -0
  24. package/dist/client/assets/{Pages-BmZj4KzS.js → Pages-DrDuXLFH.js} +2 -2
  25. package/dist/client/assets/{Pages-BmZj4KzS.js.map → Pages-DrDuXLFH.js.map} +1 -1
  26. package/dist/client/assets/PairPage-ByOBKuBB.js +2 -0
  27. package/dist/client/assets/{PairPage-CLLUweYZ.js.map → PairPage-ByOBKuBB.js.map} +1 -1
  28. package/dist/client/assets/PortalProvider-CN_81Fy3-D_japesx.js +2 -0
  29. package/dist/client/assets/{PortalProvider-BpgZwSpw-nEH0TqWT.js.map → PortalProvider-CN_81Fy3-D_japesx.js.map} +1 -1
  30. package/dist/client/assets/PortfolioOverview-BacOXO-c.js +2 -0
  31. package/dist/client/assets/{PortfolioOverview-BBKSc-yI.js.map → PortfolioOverview-BacOXO-c.js.map} +1 -1
  32. package/dist/client/assets/{PullRequestReviewPanel-Boi0A6pq.js → PullRequestReviewPanel-DwVYuZ8Q.js} +5 -5
  33. package/dist/client/assets/{PullRequestReviewPanel-Boi0A6pq.js.map → PullRequestReviewPanel-DwVYuZ8Q.js.map} +1 -1
  34. package/dist/client/assets/ReleaseRoute-C-MfQKnL.js +2 -0
  35. package/dist/client/assets/{ReleaseRoute-D4CttCjC.js.map → ReleaseRoute-C-MfQKnL.js.map} +1 -1
  36. package/dist/client/assets/ReleaseWorkset-MV3I0HCi.js +2 -0
  37. package/dist/client/assets/{ReleaseWorkset-Dt-ArwsN.js.map → ReleaseWorkset-MV3I0HCi.js.map} +1 -1
  38. package/dist/client/assets/ReviewSuggestionPublicationSurface-BZIa-Vvc.js +2 -0
  39. package/dist/client/assets/{ReviewSuggestionPublicationSurface-N9Qwdh2n.js.map → ReviewSuggestionPublicationSurface-BZIa-Vvc.js.map} +1 -1
  40. package/dist/client/assets/ServicesPage-BjeCOlsh.js +2 -0
  41. package/dist/client/assets/{ServicesPage-D0ygZTFD.js.map → ServicesPage-BjeCOlsh.js.map} +1 -1
  42. package/dist/client/assets/TimelinePage-Ccnp6Mmg.js +2 -0
  43. package/dist/client/assets/{TimelinePage-Bb2o9DGU.js.map → TimelinePage-Ccnp6Mmg.js.map} +1 -1
  44. package/dist/client/assets/{WorkspaceEntityLink-Cw675wTN.js → WorkspaceEntityLink-D3TXDcD0.js} +2 -2
  45. package/dist/client/assets/{WorkspaceEntityLink-Cw675wTN.js.map → WorkspaceEntityLink-D3TXDcD0.js.map} +1 -1
  46. package/dist/client/assets/WorkspaceEntityRoute-uUK6vwM_.js +14 -0
  47. package/dist/client/assets/WorkspaceEntityRoute-uUK6vwM_.js.map +1 -0
  48. package/dist/client/assets/WorkspaceHomeLink-D5SdEgJJ.js +2 -0
  49. package/dist/client/assets/{WorkspaceHomeLink-FGslxXCu.js.map → WorkspaceHomeLink-D5SdEgJJ.js.map} +1 -1
  50. package/dist/client/assets/WorkspacePullRequestDetails-CKedGIT8.js +3 -0
  51. package/dist/client/assets/{WorkspacePullRequestDetails-Dxg8argO.js.map → WorkspacePullRequestDetails-CKedGIT8.js.map} +1 -1
  52. package/dist/client/assets/{WorkspaceReleaseLayout-BvEiZJEb.js → WorkspaceReleaseLayout-Bdvl0q99.js} +2 -2
  53. package/dist/client/assets/{WorkspaceReleaseLayout-BvEiZJEb.js.map → WorkspaceReleaseLayout-Bdvl0q99.js.map} +1 -1
  54. package/dist/client/assets/{WorkspaceRichText-CocmKQ4T.js → WorkspaceRichText-Beh64wsV.js} +2 -2
  55. package/dist/client/assets/{WorkspaceRichText-CocmKQ4T.js.map → WorkspaceRichText-Beh64wsV.js.map} +1 -1
  56. package/dist/client/assets/WorkspaceSettingsPage-BxFq65Vf.js +2 -0
  57. package/dist/client/assets/{WorkspaceSettingsPage-iZhUs-pg.js.map → WorkspaceSettingsPage-BxFq65Vf.js.map} +1 -1
  58. package/dist/client/assets/{agent-api-CzdQFCcD.js → agent-api-CUWP1qs8.js} +2 -2
  59. package/dist/client/assets/{agent-api-CzdQFCcD.js.map → agent-api-CUWP1qs8.js.map} +1 -1
  60. package/dist/client/assets/{atlassianOAuthSetupIntentStorage-BxsxmjSm.js → atlassianOAuthSetupIntentStorage-Cy1Gw639.js} +2 -2
  61. package/dist/client/assets/{atlassianOAuthSetupIntentStorage-BxsxmjSm.js.map → atlassianOAuthSetupIntentStorage-Cy1Gw639.js.map} +1 -1
  62. package/dist/client/assets/authenticatedMutationClient-Bc_-Jpbo.js +2 -0
  63. package/dist/client/assets/{authenticatedMutationClient-DUqEcJHu.js.map → authenticatedMutationClient-Bc_-Jpbo.js.map} +1 -1
  64. package/dist/client/assets/authorizedShareTransport-kkT3Jf6q.js +2 -0
  65. package/dist/client/assets/{authorizedShareTransport-7YCNH9l3.js.map → authorizedShareTransport-kkT3Jf6q.js.map} +1 -1
  66. package/dist/client/assets/client-D3WRV6yl.js +5 -0
  67. package/dist/client/assets/client-D3WRV6yl.js.map +1 -0
  68. package/dist/client/assets/{confluenceTasks-D9yrB-oV.js → confluenceTasks-By7BV0WN.js} +2 -2
  69. package/dist/client/assets/{confluenceTasks-D9yrB-oV.js.map → confluenceTasks-By7BV0WN.js.map} +1 -1
  70. package/dist/client/assets/connectionTestTransport-CRq7l9X0.js +2 -0
  71. package/dist/client/assets/{connectionTestTransport-D8tiZ4ym.js.map → connectionTestTransport-CRq7l9X0.js.map} +1 -1
  72. package/dist/client/assets/controlCenterRelayDock-D7375HPG.js +3 -0
  73. package/dist/client/assets/controlCenterRelayDock-D7375HPG.js.map +1 -0
  74. package/dist/client/assets/controlCenterRelayDockChrome-B7jSUI3t.js +3 -0
  75. package/dist/client/assets/controlCenterRelayDockChrome-B7jSUI3t.js.map +1 -0
  76. package/dist/client/assets/index-BVikncBH.js +11 -0
  77. package/dist/client/assets/index-BVikncBH.js.map +1 -0
  78. package/dist/client/assets/index-tjRpNCt_.css +1 -0
  79. package/dist/client/assets/openPullRequest-BMlmibLP.js +2 -0
  80. package/dist/client/assets/openPullRequest-BMlmibLP.js.map +1 -0
  81. package/dist/client/assets/patterns-DAeEdyxU.js +2 -0
  82. package/dist/client/assets/patterns-DAeEdyxU.js.map +1 -0
  83. package/dist/client/assets/{presentPortfolio-c8-wbodG.js → presentPortfolio-DVP-zqTg.js} +2 -2
  84. package/dist/client/assets/{presentPortfolio-c8-wbodG.js.map → presentPortfolio-DVP-zqTg.js.map} +1 -1
  85. package/dist/client/assets/{presentWorkspaceItems-DfhyQeSY.js → presentWorkspaceItems-BY8bmqjF.js} +2 -2
  86. package/dist/client/assets/{presentWorkspaceItems-DfhyQeSY.js.map → presentWorkspaceItems-BY8bmqjF.js.map} +1 -1
  87. package/dist/client/assets/primitives-DYGtIZqB-r-Glkv2i.js +2 -0
  88. package/dist/client/assets/primitives-DYGtIZqB-r-Glkv2i.js.map +1 -0
  89. package/dist/client/assets/pullRequestReviewFailures-CCNxSXP6.js +2 -0
  90. package/dist/client/assets/{pullRequestReviewFailures-QvtS729d.js.map → pullRequestReviewFailures-CCNxSXP6.js.map} +1 -1
  91. package/dist/client/assets/pullRequestReviewThreadReplay-eI3Y4i6s.js +2 -0
  92. package/dist/client/assets/{pullRequestReviewThreadReplay-CpPdYxQE.js.map → pullRequestReviewThreadReplay-eI3Y4i6s.js.map} +1 -1
  93. package/dist/client/assets/{releaseAgentTransport-BCQDYqZt.js → releaseAgentTransport-CJjWwE8y.js} +2 -2
  94. package/dist/client/assets/{releaseAgentTransport-BCQDYqZt.js.map → releaseAgentTransport-CJjWwE8y.js.map} +1 -1
  95. package/dist/client/assets/releaseRoutes-h4FVwFvJ.js +2 -0
  96. package/dist/client/assets/{releaseRoutes-CSP_eBj6.js.map → releaseRoutes-h4FVwFvJ.js.map} +1 -1
  97. package/dist/client/assets/{serviceOnboarding-B6v5VXTG.js → serviceOnboarding-F9Lj6a7y.js} +2 -2
  98. package/dist/client/assets/{serviceOnboarding-B6v5VXTG.js.map → serviceOnboarding-F9Lj6a7y.js.map} +1 -1
  99. package/dist/client/assets/useWorkspaceDefaultLanding-DMWfrZfF.js +3 -0
  100. package/dist/client/assets/{useWorkspaceDefaultLanding-C3PRrLgk.js.map → useWorkspaceDefaultLanding-DMWfrZfF.js.map} +1 -1
  101. package/dist/client/assets/useWorkspaceItems-6KWfmFtx.js +2 -0
  102. package/dist/client/assets/{useWorkspaceItems-CHYpfLmL.js.map → useWorkspaceItems-6KWfmFtx.js.map} +1 -1
  103. package/dist/client/assets/{workspaceEntityRoutes-CFPO-iFw.js → workspaceEntityRoutes-BJ-SC0Jd.js} +2 -2
  104. package/dist/client/assets/{workspaceEntityRoutes-CFPO-iFw.js.map → workspaceEntityRoutes-BJ-SC0Jd.js.map} +1 -1
  105. package/dist/client/assets/{workspaceScrollCapture-DUj-_YMd.js → workspaceScrollCapture-CwBIBHg8.js} +2 -2
  106. package/dist/client/assets/{workspaceScrollCapture-DUj-_YMd.js.map → workspaceScrollCapture-CwBIBHg8.js.map} +1 -1
  107. package/dist/client/assets/workspaceSettingsTransport-BwRQteEH.js +2 -0
  108. package/dist/client/assets/{workspaceSettingsTransport-Kq7lfPsC.js.map → workspaceSettingsTransport-BwRQteEH.js.map} +1 -1
  109. package/dist/client/build-graph.json +63 -0
  110. package/dist/client/index.html +3 -3
  111. package/dist/server/api/index.js +1 -1
  112. package/dist/server/assets/{BindConfig-hNWrGfu2.js → BindConfig-D8aIjI_R.js} +2 -2
  113. package/dist/server/assets/{BindConfig-hNWrGfu2.js.map → BindConfig-D8aIjI_R.js.map} +1 -1
  114. package/dist/server/assets/{controlCenterApi-BcVWTP9F.js → controlCenterApi-WaKi6EUb.js} +2 -1
  115. package/dist/server/assets/controlCenterApi-WaKi6EUb.js.map +1 -0
  116. package/dist/server/index.js +1 -1
  117. package/dist/server/server/cli.js +1 -1
  118. package/dist/server/server/index.js +1 -1
  119. package/package.json +7 -6
  120. package/dist/client/assets/ActiveWorkPage-BsaIr8ah.js +0 -2
  121. package/dist/client/assets/AgentPage-Cybynsnc.js +0 -6
  122. package/dist/client/assets/AuthorizedSharePage-tfTdXNjt.js +0 -2
  123. package/dist/client/assets/BrowserCrypto-DVxU0-Oc.js +0 -2
  124. package/dist/client/assets/BrowserSessionHydrator-CvtvZstV.js +0 -2
  125. package/dist/client/assets/CommandSearch-Bf_oW_kD.js +0 -2
  126. package/dist/client/assets/Dialog-1WvU8GjA-C7r26HF0.js +0 -42
  127. package/dist/client/assets/Dialog-1WvU8GjA-C7r26HF0.js.map +0 -1
  128. package/dist/client/assets/ItemsPage-BmWEHinz.js +0 -2
  129. package/dist/client/assets/OpenPullRequestPage-DkCom6mf.js +0 -2
  130. package/dist/client/assets/OpenPullRequestPage-DkCom6mf.js.map +0 -1
  131. package/dist/client/assets/PairPage-CLLUweYZ.js +0 -2
  132. package/dist/client/assets/PortalProvider-BpgZwSpw-nEH0TqWT.js +0 -2
  133. package/dist/client/assets/PortfolioOverview-BBKSc-yI.js +0 -2
  134. package/dist/client/assets/ReleaseRoute-D4CttCjC.js +0 -2
  135. package/dist/client/assets/ReleaseWorkset-Dt-ArwsN.js +0 -2
  136. package/dist/client/assets/ReviewSuggestionPublicationSurface-N9Qwdh2n.js +0 -2
  137. package/dist/client/assets/ServicesPage-D0ygZTFD.js +0 -2
  138. package/dist/client/assets/TimelinePage-Bb2o9DGU.js +0 -2
  139. package/dist/client/assets/WorkspaceEntityRoute-rLRiaF8b.js +0 -14
  140. package/dist/client/assets/WorkspaceEntityRoute-rLRiaF8b.js.map +0 -1
  141. package/dist/client/assets/WorkspaceHomeLink-FGslxXCu.js +0 -2
  142. package/dist/client/assets/WorkspacePullRequestDetails-Dxg8argO.js +0 -3
  143. package/dist/client/assets/WorkspaceSettingsPage-iZhUs-pg.js +0 -2
  144. package/dist/client/assets/authenticatedMutationClient-DUqEcJHu.js +0 -2
  145. package/dist/client/assets/authorizedShareTransport-7YCNH9l3.js +0 -2
  146. package/dist/client/assets/client-D2F6HlDk.js +0 -5
  147. package/dist/client/assets/client-D2F6HlDk.js.map +0 -1
  148. package/dist/client/assets/connectionTestTransport-D8tiZ4ym.js +0 -2
  149. package/dist/client/assets/index-BWx9sNOT.js +0 -11
  150. package/dist/client/assets/index-BWx9sNOT.js.map +0 -1
  151. package/dist/client/assets/index-CIfiz7oF.css +0 -1
  152. package/dist/client/assets/patterns-CxMz8DKX-ByHwV03y.js +0 -2
  153. package/dist/client/assets/patterns-CxMz8DKX-ByHwV03y.js.map +0 -1
  154. package/dist/client/assets/primitives-CW89TsFB-BBLwFFPo.js +0 -2
  155. package/dist/client/assets/primitives-CW89TsFB-BBLwFFPo.js.map +0 -1
  156. package/dist/client/assets/pullRequestReviewFailures-QvtS729d.js +0 -2
  157. package/dist/client/assets/pullRequestReviewThreadReplay-CpPdYxQE.js +0 -2
  158. package/dist/client/assets/releaseRoutes-CSP_eBj6.js +0 -2
  159. package/dist/client/assets/useWorkspaceDefaultLanding-C3PRrLgk.js +0 -3
  160. package/dist/client/assets/useWorkspaceItems-CHYpfLmL.js +0 -2
  161. package/dist/client/assets/workspaceSettingsTransport-Kq7lfPsC.js +0 -2
  162. package/dist/server/assets/controlCenterApi-BcVWTP9F.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":";u4DA0BM,GAAgB,GAAwE,CAC5F,OAAQ,EAAM,KAAd,CACE,IAAK,mBACH,MAAO,CAAE,GAAI,OAAO,EAAM,aAAa,EAAG,KAAM,WAAY,KAAM,EAAM,MAAO,EACjF,IAAK,WACH,MAAO,CAAE,GAAI,OAAO,EAAM,aAAa,EAAG,KAAM,QAAS,KAAM,EAAM,IAAK,EAC5E,IAAK,gBACH,MAAO,CACL,GAAI,OAAO,EAAM,aAAa,EAC9B,KAAM,QACN,KAAM,GAAG,OAAO,EAAM,OAAO,YAAY,MAAM,EAAE,iBAAiB,OAAO,EAAM,OAAO,MAAM,MAAM,EAAE,OACtG,EACF,IAAK,aACH,MAAO,CAAE,GAAI,OAAO,EAAM,aAAa,EAAG,KAAM,SAAU,KAAM,oBAAoB,EAAM,MAAM,EAAG,EACrG,IAAK,gBACH,MAAO,CAAE,GAAI,OAAO,EAAM,aAAa,EAAG,KAAM,SAAU,KAAM,sBAAsB,EAAM,SAAU,EACxG,IAAK,kBACH,MAAO,CAAE,GAAI,OAAO,EAAM,aAAa,EAAG,KAAM,SAAU,KAAM,kCAAmC,EACrG,IAAK,yBACH,MAAO,CAAE,GAAI,OAAO,EAAM,aAAa,EAAG,KAAM,SAAU,KAAM,yBAA0B,EAC5F,IAAK,aACL,IAAK,cACL,IAAK,uBACL,IAAK,qBACL,IAAK,QACH,OAAO,IACX,CACF,EAEM,GAAiB,GACrB,EAAM,OAAS,SAAW,EAAM,SAAW,OACvC,EAAM,OAAO,OAAO,QAAS,GAAU,CACrC,IAAM,EAAU,GAAa,CAAK,EAClC,OAAO,IAAY,KAAO,CAAC,EAAI,CAAC,CAAO,CACzC,CAAC,EACD,CAAC,EAMD,GAAmB,GACvB,EAAM,OAAS,QAAW,EAAM,kBAAoB,EAAM,WAAa,KAAO,CAAC,EAAI,CAAC,EAAM,QAAQ,GAAM,CAAC,EAa9F,IAA0C,CACrD,eACA,aACA,UACA,iBACyG,CACzG,IAAM,EAAS,GAA0B,CAAY,EAC/C,EAAS,GAA2B,EAAkB,CAAC,CAAC,EAAQ,OAAO,EAS7E,OARI,GAAiB,CAAM,EAClB,GACL,IAAI,GAA0C,CAC5C,QAAS,iBACT,QACF,CAAC,CACH,EAEK,GAAkB,CACvB,QAAW,EAAY,EAAO,QAAS,CAAU,EACjD,UACE,IAAI,GAA0C,CAAE,QAAS,iBAAkB,QAAO,CAAC,CACvF,CAAC,CACH,EAEM,GAAe,GAA4C,CAC/D,IAAM,EAAU,GAAgB,CAAK,EAC/B,EAAW,EAAM,OAAS,QAAU,EAAM,SAAW,KAC3D,OAAO,EAAQ,SAAW,GAAK,IAAa,KACxC,GACA,GAAiC,CAC/B,QAAS,EAAS,WAClB,OAAQ,EAAQ,KAAK,CAAE,QAAO,iBAAkB,CAAE,GAAI,EAAY,MAAO,GAAG,EAAW,KAAK,GAAQ,EAAE,EACtG,UAAW,EAAS,WACpB,SAAU,EAAQ,KAAK,CAAE,aAAY,oBAAqB,CACxD,GAAI,EACJ,MAAO,EAAc,KACvB,EAAE,CACJ,CAAC,CACP,EAea,IAA4B,CACvC,aACA,WACA,aACA,cACA,cACA,iBACyC,CACzC,IAAM,EAAU,EAAW,OAAO,WAAW,QACvC,KAAY,eAAc,GAAY,CAAW,EAAG,CAAC,CAAW,CAAC,EACjE,KAAe,eAEjB,GAAqC,CACnC,KAAM,iBACN,MAAO,CAAE,WAAU,KAAM,GAAoB,EAAa,CAAQ,CAAE,EACpE,YACA,OAAQ,CACN,mBAAoB,EAAW,OAAO,mBACtC,cAAe,EAAW,OAAO,kBACjC,eAAgB,EAAQ,OAAS,eAAiB,EAAQ,WAAa,cACvE,aACF,CACF,CAAC,EACH,CACE,EACA,EACA,EAAW,OAAO,mBAClB,EAAW,OAAO,kBAClB,EACA,CACF,CACF,EACM,KAAe,eAAgD,CACnE,IAAM,EAAO,CACX,QAAS,CACP,CACE,GAAI,aACJ,MAAO,aACP,MAAO,EAAQ,OAAS,eAAiB,EAAQ,WAAa,aAChE,EACA,CAAE,GAAI,eAAgB,MAAO,eAAgB,MAAO,IAAI,EAAW,OAAO,mBAAoB,EAC9F,CACE,GAAI,OACJ,MAAO,eACP,MAAO,EAAQ,OAAS,eAAiB,EAAQ,aAAa,MAAM,EAAG,EAAE,EAAI,aAC/E,CACF,EACA,eACA,WACF,EACA,GAAI,EAAY,OAAS,QAAU,EAAY,OAAS,UAAW,MAAO,CAAE,GAAG,EAAM,OAAQ,SAAU,EACvG,GAAI,EAAY,OAAS,SACvB,MAAO,CAAE,GAAG,EAAM,YAAa,wDAAyD,OAAQ,OAAQ,EAE1G,IAAM,EAAU,GAAgB,CAAW,EAU3C,MATI,CAAC,GAAc,EAAY,WAAa,MAAQ,EAAY,OAAO,OAAS,cACvE,CACL,GAAG,EACH,YAAa,EACT,sDACA,oEACJ,OAAQ,aACV,EAEK,CACL,GAAG,EACH,gCAAkC,GAAY,CAC5C,IAAM,EAAS,GAA0B,CAAY,EACrD,GAAI,EAAY,SAAW,YAAc,EAAY,OAAO,OAAS,UACnE,OAAO,IAAI,GAA4C,CACrD,QAAS,iBACT,OAAQ,oBACR,QACF,CAAC,EAEH,IAAM,EAAW,EAAQ,MACtB,CAAE,gBACD,OAAO,CAAU,IAAM,OAAO,EAAQ,UAAU,OAAO,GACvD,OAAO,CAAU,IAAM,OAAO,EAAQ,UAAU,SAAS,CAC7D,EAQA,OAPI,IAAa,OACR,IAAI,GAA4C,CACrD,QAAS,iBACT,OAAQ,wBACR,QACF,CAAC,EAEI,GAAuC,CAC5C,eACA,WAAY,EAAS,WACrB,UACA,aACF,CAAC,CACH,EACA,SAAU,GAAc,CAAW,EACnC,OAAQ,OACV,CACF,EAAG,CAAC,EAAY,EAAc,EAAS,EAAW,OAAO,kBAAmB,EAAa,EAAW,CAAW,CAAC,EAEhH,OADA,EAAwB,CAAY,EAC7B,IACT,EC9LM,GAAqB,IAAI,KAAK,eAAe,QAAS,CAC1D,UAAW,SACX,UAAW,QACX,SAAU,KACZ,CAAC,EAEK,GAAa,GACjB,EACG,MAAM,WAAW,CAAC,CAClB,OAAO,OAAO,CAAC,CACf,IAAK,GAAS,GAAG,EAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,OAAO,IAAI,EAAK,MAAM,CAAC,CAAC,CAAC,kBAAkB,OAAO,GAAG,CAAC,CACxG,KAAK,GAAG,EAEP,GAAiB,GAA4B,CACjD,IAAM,EAAQ,KAAK,MAAM,EAAU,EAAE,EAC/B,EAAY,EAAU,GAE5B,OADI,IAAU,EAAU,GAAG,OAAO,CAAS,EAAE,GACtC,IAAc,EAAI,GAAG,OAAO,CAAK,EAAE,GAAK,GAAG,OAAO,CAAK,EAAE,IAAI,OAAO,CAAS,EAAE,EACxF,EAEM,GAAkB,GACtB,GAAU,KAA8B,mBAAqB,GAAmB,OAAO,EAAmB,CAAK,CAAC,EAE5G,GAAyB,GAC7B,GAAU,KACN,KACA,CACA,SAAU,EAAmB,CAAK,EAClC,MAAO,GAAmB,OAAO,EAAmB,CAAK,CAAC,CAC5D,EAEE,GAAwB,GAC5B,EAAa,UAAU,OAAS,WAChC,EAAa,UAAU,OAAS,YAChC,EAAa,UAAU,OAAS,aAE5B,IACJ,EACA,IACoD,CACpD,IAAM,EAAiB,IAAI,IACzB,EAAW,MAAM,MAAM,SAAS,CAAE,SAAQ,gBACxC,EAAW,OAAS,YAClB,EAAW,OAAO,OAAS,UAC3B,EAAW,OAAO,WAAa,EAAW,OAAO,WAAW,SAC1D,CAAC,CAAM,EACP,CAAC,CACP,CACF,EACM,EAAgB,IAAI,IAC1B,IAAK,GAAM,CAAE,SAAQ,gBAAgB,EAAW,MAAM,MAElD,EAAW,OAAS,YACpB,EAAW,OAAO,OAAS,UAC3B,EAAW,OAAO,aAAe,SACjC,EAAc,IAAI,EAAQ,EAAW,OAAO,QAAQ,EAExD,IAAM,EAAS,IAAI,IACnB,IAAK,GAAM,CAAE,gBAAgB,EAAW,MAAM,yBACxC,EAAW,cAAgB,WAAa,EAAW,aAAe,SACpE,EAAO,IAAI,EAAW,SAAU,CAAU,EAI9C,IAAM,EAAe,IAAI,IAKzB,IAAK,IAAM,KAAgB,EAAW,MAAM,cAAe,CACzD,GACE,EAAa,OAAS,mBACtB,CAAC,EAAe,IAAI,EAAa,YAAY,GAC7C,CAAC,GAAqB,CAAY,EAClC,SACF,IAAM,EAAU,EAAc,IAAI,EAAa,YAAY,EACrD,EAAQ,IAAY,OAAY,OAAY,EAAO,IAAI,CAAO,EACpE,GAAI,IAAY,QAAa,IAAU,OAAW,SAClD,IAAM,EAAW,EAAa,UAAU,OAAS,YAAc,EAAa,WAAW,OAAS,WAC1F,EAAU,EAAa,IAAI,CAAO,EACxC,GAAI,IAAY,OAAW,CACzB,EAAa,IAAI,EAAS,CACxB,iBAAkB,IAAI,IAAI,EAAa,gBAAgB,EACvD,QACA,MAAO,EAAW,WAAa,QACjC,CAAC,EACD,QACF,CACA,IAAK,IAAM,KAAmB,EAAa,iBAAkB,EAAQ,iBAAiB,IAAI,CAAe,EACpG,IAAU,EAAQ,MAAQ,SACjC,CAEA,MAAO,CAAC,GAAG,EAAa,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAS,CAAE,mBAAkB,QAAO,aAAc,CACzF,cAAe,GAAG,OAAO,EAAiB,IAAI,EAAE,iBAAiB,EAAiB,OAAS,EAAI,GAAK,MACpG,KAAM,GAAoB,EAAa,CAAO,EAC9C,IAAK,EAAM,WACX,QACA,MAAO,EAAM,KACf,EAAE,CACJ,EAGa,IACX,EACA,EACA,IAC2C,CAC3C,IAAM,EAAmB,GAAoB,EAAa,CAAU,EAC9D,EAAgB,EAAiB,QAAQ,CAAE,WAAY,IAAU,UAAU,CAAC,CAAC,OAC7E,EAAY,EAAW,OAAO,OACjC,QAAQ,CAAE,WAAY,EAAM,KAAM,GAAS,EAAK,SAAS,UAAU,CAAC,CAAC,CAAC,CACtE,KAAK,CAAE,iBAAkB,CAAW,EACjC,EAAc,EAAQ,SAAW,OACnC,OACA,EAAW,OAAO,OAAO,MAAM,CAAE,sBACjC,GAAkB,MACf,CAAE,aAAY,oBAAqB,IAAe,YAAc,IAAmB,EAAQ,MAC9F,GAAK,EACP,EACF,MAAO,CACL,kBAAmB,GAAsB,EAAW,kBAAkB,SAAS,EAC/E,eAAgB,EAAW,mBAAqB,KAC5C,2EACA,EAAW,iBAAiB,UAChC,cAAe,EAAW,mBAAqB,KAC3C,UACA,GAAU,EAAW,iBAAiB,QAAQ,EAClD,YACA,kBAAmB,EAAiB,SAAW,EAC3C,4FACA,IAAkB,EAClB,GAAG,OAAO,EAAiB,MAAM,EAAE,oBAAoB,EAAiB,SAAW,EAAI,GAAK,MAC5F,GAAG,OAAO,CAAa,EAAE,qBAAqB,IAAkB,EAAI,GAAK,IAAI,4BACjF,iBAAkB,EAAiB,SAAW,EAAI,eAAiB,aACnE,cAAe,EAAQ,SAAW,WAAa,eAC/C,iBAAkB,GAAa,aAAe,EAAQ,QAAU,+BAChE,YAAa,EAAQ,aAAe,EAAW,OAAO,WAAW,MACjE,cAAe,GAAc,EAAQ,eAAe,EACpD,QAAS,GAAe,EAAQ,OAAO,EACvC,mBACA,UAAW,EAAQ,SAAW,OAC1B,8BACA,EAAQ,OACR,SACA,WACJ,aAAc,EAAQ,WAAa,sBACnC,YAAa,qBAAqB,OAAO,EAAQ,eAAe,EAAE,eAChE,EAAQ,kBAAoB,EAAI,GAAK,MAEvC,eAAgB,EAAW,OAAO,SAClC,UAAW,GAAe,EAAQ,SAAS,EAC3C,WAAY,EAAQ,YAAc,QAAa,EAAQ,UAAY,OAC/D,+BACA,EAAQ,UAAY,KACpB,gBACA,YACJ,aAAc,EAAQ,eACxB,CACF,ECpJM,GAAqB,IAAI,KAAK,eAAe,QAAS,CAC1D,UAAW,SACX,UAAW,QACX,SAAU,KACZ,CAAC,EAEK,GAAa,GACjB,EAAM,MAAM,GAAG,CAAC,CAAC,IAAK,GAAS,GAAG,EAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,OAAO,IAAI,EAAK,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAEnG,EAAqB,GACrB,IAAU,KAAa,KACpB,GAAa,GAAc,CAAK,EAAG,CACxC,WAAc,EACd,OAAS,GAAc,GAAmB,OAAO,EAAmB,CAAS,CAAC,CAChF,CAAC,EAGG,GAAa,GACjB,EAAM,MAAQ,EAAM,UAAY,UAE5B,GAAa,GACjB,IAAW,QAAa,EAAO,SAAW,EAAI,UAAY,EAAO,KAAK,KAAK,EAEvE,GAAkB,IAAuC,CAC7D,GAAI,EACJ,KAAM,uBACN,KAAM,mBACR,GAEM,GAAa,GACjB,IAAI,KACD,EAAQ,eAAiB,CAAC,GAAG,IAAK,GAAiB,CAClD,IAAM,EAAQ,EAAa,MAAM,IAAI,EAAS,EAC9C,MAAO,CACL,EAAa,eACb,CACE,GAAI,EAAa,eACjB,KAAM,EAAa,YACnB,KAAM,EAAM,SAAW,EAAI,oBAAsB,EAAM,KAAK,KAAK,EACjE,GAAM,EAAa,YAAc,MAAS,CAAE,UAAW,EAAa,SAAU,CAChF,CACF,CACF,CAAC,CACH,EAEI,IACJ,EACA,KACuC,CACvC,UAAa,CACX,GAAI,IAAc,MAAQ,EAAM,MAAQ,KAAM,OAAO,KACrD,IAAM,EAAa,yBAAyB,KAAK,EAAU,QAAQ,CAAC,GAAG,GACvE,OAAO,IAAe,OAAY,KAAO,GAAG,EAAU,SAAS,IAAa,mBAAmB,EAAM,GAAG,GAC1G,GAAG,EACH,IAAK,EAAM,KAAO,EAAM,UAAY,gBACpC,OAAQ,EAAM,SAAW,KAAO,iBAAmB,GAAU,EAAM,MAAM,EACzE,QAAS,EAAM,SAAW,qBAC5B,GAEM,GAAe,GAAiE,CACpF,IAAM,EAAU,EAAQ,QAClB,GAAe,EAAQ,aAAe,CAAC,GAAG,IAAI,EAAS,EACvD,GAAc,EAAQ,YAAc,CAAC,GAAG,IAAI,EAAS,EAC3D,MAAO,CACL,CACE,MAAO,OACP,MAAO,EAAQ,YAAc,MAAQ,EAAQ,YAAc,OAAY,UAAY,GAAU,EAAQ,SAAS,CAChH,EACA,CACE,MAAO,UACP,MAAO,GAAY,KACf,UACA,CAAC,EAAQ,IAAK,EAAQ,IAAI,CAAC,CAAC,OAAQ,GAA2B,IAAU,IAAI,CAAC,CAAC,KAAK,KAAK,GAAK,SACpG,EACA,CACE,MAAO,aACP,MAAO,EAAQ,aAAe,MAAQ,EAAQ,aAAe,OACzD,aACA,GAAU,EAAQ,UAAU,CAClC,EACA,CAAE,MAAO,SAAU,MAAO,GAAU,EAAQ,MAAM,CAAE,EACpD,CAAE,MAAO,aAAc,MAAO,GAAU,CAAU,CAAE,EACpD,CAAE,MAAO,eAAgB,MAAO,GAAU,CAAW,CAAE,EACvD,CAAE,MAAO,UAAW,MAAO,EAAkB,EAAQ,WAAa,IAAI,GAAK,eAAgB,EAC3F,CAAE,MAAO,UAAW,MAAO,EAAkB,EAAQ,WAAa,IAAI,GAAK,eAAgB,EAC3F,CAAE,MAAO,MAAO,MAAO,EAAkB,EAAQ,SAAW,IAAI,GAAK,SAAU,CACjF,CACF,EAEM,IAAc,EAAqB,IAA8B,GAAG,GAAQ,QAAQ,KAAK,GAAM,UAGxF,IACX,EACA,IAC+B,CAC/B,IAAM,EAAS,GAAU,CAAO,EAC1B,EAAU,GACd,IAAmB,KACf,GAAe,gBAAgB,EAC9B,EAAO,IAAI,CAAc,GAAK,GAAe,CAAc,EAC5D,EAAkB,IAAI,IAAI,EAAQ,iBAAmB,CAAC,CAAC,EACvD,GAAY,EAAQ,UAAY,CAAC,GAAG,IAAK,IAAa,CAC1D,OAAQ,EAAO,EAAQ,oBAAoB,EAC3C,KAAM,EAAQ,KACd,GAAI,EAAQ,SACZ,KAAM,EAAkB,EAAQ,WAAa,EAAQ,SAAS,CAChE,EAAE,EACI,GAAW,EAAQ,SAAW,CAAC,GAAG,IAAK,IAAW,CACtD,MAAO,EAAO,EAAM,oBAAoB,EACxC,QAAS,EAAM,QAAQ,IAAK,IAAY,CAAE,MAAO,EAAO,MAAO,WAAY,GAAW,EAAO,KAAM,EAAO,EAAE,CAAE,EAAE,EAChH,GAAI,EAAM,SACV,KAAM,EAAkB,EAAM,SAAS,CACzC,EAAE,EACI,EAAe,EAAQ,cAAgB,EAAS,OAChD,EAAe,EAAQ,cAAgB,EAAQ,OAC/C,GAAqB,EAAQ,mBAAqB,KAAU,EAAe,EAAS,OACpF,GAAoB,EAAQ,kBAAoB,KAAU,EAAe,EAAQ,OACjF,EAAgB,CAAC,GAAG,CAAe,CAAC,CAAC,OACxC,GAAU,IAAU,aAAe,IAAU,WAAa,CAAC,EAC9D,EACA,MAAO,CACL,mBAAoB,EAAQ,oBAAsB,KAClD,cAAe,CAAC,GAAG,EAAO,OAAO,CAAC,EAClC,eACA,WACA,uBAAwB,EAAQ,yBAA2B,EAAgB,IAAI,UAAU,GAAK,CAAC,GAC/F,oBACA,YAAa,EAAQ,aAAe,KACpC,YAAa,EAAQ,aAAe,KACpC,UACA,eACA,mBACA,SAAU,GAAY,CAAO,EAC7B,OAAQ,EAAQ,SAAW,MAAQ,EAAQ,SAAW,OAAY,KAAO,GAAa,EAAQ,OAAQ,CAAS,EAC/G,UAAW,EAAQ,UAAY,CAAC,GAAG,IAAK,GAAY,GAAa,EAAS,CAAS,CAAC,EACpF,kBAAmB,EAAc,SAAW,EACxC,KACA,kBAAkB,EAAc,IAAI,EAAS,CAAC,CAAC,KAAK,IAAI,EAAE,yCAChE,CACF,EC5JM,GAAqB,IAAI,KAAK,eAAe,QAAS,CAC1D,UAAW,SACX,UAAW,QACX,SAAU,KACZ,CAAC,EAEK,GAAa,GACjB,EACG,MAAM,YAAY,CAAC,CACnB,OAAQ,GAAS,EAAK,OAAS,CAAC,CAAC,CACjC,IAAK,GAAS,GAAG,EAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,OAAO,IAAI,EAAK,MAAM,CAAC,GAAG,CAAC,CAC7E,KAAK,GAAG,EAEP,GAAc,GAEX,GADM,EAAU,MAAM,GAAG,CAAC,CAAC,OAAQ,GAAS,EAAK,OAAS,CAAC,CAAC,CAAC,GAAG,EAAE,GAAK,CACzD,GAAK,eAGtB,GAAa,GACjB,GAAc,KACV,KACA,CACA,GAAI,EACJ,KAAM,GAAW,CAAS,EAC1B,KAAM,qBACR,EAEE,GAAgB,GAChB,GAAU,KAAoC,KAC3C,GAAa,GAAc,CAAK,EAAG,CACxC,WAAc,KACd,OAAS,IAAe,CACtB,SAAU,EAAmB,CAAS,EACtC,MAAO,GAAmB,OAAO,EAAmB,CAAS,CAAC,CAChE,EACF,CAAC,EAGG,GAAe,GAA2D,CAC9E,OAAQ,EAAR,CACE,IAAK,WACH,MAAO,qBACT,IAAK,oBACH,MAAO,oBACT,IAAK,SACH,MAAO,SACT,IAAK,YACH,MAAO,yBACT,IAAK,gBACH,MAAO,gCACX,CACF,EAEM,GAAsB,GAA+D,CACzF,IAAM,EAAiB,IAAI,IACzB,EAAW,MAAM,MAAM,SAAS,CAAE,SAAQ,gBACxC,EAAW,OAAS,YAAc,EAAW,OAAO,OAAS,SACzD,CAAC,CAAC,EAAQ,EAAW,OAAO,QAAQ,CAAC,EACrC,CAAC,CACP,CACF,EACM,EAAiB,IAAI,IACzB,EAAW,MAAM,MAAM,SAAS,CAAE,SAAQ,gBACxC,EAAW,OAAS,YAClB,EAAW,OAAO,OAAS,UAC3B,EAAW,OAAO,WAAa,EAAW,OAAO,WAAW,SAC1D,CAAC,CAAM,EACP,CAAC,CACP,CACF,EACA,OAAO,IAAI,IAAI,EAAW,MAAM,cAAc,QAAS,GAAiB,CACtE,GACE,EAAa,UAAU,OAAS,WAChC,EAAa,UAAU,OAAS,YAChC,EAAa,UAAU,OAAS,aAChC,MAAO,CAAC,EACV,IAAM,EAAgB,EAAe,IAAI,EAAa,YAAY,EAC9D,EAAa,aACb,EAAe,IAAI,EAAa,YAAY,EAC5C,EAAa,aACb,KACE,EAAkB,IAAkB,KAAO,KAAO,EAAe,IAAI,CAAa,EACxF,OAAO,GAAqD,KAAO,CAAC,EAAI,CAAC,CAAe,CAC1F,CAAC,CAAC,CACJ,EAGa,IACX,EACA,EACA,IACqC,CACrC,IAAM,EAAY,GAAmB,CAAU,EACzC,EAAgB,GACpB,EAAW,MAAM,yBAAyB,QACvC,CAAE,gBACD,EAAW,cAAgB,WAC3B,EAAW,aAAe,GAC1B,EAAU,IAAI,EAAW,QAAQ,CACrC,CAAC,CAAC,OACE,EAAe,EAAW,OAAO,WAAW,OAC5C,EAAa,EAAa,OAAO,EACjC,EAAgB,EAAa,oBAAoB,EACjD,EAAsB,GAA0B,GAAG,OAAO,CAAK,IAAI,EAAW,MAAM,UAAY,IAAM,KAC5G,MAAO,CACL,OAAQ,GAAU,EAAQ,eAAe,EACzC,aAAc,EAAQ,cAAgB,KACtC,UAAW,GAAa,EAAQ,SAAS,EACzC,YAAa,EAAQ,aAAa,KAAK,GAAK,KAC5C,UAAW,CACT,mBAAoB,EAAO,mBAC3B,kBAAmB,EAAO,kBAC1B,SAAU,EAAO,QACnB,EACA,UAAW,EAAO,WAAW,MAAQ,KACrC,aAAc,EAAQ,aACtB,aACA,gBAAiB,EAAmB,CAAU,EAC9C,kBAAmB,EAAQ,mBAAqB,KAChD,gBACA,mBAAoB,EAAmB,CAAa,EACpD,eACA,kBAAmB,GAAG,OAAO,CAAY,IAAI,EAAW,OAAO,4BAA8B,IAAM,KACnG,YAAa,GAAY,EAAQ,WAAW,EAC5C,aAAc,EAAQ,aACtB,aAAc,EAAQ,aACtB,UAAW,GAAa,EAAQ,SAAS,CAC3C,CACF,EC1DM,GAAqB,IAAI,KAAK,eAAe,QAAS,CAC1D,UAAW,SACX,UAAW,QACX,SAAU,KACZ,CAAC,EAEK,EAAa,GACjB,EAAM,MAAM,GAAG,CAAC,CAAC,IAAK,GAAS,GAAG,EAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,OAAO,IAAI,EAAK,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAEnG,GAAe,CACnB,SAAU,WACV,WAAY,aACZ,aAAc,eACd,WAAY,aACZ,KAAM,MACR,EAEM,GAAY,CAChB,WAAY,aACZ,MAAO,QACP,KAAM,OACN,qBAAsB,qBACtB,eAAgB,eAChB,aAAc,YAChB,EAEM,GAAqB,GACzB,GAAmB,OAAO,EAAmB,CAAS,CAAC,EAEnD,GAAc,GAA0C,CAC5D,GAAI,EAAO,YAAc,KAAM,OAAO,KACtC,IAAM,EAAO,IAAI,IAAI,EAAO,UAAU,IAAI,EAI1C,OAHI,EAAO,aAAe,cAAgB,EAAK,SAAS,WAAW,UAAU,IAC3E,EAAK,SAAW,QAAQ,EAAK,YAExB,EAAK,IACd,EAEM,IAAe,EAA0B,IAC7C,MAAM,mBAAmB,CAAW,EAAE,YAAY,mBAAmB,CAAS,IAE1E,GAAiB,GAA6B,EAAS,MAAM,EAAE,EAE/D,GAAY,GAAuE,CACvF,OAAQ,EAAQ,KAAhB,CACE,IAAK,QACH,MAAO,CACL,CAAE,MAAO,WAAY,MAAO,EAAQ,UAAY,SAAU,EAC1D,CACE,MAAO,WACP,MAAO,EAAQ,iBAAmB,KAAO,gBAAkB,GAAG,EAAQ,eAAe,QACvF,CACF,EACF,IAAK,eACH,MAAO,CACL,CAAE,MAAO,aAAc,MAAO,EAAQ,UAAW,EACjD,GAAI,EAAQ,YAAc,MAAQ,EAAQ,YAAc,OACpD,CAAC,EACD,CAAC,CAAE,MAAO,QAAS,MAAO,EAAU,EAAQ,SAAS,CAAE,CAAC,EAC5D,CAAE,MAAO,WAAY,MAAO,GAAG,EAAQ,aAAa,KAAK,EAAQ,cAAe,EAChF,CAAE,MAAO,gBAAiB,MAAO,EAAQ,YAAa,CACxD,EACF,IAAK,OACH,MAAO,CACL,CAAE,MAAO,QAAS,MAAO,EAAQ,QAAS,EAC1C,CAAE,MAAO,WAAY,MAAO,EAAQ,QAAS,CAC/C,EACF,IAAK,qBACH,MAAO,CACL,CAAE,MAAO,WAAY,MAAO,EAAQ,YAAa,EACjD,CAAE,MAAO,YAAa,MAAO,EAAQ,WAAY,EACjD,CAAE,MAAO,mBAAoB,MAAO,EAAQ,eAAgB,CAC9D,EACF,IAAK,aACH,MAAO,CACL,CAAE,MAAO,cAAe,MAAO,GAAc,EAAQ,aAAa,CAAE,EACpE,CAAE,MAAO,WAAY,MAAO,EAAQ,QAAS,CAC/C,EACF,IAAK,aACH,MAAO,CACL,CAAE,MAAO,WAAY,MAAO,GAAG,EAAQ,gBAAgB,KAAM,EAC7D,CAAE,MAAO,WAAY,MAAO,EAAQ,SAAW,MAAQ,IAAK,CAC9D,CACJ,CACF,EAEM,GAAa,GAAuB,EAAU,CAAI,EAElD,GAAa,IAA4C,CAC7D,eAAgB,EAAM,eACtB,GAAI,EAAM,SACV,KAAM,EAAM,YACZ,KAAM,CAAC,GAAG,IAAI,IAAI,EAAM,MAAM,IAAI,EAAS,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAC3D,GAEM,GAAwB,GACxB,EAAM,KAAM,GAAS,EAAK,SAAS,UAAU,CAAC,EAAU,YACxD,EAAM,KAAM,GAAS,IAAS,YAAc,IAAS,SAAS,EAAU,YACxE,EAAM,SAAS,UAAU,EAAU,YACnC,EAAM,KAAM,GAAS,IAAS,UAAY,IAAS,aAAa,EAAU,UACvE,SAGH,GACJ,GAC6C,CAC7C,IAAM,EAAwD,CAC5D,UACA,SACA,YACA,YACA,WACF,EACM,MAAsC,CAAC,EACvC,EAAqC,CACzC,UAAW,EAAY,EACvB,QAAS,EAAY,EACrB,UAAW,EAAY,EACvB,OAAQ,EAAY,EACpB,UAAW,EAAY,CACzB,EACA,IAAK,IAAM,KAAS,EAAQ,EAAW,GAAqB,EAAM,KAAK,EAAE,CAAC,KAAK,GAAU,CAAK,CAAC,EAC/F,IAAM,EAAqB,EAAc,OAAQ,GAAa,EAAW,EAAS,CAAC,OAAS,CAAC,EAC7F,MAAO,CACL,GAAG,EACH,WAAY,8CACZ,oBACF,CACF,EAEM,IACJ,EACA,IAC6C,CAC7C,GAAI,IAAU,KAAM,OAAO,EAC3B,IAAM,EAAS,CAAC,GAAG,EAAc,MAAM,EACjC,EAAU,CAAC,GAAG,EAAc,OAAO,EACnC,EAAiB,IAAI,IACzB,CACE,GAAG,EAAc,UACjB,GAAG,EAAc,QACjB,GAAG,EAAc,UACjB,GAAG,EAAc,OACjB,GAAG,EAAc,SACnB,CAAC,CAAC,IAAK,GAAW,EAAO,KAAK,kBAAkB,OAAO,CAAC,CAC1D,EACM,EAAiB,IAAI,IAC3B,IAAK,IAAM,KAAU,EAAM,cAAe,CACxC,GAAI,EAAe,IAAI,EAAO,EAAE,EAAG,SACnC,EAAe,IAAI,EAAO,EAAE,EAC5B,IAAM,EAAiB,EAAO,KAAK,kBAAkB,OAAO,EACxD,EAAe,IAAI,CAAc,IACjC,EAAO,KAAK,SAAS,UAAU,EAAG,EAAO,KAAK,CAAM,EACnD,EAAQ,KAAK,CAAM,EAC1B,CACA,IAAM,EAAqD,CAAC,EACxD,EAAQ,OAAS,GAAG,EAAmB,KAAK,SAAS,EACrD,EAAO,OAAS,GAAG,EAAmB,KAAK,QAAQ,EACvD,IAAK,IAAM,KAAY,EAAc,mBAAoB,EAAmB,KAAK,CAAQ,EACzF,MAAO,CACL,GAAG,EACH,UACA,WAAY,+DACZ,mBAAoB,CAAC,GAAG,IAAI,IAAI,CAAkB,CAAC,EACnD,QACF,CACF,EAEM,IACJ,EACA,EACA,IAC6C,CAC7C,GAAI,IAAS,KAAM,OAAO,EAC1B,IAAM,EAAO,CACX,UAAW,CAAC,GAAG,EAAc,SAAS,EACtC,QAAS,CAAC,GAAG,EAAc,OAAO,EAClC,UAAW,CAAC,GAAG,EAAc,SAAS,EACtC,OAAQ,CAAC,GAAG,EAAc,MAAM,EAChC,UAAW,CAAC,GAAG,EAAc,SAAS,CACxC,EACM,EAAW,IAAI,IAAI,OAAO,OAAO,CAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAE,QAAS,CAAE,CAAC,EACjE,EAA2B,IAAI,IACnC,EAAO,QAAS,IACb,EAAM,kBAAoB,CAAC,GACzB,QAAQ,CAAE,gBAAiB,IAAe,YAAY,CAAC,CACvD,KAAK,CAAE,oBAAqB,CAAc,CAC/C,CACF,EACA,IAAK,IAAM,KAAU,EAAK,aACpB,EAAS,IAAI,EAAO,EAAE,GAAK,EAAyB,IAAI,EAAO,EAAE,IACrE,EAAS,IAAI,EAAO,EAAE,EAClB,EAAO,KAAK,SAAS,OAAO,EAAG,EAAK,OAAO,KAAK,CAAM,EACjD,EAAO,KAAK,SAAS,SAAS,EAAG,EAAK,UAAU,KAAK,CAAM,EAC/D,EAAK,QAAQ,KAAK,CAAM,GAE/B,IAAM,EAAwD,CAC5D,UACA,SACA,YACA,YACA,WACF,EACA,MAAO,CACL,GAAG,EACH,WAAY,iEACZ,mBAAoB,EAAc,OAC/B,GAAa,EAAK,EAAS,CAAC,OAAS,CACxC,CACF,CACF,EAEM,GAAgB,GAA6D,CACjF,IAAM,EAAY,EAAW,UAK7B,OAJI,IAAc,KAAa,EAAW,gBAAkB,UAAY,SACpE,EAAU,OAAS,UACd,EAAW,iBAAmB,EAAU,WAAW,OAAS,WAAa,UAAY,SAEvF,EAAU,IACnB,EAEM,GAAsB,GAA6D,CACvF,IAAM,EAAY,EAAW,UAE7B,OADI,IAAc,KAAa,EAAW,OAAO,WAC1C,EAAU,kBAAoB,EAAU,gBAAkB,EAAU,aAAa,SAC1F,EAEM,IACJ,EACA,EACA,EACA,IAC8B,CAC9B,GAAI,IAAS,OACX,MAAO,CAAE,MAAO,UAAW,MAAO,yBAA0B,OAAQ,8CAA+C,EAErH,GAAI,EAAK,WAAW,OAAS,UAC3B,MAAO,CACL,MAAO,UACP,MAAO,EAAK,WAAW,WACvB,OAAQ,GAAG,EAAU,EAAK,YAAY,EAAE,mBAC1C,EAEF,IAAM,EAAS,EAAK,WAAW,OAC/B,GAAI,EAAO,OAAS,SAAU,CAC5B,IAAM,EAAa,EAAW,IAAI,EAAO,QAAQ,EAiBjD,OAhBI,IAAe,OACV,CACL,MAAO,UACP,MAAO,GAAG,GAAU,EAAO,YAAY,GAAG,GAAc,EAAO,QAAQ,IACvE,OAAQ,uDACR,QAAS,GAAW,EAAO,UAAU,CACvC,EAEE,EAAW,cAAgB,UACtB,CACL,MAAO,UACP,MAAO,GAAG,EAAW,MAAM,YAC3B,OAAQ,kCACR,QAAS,GAAW,EAAW,UAAU,CAC3C,EAEK,CACL,MAAO,UACP,KAAM,GAAoB,EAAa,EAAW,QAAQ,EAC1D,GAAI,EAAW,SACf,UAAW,EAAW,WACtB,QAAS,GAAW,EAAW,UAAU,EACzC,MAAO,EAAW,KACpB,CACF,CAWA,OAVI,EAAO,OAAS,UACX,CACL,MAAO,UACP,KAAM,GAAY,EAAa,EAAO,SAAS,EAC/C,GAAI,EAAO,UACX,UAAW,4BAA4B,GAAc,EAAO,SAAS,IACrE,UACA,MAAO,kBACT,EAEK,CACL,MAAO,UACP,GAAI,EAAO,cACX,UAAW,gCAAgC,GAAc,EAAO,aAAa,IAC7E,UACA,MAAO,sBACT,CACF,EAEM,GAAwB,GAA+C,CAC3E,IAAM,EAAW,EAAa,iBAAiB,OACzC,EAAa,EAAa,WAAW,OAAS,WAChD,GAAG,KAAK,MAAM,EAAa,WAAW,MAAQ,GAAG,EAAE,YACnD,EAAU,EAAa,WAAW,IAAI,EAC1C,MAAO,GAAG,EAAS,iBAAiB,IAAa,EAAI,GAAK,IAAI,KAAK,GACrE,EAEM,IACJ,EACA,EACA,IACmC,CACnC,IAAM,EAAW,IAAI,IAA+B,EAAW,MAAM,MAAM,IAAK,GAAS,CAAC,EAAK,OAAQ,CAAI,CAAC,CAAC,EACvG,EAAc,CAAC,EAAW,OAAQ,GAAG,EAAW,MAAM,wBAAwB,CAAC,CAClF,KAAK,CAAE,gBAAiB,CAAU,EAC/B,EAAa,IAAI,IACrB,EAAY,IAAK,GAAe,CAAC,EAAW,SAAU,CAAU,CAAC,CACnE,EACM,EAAY,IAAI,IAAI,EAAW,OAAO,OAAO,IAAK,GAAU,CAAC,EAAM,SAAU,CAAK,CAAC,CAAC,EAC1F,OAAO,EAAW,MAAM,cAAc,IAAK,GAAiB,CAC1D,IAAM,EAAa,EAAa,WAAW,OAAS,QAChD,EAAU,IAAI,EAAa,WAAW,QAAQ,EAC9C,OACJ,MAAO,CACL,GAAM,IAAe,QAAc,CAAE,MAAO,GAAU,CAAU,CAAE,EAClE,UAAW,UACX,SAAU,GAAqB,CAAY,EAC3C,GAAI,EAAa,eACjB,KAAM,EAAU,EAAa,IAAI,EACjC,UAAW,EAAa,UAAU,KAClC,OAAQ,GAAY,EAAS,IAAI,EAAa,YAAY,EAAG,EAAY,EAAS,CAAW,EAC7F,OAAQ,GAAY,EAAS,IAAI,EAAa,YAAY,EAAG,EAAY,EAAS,CAAW,CAC/F,CACF,CAAC,CACH,EAEM,GAAe,GACnB,EAAW,SAAS,OAAO,IAAK,IAAW,CACzC,MAAO,EAAM,MAAM,MACnB,UAAW,EAAM,MAAM,KACvB,SAAU,EAAmB,EAAM,UAAU,EAC7C,OAAQ,EAAU,EAAM,UAAU,EAClC,GAAM,EAAM,OAAS,MAAS,CAAE,KAAM,EAAM,IAAK,EACjD,GAAI,EAAM,SACV,GAAM,EAAM,UAAY,MAAS,CAAE,QAAS,EAAM,OAAQ,EAC1D,KAAM,GAAkB,EAAM,UAAU,EACxC,MAAO,EAAM,KACf,EAAE,EAEE,IACJ,EACA,EACA,IACsC,CACtC,IAAM,EAAO,GAAW,EAAW,MAAM,EACzC,GAAI,IAAS,KACX,MAAO,CACL,SAAU,GACV,OACA,MAAO,EAAW,OAAO,aAAe,aAAe,qBAAuB,WAAW,GAC3F,EAEF,IAAM,EAAY,EAAW,OAAO,mBACpC,OAAO,IAAc,KACjB,CAAE,SAAU,GAAO,KAAM,KAAM,MAAO,yBAA0B,EAChE,CAAE,SAAU,GAAO,KAAM,GAAY,EAAa,CAAS,EAAG,MAAO,uBAAwB,CACnG,EAEM,GAAsB,GAAiE,CAC3F,GAAI,EAAW,OAAO,gBAAkB,CAAC,2DAA2D,EAAI,CAAC,EACzG,GAAI,EAAW,OAAO,4BAClB,CAAC,0EAA0E,EAC3E,CAAC,EACL,GAAI,EAAW,MAAM,UAAY,CAAC,qEAAqE,EAAI,CAAC,EAC5G,GAAI,EAAW,SAAS,UAAY,CAAC,2DAA2D,EAAI,CAAC,CACvG,EAUM,IAAmB,CACvB,aACA,QACA,eACA,cACA,WAEA,IAAU,KACN,GAAG,EAAW,KAAK,EAAM,KAAK,IAC9B,GAAG,EAAW,KAAK,EAAM,KAAK,EAAY,WAAW,OAAO,CAAY,EAAE,UAC1E,IAAiB,EAAI,GAAK,IAC3B,KAAK,OAAO,EAAM,YAAY,EAAE,uBAAuB,EAAM,eAAiB,EAAI,GAAK,MAG/E,IACX,EACA,IACgC,CAChC,IAAM,EAAa,EAAW,OAAO,WAC/B,EAAU,GAAW,EAAW,UAAU,EAC1C,EAAc,GAAa,GAC3B,EAAU,GAAU,EAAW,OAAO,EACtC,EAAQ,EAAW,QAAQ,OAAS,QACtC,GAAsB,EAAW,QAAS,EAAW,OAAO,SAAS,EACrE,KACE,EAAc,EAAW,QAAQ,OAAS,eAC5C,GAA4B,EAAW,QAAS,EAAW,OAAQ,CAAU,EAC7E,KACE,EAAoB,EAAW,QAAQ,OAAS,qBAClD,GAAkC,EAAW,QAAS,CAAU,EAChE,KACE,EAAiB,EAAW,QAAQ,OAAS,OAC/C,GAA+B,EAAW,QAAS,CAAU,EAC7D,KACE,EAAoB,EAAW,QAAQ,OAAS,aAClD,GAAkC,EAAa,EAAW,QAAS,CAAU,EAC7E,KACE,EAA0B,GAAmB,CAAU,EACvD,EAAe,EAAW,OAAO,WAAW,OAClD,MAAO,CACL,SAAU,GAAY,CAAU,EAChC,mBAAoB,8DACpB,aAAc,GAAgB,CAC5B,WAAY,EAAW,WACvB,QACA,eACA,cACA,MAAO,EAAW,KACpB,CAAC,EACD,cAAe,GACb,GAAuB,GAAiB,EAAW,OAAO,MAAM,EAAG,CAAK,EACxE,EACA,EAAW,OAAO,MACpB,EACA,oBACA,iBACA,eAAgB,GAAG,GAAU,EAAW,YAAY,GAAG,EAAW,WAAW,iBAAiB,EAAY,IACxG,IAAiB,EACb,qCACA,iBAAiB,IAAe,EAAW,OAAO,4BAA8B,IAAM,GAAG,UACzF,IAAiB,EAAI,GAAK,IAC3B,KAEL,WAAY,EAAW,WACvB,SAAU,CACR,WAAY,EAAW,MAAM,eAAe,OAC5C,UAAW,GAAa,CAAU,EAClC,kBAAmB,EAAmB,CAAuB,EAC7D,cAAe,GAAkB,CAAuB,EACxD,UAAW,EAAW,MAAM,cAAc,OAC1C,UAAW,GAAG,EAAW,WAAW,qBAAqB,EAAW,OAAO,UAC7E,EACA,MAAO,CACL,CAAE,MAAO,SAAU,MAAO,GAAU,EAAW,WAAY,EAC3D,CAAE,MAAO,UAAW,MAAO,CAAY,EACvC,GAAG,GAAS,EAAW,OAAO,CAChC,EACA,UAAW,GAAa,CAAU,EAClC,kBAAmB,EAAmB,CAAuB,EAC7D,cAAe,GAAkB,CAAuB,EACxD,UAAW,GAAU,EAAW,YAChC,QACA,oBACA,cACA,gBAAiB,GAAmB,CAAU,EAC9C,cAAe,GAAiB,EAAY,EAAa,CAAW,EACpE,cAAe,GAAiB,EAAY,EAAa,CAAO,EAChE,uBAAwB,gEACxB,SAAU,EAAW,OAAO,WAAW,IAAK,IAAe,CACzD,KAAM,GAAY,EAAa,CAAS,EACxC,GAAI,EACJ,MAAO,WAAW,GAAc,CAAS,GAC3C,EAAE,EACF,UACA,cACA,MAAO,EAAW,MAClB,KAAM,GAAmB,EAAW,WAAY,CAAO,CAAC,CAAC,KACzD,SACF,CACF,siCC7jBM,IAAW,CACf,WACA,UACA,WAMA,UAAC,UAAD,CAAS,UAAW,EAAO,QAA3B,WACE,UAAC,SAAD,CAAQ,UAAW,EAAO,eAA1B,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,QAAQ,gBACnB,UACG,IACN,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAC5B,UACG,EACA,CACP,IACM,IAIE,IAAqC,CAChD,aAAa,GACb,aAAa,GACb,WACA,aAAa,CAAE,KAAM,MAAO,EAC5B,eAOkB,CAClB,GAAM,CAAC,EAAc,MAAmB,YAAS,EAAE,EAC7C,CAAC,EAAW,MAAgB,YAAS,EAAE,EACvC,KAAmB,UAAgC,UAAU,EAC7D,EAAqB,CAAC,GAAc,IAAa,QAAa,EAAW,OAAS,aAClF,EAAmB,CAAC,GAAc,IAAa,QAAa,EAAW,OAAS,aAsBtF,OACE,UAAC,UAAD,CAAS,UAAW,EAAO,SAAU,+CAArC,WACE,UAAC,UAAD,CAAS,aAAW,uBAAuB,UAAW,EAAO,OAA7D,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,MAAvB,WACE,SAAC,OAAD,UAAM,eAAmB,IACzB,SAAC,SAAD,UAAS,EAAU,aAAsB,IACzC,SAAC,QAAD,UAAQ,EAAU,WAAmB,EAClC,CACL,cAAC,MAAD,CAAK,UAAW,EAAO,WAAvB,WACE,UAAC,SAAD,YACE,SAAC,OAAD,UAAM,aAAiB,IACvB,SAAC,EAAD,CACE,MAAO,EAAU,iBACjB,KAAM,EAAU,iBAAiB,SAAW,EAAI,UAAY,UAC7D,EACK,KACR,SAAC,IAAD,UAAI,EAAU,WAAe,IAC7B,UAAC,KAAD,CAAI,UAAW,EAAO,aAAtB,WACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,UAAK,EAAU,YAAiB,EAC7B,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,UAAK,EAAU,aAAkB,EAC9B,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,aAAe,IACnB,SAAC,KAAD,UAAK,EAAU,gBAAqB,EACjC,GACH,GACD,CACE,OAET,SAAC,GAAD,CAAS,QAAQ,QAAQ,KAAK,gDAC5B,oBAAC,MAAD,CAAK,UAAW,EAAO,MAAvB,WACE,SAAC,SAAD,UAAS,EAAU,aAAsB,IACzC,UAAC,KAAD,YACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,UAAK,EAAU,SAAc,EAC1B,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,OAAS,IACb,SAAC,KAAD,UAAK,EAAU,OAAY,EACxB,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,OAAS,IACb,SAAC,KAAD,UAAK,EAAU,UAAe,EAC3B,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,eAAiB,IACrB,SAAC,KAAD,UAAK,EAAU,SAAc,EAC1B,GACH,GACD,GACE,IAET,SAAC,GAAD,CAAS,QAAQ,mBAAmB,KAAK,wCACvC,oBAAC,MAAD,CAAK,UAAW,EAAO,YAAa,aAAY,EAAU,iBAAiB,SAAW,EAAI,UAAY,SAAtG,WACE,UAAC,MAAD,YACE,SAAC,SAAD,UAAS,EAAU,gBAAyB,IAC5C,SAAC,IAAD,UAAI,EAAU,iBAAqB,EAChC,IACJ,EAAU,iBAAiB,SAAW,EAAI,MACzC,SAAC,KAAD,UACG,EAAU,iBAAiB,IAAK,IAC/B,SAAC,KAAD,WACE,UAAC,EAAD,CAAM,GAAI,EAAY,KAAtB,WACE,SAAC,OAAD,UAAO,EAAY,GAAU,IAC7B,SAAC,SAAD,UAAS,EAAY,KAAc,IACnC,UAAC,QAAD,WACG,EAAY,QAAU,WAAa,WAAa,SAAS,MAAI,EAAY,aACrE,GACH,CACJ,IARK,EAAY,IAQjB,CACL,CACC,EAEH,GACE,IAET,SAAC,GAAD,CAAS,QAAQ,SAAS,KAAK,8CAC7B,oBAAC,KAAD,CAAI,UAAW,EAAO,OAAtB,WACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,aAAe,IACnB,SAAC,KAAD,UAAK,EAAU,gBAAqB,EACjC,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,WAAa,IACjB,SAAC,KAAD,UAAK,EAAU,UAAU,KAAK,KAAK,GAAK,sBAA2B,EAChE,GACH,GACG,IAET,UAAC,QAAD,CAAO,UAAW,EAAO,SAAU,4BAAnC,WACE,UAAC,SAAD,WAAQ,4BAA0B,EAAU,aAAsB,KAClE,SAAC,OAAD,UAAO,EAAU,cAAqB,GACrC,EAAU,oBAAsB,KAAO,MACtC,UAAC,OAAD,CAAM,SAAU,EAAU,kBAAkB,SAA5C,UAAsD,YAAU,EAAU,kBAAkB,KAAY,GAErG,KACP,UAAC,UAAD,CAAS,aAAW,4BAA4B,oCAAhD,WACE,UAAC,OAAD,CAAM,SA5Hc,GAA2B,CACnD,EAAM,eAAe,EAChB,GACH,EAAS,CACP,KAAM,sBACN,iBAAkB,EAAU,eAC5B,cACF,CAAC,CACL,EAoHM,WACE,UAAC,QAAD,WAAO,kBAEL,SAAC,QAAD,CACE,SAAU,EACV,UAAW,IACX,SAAW,GAAU,EAAgB,EAAM,cAAc,KAAK,EAC9D,QAAQ,6BACR,YACA,MAAO,CACR,EACI,KACP,SAAC,SAAD,CAAQ,SAAU,EAAoB,KAAK,SAAS,8BAE5C,EACJ,KACN,UAAC,OAAD,CAAM,SAnIY,GAA2B,CACjD,EAAM,eAAe,EACjB,CAAC,GAAoB,EAAU,KAAK,CAAC,CAAC,OAAS,IACjD,EAAS,CACP,KAAM,kBACN,iBAAkB,EAAU,eAC5B,SAAU,EAAiB,QAC3B,UAAW,EAAU,KAAK,CAC5B,CAAC,EACD,EAAiB,QAAU,WAE/B,EAwHM,WACE,UAAC,QAAD,WAAO,sBAEL,SAAC,QAAD,CACE,SAAU,EACV,UAAW,IACX,SAAW,GAAU,EAAa,EAAM,cAAc,KAAK,EAC3D,YACA,MAAO,CACR,EACI,KACP,SAAC,SAAD,CACE,SAAU,GAAoB,EAAU,KAAK,CAAC,CAAC,SAAW,EAC1D,YAAe,CACb,EAAiB,QAAU,UAC7B,EACA,KAAK,SACN,2BAEO,IACR,SAAC,SAAD,CACE,SAAU,GAAoB,EAAU,KAAK,CAAC,CAAC,SAAW,EAC1D,YAAe,CACb,EAAiB,QAAU,UAC7B,EACA,KAAK,SACN,0BAEO,EACJ,IACL,EAAW,OAAS,UAAW,SAAC,IAAD,CAAG,KAAK,QAAQ,sDAA8C,GAAI,KACjG,EAAW,OAAS,aAAc,UAAC,IAAD,WAAG,oBAAkB,EAAW,OAAO,KAAS,IAAI,IAChF,GACF,GAEb,ECzMa,GAA8E,CACzF,QAAS,EAAU,EAAS,IAC1B,EACE,GAAW,WAAY,CACrB,IAAM,EAAS,MAAO,GACtB,OAAc,EAAQ,KAAf,MACH,EAAO,cAAc,qBAAqB,CAC1C,OAAQ,CAAE,UAAS,EACnB,QAAS,CACX,CAAC,CAKL,CAAC,CAAC,CAAC,KAAK,GAAe,EAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ,EAGa,IACX,EACA,EACA,EACA,EACA,EAA+C,KAC5C,CACH,GAAM,CAAC,EAAO,MAAY,YAAwC,CAAE,KAAM,MAAO,CAAC,EAC5E,KAAS,UAA+B,IAAI,EAUlD,OATA,oBACE,EAAO,SAAS,MAAM,EACtB,EAAO,QAAU,KACjB,EAAS,CAAE,KAAM,MAAO,CAAC,MACZ,CACX,EAAO,SAAS,MAAM,EACtB,EAAO,QAAU,IACnB,GACC,CAAC,EAAU,CAAU,CAAC,EAClB,CACL,QACA,UAAQ,eAAa,GAAyC,CAC5D,GAAI,IAAe,MAAQ,EAAO,UAAY,KAAM,OACpD,IAAM,EAAQ,IAAI,gBAClB,EAAO,QAAU,EACjB,EAAS,CAAE,KAAM,YAAa,CAAC,EAC/B,EAAU,OAAO,EAAU,EAAS,EAAM,MAAM,CAAC,CAAC,KAC/C,GAAW,CACN,EAAO,UAAY,IACvB,EAAO,QAAU,KACjB,EAAS,CAAE,KAAM,YAAa,QAAO,CAAC,EACtC,EAAY,EACd,EACC,GAAU,CACL,EAAO,UAAY,IACvB,EAAO,QAAU,KACb,EAAmB,sBAAsB,CAAC,CAAC,CAAK,GAAG,EAAiB,CAAU,EAC7E,EAAM,OAAO,SAAS,EAAS,CAAE,KAAM,QAAS,CAAC,EACxD,CACF,CACF,EAAG,CAAC,EAAU,EAAkB,EAAa,EAAY,CAAS,CAAC,CACrE,CACF,ECxEa,GAAgC,aACvC,GAAuC,KACvC,GAA+C,IAC/C,GAAoC,IAgBpC,GAAwF,CAC5F,aAAc,EAAoB,IAAW,CAC3C,IAAM,EAAc,GAA+B,YACnD,OAAO,IAAgB,OACnB,QAAQ,OAAW,MAAM,2CAA2C,CAAC,EACrE,EAAY,EAAoB,CAAM,CAC5C,CACF,EAkBM,GAAmC,GAAc,CACrD,SAAU,EACV,WAAY,GACZ,eAAgB,GAChB,MAAO,GAAgB,CAAC,UAAW,eAAgB,QAAQ,CAAC,CAC9D,CAAC,EAIK,EAAiC,IAAI,IACrC,GAAkC,IAAI,QACtC,GAAoC,IAAI,IACxC,GAAuC,GAAW,WAAY,CAElE,OAAO,OAAO,MADe,IACD,YAC9B,CAAC,CAAC,CAAC,KAAK,GAAe,EAAmB,CAAC,EAErC,GAAoC,GAA+B,CACvE,IAAM,EAAW,GAAkC,IAAI,CAAU,EACjE,GAAI,IAAa,OAAW,OAAO,EACnC,IAAM,EAAW,GAAe,EAAoC,EAEpE,OADA,GAAkC,IAAI,EAAY,CAAQ,EACnD,CACT,EAEM,GAAsC,GAC1C,kCAAkC,IAE9B,GAA+B,GAAyD,CAC5F,GAAI,CACF,IAAM,EAAQ,aAAa,QAAQ,CAAG,EAEtC,OADI,IAAU,KAAa,KACpB,GACL,GAA2B,GAAsB,EAAgC,CAAC,CAAC,CAAC,CAAK,CAC3F,CACF,MAAQ,CACN,OAAO,IACT,CACF,EAEM,IACJ,EACA,IACS,CACT,GAAI,CACF,aAAa,QACX,EACA,GAAkB,GAAsB,EAAgC,CAAC,CAAC,CAAC,CAAe,CAC5F,CACF,MAAQ,CAER,CACF,EAEM,IACJ,EACA,IACS,CACT,IAAM,EAAU,GAA4B,CAAG,EAE7C,MAAS,QAAU,WACnB,EAAQ,WAAa,EAAS,UAC9B,EAAQ,aAAe,EAAS,WAElC,GAAI,CACF,aAAa,WAAW,CAAG,CAC7B,MAAQ,CAER,CACF,EAEM,EAAgC,MACpC,EACA,IACqB,CACrB,IAAI,EAAuB,GAwB3B,OAvBA,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAM,aAAa,OAAO,EAAG,KAAO,IAAgB,CAC3E,MAAY,SAAS,QACzB,IAAI,EAAgB,gBAAkB,EAAgB,WAAa,EAAY,SAAU,CACvF,EAAuB,GACvB,MACF,CACA,GAAI,EAAgB,QAAU,eAAgB,CAC5C,EAAY,SAAS,EAAgB,KAAK,EACtC,EAAgB,gBAAgB,EAAY,iBAAiB,EACjE,MACF,CACA,EAAY,SAAS,SAAS,EAC9B,GAAI,CACF,IAAM,EAAW,MAAM,EAAY,mBAAmB,EAAY,QAAQ,EAC1E,GAAI,EAAY,SAAS,QAAS,OAClC,EAAY,SAAS,EAAW,eAAiB,MAAM,EACnD,GAAU,EAAY,eAAe,CAC3C,OAAS,EAAS,CAChB,GAAI,EAAY,SAAS,QAAS,OAC9B,EAAmB,sBAAsB,CAAC,CAAC,CAAO,GAAG,EAAY,iBAAiB,EACtF,EAAY,SAAS,QAAQ,CAC/B,CAhBA,CAiBF,CAAC,CAAC,EACK,CACT,EAEM,IACJ,EACA,EACA,EAAQ,KACU,CAClB,GAAI,EAAM,SAAW,KAAM,OAAO,EAAM,OAAO,WAC/C,IAAM,EAAQ,IAAI,gBACZ,EAAc,EAAkB,EAAuB,EACvD,EAAa,GAAmC,CAAkB,EACpE,EAAuB,GACrB,EAAuB,SAA2B,CACtD,IAAM,EAAmB,MAAM,EACzB,EAAa,MAAM,EAAkB,EAAuB,EAC5D,EAAS,EAAM,aAAa,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAClD,GAAI,IAAW,QAAa,EAAM,OAAO,QAAS,OAClD,IAAM,EAAS,GAA4B,CAAU,EAC/C,EAAY,IAAW,KAAO,KAAO,EAAa,EAAO,WAC/D,GACE,IAAW,MACX,IAAc,MACd,EAAO,YAAc,EAAa,KACjC,CAAC,EAAO,gBAAkB,EAAO,WAAa,EAAO,YACrD,EAAO,QAAU,UACd,EAAY,GACZ,CAAC,IACA,EAAO,YAAc,GAAoB,EAAY,KAC1D,CACI,EAAO,QAAU,YAAW,EAAuB,MAAM,EAA8B,EAAO,CAAM,GACxG,MACF,CACA,IAAM,EAAU,CACd,SAAU,EAAO,SACjB,aACA,eAAgB,GAChB,MAAO,SACT,EACA,GAA6B,EAAY,CAAO,EAChD,EAAuB,MAAM,EAA8B,EAAO,CAAO,EACzE,IAAM,MAAmC,GAA6B,EAAY,CAAO,EACzF,EAAM,OAAO,iBAAiB,QAAS,EAAsB,CAAE,KAAM,EAAK,CAAC,EAC3E,GAAI,CACF,IAAM,EAAS,MAAM,EAAO,UAAU,YAAY,EAAoB,EAAM,MAAM,EAClF,GAAI,EAAM,OAAO,QAAS,OAAO,EAAqB,EACtD,IAAM,EAAY,CAChB,SAAU,EAAO,SACjB,WAAY,MAAM,EAAkB,EAAuB,EAC3D,eAAgB,GAChB,MAAO,EAAO,SAAW,eAAiB,eAAiB,QAC7D,EACA,GAA6B,EAAY,CAAS,EAClD,EAAuB,MAAM,EAA8B,EAAO,CAAS,CAC7E,OAAS,EAAS,CAChB,GAAI,EAAM,OAAO,QAAS,OAAO,EAAqB,EACtD,IAAM,EAAS,CACb,SAAU,EAAO,SACjB,WAAY,MAAM,EAAkB,EAAuB,EAC3D,eAAgB,EAAmB,sBAAsB,CAAC,CAAC,CAAO,EAClE,MAAO,QACT,EACA,GAA6B,EAAY,CAAM,EAC/C,EAAuB,MAAM,EAA8B,EAAO,CAAM,CAC1E,QAAU,CACR,EAAM,OAAO,oBAAoB,QAAS,CAAoB,CAChE,CACF,EACM,EAAc,UAAW,UAAY,UAAU,MAAQ,KACvD,GACJ,IAAgB,KACZ,EAAqB,EACrB,EAAY,QACZ,kCAAkC,IAClC,CAAE,OAAQ,EAAM,MAAO,MACjB,EAAqB,CAC7B,GACF,MAAM,KAAsB,IAA2B,CACvD,IAAM,EAAS,EAAM,aAAa,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAC9C,CAAC,EAAM,OAAO,SAAW,IAAW,SAOtC,EAAuB,MAAM,EAA8B,EAAO,CALhE,SAAU,EAAO,SACjB,WAAY,EACZ,eAAgB,EAAmB,sBAAsB,CAAC,CAAC,CAAO,EAClE,MAAO,QAEyD,CAAM,EAE5E,CAAC,CAAC,CAAC,YAAc,CACX,EAAM,QAAQ,QAAU,IAAO,EAAM,OAAS,MAC9C,GAAwB,SAAS,kBAAoB,WACvD,GAA8B,EAAoB,EAAO,EAAI,CAEjE,CAAC,EAED,MADA,GAAM,OAAS,CAAE,QAAO,YAAW,EAC5B,CACT,EAEM,IACJ,EACA,IACe,CACf,IAAI,EAAkC,KAClC,EAAa,EACb,EAAU,GACR,EAAY,GAAoC,CACpD,GAAI,GAAW,IAAsB,EAAY,OACjD,IAAM,EAAc,IAAI,gBACxB,EAAU,EACV,EAAuB,EAAa,EAA6B,EAAG,CAAE,OAAQ,EAAY,MAAO,CAAC,CAAC,CAAC,SAC5F,EAAuB,EACb,GAA4B,CAC1C,GAAI,CAAC,EAAY,OAAO,QACtB,IAAK,IAAM,KAAe,EAAM,aAAa,OAAO,EAAG,EAAY,SAAS,QAAQ,CAExF,CACF,CACF,EACM,MAAqC,CACzC,GAAc,EACd,IAAM,EAAoB,EAC1B,GAAS,MAAM,EACf,EAAU,MACS,SAAS,kBAAoB,UAC5C,GAAyB,EAAoB,CAAK,EAClD,QAAQ,QAAQ,GACJ,YAAc,EAAS,CAAiB,CAAC,CAC3D,EACM,MAAqC,CACzC,GAAI,SAAS,kBAAoB,UAAW,CAC1C,GAAc,EACd,IAAM,EAAoB,EAC1B,GAAS,MAAM,EACf,EAAU,KACV,GAA8B,EAAoB,EAAO,EAAI,CAAC,CAAC,YAAc,EAAS,CAAiB,CAAC,CAC1G,CACF,EACM,EAA6B,GAA8B,CAC/D,GAAI,EAAM,MAAQ,GAAmC,CAAkB,GAAK,EAAM,WAAa,KAAM,OACrG,IAAM,EAAkB,GACtB,GAA2B,GAAsB,EAAgC,CAAC,CAAC,CAAC,EAAM,QAAQ,CACpG,EACI,IAAoB,MACxB,EAAmC,EAAO,CAAe,CAAC,CAAC,KAAM,GAAyB,CACpF,GAAwB,SAAS,kBAAoB,WACvD,GAA8B,EAAoB,EAAO,EAAI,CAEjE,CAAC,CACH,EAIA,OAHA,SAAS,iBAAiB,mBAAoB,CAAsB,EACpE,OAAO,iBAAiB,UAAW,CAAyB,EAC5D,EAAuB,MACV,CACX,EAAU,GACV,GAAc,EACd,GAAS,MAAM,EACf,EAAU,KACV,EAAM,QAAQ,MAAM,MAAM,EAC1B,EAAM,OAAS,KACf,SAAS,oBAAoB,mBAAoB,CAAsB,EACvE,OAAO,oBAAoB,UAAW,CAAyB,CACjE,CACF,EAEM,IACJ,EACA,IACe,CACf,IAAM,EAAgB,OAAO,EACvB,EAAW,EAA+B,IAAI,CAAkB,EAChE,EAAQ,GAAY,CAAE,OAAQ,KAAM,aAAc,IAAI,GAAM,EAMlE,OALA,EAAM,aAAa,IAAI,EAAe,CAAW,EAC7C,IAAa,SACf,EAA+B,IAAI,EAAoB,CAAK,EAC5D,GAAgC,IAAI,EAAO,GAA8B,EAAoB,CAAK,CAAC,OAExF,CACX,EAAM,aAAa,OAAO,CAAa,EACnC,EAAM,aAAa,OAAS,IAChC,GAAgC,IAAI,CAAK,CAAC,GAAG,EAC7C,GAAgC,OAAO,CAAK,EACxC,EAA+B,IAAI,CAAkB,IAAM,GAC7D,EAA+B,OAAO,CAAkB,EAE5D,CACF,EAEM,GAAqC,KACzC,IACqH,CACrH,IAAM,EAAkB,GAA4B,CAAU,EAC9D,GAAI,GAAiB,QAAU,UAAW,OAAO,KACjD,IAAM,EAAM,MAAM,EAAkB,EAAuB,EAC3D,GAAI,EAAgB,WAAa,EAAM,GAA8C,OAAO,KAC5F,IAAM,EAAkB,EAAgB,WAAa,GAAoC,EACzF,OAAO,GAAmB,EAAI,KAAO,CAAE,kBAAiB,iBAAgB,CAC1E,EAEM,GAAiC,MACrC,EACA,IACkB,CAClB,IAAM,EAAa,GAAmC,CAAkB,EACxE,OAAa,CACX,GAAI,EAAqB,QAAS,OAClC,IAAM,EAAQ,MAAM,GAAmC,CAAU,EACjE,GAAI,IAAU,KAAM,OACpB,IAAM,EAAW,IAAI,gBACrB,MAAM,IAAI,QAAe,GAAY,CACnC,IAAI,EAAW,GACT,MAAqB,CACrB,IACJ,EAAW,GACX,EAAS,MAAM,EACf,OAAO,oBAAoB,UAAW,CAAc,EACpD,EAAqB,oBAAoB,QAAS,CAAM,EACxD,EAAQ,EACV,EACM,EAAkB,GAA8B,CAChD,EAAM,MAAQ,GAAY,EAAO,CACvC,EACA,OAAO,iBAAiB,UAAW,CAAc,EACjD,EAAqB,iBAAiB,QAAS,EAAQ,CAAE,KAAM,EAAK,CAAC,EACjE,EAAqB,SAAS,EAAO,EACzC,IAAM,EAAU,GAA4B,CAAU,GAEpD,GAAS,QAAU,WACnB,EAAQ,WAAa,EAAM,gBAAgB,UAC3C,EAAQ,aAAe,EAAM,gBAAgB,aAC7C,EAAO,EACT,EAAuB,EAAa,EAAM,eAAe,EAAG,CAAE,OAAQ,EAAS,MAAO,CAAC,CAAC,CAAC,KACvF,EACgB,GAA4B,CACrC,EAAS,OAAO,SAAS,EAAO,CACvC,CACF,CACF,CAAC,CACH,CACF,EAGa,IAAoC,CAC/C,UACA,mBACA,iBACA,qBACA,8BACA,aACA,0BACA,YAAY,MAUR,CACJ,GAAM,CAAC,EAAO,MAAY,YAA6C,MAAM,EACvE,KAAuB,UAA+B,IAAI,EAC1D,KAAiB,UAAO,CAAgB,EACxC,KAAe,UAAO,CAAc,EACpC,KAAiB,UAAO,CAA2B,EACnD,KAAgB,UAAO,CAAE,qBAAoB,aAAY,MAAO,CAAwB,CAAC,EAC/F,EAAe,QAAU,EACzB,EAAa,QAAU,EACvB,EAAe,QAAU,EAEvB,EAAc,QAAQ,qBAAuB,GAC7C,EAAc,QAAQ,aAAe,EAErC,EAAc,QAAU,CAAE,qBAAoB,aAAY,MAAO,CAAwB,EAEzF,IAA4B,OAC3B,EAAc,QAAQ,QAAU,MAAQ,EAA0B,EAAc,QAAQ,SAEzF,EAAc,QAAQ,MAAQ,GAEhC,IAAM,KAAqB,eAAY,KAAO,IAA0C,CACtF,IAAM,EAAkB,MAAM,EAAe,QAAQ,CAAM,EACrD,EAAmB,EAAc,QAAQ,MAG/C,OAFI,IAAoB,MAAQ,IAAqB,MAAQ,GAAmB,EAAyB,IACzG,EAAc,QAAQ,MAAQ,EACvB,GACT,EAAG,CAAC,CAAC,EAEC,KAAc,mBAAiC,CACnD,GAAI,CAAC,GAAW,IAAuB,MAAQ,IAAe,KAAM,OAAO,QAAQ,QAAQ,EAC3F,IAAM,EAAQ,EAA+B,IAAI,CAAkB,EACnE,OAAO,IAAU,OAAY,QAAQ,QAAQ,EAAI,GAAyB,EAAoB,EAAO,EAAI,CAC3G,EAAG,CAAC,EAAS,EAAoB,CAAU,CAAC,EAEtC,KAAuB,mBAAwB,CACnD,IAAM,EAAW,EAAqB,SAAS,OAC/C,GAAI,IAAa,QAAa,EAAS,QAAS,OAChD,IAAM,EAAW,IAAuB,KACpC,OACA,EAA+B,IAAI,CAAkB,CAAC,EAAE,QAAQ,YAC7D,GAA+B,EAAoB,CAAQ,EAC9D,IAAa,OAAW,EAAiB,EAE3C,EAAc,SAAW,CAClB,EAAS,SAAS,EAAiB,CAC1C,CAAC,CAEL,EAAG,CAAC,EAAoB,CAAW,CAAC,EAwBpC,OAtBA,mBAAgB,CAEd,GADA,EAAS,MAAM,EACX,CAAC,GAAW,IAAuB,MAAQ,IAAe,KAAM,OACpE,IAAM,EAAW,IAAI,gBACrB,EAAqB,QAAU,EAC/B,IAAM,EAAa,GAAiC,EAAoB,CACtE,SAAU,EAAS,OACnB,qBAAwB,EAAe,QAAQ,CAAU,EACzD,mBAAsB,EAAa,QAAQ,EAC3C,SAAU,GAAiC,CAAU,EACrD,aACA,WACA,YACA,oBACF,CAAC,EACD,UAAa,CACX,EAAS,MAAM,EACX,EAAqB,UAAY,IAAU,EAAqB,QAAU,MAC9E,EAAW,CACb,CACF,EAAG,CAAC,EAAS,EAAoB,EAAY,EAAW,CAAkB,CAAC,EAEpE,CACL,QACA,yBAA0B,EAC1B,eAAgB,CAClB,CACF,8xBCzdM,GAAkB,GAA0B,EAAM,QAAQ,mBAAoB,MAAM,EACpF,GAAiB,GAAgC,EAAK,WAAa,KAAK,aACxE,GAAmB,GACvB,EAAK,QAAQ,kBAAkB,OAAO,IAAM,SAC5C,SAAU,GACV,EAAK,OAAS,YACd,YAAa,GACb,GAAoB,EAAK,OAAO,EAE5B,EAAkB,GAAuB,CAC7C,GAAI,EAAK,WAAa,KAAK,UAAW,OAAO,GAAe,EAAK,aAAe,EAAE,EAClF,GAAI,CAAC,GAAc,CAAI,EAAG,MAAO,GACjC,IAAM,EAAU,CAAC,GAAG,EAAK,UAAU,CAAC,CAAC,IAAI,CAAc,CAAC,CAAC,KAAK,EAAE,EAChE,OAAQ,EAAK,QAAQ,kBAAkB,OAAO,EAA9C,CACE,IAAK,SACL,IAAK,IACH,MAAO,KAAK,EAAQ,IACtB,IAAK,KACL,IAAK,IACH,MAAO,IAAI,EAAQ,GACrB,IAAK,IACL,IAAK,MACH,MAAO,KAAK,EAAQ,IACtB,IAAK,OACH,MAAO,MAAM,EAAK,aAAe,IAAI,QAAQ,MAAO,KAAK,EAAE,IAC7D,IAAK,IAAK,CACR,IAAM,EAAO,EAAK,aAAa,MAAM,EACrC,OAAO,IAAS,KAAO,EAAU,IAAI,EAAQ,IAAI,EAAK,QAAQ,OAAQ,KAAK,EAAE,EAC/E,CACA,IAAK,KACH,MAAO;EACT,QACE,OAAO,CACX,CACF,EAEM,IAAgB,EAAkB,EAAkB,EAAQ,IAChE,CAAC,GAAG,EAAQ,QAAQ,CAAC,CAClB,OAAQ,GAAU,EAAM,QAAQ,kBAAkB,OAAO,IAAM,IAAI,CAAC,CACpE,KAAK,EAAO,IAAU,CACrB,IAAM,EAAO,CAAC,GAAG,EAAM,QAAQ,CAAC,CAAC,KAAK,EAAe,EAC/C,EAAS,IAAS,OAAY,GAAK,IAAI,EAAK,QAAU,IAAM,IAAI,IAChE,EAAc,CAAC,GAAG,EAAM,QAAQ,CAAC,CAAC,OAAQ,GAAS,eAAe,KAAK,EAAK,QAAQ,YAAY,CAAC,CAAC,EAClG,EAAQ,CAAC,GAAG,EAAM,UAAU,CAAC,CAChC,OAAQ,GAAS,CAAC,GAAc,CAAI,GAAK,CAAC,eAAe,KAAK,EAAK,QAAQ,YAAY,CAAC,CAAC,CAAC,CAC1F,IAAI,CAAc,CAAC,CACnB,KAAK,EAAE,CAAC,CACR,KAAK,EACF,EAAS,KAAK,OAAO,CAAK,EAC1B,EAAS,EAAY,IAAK,GAAS,GAAa,EAAM,EAAK,QAAQ,YAAY,IAAM,KAAM,EAAQ,CAAC,CAAC,EAC3G,MAAO,CACL,GAAG,IAAS,EAAU,GAAG,OAAO,EAAQ,CAAC,EAAE,GAAK,IAAI,GAAG,IAAS,OAAY,GAAK,IAAS,IAC1F,GAAG,CACL,CAAC,CAAC,KAAK;CAAI,CACb,CAAC,CAAC,CACD,KAAK;CAAI,EAER,GAAiB,GAAuB,CAC5C,GAAI,EAAK,WAAa,KAAK,UAAW,OAAO,GAAe,EAAK,aAAe,EAAE,EAClF,GAAI,CAAC,GAAc,CAAI,EAAG,MAAO,GACjC,IAAM,EAAM,EAAK,QAAQ,kBAAkB,OAAO,EAClD,OAAQ,EAAR,CACE,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACH,MAAO,GAAG,IAAI,OAAO,OAAO,EAAI,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAe,CAAI,CAAC,CAAC,KAAK,IAC1E,IAAK,KACH,OAAO,GAAa,EAAM,EAAK,EACjC,IAAK,KACH,OAAO,GAAa,EAAM,EAAI,EAChC,IAAK,aACH,OAAO,EAAe,CAAI,CAAC,CACxB,KAAK,CAAC,CACN,MAAM;CAAI,CAAC,CACX,IAAK,GAAS,KAAK,GAAM,CAAC,CAC1B,KAAK;CAAI,EACd,IAAK,MAAO,CACV,IAAM,EAAU,EAAK,aAAe,GAC9B,EAAe,KAAK,IAAI,EAAG,GAAG,CAAC,GAAG,EAAQ,SAAS,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAY,EAAO,MAAM,CAAC,EAC5F,EAAQ,IAAI,OAAO,KAAK,IAAI,EAAG,EAAe,CAAC,CAAC,EACtD,MAAO,GAAG,EAAM,IAAI,EAAQ,IAAI,GAClC,CACA,IAAK,KACH,MAAO,MACT,IAAK,IACL,IAAK,MACL,IAAK,UACL,IAAK,UAIH,MAHsB,CAAC,GAAG,EAAK,QAAQ,CAAC,CAAC,KAAM,GAC7C,8DAA8D,KAAK,EAAM,QAAQ,kBAAkB,OAAO,CAAC,CAEtG,EACH,CAAC,GAAG,EAAK,UAAU,CAAC,CACjB,IAAI,EAAa,CAAC,CAClB,OAAQ,GAAS,EAAK,KAAK,CAAC,CAAC,OAAS,CAAC,CAAC,CACxC,KAAK;;CAAM,EACd,EAAe,CAAI,CAAC,CAAC,KAAK,EAEhC,QACE,OAAO,EAAe,CAAI,CAAC,CAAC,KAAK,CACrC,CACF,EAGa,GAA4B,GACvC,CAAC,GAAG,EAAK,UAAU,CAAC,CACjB,IAAI,EAAa,CAAC,CAClB,OAAQ,GAAS,EAAK,KAAK,CAAC,CAAC,OAAS,CAAC,CAAC,CACxC,KAAK;;CAAM,CAAC,CACZ,QAAQ,WAAY;;CAAM,CAAC,CAC3B,KAAK,EAEJ,GAAoB,EAAiB,IAAyB,CAClE,SAAS,YAAY,EAAS,GAAO,CAAK,CAC5C,EAGa,GAAgC,GAAgC,CAC3E,IAAM,EAAS,IAAI,MAAM,CAAI,EAC7B,OAAO,IAAW,OAAS,EAAO,WAAa,SAAW,EAAO,WAAa,UAAY,EAAO,KAAO,IAC1G,EAEa,GAA+B,GAA2B,IAAU,YAE3E,MAAoB,SACvB,CAAE,eAA4D,SAAC,GAAD,CAAmB,MAAO,CAAW,OAC9F,EACR,EAca,IAAmC,CAC9C,UACA,WACA,aACA,UACA,OACA,YACA,oBAAoB,GACpB,WACwD,CACxD,GAAM,CAAC,EAAO,MAAY,YAAsB,CAAE,KAAM,MAAO,CAAC,EAC1D,CAAC,EAAgB,MAAqB,YAAwB,IAAI,EAClE,CAAC,EAAgB,MAAqB,YAAS,EAAK,EACpD,CAAC,EAAY,MAAiB,YAAS,CAAK,EAC5C,KAAY,UAAuB,IAAI,EACvC,EAAU,EAAM,OAAS,QAAU,EAAM,OAAS,QAClD,EAAO,EAAM,OAAS,SACtB,EAAc,GAAsB,EAAK,SAAW,EAAE,GAE5D,mBAAgB,CACd,EAAc,CAAK,EACnB,EAAS,CAAE,KAAM,MAAO,CAAC,EACzB,EAAkB,IAAI,EACtB,EAAkB,EAAK,CACzB,EAAG,CAAC,EAAK,SAAU,CAAK,CAAC,EAEzB,IAAM,GAAkB,EAAmB,IAA2B,CACpE,GAAI,CAAC,GAAW,CAAC,EAAK,iBAAmB,IAAc,MAAQ,EAAK,UAAY,MAAQ,IAAmB,KACzG,OAEF,IAAM,EAAkB,GAAyB,EAAK,QAAS,EAAW,CAAO,EAC7E,IAAoB,OACxB,EAAkB,CAAS,EAC3B,EAAkB,EAAK,EACvB,EAAkB,CAChB,YACA,SAAU,aACV,QACA,SAAU,EACV,eAAgB,EAChB,eAAgB,GAAS,KAAK,EAAK,QAAQ,EAC3C,OAAQ,YAAY,QAAQ,GAAM,CACpC,CAAC,CAAC,CACC,KACE,GAAW,CACN,GAA4B,EAAO,KAAK,EAAG,EAAQ,EAClD,EAAkB,EAAI,CAC7B,MACM,EAAkB,EAAI,CAC9B,CAAC,CACA,YAAc,EAAkB,IAAI,CAAC,EAC1C,EAsHA,OArFK,GAsFH,UAAC,MAAD,CAAK,UAAW,EAAO,aAAc,mCAArC,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,cAAvB,WACE,UAAC,MAAD,YACE,UAAC,EAAD,CAAM,GAAG,SAAT,UAAkB,oBAAkB,EAAK,QAAe,CACxD,aAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAAO,0FAEhC,EACH,KACL,UAAC,MAAD,CAAK,UAAW,EAAO,cAAvB,WACE,SAAC,EAAD,CAAQ,SAAU,EAAM,QAAS,EAAY,QAAQ,YAAY,oBAEzD,IACR,SAAC,EAAD,CAAQ,SAAU,EAAM,YAAe,EAAS,CAAE,KAAM,MAAO,CAAC,EAAG,QAAQ,YAAY,iBAE/E,IACR,SAAC,EAAD,CAAQ,SAAU,EAAM,QAAS,EAAM,YApItB,CACvB,IAAM,EAAS,EAAU,QACzB,GAAI,IAAW,MAAQ,IAAc,MAAQ,EAAM,OACnD,IAAM,EAAW,GAAyB,CAAM,EAC1C,EAAkB,EAAW,KAAK,EACxC,GAAI,EAAgB,SAAW,GAAK,EAAS,SAAW,EAAG,CACzD,EAAS,CAAE,KAAM,QAAS,CAAC,EAC3B,MACF,CACA,EAAS,CAAE,KAAM,QAAS,CAAC,EAC3B,EAAkB,CAChB,YACA,SAAU,aACV,MAAO,EACP,WACA,eAAgB,EAChB,eAAgB,GAAS,KAAK,EAAK,QAAQ,EAC3C,OAAQ,YAAY,QAAQ,GAAM,CACpC,CAAC,CAAC,CAAC,KACA,GAAW,CACN,GAA4B,EAAO,KAAK,GAC1C,EAAS,CAAE,KAAM,OAAQ,CAAC,EAC1B,EAAQ,GAER,EAAS,CAAE,KAAM,QAAS,CAAC,CAE/B,MACM,EAAS,CAAE,KAAM,QAAS,CAAC,CACnC,CACF,EAuG8D,6BAE9C,EACL,CACF,MACJ,EAAK,eAAiB,UAAY,EAAK,UAAY,MAClD,SAAC,EAAD,CACE,YAAY,iIACZ,MAAM,uBACN,KAAK,SACN,GACC,MACJ,SAAC,EAAD,CAAO,MAAM,aACT,aACA,SAAC,QAAD,CACE,GAAI,EACJ,SAAU,EACV,UAAW,IACX,SAAW,GAAU,EAAc,EAAM,OAAO,KAAK,EACrD,MAAO,CACR,EAEE,IACP,UAAC,MAAD,CACE,aAAW,sBACX,UAAW,EAAO,cAClB,YAAc,GAAU,EAAM,eAAe,EAC7C,KAAK,UAJP,WAME,SAAC,SAAD,CAAQ,YAAe,EAAiB,cAAe,GAAG,EAAG,KAAK,SAAS,oBAEnE,IACR,SAAC,SAAD,CAAQ,YAAe,EAAiB,cAAe,IAAI,EAAG,KAAK,SAAS,oBAEpE,IACR,SAAC,SAAD,CAAQ,YAAe,EAAiB,cAAe,IAAI,EAAG,KAAK,SAAS,oBAEpE,IACR,SAAC,SAAD,CAAQ,aAAW,OAAO,YAAe,EAAiB,MAAM,EAAG,KAAK,SACtE,mBAAC,SAAD,UAAQ,GAAS,EACX,IACR,SAAC,SAAD,CAAQ,aAAW,SAAS,YAAe,EAAiB,QAAQ,EAAG,KAAK,SAC1E,mBAAC,KAAD,UAAI,GAAK,EACH,IACR,SAAC,SAAD,CAAQ,YAAe,EAAiB,qBAAqB,EAAG,KAAK,SAAS,kBAEtE,IACR,SAAC,SAAD,CAAQ,YAAe,EAAiB,mBAAmB,EAAG,KAAK,SAAS,mBAEpE,IACR,SAAC,SAAD,CACE,YAAe,CACb,IAAM,EAAO,OAAO,OAAO,cAAc,EACnC,EAAW,IAAS,KAAO,KAAO,GAA6B,CAAI,EACrE,IAAa,MAAM,EAAiB,aAAc,CAAQ,CAChE,EACA,KAAK,SACN,eAEO,EACL,KACL,SAAC,MAAD,CACE,aAAW,uBACX,iBAAe,OACf,UAAW,GAAG,EAAO,aAAa,GAAG,EAAO,WAC5C,gBAAiB,CAAC,EAClB,IAAK,EACL,KAAK,UACL,kCAEA,mBAAC,GAAD,CAAmB,SAAU,EAAK,SAAW,EAAK,EAC/C,GACJ,EAAM,OAAS,UACd,SAAC,EAAD,CACE,YAAY,yFACZ,MAAM,yBACN,KAAK,UACN,GACC,IACD,KAlLH,UAAC,MAAD,CAAK,UAAW,EAAO,aAAvB,UACG,EAAK,eAAiB,UAAY,EAAK,UAAY,MAClD,SAAC,GAAD,CAAmB,UAAW,EAAO,SAAU,MAAO,EAAK,OAAU,IAErE,UAAC,MAAD,CAAK,UAAW,EAAO,aAAc,qBAAoB,EAAK,aAA9D,WACE,SAAC,SAAD,UACG,EAAK,eAAiB,OAAS,8BAAgC,+BAC1D,IACR,SAAC,EAAD,CAAM,KAAK,YAAY,4JAGjB,EACH,IAEN,EAAY,QAAU,EAAI,MACzB,UAAC,UAAD,CAAS,kBAAgB,2BAA2B,UAAW,EAAO,aAAtE,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,mBAAvB,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,GAAG,2BAA2B,QAAQ,aAAa,wBAE3D,IACN,UAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAA/B,UACG,EAAY,UAAU,OAAK,EAAY,MAAM,WAC1C,CACH,OACL,SAAC,KAAD,CAAI,UAAW,EAAO,gBACnB,WAAY,MAAM,IAAK,IACtB,UAAC,KAAD,YACE,UAAC,QAAD,YACE,SAAC,QAAD,CACE,QAAS,EAAK,QACd,SAAU,CAAC,GAAW,CAAC,EAAK,iBAAmB,IAAc,MAAQ,IAAmB,KACxF,SAAW,GAAU,EAAe,EAAK,UAAW,EAAM,OAAO,OAAO,EACxE,KAAK,UACN,IACD,SAAC,OAAD,UAAO,EAAK,KAAY,EACnB,IACN,IAAmB,EAAK,WAAY,SAAC,EAAD,CAAM,QAAQ,OAAO,kBAAa,GAAI,IACzE,GAXK,GAAG,OAAO,EAAK,SAAS,EAAE,GAAG,EAAK,OAWvC,CACL,CACC,GACH,EAAY,cAAgB,GAC3B,SAAC,EAAD,UAAM,oCAAwC,IAE9C,UAAC,EAAD,CAAM,KAAK,YAAX,UACG,EAAY,YAAY,QAAM,EAAY,cAAgB,EAAI,GAAK,IAAI,6BACpE,IAEN,EAAK,gBAKH,MAJF,SAAC,EAAD,CAAM,KAAK,YAAY,iLAGjB,GAEP,GACC,SAAC,EAAD,CACE,YAAY,oEACZ,MAAM,2BACN,KAAK,UACN,GACC,IACG,KAEX,UAAC,MAAD,CAAK,UAAW,EAAO,YAAvB,WACE,SAAC,EAAD,CAAQ,SAAU,CAAC,GAAW,IAAc,KAAM,YAAe,EAAS,CAAE,KAAM,SAAU,CAAC,EAC1F,WAAK,eAAiB,UAAY,EAAK,UAAY,KAChD,oBACA,8BACE,IACR,SAAC,EAAD,CAAQ,QAAS,EAAY,QAAQ,YAAY,4BAEzC,GACP,EAAM,OAAS,SAAU,SAAC,EAAD,UAAM,sBAA0B,GAAI,KAC5D,EAEE,MADF,SAAC,EAAD,CAAM,KAAK,YAAY,+EAA0E,GAElG,GAAW,IAAc,MACxB,SAAC,EAAD,CAAM,KAAK,YAAY,kEAA6D,GAClF,IACD,GACF,GAqGX,EClaM,IAAW,CACf,WACA,UACA,WAMA,UAAC,UAAD,CAAS,UAAW,EAAO,QAA3B,WACE,UAAC,SAAD,CAAQ,UAAW,EAAO,eAA1B,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,QAAQ,gBACnB,UACG,IACN,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAC5B,UACG,EACA,CACP,IACM,IAIE,IAAkC,CAC7C,SACA,UAIkB,CAClB,GAAM,CAAC,EAAgB,MAAqB,YAAS,EAAK,EAC1D,OACE,UAAC,UAAD,CAAS,UAAW,EAAO,SAAU,2CAArC,WACE,UAAC,UAAD,CAAS,aAAW,oBAAoB,UAAW,EAAO,MAA1D,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,SAAvB,WACE,SAAC,OAAD,UAAM,UAAc,IACpB,SAAC,SAAD,UAAS,EAAK,QAAiB,EAC5B,CACL,cAAC,MAAD,CAAK,UAAW,EAAO,UAAvB,WACE,SAAC,EAAD,CACE,MAAO,EAAK,OACZ,KAAM,EAAK,SAAW,aAAe,UAAY,EAAK,SAAW,UAAY,WAAa,SAC3F,IACD,UAAC,KAAD,YACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,OAAS,IACb,SAAC,KAAD,UAAK,EAAK,aAAkB,EACzB,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,UACG,EAAK,YAAc,KAClB,oBAEA,SAAC,OAAD,CAAM,SAAU,EAAK,UAAU,SAAW,WAAK,UAAU,KAAY,EAErE,EACD,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,UACG,EAAK,YAAc,KAClB,oBAEA,SAAC,OAAD,CAAM,SAAU,EAAK,UAAU,SAAW,WAAK,UAAU,KAAY,EAErE,EACD,GACH,GACD,CACE,OAET,SAAC,GAAD,CAAS,QAAQ,WAAW,KAAK,8EAC/B,mBAAC,GAAD,CAAiC,GAAI,EAAc,MAAO,EACnD,IAET,SAAC,GAAD,CAAS,QAAQ,SAAS,KAAM,EAAK,sBAClC,WAAK,aAAa,SAAW,GAC5B,SAAC,EAAD,CAAM,KAAK,YAAY,uEAAkE,IAEzF,SAAC,EAAD,CACE,aAAW,qBACX,SAAU,EACV,MAAO,EACP,iBAAkB,EAClB,OAAQ,EAAK,YACd,EAEI,IAET,UAAC,MAAD,CAAK,UAAW,EAAO,YAAvB,WACE,SAAC,GAAD,CAAS,QAAQ,mBAAmB,KAAM,EAAK,sBAC5C,WAAK,SAAS,SAAW,GACxB,SAAC,EAAD,CAAM,KAAK,YAAY,gDAA2C,IAElE,SAAC,KAAD,CAAI,UAAW,EAAO,SACnB,WAAK,SAAS,IAAK,IAClB,UAAC,KAAD,YACE,UAAC,SAAD,WAAQ,IAAE,EAAQ,MAAe,KACjC,SAAC,OAAD,UAAO,EAAQ,OAAc,IAC7B,UAAC,QAAD,WACG,EAAQ,OAAO,OAAG,SAAC,OAAD,CAAM,SAAU,EAAQ,UAAU,SAAW,WAAQ,UAAU,KAAY,GAC7F,EAAQ,UAAY,gBAAkB,EAClC,GACL,GAPK,GAAG,OAAO,EAAQ,MAAM,EAAE,GAAG,EAAQ,UAAU,UAOpD,CACL,CACC,EAEC,IAET,SAAC,GAAD,CAAS,QAAQ,cAAc,KAAM,EAAK,yBACvC,WAAK,YAAY,SAAW,GAC3B,SAAC,EAAD,CAAM,KAAK,YAAY,mDAA8C,IAErE,SAAC,KAAD,CAAI,UAAW,EAAO,YACnB,WAAK,YAAY,IAAK,IACrB,UAAC,KAAD,YACE,SAAC,SAAD,UAAS,EAAW,KAAc,IAClC,UAAC,OAAD,WACG,EAAW,UAAU,MAAI,EAAW,SAAS,MAAI,EAAW,OACzD,KACN,SAAC,QAAD,UAAO,8CAAmD,EACxD,GANK,EAAW,EAMhB,CACL,CACC,EAEC,EACN,KAEL,SAAC,GAAD,CAAS,QAAQ,mBAAmB,KAAK,+CACvC,oBAAC,MAAD,CAAK,UAAW,EAAO,cAAvB,WACE,SAAC,SAAD,UAAS,EAAK,oBAA6B,IAC3C,UAAC,OAAD,WAAM,gBAAc,EAAK,uBAAyB,EAAI,GAAK,IAAI,+BAAmC,GAC/F,GACE,EACF,GAEb,mdC5IM,GAAW,CACf,WACA,UACA,WAMA,UAAC,UAAD,CAAS,UAAW,EAAO,QAA3B,WACE,UAAC,SAAD,CAAQ,UAAW,EAAO,eAA1B,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,QAAQ,gBACnB,UACG,GACL,IAAS,OAAY,MACpB,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAC5B,UACG,EAEF,CACP,IACM,IAGL,IAAY,CAAE,QAAO,WACzB,IAAU,MACR,SAAC,EAAD,CAAM,KAAK,YAAa,UAAY,IAEpC,SAAC,GAAD,CAAmB,UAAW,EAAO,SAAiB,OAAQ,GAIrD,IAAyB,CAAE,YACtC,UAAC,UAAD,CAAS,UAAW,EAAO,SAAU,iCAArC,UACG,EAAM,oBAAsB,KAAO,MAClC,SAAC,EAAD,CAAM,UAAW,EAAO,eAAgB,KAAK,YAC1C,WAAM,iBACH,IAGR,SAAC,EAAD,CAAS,QAAQ,cAAc,KAAK,uBAClC,mBAAC,GAAD,CAAU,MAAM,6CAA6C,MAAO,EAAM,WAAc,EACjF,IAET,SAAC,EAAD,CAAS,QAAQ,sBAAsB,KAAK,kBAC1C,mBAAC,MAAD,CAAK,UAAW,EAAO,SACrB,mBAAC,GAAD,CAAU,MAAM,4CAA4C,MAAO,EAAM,kBAAqB,EAC3F,EACE,GAER,EAAM,cAAgB,KAAO,MAC5B,SAAC,EAAD,CAAS,QAAQ,cAAc,KAAK,qBAClC,mBAAC,GAAD,CAAU,MAAM,mCAAmC,MAAO,EAAM,WAAc,EACvE,IAGX,SAAC,EAAD,CAAS,QAAQ,SAAS,KAAM,GAAG,OAAO,EAAM,cAAc,MAAM,EAAE,gBACnE,WAAM,cAAc,SAAW,GAC9B,SAAC,EAAD,CAAM,KAAK,YAAY,gEAA2D,IAElF,SAAC,KAAD,CAAI,UAAW,EAAO,OACnB,WAAM,cAAc,IAAK,IACxB,SAAC,KAAD,WACE,SAAC,EAAD,CAAgB,QAAS,EACvB,EAFK,EAAO,EAEZ,CACL,CACC,EAEC,IAET,SAAC,EAAD,CAAS,QAAQ,gBAAgB,KAAK,sBACpC,mBAAC,KAAD,CAAI,UAAW,EAAO,SACnB,WAAM,SAAS,IAAK,IACnB,UAAC,MAAD,YACE,SAAC,KAAD,UAAK,EAAM,KAAU,IACrB,SAAC,KAAD,UAAK,EAAM,KAAU,EAClB,GAHK,EAAM,KAGX,CACN,CACC,EACG,GAER,EAAM,SAAW,MAAQ,EAAM,SAAS,SAAW,EAAI,MACtD,SAAC,EAAD,CAAS,QAAQ,oBAAoB,KAAK,mBACxC,oBAAC,MAAD,CAAK,UAAW,EAAO,QAAvB,UACG,EAAM,SAAW,KAAO,MACvB,UAAC,MAAD,YACE,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAAO,iBAEhC,GACL,EAAM,OAAO,OAAS,MACrB,SAAC,SAAD,UAAS,EAAM,OAAO,GAAY,IAElC,SAAC,IAAD,CAAG,KAAM,EAAM,OAAO,KAAM,IAAI,aAAa,OAAO,SACjD,WAAM,OAAO,GACb,IAEL,SAAC,OAAD,UAAO,EAAM,OAAO,OAAc,IAClC,SAAC,QAAD,UAAQ,EAAM,OAAO,MAAc,EAChC,IAEN,EAAM,SAAS,IAAK,IACnB,UAAC,MAAD,YACE,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAAO,kBAEhC,GACL,EAAQ,OAAS,MAChB,SAAC,SAAD,UAAS,EAAQ,GAAY,IAE7B,SAAC,IAAD,CAAG,KAAM,EAAQ,KAAM,IAAI,aAAa,OAAO,SAC5C,WAAQ,GACR,IAEL,SAAC,OAAD,UAAO,EAAQ,OAAc,IAC7B,SAAC,QAAD,UAAQ,EAAQ,MAAc,EAC3B,GAbK,EAAQ,GAab,CACN,CACE,GACE,IAGX,UAAC,EAAD,CAAS,QAAQ,WAAW,KAAM,GAAG,OAAO,EAAM,YAAY,EAAE,WAAhE,UACG,EAAM,wBACL,SAAC,EAAD,CAAM,UAAW,EAAO,iBAAkB,KAAK,YAAY,gFAErD,GACJ,KACH,EAAM,mBACL,SAAC,EAAD,CAAM,UAAW,EAAO,iBAAkB,KAAK,YAAY,2DAErD,GACJ,KACH,EAAM,SAAS,SAAW,GACzB,SAAC,EAAD,CAAM,KAAK,YAAY,sDAAiD,IAExE,SAAC,KAAD,CAAI,UAAW,EAAO,aACnB,WAAM,SAAS,IAAK,IACnB,UAAC,KAAD,YACE,UAAC,MAAD,CAAK,UAAW,EAAO,YAAvB,WACE,SAAC,EAAD,CAAQ,OAAQ,EAAQ,OAAQ,KAAK,SAAW,GAC/C,EAAQ,OAAS,KAAO,MAAO,SAAC,OAAD,UAAO,EAAQ,IAAW,EACvD,CACL,aAAC,GAAD,CAAmB,UAAW,EAAO,YAAa,MAAO,EAAQ,MAAQ,2BAA8B,EACrG,GANK,EAAQ,EAMb,CACL,CACC,EAEC,KAET,UAAC,EAAD,CAAS,QAAQ,UAAU,KAAM,GAAG,OAAO,EAAM,YAAY,EAAE,UAA/D,UACG,EAAM,kBACL,SAAC,EAAD,CAAM,UAAW,EAAO,iBAAkB,KAAK,YAAY,yDAErD,GACJ,KACH,EAAM,QAAQ,SAAW,GACxB,SAAC,EAAD,CAAM,KAAK,YAAY,4DAAuD,IAE9E,SAAC,KAAD,CAAI,UAAW,EAAO,QACnB,WAAM,QAAQ,IAAK,IAClB,UAAC,KAAD,YACE,UAAC,MAAD,CAAK,UAAW,EAAO,YAAvB,WACE,SAAC,EAAD,CAAQ,OAAQ,EAAM,MAAO,KAAK,SAAW,GAC5C,EAAM,OAAS,KAAO,MAAO,SAAC,OAAD,UAAO,EAAM,IAAW,EACnD,CACL,aAAC,KAAD,UACG,EAAM,QAAQ,KAAK,EAAQ,KAC1B,UAAC,MAAD,YACE,SAAC,KAAD,UAAK,EAAO,KAAU,IACtB,SAAC,KAAD,UAAK,EAAO,UAAe,EACxB,GAHK,GAAG,EAAO,MAAM,GAAG,OAAO,CAAK,GAGpC,CACN,CACC,EACF,GAbK,EAAM,EAaX,CACL,CACC,EAEC,GACF,+gBClLL,IAAW,CACf,WACA,UACA,WAMA,UAAC,UAAD,CAAS,UAAW,EAAO,QAA3B,WACE,UAAC,SAAD,CAAQ,UAAW,EAAO,eAA1B,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,QAAQ,gBACnB,UACG,IACN,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAC5B,UACG,EACA,CACP,IACM,IAGL,IAAa,CAAE,WACnB,IAAU,MAAO,8BAAE,kBAAkB,IAAI,SAAC,OAAD,CAAM,SAAU,EAAM,SAAW,WAAM,KAAY,GAGjF,IAAqC,CAChD,eAIA,UAAC,UAAD,CAAS,UAAW,EAAO,SAAU,8CAArC,WACE,UAAC,UAAD,CAAS,aAAW,qBAAqB,UAAW,EAAO,KAA3D,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,YAAvB,WACE,SAAC,OAAD,UAAM,WAAe,IACrB,SAAC,SAAD,UAAS,EAAS,WAAoB,IACtC,SAAC,EAAD,CACE,MAAO,EAAS,OAChB,KACE,EAAS,SAAW,YAChB,WACA,EAAS,SAAW,SAClB,WACA,EAAS,SAAW,UAClB,WACA,EAAS,SAAW,UAClB,UACA,SAEb,EACE,IACJ,EAAS,gBAAkB,KAAO,MAAO,SAAC,IAAD,CAAG,UAAW,EAAO,QAAU,WAAS,aAAiB,IACnG,UAAC,KAAD,CAAI,UAAW,EAAO,UAAtB,WACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,KAAO,IACX,UAAC,KAAD,WACG,EAAS,aACV,SAAC,QAAD,UAAQ,EAAS,aAAqB,EACpC,GACD,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,SAAC,KAAD,WACE,SAAC,OAAD,UAAO,EAAS,eAAsB,EACpC,EACD,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,OAAS,IACb,SAAC,KAAD,UAAK,EAAS,iBAAsB,EACjC,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,SAAC,KAAD,UAAK,EAAS,QAAa,EACxB,GACH,KACJ,UAAC,KAAD,CAAI,UAAW,EAAO,cAAtB,WACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,UAAC,KAAD,WACG,EAAS,aAAa,MAAI,EAAS,eAClC,GACD,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,WACE,SAAC,GAAD,CAAW,MAAO,EAAS,SAAY,EACrC,EACD,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,SAAW,IACf,SAAC,KAAD,WACE,SAAC,GAAD,CAAW,MAAO,EAAS,SAAY,EACrC,EACD,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,MAAQ,IACZ,SAAC,KAAD,UAAK,EAAS,aAAkB,EAC7B,GACH,GACG,KAET,SAAC,GAAD,CACE,UAAW,EAAO,UAClB,WAAW,uDACX,QAAQ,iBACR,OAAQ,EAAS,MAClB,IAED,SAAC,GAAD,CAAS,QAAQ,SAAS,KAAK,yDAC7B,oBAAC,MAAD,CAAK,UAAW,EAAO,YAAvB,WACE,UAAC,MAAD,YACE,SAAC,QAAD,UAAO,WAAgB,IACvB,SAAC,SAAD,UAAS,EAAS,UAAU,KAAK,KAAK,GAAK,kBAA2B,EACnE,KACL,UAAC,MAAD,YACE,SAAC,QAAD,UAAO,WAAgB,IACvB,SAAC,SAAD,UAAS,EAAS,UAAU,KAAK,KAAK,GAAK,sBAA+B,EACvE,GACF,GACE,IAET,UAAC,GAAD,CACE,QAAQ,UACR,KAAM,GAAG,EAAS,iBAAiB,aAAa,OAAO,EAAS,SAAS,EAAE,qBAF7E,UAIG,EAAS,kBACR,SAAC,IAAD,CAAG,UAAW,EAAO,QAAS,mFAA2E,GACvG,KACH,EAAS,QAAQ,SAAW,GAC3B,SAAC,EAAD,CAAM,KAAK,YAAY,gEAA2D,IAElF,SAAC,KAAD,CAAI,UAAW,EAAO,QACnB,WAAS,QAAQ,IAAK,IACrB,UAAC,KAAD,CAAI,YAAW,EAAO,KAAtB,WACE,UAAC,SAAD,YACE,UAAC,OAAD,YACE,SAAC,QAAD,UAAQ,EAAO,SAAiB,IAChC,SAAC,SAAD,UAAS,EAAO,IAAa,EACzB,KACN,SAAC,EAAD,CAAY,MAAO,EAAO,OAAQ,KAAM,EAAO,IAAO,EAChD,KACR,UAAC,KAAD,YACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,SAAC,KAAD,UAAK,EAAO,QAAa,EACtB,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,SAAC,KAAD,UAAK,EAAO,QAAa,EACtB,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,OAAS,IACb,SAAC,KAAD,UAAK,EAAO,OAAS,kBAAuB,EACzC,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,QAAU,IACd,SAAC,KAAD,UAAK,EAAO,QAAU,kBAAuB,EAC1C,GACH,IACH,EAAO,UAAY,KAAO,MAAO,SAAC,IAAD,UAAI,EAAO,OAAW,GACvD,EAAO,QAAU,KAAO,MAAO,SAAC,IAAD,CAAG,UAAW,EAAO,MAAQ,WAAO,KAAS,GAC5E,EAAO,UAAU,SAAW,EAAI,MAC/B,SAAC,KAAD,CAAI,UAAW,EAAO,UACnB,WAAO,UAAU,KAAK,EAAU,KAC/B,UAAC,KAAD,YACE,SAAC,OAAD,UAAO,EAAS,SAAgB,IAChC,SAAC,SAAD,UAAS,EAAS,IAAa,IAC/B,SAAC,QAAD,UAAQ,EAAS,WAAmB,EAClC,GAJK,GAAG,EAAS,UAAU,GAAG,EAAS,KAAK,GAAG,OAAO,CAAK,GAI3D,CACL,CACC,EAEJ,CAvC6B,IAAO,EAuCpC,CACL,CACC,EAEC,KAET,SAAC,GAAD,CAAS,QAAQ,mBAAmB,KAAK,8DACtC,WAAS,gBAAgB,SAAW,GACnC,SAAC,EAAD,CAAM,KAAK,YAAY,wDAAmD,IAE1E,SAAC,KAAD,CAAI,UAAW,EAAO,gBACnB,WAAS,gBAAgB,IAAK,IAC7B,UAAC,KAAD,YACE,UAAC,OAAD,YACE,SAAC,SAAD,UAAS,EAAS,IAAa,IAC/B,SAAC,OAAD,UAAO,EAAS,QAAe,EAC3B,KACN,UAAC,OAAD,WACG,EAAS,SAAW,cACrB,SAAC,QAAD,UAAQ,EAAS,WAAmB,EAChC,GACJ,GATK,GAAG,EAAS,KAAK,GAAG,EAAS,UASlC,CACL,CACC,EAEC,IAET,UAAC,GAAD,CAAS,QAAQ,oBAAoB,KAAK,uDAA1C,WACE,UAAC,KAAD,CAAI,UAAW,EAAO,eAAtB,WACE,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,SAAC,KAAD,UAAK,EAAS,iBAAsB,EACjC,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,eAAiB,IACrB,SAAC,KAAD,UAAK,EAAS,qBAA0B,EACrC,KACL,UAAC,MAAD,YACE,SAAC,KAAD,UAAI,UAAY,IAChB,SAAC,KAAD,UAAK,EAAS,iBAAsB,EACjC,GACH,CACJ,aAAC,EAAD,CAAM,KAAK,YAAY,uGAEjB,EACC,GACF,IC/NL,GAAqB,KAAgC,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,CAAa,EAAG,GAAiB,iCAAiC,CAAC,EACnL,GAAa,GAAgB,CAAC,SAAU,WAAY,QAAS,SAAS,CAAC,EAC9C,GAAc,CAChD,GAAI,GAAkB,GAAG,EACzB,OAAoB,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,GAAG,CAAC,EAC1F,KAAM,GACN,SAAU,GAAkB,GAAG,EAC/B,QAAS,GAAkB,GAAG,EAC9B,QAAqB,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,GAAG,CAAC,EAC3F,SAAU,GAAa,GAAkB,GAAG,CAAC,CAAC,CAAC,MAAM,EAAmB,EAAE,EAAG,GAAgB,CAAC,CAClG,CAAC,EACmC,GAAc,CAC9C,UAAW,GAAkB,GAAG,EAChC,YAAyB,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,IAAK,CAAC,EACjG,aAA0B,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,IAAK,CAAC,EAClG,aAAc,KAA4B,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,IAAK,CAAC,CAAC,EACnH,eAA4B,MAAM,EAAiB,EAAG,EAAkB,EAAG,EAAmB,IAAK,CAAC,CACxG,CAAC,EAED,IAAa,GAAmB,GAAa,KAAK,UAAU,CACxD,EAAS,UACT,EAAS,UACT,EAAS,WACT,EAAS,aACT,EAAS,YACb,CAAC,EACY,IAAoB,EAAM,IAAU,GAAgB,CAAI,IAAM,GAAgB,CAAK,ECI1F,SAA2B,OAAO,+EAClC,EAA2B,GAAyB,MACvD,CAAE,+CAAgD,CACrD,EAEM,GACJ,GACmD,EAAmB,EAAS,qBAAqB,EAEhG,GAAiD,GAAiD,CACtG,GAAI,CAAC,GAA2B,CAAO,EAAG,OAAO,EAAa,GAAiB,CAAC,CAAC,EACjF,IAAM,EAAU,EAAQ,QAExB,OADI,IAAY,KAAa,EAAa,GAAiB,CAAC,CAAC,EACtD,GAAe,GAAe,GACnC,EACE,GACE,KAAK,IAAI,EAAG,GAAuB,CAAO,EAAI,GAAuB,CAAG,CAAC,CAC3E,CACF,CAAC,CACL,EAuHa,GAAb,cAAqD,GAAiB,iCAAiC,CAAC,CAAM,EAExG,GAAqB,GAA0E,CACnG,IAAM,EAAW,CAAmC,EACpD,IAAK,IAAM,KAAY,EAAQ,UAAW,CACxC,IAAM,EAAQ,EAAS,OAAO,GAE5B,EAAS,SAAW,aACpB,EAAS,aAAa,SAAS,WAAW,GAC1C,EAAS,gBAAkB,QAC3B,IAAU,QAEV,EAAS,KAAK,CACZ,WAAY,EAAS,WACrB,QACA,cAAe,EAAS,cACxB,GAAM,EAAS,cAAgB,QAAc,CAAE,YAAa,EAAS,WAAY,CACnF,CAAC,CAEL,CACA,OAAO,CACT,EAGa,GAAgE,CAC3E,SAAU,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,QAAQ,GAAG,CAAI,CAAC,EAC7F,QAAS,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,OAAQ,GAAG,CAAI,CAAC,EAC5F,cAAe,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,aAAc,GAAG,CAAI,CAAC,EACxG,MAAO,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,KAAK,GAAG,CAAI,CAAC,EACvF,YAAa,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,WAAW,GAAG,CAAI,CAAC,EACnG,oBAAqB,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,mBAAmB,GAAG,CAAI,CAAC,EACnH,WAAY,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,UAAU,GAAG,CAAI,CAAC,EACjG,mBAAoB,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,kBAAkB,GAAG,CAAI,CAAC,EACjH,kBAAmB,GAAG,IAAS,EAAyB,KAAM,GAAc,EAAU,iBAAkB,GAAG,CAAI,CAAC,CAClH,EAEM,GACJ,EACA,IACY,GAAiB,GAA0B,CAAI,EAAG,GAA0B,CAAK,CAAC,EAGnF,IACX,EACA,EACA,EACA,EACA,IAGS,CACT,EAAK,MAAsB,GAA2B,CAElD,EAAO,SACP,EAAY,UAAY,MACxB,CAAC,EAAgB,EAAY,QAAS,CAAO,IAE/C,GAAe,GAAgB,8CAA+C,CAAO,CAAC,EACtF,EAAU,GACR,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,EACtD,CAAE,GAAG,EAAQ,cAAe,QAAS,EACrC,CACN,EACF,CAAC,CACH,EAGa,IACX,EACA,EACA,EACA,EACA,EACA,IAGS,CAEP,EAAO,SACP,EAAY,UAAY,MACxB,CAAC,EAAgB,EAAY,QAAS,CAAO,GAE/C,EAAU,GACR,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,EACtD,CAAE,GAAG,EAAQ,OAAQ,EAAa,SAAW,CAAU,EACvD,CACN,CACF,EAEM,IACJ,EACA,IAEA,EAAO,OAAS,eAEd,EAAO,QAAQ,eAAiB,EAAM,cACtC,EAAO,QAAQ,eAAiB,EAAM,aAI7B,IACX,EACA,EACA,EACA,EACA,EACA,EACA,EAAwC,KACrC,CACH,GAAM,CAAC,EAAiB,MAAsB,YAAS,CAAC,EAClD,CAAC,EAAO,MAAY,YAA2C,CAAE,KAAM,MAAO,CAAC,EAC/E,CAAC,EAAa,MAAkB,YAA4C,CAAE,KAAM,MAAO,CAAC,EAC5F,KAAe,UAA+B,IAAI,EAClD,KAAgB,UAA+B,IAAI,EACnD,KAAmB,UAA+B,IAAI,EACtD,KAAsB,UAAsC,IAAI,EAChE,KAAc,UAAsC,IAAI,EACxD,KAAe,UAAuC,IAAI,EAC1D,KAAQ,eAEV,IAAe,MAAQ,IAAiB,KACpC,KACA,CAAE,eAAc,WAAU,eAAc,YAAW,EACzD,CAAC,EAAc,EAAU,EAAc,CAAU,CACnD,GACA,yBAAsB,CACpB,EAAY,QAAU,CACxB,EAAG,CAAC,CAAK,CAAC,GACV,yBAAsB,CACpB,EAAa,QAAU,IACzB,EAAG,CAAC,EAAU,CAAU,CAAC,GAEzB,mBAAgB,CACd,GAAI,IAAe,MAAQ,IAAiB,KAAM,CAChD,EAAS,CAAE,KAAM,MAAO,CAAC,EACzB,MACF,CACA,IAAM,EAAQ,CAAE,eAAc,WAAU,eAAc,YAAW,EAC3D,EAAiB,EAAa,SAAW,OACzC,EAAQ,IAAI,gBACZ,GAAyC,EAAiB,IAE5D,EAAoB,UAAY,MAChC,EAAgB,EAAoB,QAAS,CAAK,EAC3C,IACT,EAAoB,QAAU,EAC9B,GAAe,GAAkB,EAAS,CAAO,CAAC,EAClD,EAAkB,GAA+B,CAAO,EAAG,CAAE,OAAQ,EAAM,MAAO,CAAC,CAAC,CAAC,SAC7E,CACC,EAAM,OAAO,SAAS,EAAoB,GAAa,EAAW,CAAC,CAC1E,EACgB,GAAiC,CAC1C,EAAM,OAAO,SAAS,EAAS,CAAE,KAAM,SAAU,GAAG,CAAM,CAAC,CAClE,CACF,EACO,IA4DT,OA1DA,EAAU,GACR,EAAQ,OAAS,SAAW,EAAgB,EAAS,CAAK,EACtD,EACA,CAAE,KAAM,UAAW,GAAG,CAAM,CAClC,EACA,GAAyB,MACtB,CAAE,mCACD,EACE,EACA,EACA,EACA,EAAM,OACN,EACA,CACF,CACJ,CAAC,CAAC,MACC,CAAE,UAAS,oBAAmB,SAAQ,YAAa,CAClD,GAAI,CAAC,EAAM,OAAO,QAAS,CACpB,IAAmB,EAAoB,QAAU,MACtD,IAAM,EAAkB,GAAkB,CAAO,EACjD,EACE,GAAa,EAAQ,CAAK,EACtB,CACA,KAAM,QACN,GAAG,EACH,OAAQ,OACR,cAAe,OACf,SAAU,EAAgB,IAAM,KAChC,kBACA,SACA,QACF,EACE,CAAE,KAAM,SAAU,GAAG,CAAM,CACjC,EACI,GACF,EAAuB,iEAAiE,CAE5F,CACF,EACC,GAAY,CACP,MAAM,OAAO,QACjB,IAAI,EAAuC,CAAO,EAAG,CACnD,EAAiB,CAAU,EAC3B,EAAS,CAAE,KAAM,SAAU,GAAG,CAAM,CAAC,EACrC,MACF,CAEE,GAAsC,CAAO,GAC7C,EACE,0DACA,CACF,GAIF,EAAS,CAAE,KAAM,SAAU,GAAG,CAAM,CAAC,CAVrC,CAWF,CACF,MACa,EAAM,MAAM,CAC3B,EAAG,CACD,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,CAAC,GAED,mBAAgB,CACd,GAAI,EAAM,OAAS,SAAW,EAAM,OAAO,OAAS,UAAW,OAC/D,IAAM,EAAQ,IAAI,gBAiBlB,OAhBA,EAAkB,EAAa,WAAW,EAAG,CAAE,OAAQ,EAAM,MAAO,CAAC,CAAC,CAAC,SAC/D,CACC,EAAM,OAAO,SAAS,EAAoB,GAAa,EAAW,CAAC,CAC1E,EACgB,GAA4B,CACrC,EAAM,OAAO,SAChB,EAAS,CACP,KAAM,SACN,aAAc,EAAM,aACpB,SAAU,EAAM,SAChB,aAAc,EAAM,aACpB,WAAY,EAAM,UACpB,CAAC,CAEL,CACF,MACa,EAAM,MAAM,CAC3B,EAAG,CAAC,CAAK,CAAC,GAEV,uBACc,CACV,EAAa,SAAS,MAAM,EAC5B,EAAc,SAAS,MAAM,EAC7B,EAAiB,SAAS,MAAM,CAClC,EACA,CAAC,CACH,GACA,mBAAgB,CACd,EAAa,SAAS,MAAM,EAC5B,EAAa,QAAU,KACvB,EAAc,SAAS,MAAM,EAC7B,EAAc,QAAU,KACxB,EAAiB,SAAS,MAAM,EAChC,EAAiB,QAAU,KAC3B,EAAe,CAAE,KAAM,MAAO,CAAC,CACjC,EAAG,CAAC,EAAU,CAAU,CAAC,GACzB,yBAAsB,CACpB,EAAc,SAAS,MAAM,EAC7B,EAAc,QAAU,KACxB,EAAgB,GAAY,EAAQ,OAAS,aAAe,EAAU,CAAE,KAAM,MAAO,CAAC,CACxF,EAAG,CAAC,EAAc,CAAY,CAAC,EAE/B,IAAM,KAAgB,gBACpB,EACA,IACS,CACT,IAAM,EAAW,EAAa,SAAW,OACzC,GAAyB,MACtB,CAAE,oCACD,EACE,EACA,EAAa,SACb,EACA,EACA,CACF,CACJ,CAAC,CAAC,KACC,GAAW,CACV,GACE,EACA,EACA,EACA,EACA,EACA,CACF,CACF,MACM,MACR,CACF,EAAG,CAAC,CAAS,CAAC,EAER,KAAc,mBAAkB,CACpC,GACE,EAAM,OAAS,SACf,EAAM,gBAAkB,WACxB,EAAM,SAAW,QACjB,CAAC,EAAM,OAAO,WACd,OACF,IAAM,EAAU,EACV,EAAgB,EAAM,OAC5B,EAAa,SAAS,MAAM,EAC5B,IAAM,EAAQ,IAAI,gBAClB,EAAa,QAAU,EACvB,EAAS,CAAE,GAAG,EAAS,cAAe,SAAU,CAAC,EACjD,GACE,GAAyB,MACtB,CAAE,iDACD,EACE,EACA,EACA,EACA,EAAM,OACN,EACA,EACA,EACA,CACF,CACJ,EACA,EAAM,OACN,EACA,EACA,CACF,CACF,EAAG,CAAC,EAAkB,EAAO,CAAS,CAAC,EAEjC,KAAiB,gBACrB,EACA,IACkB,CAClB,GAAI,EAAM,OAAS,SAAW,EAAM,OAAO,OAAS,cAAe,OAAO,QAAQ,QAAQ,EAC1F,IAAM,EAAW,IAAe,OAC5B,EAAM,SACN,EAAM,iBAAiB,KAAM,GAAc,EAAU,aAAe,CAAU,GAAK,KACvF,GAAI,IAAa,KAAM,OAAO,QAAQ,QAAQ,EAC9C,IAAM,EAAU,EAChB,EAAc,SAAS,MAAM,EAC7B,IAAM,EAAQ,IAAI,gBAGlB,MAFA,GAAc,QAAU,EACxB,EAAS,CAAE,GAAG,EAAS,OAAQ,UAAW,CAAC,EACpC,EAAU,QAAQ,EAAU,EAAU,EAAQ,EAAM,MAAM,CAAC,CAAC,KAChE,GAAW,CACV,GAAI,EAAM,OAAO,QAAS,OAAO,QAAQ,OAAO,IAAI,EAAiC,EACrF,EAAU,GACR,EAAO,OAAS,SACd,EAAgB,EAAQ,CAAO,GAC/B,GAAa,EAAQ,CAAO,EAC1B,CAAE,GAAG,EAAQ,OAAQ,OAAQ,QAAO,EACpC,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,EAC1D,CACA,KAAM,SACN,aAAc,EAAQ,aACtB,SAAU,EAAQ,SAClB,aAAc,EAAQ,aACtB,WAAY,EAAQ,UACtB,EACE,CACN,CACF,EACC,GACK,EAAM,OAAO,QAAgB,QAAQ,OAAO,IAAI,EAAiC,GACjF,EAAuC,CAAO,GAAG,EAAiB,EAAQ,UAAU,EACxF,EAAU,GACR,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,EACtD,CAAE,GAAG,EAAQ,OAAQ,QAAS,EAC9B,CACN,EACO,QAAQ,OAAO,CAAO,EAEjC,CACF,EAAG,CAAC,EAAU,EAAkB,EAAO,CAAS,CAAC,EAE3C,KAAQ,gBACZ,EACA,IACS,CACT,EAAoB,EAAQ,CAAU,CAAC,CAAC,MAAsB,GAA2B,CACnF,EAAmB,EAAS,iCAAiC,GACjE,GAAe,GAAgB,qCAAsC,CAAO,CAAC,CAC/E,CAAC,CACH,EAAG,CAAC,CAAc,CAAC,EAEb,KAAsB,eAC1B,GACG,CACH,GAAI,EAAM,OAAS,QAAS,OAC5B,IAAM,EAAS,EAAM,OACrB,GAAI,EAAO,OAAS,UAAW,OAC/B,IAAM,EAAU,EAChB,EAAc,SAAS,MAAM,EAC7B,IAAM,EAAQ,IAAI,gBAClB,EAAc,QAAU,EACxB,EAAU,EAAO,MAAO,EAAM,MAAM,CAAC,CAAC,KACnC,GAAW,CACN,EAAM,OAAO,SACjB,EAAU,GACR,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,GAAK,GAAa,EAAQ,CAAO,EACvF,CAAE,GAAG,EAAQ,QAAO,EACpB,CACN,CACF,EACC,GAAY,CACP,EAAM,OAAO,SACb,EAAuC,CAAO,GAAG,EAAiB,EAAQ,UAAU,CAC1F,CACF,CACF,EAAG,CAAC,EAAkB,CAAK,CAAC,EAEtB,KAAqB,eAAa,GAAiD,CACvF,GACE,EAAM,OAAS,SACf,EAAM,OAAO,OAAS,aACtB,EAAM,OAAO,QAAU,EAAU,OACjC,CAAC,EAAM,OAAO,OAAO,YAAY,MAC9B,CAAE,kBAAmB,IAAiB,EAAU,YACnD,EACA,OACF,IAAM,EAAU,EAChB,EAAc,SAAS,MAAM,EAC7B,IAAM,EAAQ,IAAI,gBAClB,EAAc,QAAU,EACxB,EAAe,CAAE,KAAM,aAAc,WAAU,CAAC,EAChD,EAAU,mBAAmB,EAAU,EAAW,EAAM,MAAM,CAAC,CAAC,KAC7D,GAAY,CACP,EAAM,OAAO,SACjB,EACE,EAAQ,QAAQ,eAAiB,EAAQ,aACrC,CAAE,KAAM,UAAW,SAAQ,EAC3B,CAAE,KAAM,SAAU,QAAS,KAAM,WAAU,CACjD,CACF,EACC,GAAY,CACP,EAAM,OAAO,UACb,EAAuC,CAAO,GAAG,EAAiB,EAAQ,UAAU,EACxF,EAAe,CAAE,KAAM,SAAU,QAAS,KAAM,WAAU,CAAC,EAC7D,CACF,CACF,EAAG,CAAC,EAAU,EAAkB,EAAO,CAAS,CAAC,EAE3C,MAAoB,eAAa,GAAqD,CAC1F,GAAI,EAAM,OAAS,QAAS,OAC5B,IAAM,EAAU,EAAY,OAAS,WAEjC,EAAY,OAAS,SADrB,EAAY,QAGZ,KACJ,GAAI,IAAY,KAAM,OACtB,IAAM,EAAU,EACV,EAAY,CAChB,MAAO,EAAQ,MACf,aAAc,EAAQ,aACtB,WAAY,EAAQ,UACtB,EACA,EAAiB,SAAS,MAAM,EAChC,IAAM,EAAQ,IAAI,gBAClB,EAAiB,QAAU,EAC3B,EAAe,CAAE,KAAM,aAAc,SAAQ,CAAC,EAC9C,EAAU,kBACR,EACA,EACA,EACA,EAAQ,iBACR,EAAM,MACR,CAAC,CAAC,KACC,GAAc,CACb,GAAI,EAAM,OAAO,QAAS,OAC1B,IAAM,EAAiB,EAAU,mBAAmB,eAClD,EAAQ,mBAAmB,aACzB,GACF,EAAU,GACR,EAAO,OAAS,SAAW,EAAO,OAAO,OAAS,aAChD,EAAO,OAAO,QAAU,EAAU,MAChC,CACA,GAAG,EACH,OAAQ,CACN,GAAG,EAAO,OACV,OAAQ,CACN,GAAG,EAAO,OAAO,OACjB,YAAa,EAAO,OAAO,OAAO,YAAY,IAAK,GAC7C,EAAW,eAAiB,EAAU,aAEnC,CADmC,GAAG,EAAY,MAAO,WACzD,EAFwD,CAGhE,CACH,CACF,CACF,EACE,CACN,EAEF,EACE,EACI,CACA,KAAM,YACN,eAAgB,EAAY,UAAY,MACtC,EAAU,QAAQ,eAAiB,EAAY,QAAQ,cACvD,EAAU,QAAQ,eAAiB,EAAY,QAAQ,aACzD,UACA,YAAa,CACf,EACE,CAAE,KAAM,mBAAoB,UAAS,YAAa,CAAU,CAClE,EACA,IAAM,EAAc,EAAY,QAE9B,IAAgB,MAChB,EAAY,WAAa,EAAQ,UACjC,EAAY,aAAe,EAAQ,YACnC,EAAc,EAAa,EAAM,MAAM,CAC3C,EACC,GAAY,CACP,EAAM,OAAO,UACb,EAAuC,CAAO,GAAG,EAAiB,EAAQ,UAAU,EACxF,EAAe,CAAE,KAAM,SAAU,UAAS,WAAU,CAAC,EACvD,CACF,CACF,EAAG,CAAC,EAAU,EAAkB,EAAa,EAAe,EAAO,CAAS,CAAC,EAEvE,MAAmB,eAAa,GAAmC,CAQvE,GANE,EAAM,OAAS,SACf,EAAM,OAAO,OAAS,aACtB,EAAM,OAAO,QAAU,EAAO,OAC9B,EAAM,WAAa,MACnB,CAAC,EAAM,OAAO,OAAO,YAAY,MAAM,CAAE,kBAAmB,IAAiB,EAAO,YAAY,GAE9F,EAAU,mBAAqB,OAAW,OAC9C,IAAM,EAAU,EAChB,EAAc,SAAS,MAAM,EAC7B,IAAM,EAAQ,IAAI,gBAClB,EAAc,QAAU,EACxB,EAAS,CAAE,GAAG,EAAS,OAAQ,UAAW,CAAC,EAC3C,EAAU,iBAAiB,EAAU,EAAQ,EAAM,SAAU,EAAM,MAAM,CAAC,CAAC,KACxE,GAAW,CACN,EAAM,OAAO,SACjB,EAAU,GACR,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,GAAK,GAAa,EAAQ,CAAO,EACvF,CAAE,GAAG,EAAQ,OAAQ,OAAQ,QAAO,EACpC,CACN,CACF,EACC,GAAY,CACP,EAAM,OAAO,UACb,EAAuC,CAAO,GAAG,EAAiB,EAAQ,UAAU,EACxF,EAAU,GACR,EAAO,OAAS,SAAW,EAAgB,EAAQ,CAAO,EACtD,CAAE,GAAG,EAAQ,OAAQ,QAAS,EAC9B,CACN,EACF,CACF,CACF,EAAG,CAAC,EAAU,EAAkB,EAAO,CAAS,CAAC,EAE3C,GAAiD,IAAU,KAC7D,CAAE,KAAM,MAAO,EACf,EAAM,OAAS,QAAU,EAAgB,EAAO,CAAK,EACrD,EACA,CAAE,KAAM,UAAW,GAAG,CAAM,EAEhC,MAAO,CACL,UAAQ,mBAAkB,CACpB,EAAU,SAAW,QACzB,GAAqB,EAAO,IAAW,EAAU,OAAQ,EAAU,EAAO,CAAM,CAAC,CACnF,EAAG,CAAC,EAAU,EAAqB,CAAS,CAAC,EAC7C,qBAAmB,mBAAkB,CACnC,EAAc,SAAS,MAAM,EAC7B,EAAc,QAAU,KACxB,EAAiB,SAAS,MAAM,EAChC,EAAiB,QAAU,KAC3B,EAAe,CAAE,KAAM,MAAO,CAAC,CACjC,EAAG,CAAC,CAAC,EACL,gBAAc,mBAAkB,CAC1B,EAAU,eAAiB,QAC/B,GAAqB,EAAO,IAAW,EAAU,aAAc,EAAU,EAAO,CAAM,CAAC,CACzF,EAAG,CAAC,EAAU,EAAqB,CAAS,CAAC,EAC7C,cACA,qBACA,cACA,qBACA,oBACA,SAAO,mBAAkB,CACvB,EAAoB,QAAU,KAC9B,EAAoB,GAAa,EAAW,CAAC,CAC/C,EAAG,CAAC,CAAC,EACL,QACA,iBACA,MAAO,EACT,CACF,ECvsBM,MAA8B,kBAClC,OAAO,4CAAmC,CAAC,KAAM,IAAY,CAC3D,QAAS,EAAO,2BAClB,EAAE,yFACJ,EAEM,IAAe,EAAc,IAAyC,CAC1E,IAAM,EAAW,EAAK,MAAM,QAAS,CAAC,CAAC,CAAC,IAAM,GAK9C,OAJI,IAAa,GAA0B,CAAW,EAAU,gBAC5D,EAAS,SAAS,YAAY,EAAU,kBACxC,EAAS,SAAS,OAAO,EAAU,sBACnC,EAAS,SAAS,WAAW,EAAU,mBACpC,mBACT,EAEM,IAAc,CAClB,SACA,cACA,QACA,OAAO,aAMW,CAClB,IAAM,KAAM,UAAoB,IAAI,EAEpC,OADA,mBAAgB,EAAI,SAAS,MAAM,EAAG,CAAC,CAAC,GAEtC,SAAC,UAAD,CAAS,UAAW,EAAO,MAAO,8BAA6B,EAAW,MAAK,SAAU,GACvF,mBAAC,EAAD,CAAoB,SAAqB,cAAoB,QAAa,MAAO,EAC1E,EAEb,EAEM,QACJ,UAAC,UAAD,CAAS,aAAW,2BAA2B,UAAW,EAAO,QAAjE,WACE,SAAC,EAAD,CAAU,WAAY,GAAO,OAAO,QAAQ,MAAM,2BAA2B,QAAQ,OAAS,IAC9F,UAAC,MAAD,CAAK,UAAW,EAAO,eAAvB,WACE,SAAC,EAAD,CAAU,OAAO,QAAQ,QAAQ,OAAS,IAC1C,SAAC,EAAD,CAAU,OAAO,QAAQ,QAAQ,OAAS,EACvC,CACE,MAGL,IAAmB,CACvB,YAII,EAAO,OAAS,MAEhB,SAAC,EAAD,CAAQ,YAAS,KAAK,YAAY,WAAQ,QAAQ,UAC/C,WAAO,KACF,GAGL,EAAO,UACZ,SAAC,IAAD,CAAG,UAAW,EAAO,gBAAiB,KAAM,EAAO,KAAM,IAAI,aAAa,OAAO,SAC9E,WAAO,KACP,IAEH,SAAC,EAAD,CAAM,UAAW,EAAO,gBAAiB,GAAI,EAAO,KACjD,WAAO,KACJ,GAKG,IAAsB,EAA2B,IAAkC,CAC9F,GAAI,IAAe,KAAM,OAAO,KAChC,IAAM,EAAS,IAAI,MAAM,CAAU,EACnC,GAAI,IAAW,MAAQ,EAAO,WAAa,SAAU,OAAO,KAC5D,IAAM,EAAQ,oDAAoD,KAAK,EAAO,QAAQ,EAKtF,OAJI,IAAQ,KAAO,QAAa,EAAM,KAAO,mBAAmB,CAAM,EAAU,MAChF,EAAO,SAAW,gBAAgB,EAAM,GAAG,iBAAiB,mBAAmB,CAAM,IACrF,EAAO,OAAS,GAChB,EAAO,KAAO,GACP,EAAO,KAChB,EAEM,IAAiB,CACrB,0BACA,eACA,0BAKkB,CAClB,IAAM,EACJ,EAAa,iBAAmB,KAC5B,KACA,GAAmB,EAAa,cAAc,KAAM,EAAa,UAAU,EACjF,OACE,UAAC,MAAD,CAAK,UAAW,EAAO,cAAvB,WACE,SAAC,GAAD,CAAiB,OAAQ,EAAa,aAAgB,GACrD,IAAa,KAAO,MACnB,SAAC,IAAD,CAAG,UAAW,EAAO,gBAAiB,KAAM,EAAU,IAAI,aAAa,OAAO,SAAS,6BAEpF,GAEJ,EAAa,iBAAmB,MAAQ,IAAyB,KAAO,MACvE,UAAC,MAAD,CAAK,UAAW,EAAO,oBAAvB,WACE,SAAC,EAAD,CACE,SAAU,IAAyB,UACnC,QAAS,IAAyB,UAClC,QAAS,EACT,QAAQ,YACT,mBAEO,IACR,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAC5B,aAAyB,SACtB,0BACA,IAAyB,eACvB,wDACA,0CACF,EACH,GAEJ,GAET,EAEM,IAAgB,CAAE,mBACtB,UAAC,UAAD,CAAS,kBAAgB,wBAAwB,UAAW,EAAO,aAAnE,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,eAAvB,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,GAAG,wBAAwB,QAAQ,gBAAgB,wBAE3D,IACN,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAAO,gCAEhC,EACH,KACL,UAAC,MAAD,CAAK,UAAW,EAAO,SAAvB,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,SAAvB,WACE,SAAC,EAAD,CAAa,QAAS,EAAa,QAAS,KAAK,SAAW,IAC5D,UAAC,OAAD,YACE,SAAC,SAAD,UAAS,EAAa,WAAoB,IAC1C,SAAC,OAAD,UAAO,EAAa,UAAiB,EACjC,GACH,CACJ,KAAa,SAAS,SAAW,GAChC,SAAC,MAAD,CAAK,UAAW,EAAO,UAAW,oCAA8B,IAEhE,SAAC,KAAD,CAAI,UAAW,EAAO,YACnB,WAAa,SAAS,IAAK,IAC1B,SAAC,KAAD,WACE,SAAC,EAAD,CAAM,GAAI,EAAQ,KAAO,WAAQ,KAAY,EAC3C,EAFK,EAAQ,EAEb,CACL,CACC,EAEH,KACL,SAAC,EAAD,CAAM,KAAK,YAAa,WAAa,cAAqB,EACnD,IAGL,IAAe,CAAE,mBACrB,UAAC,UAAD,CAAS,kBAAgB,yBAAyB,UAAW,EAAO,MAApE,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,GAAG,yBAAyB,QAAQ,aAAa,sBAEzD,IACN,SAAC,KAAD,UACG,EAAa,MAAM,IAAK,IACvB,UAAC,MAAD,YACE,SAAC,KAAD,UAAK,EAAK,KAAU,IACpB,SAAC,KAAD,UAAK,EAAK,KAAU,EACjB,GAHK,EAAK,KAGV,CACN,CACC,EACG,IAGL,IAAkB,CAAE,mBACxB,UAAC,UAAD,CAAS,kBAAgB,4BAA4B,UAAW,EAAO,SAAvE,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,GAAG,4BAA4B,QAAQ,aAAa,qBAE5D,IACN,SAAC,EAAD,CACE,UAAW,EAAa,SAAS,UACjC,kBAAmB,EAAa,SAAS,kBACzC,cAAe,EAAa,SAAS,cACrC,UAAW,EAAa,SAAS,UACjC,QAAS,EAAa,OACvB,IACD,UAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAA/B,UACG,EAAa,SAAS,UAAU,iBAAe,EAAa,SAAS,YAAc,EAAI,GAAK,IAAI,KAAG,IACnG,EAAa,SAAS,WAAW,SAAO,EAAa,SAAS,aAAe,EAAI,GAAK,GACnF,GACC,IAGL,IAAuB,CAC3B,kBAGkB,CAClB,GAAM,CAAC,EAAU,MAAe,YAC9B,EAAa,cAAc,kBAC7B,EACA,OACE,SAAC,MAAD,CAAK,UAAW,EAAO,cACrB,mBAAC,GAAD,CACE,UAAW,EAAa,cAAc,UACtC,QAAS,EAAa,cAAc,QACpC,WAAY,EAAa,cAAc,WACvC,mBAAoB,EACpB,QAAQ,iBACR,MAAO,EACP,0BAA2B,EAAU,IAAiB,CACpD,EAAa,GACX,EAAe,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAS,CAAQ,CAAC,CAAC,EAAI,EAAQ,OAAQ,GAAc,IAAc,CAAQ,CAC5G,CACF,EACA,UAAW,EAAa,cAAc,UACtC,OAAQ,EAAa,cAAc,OACnC,UAAW,EAAa,cAAc,UACtC,KAAK,SACN,EACE,EAET,EAEM,IAAuB,CAAE,kBAC7B,EAAa,cAAc,QAAU,GACnC,SAAC,EAAD,CACE,WAAY,EAAa,uBACzB,QAAQ,yBACR,cAAe,EAAa,aAC7B,IAED,SAAC,EAAD,CACE,WAAY,EAAa,uBACzB,QAAQ,yBACR,cAAe,EAAa,aAC7B,GAGC,IAAkB,CAAE,mBACxB,UAAC,UAAD,CAAS,kBAAgB,4BAA4B,UAAW,EAAO,SAAvE,WACE,UAAC,MAAD,CAAK,UAAW,EAAO,eAAvB,WACE,SAAC,EAAD,CAAM,GAAG,KAAK,GAAG,4BAA4B,QAAQ,gBAAgB,mBAE/D,IACN,SAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,OAAO,sCAEhC,EACH,CACJ,KAAa,SAAS,SAAW,GAChC,SAAC,EAAD,CAAM,KAAK,YAAa,WAAa,kBAAyB,IAE9D,SAAC,KAAD,CAAI,UAAW,EAAO,SACnB,WAAa,SAAS,KAAK,EAAO,KACjC,SAAC,EAAD,CAAa,UAAW,EAAQ,EAAa,SAAS,OAAS,EAAU,OAAuB,EAAX,EAAM,EAAK,CACjG,CACC,EAEC,IAGL,GAAgB,GAA6E,CACjG,OAAQ,EAAM,OAAd,CACE,IAAK,aACH,MAAO,uFACT,IAAK,iBACH,MAAO,kGACT,IAAK,eACH,MAAO,wFACX,CACF,EAEM,IAAiB,CACrB,2BACA,2BACA,sBACA,uBACA,mBACA,mBACA,eACA,QACA,mBACA,eACA,qBACA,oBACA,oBACA,0BACA,2BACA,cACA,cACA,cACA,0BACA,oCACA,yBACA,aACA,YA0BA,UAAC,MAAD,CAAK,UAAW,EAAO,QAAvB,UACG,IAAU,KAAO,MAChB,SAAC,EAAD,CACE,OAAQ,EAAM,SAAW,aAAe,QAAY,SAAC,EAAD,CAAQ,QAAS,EAAO,wBAAqB,GACjG,SAAU,EAAM,SAAW,iBAAmB,SAAW,MACzD,YAAa,GAAa,CAAK,EAC/B,MAAO,EAAM,SAAW,aAAe,oBAAsB,+BAC7D,KAAK,SACN,GAEF,EAAa,gBAAgB,IAAK,IACjC,SAAC,EAAD,CAAY,YAAa,EAAuB,MAAM,yBAAyB,KAAK,SAAW,EAAxD,CAAwD,CAChG,EACA,EAAa,oBAAsB,KAAO,MACzC,SAAC,GAAD,CACE,WAAY,EACZ,WAAY,EACZ,SAAU,EACV,WAAY,EACZ,UAAW,EAAa,iBACzB,GAEF,EAAa,QAAU,KAAO,MAAO,SAAC,GAAD,CAAuB,MAAO,EAAa,KAAQ,GACxF,EAAa,iBAAmB,KAAO,MACtC,SAAC,GAAD,CAAgC,OAAQ,EAAkB,KAAM,EAAa,cAAiB,GAE/F,EAAa,oBAAsB,KAAO,MACzC,SAAC,GAAD,CAAmC,SAAU,EAAa,iBAAoB,GAE/E,EAAa,cAAgB,KAAO,MACnC,SAAC,WAAD,CAAU,UAAU,SAAC,EAAD,CAAU,WAAY,GAAO,OAAO,QAAQ,MAAM,uBAAuB,QAAQ,OAAS,GAC5G,mBAAC,GAAD,CACE,UAAW,EAAa,cAAc,UACpB,mBAClB,eAAgB,EAChB,qBAAsB,EACtB,oBAAqB,EACrB,0BAA2B,EAC3B,2BAA4B,EAC5B,cAAe,EACf,0BAA2B,EAC3B,yBAA0B,EAC1B,cAAe,EACf,YAAa,EAAa,YACR,mBACC,oBACnB,GAAK,IAAsC,OAAY,CAAC,EAAI,CAAE,mCAAkC,EACnF,cACb,UAAW,EAAa,cAAc,UAC1B,YACb,EACO,IAEZ,SAAC,GAAD,CAA4B,cAAe,EACxC,IAoCD,GAA2B,GAA8B,OACzD,MAA2B,OAGpB,IAAuB,CAClC,2BAA2B,GAC3B,2BAA2B,GAC3B,sBAAsB,CAAE,KAAM,MAAO,EACrC,uBAAuB,EACvB,oBAAoB,GACpB,iCAAiC,KACjC,aACA,oBACA,0BAA0B,EAC1B,mBAAmB,GACnB,aACA,YAAa,EACb,cACA,QACA,mBAAmB,GACnB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,CAAE,KAAM,MAAO,EACnC,0BAA0B,EAC1B,2BAA2B,EAC3B,cAAc,EACd,eAAc,EACd,eAAc,CAAE,KAAM,MAAO,EAC7B,0BAA0B,EAC1B,qCACA,0BAAyB,EACzB,cAAa,KACb,QACA,kBAC4C,CAC5C,IAAM,MAAW,UAAoB,IAAI,EACnC,GACJ,EAAM,OAAS,SAAW,EAAM,OAAS,QAAU,EAAM,WAAW,OAAO,WAAW,SAAW,EAAM,KAGzG,IAFA,mBAAgB,GAAS,SAAS,MAAM,EAAG,CAAC,EAAe,CAAC,EAExD,EAAM,OAAS,OACjB,OACE,SAAC,GAAD,CACE,QACE,SAAC,EAAD,CAAM,MAAO,EAAa,GAAI,EAC3B,UACG,GAER,YAAY,6EACZ,MAAM,oBACP,GAGL,GAAI,EAAM,OAAS,UAAW,OAAO,SAAC,GAAD,CAAgB,GACrD,GAAI,EAAM,OAAS,YACjB,OACE,SAAC,GAAD,CACE,QACE,SAAC,EAAD,CAAM,MAAO,EAAa,GAAI,EAC3B,UACG,GAER,YAAY,6GACZ,MAAM,kBACP,GAGL,GAAI,EAAM,OAAS,SACjB,OACE,SAAC,GAAD,CACE,QAAQ,SAAC,EAAD,CAAQ,QAAS,EAAO,uBAAoB,GACpD,YAAY,0FACZ,MAAM,wBACN,KAAK,UACN,GAIL,IAAM,EAAe,GAAuB,GAAa,EAAM,UAAU,EACnE,GACJ,EAAM,OAAS,SAAW,EAAM,WAAW,iBAAmB,EAAM,WAAW,uBAC3E,GAAsB,GAAqB,EACjD,OACE,SAAC,EAAD,CAAc,UAAW,GACvB,mBAAC,EAAD,CACE,SACE,SAAC,GAAD,CAC2B,0BACX,eACd,qBAAsB,CACvB,GAEH,UAAU,SAAC,GAAD,CAA8B,cAAe,GACvD,YACE,SAAC,GAAD,CACE,YAAa,EAAa,iBAAmB,KAAO,wBAA0B,mBAC9E,UAAU,QACV,QAAS,EAAa,aACtB,QAAS,CACV,GAEH,eACE,SAAC,GAAD,CAAqF,cAAe,EAA1E,EAAM,WAAW,OAAO,WAAW,QAAuC,EAEtG,UAAW,EAAO,MAClB,SACE,SAAC,GAAD,CACE,yBAA0B,IAA0B,EACpD,yBAA0B,IAA0B,EAC/B,sBACC,uBACtB,iBAAkB,CAChB,QACE,GACA,EAAM,OAAS,SACf,EAAM,WAAW,iBACjB,EAAM,WAAW,uBACnB,SAAU,EAAM,WAAW,OAAO,WAAW,SAC7C,aACA,QAAS,GACT,UAAW,EAAM,WAAW,OAAO,mBACnC,MAAO,EAAa,KACtB,EACkB,mBACJ,eACI,mBACJ,eACM,qBACD,oBACM,0BACN,oBACO,2BACb,cACb,GAAK,KAAsC,OAAY,CAAC,EAAI,CAAE,oCAAkC,EACvE,0BACD,0BACX,eACA,eACN,QACK,cACZ,MAAO,EAAM,OAAS,QAAU,EAAQ,IACzC,GAEH,eAAc,EAAa,QAC3B,2BAA0B,EAAM,WAAW,OAAO,WAAW,SAC7D,UAAU,SAAC,GAAD,CAA8B,cAAe,GACvD,OAAO,SAAC,GAAD,CAA2B,cAAe,GACjD,UAAW,EAAa,UACxB,kBAAmB,EAAa,kBAChC,cAAe,EAAa,cAC5B,YACE,SAAC,EAAD,CAAM,UAAW,EAAO,KAAM,MAAO,EAAa,GAAI,EACnD,UACG,GAER,OAAQ,GAAG,EAAa,WAAW,MAAM,EAAa,QAAQ,kBAAkB,OAAO,EAAE,MAAM,EAAa,YAAY,GACxH,IAAK,GACL,eAAe,SAAC,GAAD,CAAmC,cAAe,GACjE,QAAS,EAAa,QACtB,SAAU,GACV,MAAO,EAAa,MACpB,KAAM,EAAa,KACnB,QAAS,EAAa,OACvB,EACW,EAElB,EAEM,IAA4B,CAChC,WACA,iBAIkB,CAClB,IAAM,EAAU,EAAgD,EAC1D,EAAiB,EAAkB,EACnC,EAAW,EAAY,EACvB,EAAW,EAAY,EACvB,EACJ,EAAQ,WAAW,MAAM,OAAS,QAAU,EAAQ,WAAW,MAAM,UAAU,YAAc,UACzF,EAAa,EAA0B,EAAe,KAAK,EAC3D,EAAa,GAAmB,EAAa,EAAU,EAAY,EAAY,EAAe,iBAAiB,EAC/G,GACH,EAAW,MAAM,OAAS,SAAW,EAAW,MAAM,OAAS,UAChE,EAAW,MAAM,WAAW,OAAO,WAAW,QAAQ,OAAS,OAC3D,EAAW,MAAM,WAAW,OAAO,mBACnC,KACA,EACJ,IAAiC,OAChC,EAAW,MAAM,OAAS,SAAW,EAAW,MAAM,OAAS,UAChE,EAAW,MAAM,WAAW,gCAC5B,EAAe,MAAM,OAAS,iBAC9B,EAAe,MAAM,QAAQ,aAAe,kBACxC,EACJ,IAAiC,OAAS,EAAW,MAAM,OAAS,SAAW,EAAW,MAAM,OAAS,SACrG,GAAuB,EAAW,MAAM,WAAW,OAAO,cAAc,EACxE,KACA,KAAwC,eAC5C,KAAO,IAAgD,CACrD,GAAI,IAAiC,KAAM,OAAO,KAClD,IAAM,EAAU,MAAM,GAAgC,KAAK,EAAU,CAAM,EAC3E,OAAO,EAAQ,OAAO,WAAW,WAAa,GAC5C,EAAQ,OAAO,qBAAuB,EACpC,GAAuB,EAAQ,OAAO,cAAc,EACpD,IACN,EACA,CAAC,EAA8B,CAAQ,CACzC,EACM,EAA4B,GAAiC,CACjE,QAAS,EACT,iBAAkB,EAAe,kBACjC,eAAgB,EAAW,MAC3B,mBAAoB,EACpB,4BAA6B,EAC7B,aACA,wBAAyB,CAC3B,CAAC,EACK,EAAkB,GACtB,EACA,EACA,EAAe,kBACf,EAAW,KACb,EACM,EACJ,EAAe,MAAM,OAAS,iBAAmB,EAAe,MAAM,QAAQ,aAAe,kBACzF,GACH,EAAW,MAAM,OAAS,SAAW,EAAW,MAAM,OAAS,UAChE,EAAW,MAAM,WAAW,OAAO,WAAW,QAAQ,OAAS,eAC3D,CACE,aAAc,EAAW,MAAM,WAAW,OAAO,WAAW,QAAQ,cAAgB,KACpF,aAAc,EAAW,MAAM,WAAW,OAAO,WAAW,QAAQ,YACtE,EACA,KACA,EAAmB,GACvB,EACA,GAAe,cAAgB,KAC/B,GAAe,cAAgB,KAC/B,EACA,EACA,EAAe,iBACjB,EACM,EAAiB,GAA6B,EAAS,MAAO,EAAa,CAAQ,EACnF,EAAqB,GAA0B,EAAe,MAAM,EACpE,EACJ,EAAW,MAAM,OAAS,SAAW,EAAW,MAAM,OAAS,QAC3D,EAAW,MAAM,WAAW,OAC5B,CAAE,mBAAoB,KAAM,WAAY,CAAC,EAAG,4BAA6B,EAAM,EAC/E,GAAqB,IAAI,IAC7B,EAAQ,WAAW,MAAM,OAAS,QAAU,EAAQ,WAAW,MAAM,UAAU,SAAS,KAAK,CAAE,QAAS,CAAE,EAAI,CAAC,CACjH,EACM,GAAY,GAChB,EAAe,OACf,EACA,EACA,EACA,EACF,EACA,OACE,iCACI,EAAW,MAAM,OAAS,SAAW,EAAW,MAAM,OAAS,UACjE,EAAW,MAAM,WAAW,OAAO,WAAW,QAAQ,OAAS,gBAC7D,SAAC,GAAD,CACE,WAAY,EACF,WACV,WAAY,EAAW,MAAM,WAC7B,YAAa,EAAiB,MAC9B,YAAa,EAAiB,eACjB,aACd,GACC,MACJ,SAAC,GAAD,CACE,yBACE,EAAe,MAAM,OAAS,kBAC7B,EAAe,MAAM,QAAQ,aAAe,mBAC3C,EAAe,MAAM,QAAQ,aAAe,sBAEhD,yBACE,EAAe,MAAM,OAAS,iBAAmB,EAAe,MAAM,QAAQ,aAAe,kBAE/F,oBAAqB,EAAgB,MACrC,qBAAsB,EAAgB,OACtC,kBACE,EAAe,MAAM,OAAS,iBAAmB,EAAe,MAAM,QAAQ,aAAe,kBAE/F,+BAAgC,EAA2B,EAA0B,MAAQ,KAC7F,eAAkB,EAAS,GAAW,CAAE,MAAO,EAAS,KAAM,CAAC,EAC/D,kBAAmB,EAA0B,yBAC7C,wBAAyB,EAA0B,eACnD,iBAAkB,EAAe,kBACjC,WAAY,EACZ,YAAa,GAAY,EAAoB,CAAW,EACxD,YAAa,EAAe,OAAO,MACnC,MAAO,EAAW,MACA,mBAClB,aAAc,EAAiB,OAC/B,mBAAoB,EAAiB,aACrC,kBAAmB,EAAiB,YACpC,wBAAyB,EAAiB,kBAC1C,kBAAmB,EAAiB,YACpC,yBAA0B,EAAiB,mBAC3C,YAAa,EAAiB,MAC9B,wBAAyB,EAAiB,kBAC1C,uBAAwB,EAAiB,iBACzC,YAAa,EAAiB,MAC9B,YAAa,EAAiB,MAC9B,MAAO,EAAW,MACN,aACC,aACd,EACD,GAEN,EAGa,OAA2C,CACtD,IAAM,EAAU,EAAgD,EAC1D,EAAS,EAAU,EACnB,EAAW,GAAoB,EAAO,QAAQ,EACpD,OAAO,IAAa,MAClB,SAAC,GAAD,CACE,QAAQ,SAAC,EAAD,CAAM,GAAI,GAA0B,EAAQ,WAAW,EAAG,wBAAmB,GACrF,YAAY,2DACZ,MAAM,kBACP,IAED,SAAC,GAAD,CAAoC,WAAU,YAAa,EAAQ,WAAc,EAErF","names":[],"ignoreList":[],"sources":["../../../src/client/controlCenterRelayThread.tsx","../../../src/client/entities/presentWorkspaceClockifyTimeEntry.ts","../../../src/client/entities/presentWorkspaceIssue.ts","../../../src/client/entities/presentWorkspacePullRequest.ts","../../../src/client/entities/presentWorkspaceEntity.ts","../../../src/client/entities/WorkspaceClockifyTimeEntryDetails.tsx","../../../src/client/entities/useClockifyActionSubmission.ts","../../../src/client/entities/useOpenConfluenceSynchronization.ts","../../../src/client/entities/WorkspaceConfluenceVisualEditor.tsx","../../../src/client/entities/WorkspaceConfluencePageDetails.tsx","../../../src/client/entities/WorkspaceIssueDetails.tsx","../../../src/client/entities/WorkspacePipelineExecutionDetails.tsx","../../../../review/dist/model.js","../../../src/client/entities/usePullRequestReview.ts","../../../src/client/entities/WorkspaceEntityRoute.tsx"],"sourcesContent":["import {\n PullRequestConversationContinuationFailed,\n PullRequestConversationContinuationRejected,\n type ContinuePullRequestConversationRequest,\n type PullRequestConversation,\n pullRequestThreadIdentity,\n type RelayProductDockMessage,\n type RelayPullRequestDockRegistration,\n useRelayPullRequestDock\n} from \"@knpkv/relay-product\"\nimport * as Effect from \"effect/Effect\"\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport { useMemo } from \"react\"\n\nimport { DurableAgentPrompt, type DurableAgentProviderId, type PullRequestReviewThreadEvent } from \"../api/agent.js\"\nimport type { WorkspaceEntityInspection } from \"../api/deliveryGraph.js\"\nimport type { EntityId, WorkspaceId } from \"../domain/identifiers.js\"\nimport {\n controlCenterRelayHostSelection,\n decodeControlCenterRelayConversation,\n decodeControlCenterRelaySelector\n} from \"./controlCenterRelayDock.js\"\nimport type { PullRequestReviewControllerState } from \"./entities/usePullRequestReview.js\"\nimport { workspaceEntityPath } from \"./workspaceEntityPaths.js\"\n\nconst eventMessage = (event: PullRequestReviewThreadEvent): RelayProductDockMessage | null => {\n switch (event._tag) {\n case \"operator-message\":\n return { id: String(event.eventSequence), role: \"operator\", text: event.prompt }\n case \"progress\":\n return { id: String(event.eventSequence), role: \"relay\", text: event.text }\n case \"review-report\":\n return {\n id: String(event.eventSequence),\n role: \"relay\",\n text: `${String(event.report.suggestions.length)} suggestions · ${String(event.report.notes.length)} notes`\n }\n case \"run-failed\":\n return { id: String(event.eventSequence), role: \"system\", text: `Review failed at ${event.stage}.` }\n case \"run-completed\":\n return { id: String(event.eventSequence), role: \"system\", text: `Review completed · ${event.outcome}` }\n case \"run-interrupted\":\n return { id: String(event.eventSequence), role: \"system\", text: \"Review interrupted by a restart.\" }\n case \"cancellation-requested\":\n return { id: String(event.eventSequence), role: \"system\", text: \"Cancellation requested.\" }\n case \"run-queued\":\n case \"run-started\":\n case \"suggestion-published\":\n case \"suggestion-revised\":\n case \"usage\":\n return null\n }\n}\n\nconst relayMessages = (state: PullRequestReviewControllerState): ReadonlyArray<RelayProductDockMessage> =>\n state._tag === \"ready\" && state.thread !== undefined\n ? state.thread.events.flatMap((event) => {\n const message = eventMessage(event)\n return message === null ? [] : [message]\n })\n : []\n\ntype ReviewProviderSelection = NonNullable<\n Extract<PullRequestReviewControllerState, { readonly _tag: \"ready\" }>[\"provider\"]\n>\n\nconst providerPresets = (state: PullRequestReviewControllerState): ReadonlyArray<ReviewProviderSelection> =>\n state._tag === \"ready\" ? (state.providerPresets ?? (state.provider === null ? [] : [state.provider])) : []\n\ninterface ControlCenterRelayContinuationInput {\n readonly conversation: PullRequestConversation\n readonly providerId: typeof DurableAgentProviderId.Type\n readonly request: ContinuePullRequestConversationRequest\n readonly startReview: (\n prompt?: typeof DurableAgentPrompt.Type,\n providerId?: typeof DurableAgentProviderId.Type\n ) => Promise<void>\n}\n\n/** Await the durable enqueue so the shared dock can retain input on transport failure. */\nexport const continueControlCenterRelayConversation = ({\n conversation,\n providerId,\n request,\n startReview\n}: ControlCenterRelayContinuationInput): Effect.Effect<void, PullRequestConversationContinuationFailed> => {\n const thread = pullRequestThreadIdentity(conversation)\n const prompt = Schema.decodeUnknownResult(DurableAgentPrompt)(request.message)\n if (Result.isFailure(prompt)) {\n return Effect.fail(\n new PullRequestConversationContinuationFailed({\n product: \"control-center\",\n thread\n })\n )\n }\n return Effect.tryPromise({\n try: () => startReview(prompt.success, providerId),\n catch: (): PullRequestConversationContinuationFailed =>\n new PullRequestConversationContinuationFailed({ product: \"control-center\", thread })\n })\n}\n\nconst selectorFor = (state: PullRequestReviewControllerState) => {\n const presets = providerPresets(state)\n const selected = state._tag === \"ready\" ? state.provider : null\n return presets.length === 0 || selected === null\n ? controlCenterRelayHostSelection\n : decodeControlCenterRelaySelector({\n modelId: selected.providerId,\n models: presets.map(({ model, providerId }) => ({ id: providerId, label: `${providerId} · ${model}` })),\n profileId: selected.providerId,\n profiles: presets.map(({ providerId, reviewProfile }) => ({\n id: providerId,\n label: reviewProfile.label\n }))\n })\n}\n\ninterface ControlCenterRelayThreadProps {\n readonly canEnqueue: boolean\n readonly entityId: EntityId\n readonly inspection: WorkspaceEntityInspection\n readonly reviewState: PullRequestReviewControllerState\n readonly startReview: (\n prompt?: typeof DurableAgentPrompt.Type,\n providerId?: ReviewProviderSelection[\"providerId\"]\n ) => Promise<void>\n readonly workspaceId: WorkspaceId\n}\n\n/** Register Control Center's existing durable PR event log with the shared shell dock. */\nexport const ControlCenterRelayThread = ({\n canEnqueue,\n entityId,\n inspection,\n reviewState,\n startReview,\n workspaceId\n}: ControlCenterRelayThreadProps): null => {\n const details = inspection.entity.projection.details\n const selection = useMemo(() => selectorFor(reviewState), [reviewState])\n const conversation = useMemo(\n () =>\n decodeControlCenterRelayConversation({\n _tag: \"control-center\",\n route: { entityId, href: workspaceEntityPath(workspaceId, entityId) },\n selection,\n thread: {\n pluginConnectionId: inspection.source.pluginConnectionId,\n pullRequestId: inspection.source.vendorImmutableId,\n repositoryName: details._tag === \"pull-request\" ? details.repository : \"unavailable\",\n workspaceId\n }\n }),\n [\n details,\n entityId,\n inspection.source.pluginConnectionId,\n inspection.source.vendorImmutableId,\n selection,\n workspaceId\n ]\n )\n const registration = useMemo<RelayPullRequestDockRegistration>(() => {\n const base = {\n context: [\n {\n id: \"repository\",\n label: \"Repository\",\n value: details._tag === \"pull-request\" ? details.repository : \"Unavailable\"\n },\n { id: \"pull-request\", label: \"Pull request\", value: `#${inspection.source.vendorImmutableId}` },\n {\n id: \"head\",\n label: \"Current head\",\n value: details._tag === \"pull-request\" ? details.headRevision.slice(0, 12) : \"Unavailable\"\n }\n ],\n conversation,\n selection\n }\n if (reviewState._tag === \"idle\" || reviewState._tag === \"loading\") return { ...base, status: \"loading\" }\n if (reviewState._tag === \"failed\") {\n return { ...base, description: \"Control Center could not load this durable PR thread.\", status: \"error\" }\n }\n const presets = providerPresets(reviewState)\n if (!canEnqueue || reviewState.provider === null || reviewState.review._tag === \"unavailable\") {\n return {\n ...base,\n description: canEnqueue\n ? \"No available PR-review agent profile is configured.\"\n : \"A workspace owner session is required to continue this PR thread.\",\n status: \"unavailable\"\n }\n }\n return {\n ...base,\n continuePullRequestConversation: (request) => {\n const thread = pullRequestThreadIdentity(conversation)\n if (reviewState.action === \"starting\" || reviewState.review._tag === \"pending\") {\n return new PullRequestConversationContinuationRejected({\n product: \"control-center\",\n reason: \"conversation-busy\",\n thread\n })\n }\n const selected = presets.find(\n ({ providerId }) =>\n String(providerId) === String(request.selection.modelId) &&\n String(providerId) === String(request.selection.profileId)\n )\n if (selected === undefined) {\n return new PullRequestConversationContinuationRejected({\n product: \"control-center\",\n reason: \"selection-unavailable\",\n thread\n })\n }\n return continueControlCenterRelayConversation({\n conversation,\n providerId: selected.providerId,\n request,\n startReview\n })\n },\n messages: relayMessages(reviewState),\n status: \"ready\"\n }\n }, [canEnqueue, conversation, details, inspection.source.vendorImmutableId, reviewState, selection, startReview])\n useRelayPullRequestDock(registration)\n return null\n}\n","import * as DateTime from \"effect/DateTime\"\n\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { DeliveryEntityDetails, DeliveryRelationship } from \"../../domain/deliveryGraph.js\"\nimport type { EntityId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport type { Revision } from \"../../domain/sourceRevision.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\n\ntype TimeEntryDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"time-entry\" }>\n\nexport interface WorkspaceClockifyJiraAssociation {\n readonly evidenceLabel: string\n readonly href: string\n readonly key: string\n readonly state: \"inferred\" | \"linked\"\n readonly title: string\n}\n\nexport interface WorkspaceClockifyTimeEntryPresentation {\n readonly approvalDecidedAt: {\n readonly dateTime: string\n readonly label: string\n } | null\n readonly approvalDetail: string\n readonly approvalLabel: string\n readonly approvers: ReadonlyArray<string>\n readonly associationDetail: string\n readonly associationLabel: string\n readonly billableLabel: string\n readonly contributorLabel: string\n readonly description: string\n readonly durationLabel: string\n readonly endedAt: string\n readonly jiraAssociations: ReadonlyArray<WorkspaceClockifyJiraAssociation>\n readonly lockLabel: string\n readonly projectLabel: string\n readonly rollupLabel: string\n readonly sourceRevision: Revision\n readonly startedAt: string\n readonly timerLabel: string\n readonly totalMinutes: number\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value\n .split(/[_\\-\\s]+/u)\n .filter(Boolean)\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1).toLocaleLowerCase(\"en-US\")}`)\n .join(\" \")\n\nconst durationLabel = (minutes: number): string => {\n const hours = Math.floor(minutes / 60)\n const remainder = minutes % 60\n if (hours === 0) return `${String(remainder)}m`\n return remainder === 0 ? `${String(hours)}h` : `${String(hours)}h ${String(remainder)}m`\n}\n\nconst timestampLabel = (value: DateTime.DateTime | null | undefined): string =>\n value === null || value === undefined ? \"Not synchronized\" : timestampFormatter.format(DateTime.toDateUtc(value))\n\nconst timestampPresentation = (value: DateTime.DateTime | null | undefined) =>\n value === null || value === undefined\n ? null\n : {\n dateTime: DateTime.formatIso(value),\n label: timestampFormatter.format(DateTime.toDateUtc(value))\n }\n\nconst acceptedRelationship = (relationship: DeliveryRelationship): boolean =>\n relationship.lifecycle._tag !== \"missing\" &&\n relationship.lifecycle._tag !== \"rejected\" &&\n relationship.lifecycle._tag !== \"superseded\"\n\nconst jiraAssociationsFor = (\n workspaceId: WorkspaceId,\n inspection: WorkspaceEntityInspection\n): ReadonlyArray<WorkspaceClockifyJiraAssociation> => {\n const subjectNodeIds = new Set(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }) =>\n resolution._tag === \"resolved\" &&\n resolution.target._tag === \"entity\" &&\n resolution.target.entityId === inspection.entity.projection.entityId\n ? [nodeId]\n : []\n )\n )\n const issueIdByNode = new Map<string, EntityId>()\n for (const { nodeId, resolution } of inspection.graph.nodes) {\n if (\n resolution._tag === \"resolved\" &&\n resolution.target._tag === \"entity\" &&\n resolution.target.entityKind === \"issue\"\n ) issueIdByNode.set(nodeId, resolution.target.entityId)\n }\n const issues = new Map<EntityId, WorkspaceEntityInspection[\"entity\"][\"projection\"]>()\n for (const { projection } of inspection.graph.relatedEntityProjections) {\n if (projection.entityState === \"present\" && projection.entityType === \"issue\") {\n issues.set(projection.entityId, projection)\n }\n }\n\n const associations = new Map<EntityId, {\n readonly evidenceClaimIds: Set<string>\n readonly issue: WorkspaceEntityInspection[\"entity\"][\"projection\"]\n state: \"inferred\" | \"linked\"\n }>()\n for (const relationship of inspection.graph.relationships) {\n if (\n relationship.kind !== \"tracks-time-for\" ||\n !subjectNodeIds.has(relationship.sourceNodeId) ||\n !acceptedRelationship(relationship)\n ) continue\n const issueId = issueIdByNode.get(relationship.targetNodeId)\n const issue = issueId === undefined ? undefined : issues.get(issueId)\n if (issueId === undefined || issue === undefined) continue\n const inferred = relationship.lifecycle._tag === \"inferred\" || relationship.confidence._tag === \"inferred\"\n const current = associations.get(issueId)\n if (current === undefined) {\n associations.set(issueId, {\n evidenceClaimIds: new Set(relationship.evidenceClaimIds),\n issue,\n state: inferred ? \"inferred\" : \"linked\"\n })\n continue\n }\n for (const evidenceClaimId of relationship.evidenceClaimIds) current.evidenceClaimIds.add(evidenceClaimId)\n if (!inferred) current.state = \"linked\"\n }\n\n return [...associations.entries()].map(([issueId, { evidenceClaimIds, issue, state }]) => ({\n evidenceLabel: `${String(evidenceClaimIds.size)} evidence claim${evidenceClaimIds.size === 1 ? \"\" : \"s\"}`,\n href: workspaceEntityPath(workspaceId, issueId),\n key: issue.displayKey,\n state,\n title: issue.title\n }))\n}\n\n/** Present one immutable Clockify entry with its current Control Center approval. */\nexport const presentWorkspaceClockifyTimeEntry = (\n workspaceId: WorkspaceId,\n details: TimeEntryDetails,\n inspection: WorkspaceEntityInspection\n): WorkspaceClockifyTimeEntryPresentation => {\n const jiraAssociations = jiraAssociationsFor(workspaceId, inspection)\n const inferredCount = jiraAssociations.filter(({ state }) => state === \"inferred\").length\n const approvers = inspection.entity.owners\n .filter(({ roles }) => roles.some((role) => role.includes(\"approver\")))\n .map(({ displayName }) => displayName)\n const contributor = details.userId === undefined\n ? undefined\n : inspection.entity.owners.find(({ sourceIdentities }) =>\n sourceIdentities?.some(\n ({ providerId, vendorPersonId }) => providerId === \"clockify\" && vendorPersonId === details.userId\n ) ?? false\n )\n return {\n approvalDecidedAt: timestampPresentation(inspection.clockifyApproval?.decidedAt),\n approvalDetail: inspection.clockifyApproval === null\n ? \"No Control Center decision is recorded for this exact Clockify revision.\"\n : inspection.clockifyApproval.rationale,\n approvalLabel: inspection.clockifyApproval === null\n ? \"Pending\"\n : titleCase(inspection.clockifyApproval.decision),\n approvers,\n associationDetail: jiraAssociations.length === 0\n ? \"No current Jira relationship explains where this time belongs. The entry remains visible.\"\n : inferredCount === 0\n ? `${String(jiraAssociations.length)} current Jira link${jiraAssociations.length === 1 ? \"\" : \"s\"}`\n : `${String(inferredCount)} inferred Jira link${inferredCount === 1 ? \"\" : \"s\"} — verify before reporting`,\n associationLabel: jiraAssociations.length === 0 ? \"Unattributed\" : \"Attributed\",\n billableLabel: details.billable ? \"Billable\" : \"Non-billable\",\n contributorLabel: contributor?.displayName ?? details.userId ?? \"Contributor not synchronized\",\n description: details.description ?? inspection.entity.projection.title,\n durationLabel: durationLabel(details.durationMinutes),\n endedAt: timestampLabel(details.endedAt),\n jiraAssociations,\n lockLabel: details.locked === undefined\n ? \"Lock state not synchronized\"\n : details.locked\n ? \"Locked\"\n : \"Unlocked\",\n projectLabel: details.projectId ?? \"No Clockify project\",\n rollupLabel: `1 visible entry · ${String(details.durationMinutes)} exact minute${\n details.durationMinutes === 1 ? \"\" : \"s\"\n }`,\n sourceRevision: inspection.source.revision,\n startedAt: timestampLabel(details.startedAt),\n timerLabel: details.startedAt === undefined || details.endedAt === undefined\n ? \"Timer state not synchronized\"\n : details.endedAt === null\n ? \"Timer running\"\n : \"Completed\",\n totalMinutes: details.durationMinutes\n }\n}\n","import type { RlyPerson } from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Option from \"effect/Option\"\n\nimport type { DeliveryEntityDetails } from \"../../domain/deliveryGraph.js\"\nimport type { SourceRevision } from \"../../domain/sourceRevision.js\"\n\ntype IssueDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"issue\" }>\n\nexport interface WorkspaceIssueMetadata {\n readonly label: string\n readonly value: string\n}\n\nexport interface WorkspaceIssueCommentPresentation {\n readonly author: RlyPerson\n readonly body: string | null\n readonly id: string\n readonly time: string | null\n}\n\nexport interface WorkspaceIssueHistoryPresentation {\n readonly actor: RlyPerson\n readonly changes: ReadonlyArray<{ readonly field: string; readonly transition: string }>\n readonly id: string\n readonly time: string | null\n}\n\nexport interface WorkspaceIssueRelatedPresentation {\n readonly href: string | null\n readonly key: string\n readonly status: string\n readonly summary: string\n}\n\nexport interface WorkspaceIssuePresentation {\n readonly acceptanceCriteria: string | null\n readonly collaborators: ReadonlyArray<RlyPerson>\n readonly commentCount: number\n readonly comments: ReadonlyArray<WorkspaceIssueCommentPresentation>\n readonly commentBodiesTruncated: boolean\n readonly commentsTruncated: boolean\n readonly description: string | null\n readonly environment: string | null\n readonly history: ReadonlyArray<WorkspaceIssueHistoryPresentation>\n readonly historyCount: number\n readonly historyTruncated: boolean\n readonly metadata: ReadonlyArray<WorkspaceIssueMetadata>\n readonly parent: WorkspaceIssueRelatedPresentation | null\n readonly subtasks: ReadonlyArray<WorkspaceIssueRelatedPresentation>\n readonly truncationMessage: string | null\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value.split(\"-\").map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`).join(\" \")\n\nconst readableTimestamp = (value: string | null): string | null => {\n if (value === null) return null\n return Option.match(DateTime.make(value), {\n onNone: () => value,\n onSome: (timestamp) => timestampFormatter.format(DateTime.toDateUtc(timestamp))\n })\n}\n\nconst valueName = (value: { readonly name: string | null; readonly sourceId: string | null }): string =>\n value.name ?? value.sourceId ?? \"Not set\"\n\nconst listValue = (values: ReadonlyArray<string> | undefined): string =>\n values === undefined || values.length === 0 ? \"Not set\" : values.join(\" · \")\n\nconst personFallback = (sourcePersonId: string): RlyPerson => ({\n id: sourcePersonId,\n name: \"Unknown collaborator\",\n role: \"Jira collaborator\"\n})\n\nconst peopleFor = (details: IssueDetails): ReadonlyMap<string, RlyPerson> =>\n new Map(\n (details.collaborators ?? []).map((collaborator) => {\n const roles = collaborator.roles.map(titleCase)\n return [\n collaborator.sourcePersonId,\n {\n id: collaborator.sourcePersonId,\n name: collaborator.displayName,\n role: roles.length === 0 ? \"Jira collaborator\" : roles.join(\" · \"),\n ...(!(collaborator.avatarUrl === null) && { avatarSrc: collaborator.avatarUrl })\n }\n ]\n })\n )\n\nconst relatedIssue = (\n value: NonNullable<IssueDetails[\"parent\"]>,\n sourceUrl: SourceRevision[\"sourceUrl\"]\n): WorkspaceIssueRelatedPresentation => ({\n href: (() => {\n if (sourceUrl === null || value.key === null) return null\n const browsePath = /^(.*\\/browse\\/)[^/]+$/u.exec(sourceUrl.pathname)?.[1]\n return browsePath === undefined ? null : `${sourceUrl.origin}${browsePath}${encodeURIComponent(value.key)}`\n })(),\n key: value.key ?? value.sourceId ?? \"Unknown issue\",\n status: value.status === null ? \"Status unknown\" : valueName(value.status),\n summary: value.summary ?? \"Summary unavailable\"\n})\n\nconst metadataFor = (details: IssueDetails): ReadonlyArray<WorkspaceIssueMetadata> => {\n const project = details.project\n const fixVersions = (details.fixVersions ?? []).map(valueName)\n const components = (details.components ?? []).map(valueName)\n return [\n {\n label: \"Type\",\n value: details.issueType === null || details.issueType === undefined ? \"Not set\" : valueName(details.issueType)\n },\n {\n label: \"Project\",\n value: project === null || project === undefined\n ? \"Not set\"\n : [project.key, project.name].filter((value): value is string => value !== null).join(\" · \") || \"Not set\"\n },\n {\n label: \"Resolution\",\n value: details.resolution === null || details.resolution === undefined\n ? \"Unresolved\"\n : valueName(details.resolution)\n },\n { label: \"Labels\", value: listValue(details.labels) },\n { label: \"Components\", value: listValue(components) },\n { label: \"Fix versions\", value: listValue(fixVersions) },\n { label: \"Created\", value: readableTimestamp(details.createdAt ?? null) ?? \"Not available\" },\n { label: \"Updated\", value: readableTimestamp(details.updatedAt ?? null) ?? \"Not available\" },\n { label: \"Due\", value: readableTimestamp(details.dueDate ?? null) ?? \"Not set\" }\n ]\n}\n\nconst transition = (from: string | null, to: string | null): string => `${from ?? \"Empty\"} → ${to ?? \"Empty\"}`\n\n/** Present provider-neutral synchronized issue detail for the canonical entity document. */\nexport const presentWorkspaceIssue = (\n details: IssueDetails,\n sourceUrl: SourceRevision[\"sourceUrl\"]\n): WorkspaceIssuePresentation => {\n const people = peopleFor(details)\n const person = (sourcePersonId: string | null): RlyPerson =>\n sourcePersonId === null\n ? personFallback(\"unknown-person\")\n : (people.get(sourcePersonId) ?? personFallback(sourcePersonId))\n const truncatedFields = new Set(details.truncatedFields ?? [])\n const comments = (details.comments ?? []).map((comment) => ({\n author: person(comment.authorSourcePersonId),\n body: comment.body,\n id: comment.sourceId,\n time: readableTimestamp(comment.updatedAt ?? comment.createdAt)\n }))\n const history = (details.history ?? []).map((entry) => ({\n actor: person(entry.authorSourcePersonId),\n changes: entry.changes.map((change) => ({ field: change.field, transition: transition(change.from, change.to) })),\n id: entry.sourceId,\n time: readableTimestamp(entry.createdAt)\n }))\n const commentCount = details.commentTotal ?? comments.length\n const historyCount = details.historyTotal ?? history.length\n const commentsTruncated = (details.commentsTruncated ?? false) || commentCount > comments.length\n const historyTruncated = (details.historyTruncated ?? false) || historyCount > history.length\n const reducedFields = [...truncatedFields].filter(\n (field) => field !== \"comments\" && (field !== \"history\" || !historyTruncated)\n )\n return {\n acceptanceCriteria: details.acceptanceCriteria ?? null,\n collaborators: [...people.values()],\n commentCount,\n comments,\n commentBodiesTruncated: details.commentBodiesTruncated ?? (truncatedFields.has(\"comments\") && !commentsTruncated),\n commentsTruncated,\n description: details.description ?? null,\n environment: details.environment ?? null,\n history,\n historyCount,\n historyTruncated,\n metadata: metadataFor(details),\n parent: details.parent === null || details.parent === undefined ? null : relatedIssue(details.parent, sourceUrl),\n subtasks: (details.subtasks ?? []).map((subtask) => relatedIssue(subtask, sourceUrl)),\n truncationMessage: reducedFields.length === 0\n ? null\n : `Jira shortened ${reducedFields.map(titleCase).join(\", \")} to keep this synchronized view bounded.`\n }\n}\n","import type { RlyPerson } from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Option from \"effect/Option\"\n\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { DeliveryEntityDetails } from \"../../domain/deliveryGraph.js\"\nimport type { SourceRevision } from \"../../domain/sourceRevision.js\"\nimport type { WorkspacePullRequestDiffScope } from \"./WorkspacePullRequestDiff.js\"\n\ntype PullRequestDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"pull-request\" }>\n\nexport interface WorkspacePullRequestTimestamp {\n readonly dateTime: string\n readonly label: string\n}\n\nexport interface WorkspacePullRequestPresentation {\n readonly author: RlyPerson | null\n readonly baseRevision: string | null\n readonly createdAt: WorkspacePullRequestTimestamp | null\n readonly description: string | null\n readonly diffScope: WorkspacePullRequestDiffScope\n readonly filesHref: string | null\n readonly headRevision: string\n readonly issueCount: number\n readonly issueCountLabel: string\n readonly mergeBaseRevision: string | null\n readonly pipelineCount: number\n readonly pipelineCountLabel: string\n readonly releaseCount: number\n readonly releaseCountLabel: string\n readonly reviewLabel: string\n readonly sourceBranch: string\n readonly targetBranch: string\n readonly updatedAt: WorkspacePullRequestTimestamp | null\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value\n .split(/[._\\-\\s]+/u)\n .filter((part) => part.length > 0)\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`)\n .join(\" \")\n\nconst authorName = (reference: string): string => {\n const leaf = reference.split(\"/\").filter((part) => part.length > 0).at(-1) ?? reference\n return titleCase(leaf) || \"AWS identity\"\n}\n\nconst authorFor = (reference: string | null | undefined): RlyPerson | null =>\n reference === null || reference === undefined\n ? null\n : {\n id: reference,\n name: authorName(reference),\n role: \"Pull request author\"\n }\n\nconst timestampFor = (value: PullRequestDetails[\"createdAt\"]): WorkspacePullRequestTimestamp | null => {\n if (value === null || value === undefined) return null\n return Option.match(DateTime.make(value), {\n onNone: () => null,\n onSome: (timestamp) => ({\n dateTime: DateTime.formatIso(timestamp),\n label: timestampFormatter.format(DateTime.toDateUtc(timestamp))\n })\n })\n}\n\nconst reviewLabel = (reviewState: PullRequestDetails[\"reviewState\"]): string => {\n switch (reviewState) {\n case \"approved\":\n return \"Approved by people\"\n case \"changes-requested\":\n return \"Changes requested\"\n case \"merged\":\n return \"Merged\"\n case \"requested\":\n return \"Human review requested\"\n case \"not-requested\":\n return \"No human approval synchronized\"\n }\n}\n\nconst connectedEntityIds = (inspection: WorkspaceEntityInspection): ReadonlySet<string> => {\n const entityIdByNode = new Map(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }): ReadonlyArray<readonly [string, string]> =>\n resolution._tag === \"resolved\" && resolution.target._tag === \"entity\"\n ? [[nodeId, resolution.target.entityId]]\n : []\n )\n )\n const subjectNodeIds = new Set(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }) =>\n resolution._tag === \"resolved\" &&\n resolution.target._tag === \"entity\" &&\n resolution.target.entityId === inspection.entity.projection.entityId\n ? [nodeId]\n : []\n )\n )\n return new Set(inspection.graph.relationships.flatMap((relationship) => {\n if (\n relationship.lifecycle._tag === \"missing\" ||\n relationship.lifecycle._tag === \"rejected\" ||\n relationship.lifecycle._tag === \"superseded\"\n ) return []\n const relatedNodeId = subjectNodeIds.has(relationship.sourceNodeId)\n ? relationship.targetNodeId\n : subjectNodeIds.has(relationship.targetNodeId)\n ? relationship.sourceNodeId\n : null\n const relatedEntityId = relatedNodeId === null ? null : entityIdByNode.get(relatedNodeId)\n return relatedEntityId === undefined || relatedEntityId === null ? [] : [relatedEntityId]\n }))\n}\n\n/** Present one immutable pull-request revision without conflating agent and human review. */\nexport const presentWorkspacePullRequest = (\n details: PullRequestDetails,\n source: SourceRevision,\n inspection: WorkspaceEntityInspection\n): WorkspacePullRequestPresentation => {\n const connected = connectedEntityIds(inspection)\n const relatedCount = (entityType: \"issue\" | \"pipeline-execution\"): number =>\n inspection.graph.relatedEntityProjections.filter(\n ({ projection }) =>\n projection.entityState === \"present\" &&\n projection.entityType === entityType &&\n connected.has(projection.entityId)\n ).length\n const releaseCount = inspection.entity.releaseIds.length\n const issueCount = relatedCount(\"issue\")\n const pipelineCount = relatedCount(\"pipeline-execution\")\n const evidenceCountLabel = (count: number): string => `${String(count)}${inspection.graph.truncated ? \"+\" : \"\"}`\n return {\n author: authorFor(details.authorReference),\n baseRevision: details.baseRevision ?? null,\n createdAt: timestampFor(details.createdAt),\n description: details.description?.trim() || null,\n diffScope: {\n pluginConnectionId: source.pluginConnectionId,\n vendorImmutableId: source.vendorImmutableId,\n revision: source.revision\n },\n filesHref: source.sourceUrl?.href ?? null,\n headRevision: details.headRevision,\n issueCount,\n issueCountLabel: evidenceCountLabel(issueCount),\n mergeBaseRevision: details.mergeBaseRevision ?? null,\n pipelineCount,\n pipelineCountLabel: evidenceCountLabel(pipelineCount),\n releaseCount,\n releaseCountLabel: `${String(releaseCount)}${inspection.entity.releaseMembershipsTruncated ? \"+\" : \"\"}`,\n reviewLabel: reviewLabel(details.reviewState),\n sourceBranch: details.sourceBranch,\n targetBranch: details.targetBranch,\n updatedAt: timestampFor(details.updatedAt)\n }\n}\n","import type {\n RlyCollaboratorCategory,\n RlyFreshnessState,\n RlyPerson,\n RlyRelationship,\n RlyService,\n RlyTimelineEvent,\n RlyVerdictTone\n} from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\n\nimport type { WorkspaceEntityInspection, WorkspaceEntityOwner } from \"../../api/deliveryGraph.js\"\nimport type { Role } from \"../../domain/actors.js\"\nimport type {\n DeliveryEntityDetails,\n DeliveryEntityKind,\n DeliveryNode,\n DeliveryRelationship\n} from \"../../domain/deliveryGraph.js\"\nimport type { EntityId, GraphNodeId, ReleaseId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport type { SourceRevision } from \"../../domain/sourceRevision.js\"\nimport { serviceFor, statusFor, statusPresentation } from \"../items/presentWorkspaceItems.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\nimport {\n presentWorkspaceClockifyTimeEntry,\n type WorkspaceClockifyTimeEntryPresentation\n} from \"./presentWorkspaceClockifyTimeEntry.js\"\nimport {\n presentWorkspaceConfluencePage,\n type WorkspaceConfluencePagePresentation\n} from \"./presentWorkspaceConfluencePage.js\"\nimport { presentWorkspaceIssue, type WorkspaceIssuePresentation } from \"./presentWorkspaceIssue.js\"\nimport {\n presentWorkspacePipelineExecution,\n type WorkspacePipelineExecutionPresentation\n} from \"./presentWorkspacePipelineExecution.js\"\nimport { presentWorkspacePullRequest } from \"./presentWorkspacePullRequest.js\"\nimport type { WorkspacePullRequestPresentation } from \"./presentWorkspacePullRequest.js\"\n\nexport interface WorkspaceEntityFact {\n readonly label: string\n readonly value: string\n}\n\nexport interface WorkspaceEntityActionPresentation {\n readonly external: boolean\n readonly href: string | null\n readonly label: string\n}\n\nexport interface WorkspaceEntityCollaboratorsPresentation {\n readonly approvers: ReadonlyArray<RlyPerson>\n readonly authors: ReadonlyArray<RlyPerson>\n readonly emptyLabel: string\n readonly expandedCategories: ReadonlyArray<RlyCollaboratorCategory>\n readonly operators: ReadonlyArray<RlyPerson>\n readonly owners: ReadonlyArray<RlyPerson>\n readonly reviewers: ReadonlyArray<RlyPerson>\n}\n\ninterface CollaboratorCategories extends Record<RlyCollaboratorCategory, Array<RlyPerson>> {}\n\nexport interface WorkspaceEntityEvidencePresentation {\n readonly claimCount: number\n readonly freshness: RlyFreshnessState\n readonly freshnessDateTime: string\n readonly freshnessTime: string\n readonly itemCount: number\n readonly reference: string\n}\n\nexport interface WorkspaceEntityReleasePresentation {\n readonly href: string\n readonly id: ReleaseId\n readonly label: string\n}\n\nexport interface WorkspaceEntityPresentation {\n readonly activity: ReadonlyArray<RlyTimelineEvent>\n readonly activityEmptyLabel: string\n readonly agentContext: string\n readonly collaborators: WorkspaceEntityCollaboratorsPresentation\n readonly clockifyTimeEntry: WorkspaceClockifyTimeEntryPresentation | null\n readonly confluencePage: WorkspaceConfluencePagePresentation | null\n readonly contentSummary: string\n readonly displayKey: string\n readonly evidence: WorkspaceEntityEvidencePresentation\n readonly facts: ReadonlyArray<WorkspaceEntityFact>\n readonly freshness: RlyFreshnessState\n readonly freshnessDateTime: string\n readonly freshnessTime: string\n readonly kindLabel: string\n readonly issue: WorkspaceIssuePresentation | null\n readonly pipelineExecution: WorkspacePipelineExecutionPresentation | null\n readonly pullRequest: WorkspacePullRequestPresentation | null\n readonly partialMessages: ReadonlyArray<string>\n readonly primaryAction: WorkspaceEntityActionPresentation\n readonly relationships: ReadonlyArray<RlyRelationship>\n readonly relationshipEmptyLabel: string\n readonly releases: ReadonlyArray<WorkspaceEntityReleasePresentation>\n readonly service: RlyService\n readonly serviceName: string\n readonly title: string\n readonly tone: RlyVerdictTone\n readonly verdict: string\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value.split(\"-\").map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`).join(\" \")\n\nconst serviceNames = {\n clockify: \"Clockify\",\n codecommit: \"CodeCommit\",\n codepipeline: \"CodePipeline\",\n confluence: \"Confluence\",\n jira: \"Jira\"\n} satisfies Readonly<Record<RlyService, string>>\n\nconst kindNames = {\n deployment: \"Deployment\",\n issue: \"Issue\",\n page: \"Page\",\n \"pipeline-execution\": \"Pipeline execution\",\n \"pull-request\": \"Pull request\",\n \"time-entry\": \"Time entry\"\n} satisfies Readonly<Record<DeliveryEntityKind, string>>\n\nconst readableTimestamp = (timestamp: DateTime.DateTime): string =>\n timestampFormatter.format(DateTime.toDateUtc(timestamp))\n\nconst sourceHref = (source: SourceRevision): string | null => {\n if (source.sourceUrl === null) return null\n const href = new URL(source.sourceUrl.href)\n if (source.providerId === \"confluence\" && href.pathname.startsWith(\"/spaces/\")) {\n href.pathname = `/wiki${href.pathname}`\n }\n return href.href\n}\n\nconst releaseHref = (workspaceId: WorkspaceId, releaseId: ReleaseId): string =>\n `/w/${encodeURIComponent(workspaceId)}/releases/${encodeURIComponent(releaseId)}`\n\nconst shortIdentity = (identity: string): string => identity.slice(-8)\n\nconst factsFor = (details: DeliveryEntityDetails): ReadonlyArray<WorkspaceEntityFact> => {\n switch (details._tag) {\n case \"issue\":\n return [\n { label: \"Priority\", value: details.priority ?? \"Not set\" },\n {\n label: \"Estimate\",\n value: details.estimatePoints === null ? \"Not estimated\" : `${details.estimatePoints} points`\n }\n ]\n case \"pull-request\":\n return [\n { label: \"Repository\", value: details.repository },\n ...(details.lifecycle === null || details.lifecycle === undefined\n ? []\n : [{ label: \"State\", value: titleCase(details.lifecycle) }]),\n { label: \"Branches\", value: `${details.sourceBranch} → ${details.targetBranch}` },\n { label: \"Head revision\", value: details.headRevision }\n ]\n case \"page\":\n return [\n { label: \"Space\", value: details.spaceKey },\n { label: \"Revision\", value: details.revision }\n ]\n case \"pipeline-execution\":\n return [\n { label: \"Pipeline\", value: details.pipelineName },\n { label: \"Execution\", value: details.executionId },\n { label: \"Trigger revision\", value: details.triggerRevision }\n ]\n case \"deployment\":\n return [\n { label: \"Environment\", value: shortIdentity(details.environmentId) },\n { label: \"Revision\", value: details.revision }\n ]\n case \"time-entry\":\n return [\n { label: \"Duration\", value: `${details.durationMinutes} min` },\n { label: \"Billable\", value: details.billable ? \"Yes\" : \"No\" }\n ]\n }\n}\n\nconst roleLabel = (role: Role): string => titleCase(role)\n\nconst personFor = (owner: WorkspaceEntityOwner): RlyPerson => ({\n avatarFallback: owner.avatarFallback,\n id: owner.personId,\n name: owner.displayName,\n role: [...new Set(owner.roles.map(roleLabel))].join(\" · \")\n})\n\nconst collaboratorCategory = (roles: ReadonlyArray<Role>): RlyCollaboratorCategory => {\n if (roles.some((role) => role.includes(\"approver\"))) return \"approvers\"\n if (roles.some((role) => role === \"reviewer\" || role === \"watcher\")) return \"reviewers\"\n if (roles.includes(\"operator\")) return \"operators\"\n if (roles.some((role) => role === \"author\" || role === \"contributor\")) return \"authors\"\n return \"owners\"\n}\n\nconst collaboratorsFor = (\n owners: ReadonlyArray<WorkspaceEntityOwner>\n): WorkspaceEntityCollaboratorsPresentation => {\n const categoryOrder: ReadonlyArray<RlyCollaboratorCategory> = [\n \"authors\",\n \"owners\",\n \"reviewers\",\n \"operators\",\n \"approvers\"\n ]\n const emptyPeople = (): Array<RlyPerson> => []\n const categories: CollaboratorCategories = {\n approvers: emptyPeople(),\n authors: emptyPeople(),\n operators: emptyPeople(),\n owners: emptyPeople(),\n reviewers: emptyPeople()\n }\n for (const owner of owners) categories[collaboratorCategory(owner.roles)].push(personFor(owner))\n const expandedCategories = categoryOrder.filter((category) => categories[category].length > 0)\n return {\n ...categories,\n emptyLabel: \"No collaborator is assigned to this object.\",\n expandedCategories\n }\n}\n\nconst collaboratorsWithIssue = (\n collaborators: WorkspaceEntityCollaboratorsPresentation,\n issue: WorkspaceIssuePresentation | null\n): WorkspaceEntityCollaboratorsPresentation => {\n if (issue === null) return collaborators\n const owners = [...collaborators.owners]\n const authors = [...collaborators.authors]\n const canonicalNames = new Set(\n [\n ...collaborators.approvers,\n ...collaborators.authors,\n ...collaborators.operators,\n ...collaborators.owners,\n ...collaborators.reviewers\n ].map((person) => person.name.toLocaleLowerCase(\"en-US\"))\n )\n const issuePersonIds = new Set<string>()\n for (const person of issue.collaborators) {\n if (issuePersonIds.has(person.id)) continue\n issuePersonIds.add(person.id)\n const normalizedName = person.name.toLocaleLowerCase(\"en-US\")\n if (canonicalNames.has(normalizedName)) continue\n if (person.role.includes(\"Assignee\")) owners.push(person)\n else authors.push(person)\n }\n const expandedCategories: Array<RlyCollaboratorCategory> = []\n if (authors.length > 0) expandedCategories.push(\"authors\")\n if (owners.length > 0) expandedCategories.push(\"owners\")\n for (const category of collaborators.expandedCategories) expandedCategories.push(category)\n return {\n ...collaborators,\n authors,\n emptyLabel: \"No collaborator was synchronized or assigned to this object.\",\n expandedCategories: [...new Set(expandedCategories)],\n owners\n }\n}\n\nconst collaboratorsWithPage = (\n collaborators: WorkspaceEntityCollaboratorsPresentation,\n page: WorkspaceConfluencePagePresentation | null,\n owners: ReadonlyArray<WorkspaceEntityOwner>\n): WorkspaceEntityCollaboratorsPresentation => {\n if (page === null) return collaborators\n const next = {\n approvers: [...collaborators.approvers],\n authors: [...collaborators.authors],\n operators: [...collaborators.operators],\n owners: [...collaborators.owners],\n reviewers: [...collaborators.reviewers]\n }\n const knownIds = new Set(Object.values(next).flat().map(({ id }) => id))\n const knownConfluenceSourceIds = new Set<string>(\n owners.flatMap((owner) =>\n (owner.sourceIdentities ?? [])\n .filter(({ providerId }) => providerId === \"confluence\")\n .map(({ vendorPersonId }) => vendorPersonId)\n )\n )\n for (const person of page.contributors) {\n if (knownIds.has(person.id) || knownConfluenceSourceIds.has(person.id)) continue\n knownIds.add(person.id)\n if (person.role.includes(\"Owner\")) next.owners.push(person)\n else if (person.role.includes(\"Watcher\")) next.reviewers.push(person)\n else next.authors.push(person)\n }\n const categoryOrder: ReadonlyArray<RlyCollaboratorCategory> = [\n \"authors\",\n \"owners\",\n \"reviewers\",\n \"operators\",\n \"approvers\"\n ]\n return {\n ...next,\n emptyLabel: \"No collaborator was synchronized or assigned to this document.\",\n expandedCategories: categoryOrder.filter(\n (category) => next[category].length > 0\n )\n }\n}\n\nconst freshnessFor = (inspection: WorkspaceEntityInspection): RlyFreshnessState => {\n const freshness = inspection.freshness\n if (freshness === null) return inspection.isSourceCurrent ? \"current\" : \"cached\"\n if (freshness._tag === \"current\") {\n return inspection.isSourceCurrent && freshness.provenance._tag === \"provider\" ? \"current\" : \"cached\"\n }\n return freshness._tag\n}\n\nconst freshnessTimestamp = (inspection: WorkspaceEntityInspection): DateTime.DateTime => {\n const freshness = inspection.freshness\n if (freshness === null) return inspection.entity.recordedAt\n return freshness.sourceObservedAt ?? freshness.synchronizedAt ?? freshness.pluginHealth.checkedAt\n}\n\nconst endpointFor = (\n node: DeliveryNode | undefined,\n entityById: ReadonlyMap<EntityId, WorkspaceEntityInspection[\"entity\"][\"projection\"]>,\n service: RlyService,\n workspaceId: WorkspaceId\n): RlyRelationship[\"source\"] => {\n if (node === undefined) {\n return { state: \"missing\", label: \"Unknown graph endpoint\", reason: \"The endpoint is outside this graph response.\" }\n }\n if (node.resolution._tag === \"missing\") {\n return {\n state: \"missing\",\n label: node.resolution.missingKey,\n reason: `${titleCase(node.endpointKind)} is not connected.`\n }\n }\n const target = node.resolution.target\n if (target._tag === \"entity\") {\n const projection = entityById.get(target.entityId)\n if (projection === undefined) {\n return {\n state: \"missing\",\n label: `${kindNames[target.entityKind]} ${shortIdentity(target.entityId)}`,\n reason: \"The related object is outside this bounded response.\",\n service: serviceFor(target.entityKind)\n }\n }\n if (projection.entityState === \"deleted\") {\n return {\n state: \"missing\",\n label: `${projection.title} · Deleted`,\n reason: \"The related object was deleted.\",\n service: serviceFor(projection.entityType)\n }\n }\n return {\n state: \"present\",\n href: workspaceEntityPath(workspaceId, projection.entityId),\n id: projection.entityId,\n reference: projection.displayKey,\n service: serviceFor(projection.entityType),\n title: projection.title\n }\n }\n if (target._tag === \"release\") {\n return {\n state: \"present\",\n href: releaseHref(workspaceId, target.releaseId),\n id: target.releaseId,\n reference: `Control Center release · ${shortIdentity(target.releaseId)}`,\n service,\n title: \"Delivery release\"\n }\n }\n return {\n state: \"present\",\n id: target.environmentId,\n reference: `Control Center environment · ${shortIdentity(target.environmentId)}`,\n service,\n title: \"Delivery environment\"\n }\n}\n\nconst relationshipEvidence = (relationship: DeliveryRelationship): string => {\n const evidence = relationship.evidenceClaimIds.length\n const confidence = relationship.confidence._tag === \"inferred\"\n ? `${Math.round(relationship.confidence.score * 100)}% inferred`\n : titleCase(relationship.confidence._tag)\n return `${evidence} evidence claim${evidence === 1 ? \"\" : \"s\"} · ${confidence}`\n}\n\nconst relationshipsFor = (\n inspection: WorkspaceEntityInspection,\n workspaceId: WorkspaceId,\n service: RlyService\n): ReadonlyArray<RlyRelationship> => {\n const nodeById = new Map<GraphNodeId, DeliveryNode>(inspection.graph.nodes.map((node) => [node.nodeId, node]))\n const projections = [inspection.entity, ...inspection.graph.relatedEntityProjections]\n .map(({ projection }) => projection)\n const entityById = new Map<EntityId, WorkspaceEntityInspection[\"entity\"][\"projection\"]>(\n projections.map((projection) => [projection.entityId, projection])\n )\n const ownerById = new Map(inspection.entity.owners.map((owner) => [owner.personId, owner]))\n return inspection.graph.relationships.map((relationship) => {\n const actorOwner = relationship.recordedBy._tag === \"human\"\n ? ownerById.get(relationship.recordedBy.personId)\n : undefined\n return {\n ...(!(actorOwner === undefined) && { actor: personFor(actorOwner) }),\n direction: \"forward\",\n evidence: relationshipEvidence(relationship),\n id: relationship.relationshipId,\n kind: titleCase(relationship.kind),\n lifecycle: relationship.lifecycle._tag,\n source: endpointFor(nodeById.get(relationship.sourceNodeId), entityById, service, workspaceId),\n target: endpointFor(nodeById.get(relationship.targetNodeId), entityById, service, workspaceId)\n }\n })\n}\n\nconst activityFor = (inspection: WorkspaceEntityInspection): ReadonlyArray<RlyTimelineEvent> =>\n inspection.activity.events.map((event) => ({\n actor: event.actor.label,\n actorKind: event.actor.kind,\n dateTime: DateTime.formatIso(event.occurredAt),\n detail: titleCase(event.sourceKind),\n ...(!(event.href === null) && { href: event.href }),\n id: event.eventKey,\n ...(!(event.service === null) && { service: event.service }),\n time: readableTimestamp(event.occurredAt),\n title: event.title\n }))\n\nconst primaryActionFor = (\n inspection: WorkspaceEntityInspection,\n workspaceId: WorkspaceId,\n serviceName: string\n): WorkspaceEntityActionPresentation => {\n const href = sourceHref(inspection.source)\n if (href !== null) {\n return {\n external: true,\n href,\n label: inspection.source.providerId === \"confluence\" ? \"View in Confluence\" : `Open in ${serviceName}`\n }\n }\n const releaseId = inspection.entity.canonicalReleaseId\n return releaseId === null\n ? { external: false, href: null, label: \"Source link unavailable\" }\n : { external: false, href: releaseHref(workspaceId, releaseId), label: \"Open delivery release\" }\n}\n\nconst partialMessagesFor = (inspection: WorkspaceEntityInspection): ReadonlyArray<string> => [\n ...(inspection.entity.ownersTruncated ? [\"More collaborators exist than this bounded view can show.\"] : []),\n ...(inspection.entity.releaseMembershipsTruncated\n ? [\"More release memberships exist than this bounded delivery path can show.\"]\n : []),\n ...(inspection.graph.truncated ? [\"The relationship graph is partial; additional delivery links exist.\"] : []),\n ...(inspection.activity.truncated ? [\"The activity list is partial; older events are not shown.\"] : [])\n]\n\ninterface AgentContextInput {\n readonly displayKey: string\n readonly issue: WorkspaceIssuePresentation | null\n readonly releaseCount: number\n readonly serviceName: string\n readonly title: string\n}\n\nconst agentContextFor = ({\n displayKey,\n issue,\n releaseCount,\n serviceName,\n title\n}: AgentContextInput): string =>\n issue === null\n ? `${displayKey} · ${title} · ${serviceName}`\n : `${displayKey} · ${title} · ${serviceName} issue · ${String(releaseCount)} release${\n releaseCount === 1 ? \"\" : \"s\"\n } · ${String(issue.commentCount)} synchronized comment${issue.commentCount === 1 ? \"\" : \"s\"}`\n\n/** Turn one provider-neutral canonical read into explicit application-owned Rly inputs. */\nexport const presentWorkspaceEntity = (\n workspaceId: WorkspaceId,\n inspection: WorkspaceEntityInspection\n): WorkspaceEntityPresentation => {\n const projection = inspection.entity.projection\n const service = serviceFor(projection.entityType)\n const serviceName = serviceNames[service]\n const verdict = statusFor(projection.details)\n const issue = projection.details._tag === \"issue\"\n ? presentWorkspaceIssue(projection.details, inspection.source.sourceUrl)\n : null\n const pullRequest = projection.details._tag === \"pull-request\"\n ? presentWorkspacePullRequest(projection.details, inspection.source, inspection)\n : null\n const pipelineExecution = projection.details._tag === \"pipeline-execution\"\n ? presentWorkspacePipelineExecution(projection.details, inspection)\n : null\n const confluencePage = projection.details._tag === \"page\"\n ? presentWorkspaceConfluencePage(projection.details, inspection)\n : null\n const clockifyTimeEntry = projection.details._tag === \"time-entry\"\n ? presentWorkspaceClockifyTimeEntry(workspaceId, projection.details, inspection)\n : null\n const freshnessTimestampValue = freshnessTimestamp(inspection)\n const releaseCount = inspection.entity.releaseIds.length\n return {\n activity: activityFor(inspection),\n activityEmptyLabel: \"No attributable activity has been recorded for this object.\",\n agentContext: agentContextFor({\n displayKey: projection.displayKey,\n issue,\n releaseCount,\n serviceName,\n title: projection.title\n }),\n collaborators: collaboratorsWithPage(\n collaboratorsWithIssue(collaboratorsFor(inspection.entity.owners), issue),\n confluencePage,\n inspection.entity.owners\n ),\n clockifyTimeEntry,\n confluencePage,\n contentSummary: `${kindNames[projection.entityType]} ${projection.displayKey} is tracked in ${serviceName}. ${\n releaseCount === 0\n ? \"It is not linked to a release yet.\"\n : `It belongs to ${releaseCount}${inspection.entity.releaseMembershipsTruncated ? \"+\" : \"\"} release${\n releaseCount === 1 ? \"\" : \"s\"\n }.`\n }`,\n displayKey: projection.displayKey,\n evidence: {\n claimCount: inspection.graph.evidenceClaims.length,\n freshness: freshnessFor(inspection),\n freshnessDateTime: DateTime.formatIso(freshnessTimestampValue),\n freshnessTime: readableTimestamp(freshnessTimestampValue),\n itemCount: inspection.graph.evidenceItems.length,\n reference: `${projection.displayKey} · source revision ${inspection.source.revision}`\n },\n facts: [\n { label: \"Object\", value: kindNames[projection.entityType] },\n { label: \"Service\", value: serviceName },\n ...factsFor(projection.details)\n ],\n freshness: freshnessFor(inspection),\n freshnessDateTime: DateTime.formatIso(freshnessTimestampValue),\n freshnessTime: readableTimestamp(freshnessTimestampValue),\n kindLabel: kindNames[projection.entityType],\n issue,\n pipelineExecution,\n pullRequest,\n partialMessages: partialMessagesFor(inspection),\n primaryAction: primaryActionFor(inspection, workspaceId, serviceName),\n relationships: relationshipsFor(inspection, workspaceId, service),\n relationshipEmptyLabel: \"No delivery relationships have been recorded for this object.\",\n releases: inspection.entity.releaseIds.map((releaseId) => ({\n href: releaseHref(workspaceId, releaseId),\n id: releaseId,\n label: `Release ${shortIdentity(releaseId)}`\n })),\n service,\n serviceName,\n title: projection.title,\n tone: statusPresentation(projection.entityType, verdict).tone,\n verdict\n }\n}\n","import { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport { useRef, useState, type FormEvent, type ReactElement, type ReactNode } from \"react\"\nimport { Link } from \"react-router\"\n\nimport type { SubmitClockifyActionRequest } from \"../../api/deliveryGraph.js\"\nimport type { WorkspaceClockifyTimeEntryPresentation } from \"./presentWorkspaceClockifyTimeEntry.js\"\nimport type { ClockifyActionSubmissionState } from \"./useClockifyActionSubmission.js\"\nimport styles from \"./WorkspaceClockifyTimeEntryDetails.module.css\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n </header>\n {children}\n </section>\n)\n\n/** Render one immutable Clockify entry and its Control Center-owned approval. */\nexport const WorkspaceClockifyTimeEntryDetails = ({\n canApprove = false,\n canCorrect = false,\n onSubmit,\n submission = { _tag: \"idle\" },\n timeEntry\n}: {\n readonly canApprove?: boolean\n readonly canCorrect?: boolean\n readonly onSubmit?: (request: SubmitClockifyActionRequest) => void\n readonly submission?: ClockifyActionSubmissionState\n readonly timeEntry: WorkspaceClockifyTimeEntryPresentation\n}): ReactElement => {\n const [jiraIssueKey, setJiraIssueKey] = useState(\"\")\n const [rationale, setRationale] = useState(\"\")\n const approvalDecision = useRef<\"approved\" | \"rejected\">(\"approved\")\n const correctionDisabled = !canCorrect || onSubmit === undefined || submission._tag === \"submitting\"\n const approvalDisabled = !canApprove || onSubmit === undefined || submission._tag === \"submitting\"\n const submitCorrection = (event: FormEvent): void => {\n event.preventDefault()\n if (!correctionDisabled)\n onSubmit({\n _tag: \"correct-association\",\n expectedRevision: timeEntry.sourceRevision,\n jiraIssueKey\n })\n }\n const submitApproval = (event: FormEvent): void => {\n event.preventDefault()\n if (!approvalDisabled && rationale.trim().length > 0) {\n onSubmit({\n _tag: \"record-approval\",\n expectedRevision: timeEntry.sourceRevision,\n decision: approvalDecision.current,\n rationale: rationale.trim()\n })\n approvalDecision.current = \"approved\"\n }\n }\n return (\n <article className={styles.document} data-workspace-clockify-time-entry-detail>\n <section aria-label=\"Clockify time ledger\" className={styles.ledger}>\n <div className={styles.total}>\n <span>Total tracked</span>\n <strong>{timeEntry.durationLabel}</strong>\n <small>{timeEntry.rollupLabel}</small>\n </div>\n <div className={styles.ledgerBody}>\n <header>\n <span>Time ledger</span>\n <StateLabel\n label={timeEntry.associationLabel}\n tone={timeEntry.jiraAssociations.length === 0 ? \"caution\" : \"positive\"}\n />\n </header>\n <p>{timeEntry.description}</p>\n <dl className={styles.primaryFacts}>\n <div>\n <dt>Project</dt>\n <dd>{timeEntry.projectLabel}</dd>\n </div>\n <div>\n <dt>Billing</dt>\n <dd>{timeEntry.billableLabel}</dd>\n </div>\n <div>\n <dt>Contributor</dt>\n <dd>{timeEntry.contributorLabel}</dd>\n </div>\n </dl>\n </div>\n </section>\n\n <Section heading=\"Entry\" meta=\"The exact source record included in the total\">\n <div className={styles.entry}>\n <strong>{timeEntry.durationLabel}</strong>\n <dl>\n <div>\n <dt>Started</dt>\n <dd>{timeEntry.startedAt}</dd>\n </div>\n <div>\n <dt>Ended</dt>\n <dd>{timeEntry.endedAt}</dd>\n </div>\n <div>\n <dt>State</dt>\n <dd>{timeEntry.timerLabel}</dd>\n </div>\n <div>\n <dt>Provider lock</dt>\n <dd>{timeEntry.lockLabel}</dd>\n </div>\n </dl>\n </div>\n </Section>\n\n <Section heading=\"Jira attribution\" meta=\"Current delivery-ledger relationships\">\n <div className={styles.attribution} data-state={timeEntry.jiraAssociations.length === 0 ? \"missing\" : \"linked\"}>\n <div>\n <strong>{timeEntry.associationLabel}</strong>\n <p>{timeEntry.associationDetail}</p>\n </div>\n {timeEntry.jiraAssociations.length === 0 ? null : (\n <ul>\n {timeEntry.jiraAssociations.map((association) => (\n <li key={association.href}>\n <Link to={association.href}>\n <span>{association.key}</span>\n <strong>{association.title}</strong>\n <small>\n {association.state === \"inferred\" ? \"Inferred\" : \"Linked\"} · {association.evidenceLabel}\n </small>\n </Link>\n </li>\n ))}\n </ul>\n )}\n </div>\n </Section>\n\n <Section heading=\"People\" meta=\"Provider contributor and assigned approvers\">\n <dl className={styles.people}>\n <div>\n <dt>Contributor</dt>\n <dd>{timeEntry.contributorLabel}</dd>\n </div>\n <div>\n <dt>Approvers</dt>\n <dd>{timeEntry.approvers.join(\" · \") || \"No approval recorded\"}</dd>\n </div>\n </dl>\n </Section>\n\n <aside className={styles.readOnly} data-clockify-approval>\n <strong>Control Center approval: {timeEntry.approvalLabel}</strong>\n <span>{timeEntry.approvalDetail}</span>\n {timeEntry.approvalDecidedAt === null ? null : (\n <time dateTime={timeEntry.approvalDecidedAt.dateTime}>Recorded {timeEntry.approvalDecidedAt.label}</time>\n )}\n </aside>\n <section aria-label=\"Governed Clockify actions\" data-clockify-governed-actions>\n <form onSubmit={submitCorrection}>\n <label>\n Jira issue key\n <input\n disabled={correctionDisabled}\n maxLength={100}\n onChange={(event) => setJiraIssueKey(event.currentTarget.value)}\n pattern=\"[A-Z][A-Z0-9]*-[1-9][0-9]*\"\n required\n value={jiraIssueKey}\n />\n </label>\n <button disabled={correctionDisabled} type=\"submit\">\n Correct association\n </button>\n </form>\n <form onSubmit={submitApproval}>\n <label>\n Approval rationale\n <input\n disabled={approvalDisabled}\n maxLength={1_000}\n onChange={(event) => setRationale(event.currentTarget.value)}\n required\n value={rationale}\n />\n </label>\n <button\n disabled={approvalDisabled || rationale.trim().length === 0}\n onClick={() => {\n approvalDecision.current = \"approved\"\n }}\n type=\"submit\"\n >\n Approve revision\n </button>\n <button\n disabled={approvalDisabled || rationale.trim().length === 0}\n onClick={() => {\n approvalDecision.current = \"rejected\"\n }}\n type=\"submit\"\n >\n Reject revision\n </button>\n </form>\n {submission._tag === \"failed\" ? <p role=\"alert\">The governed action could not be submitted.</p> : null}\n {submission._tag === \"succeeded\" ? <p>Action recorded: {submission.result.state}</p> : null}\n </section>\n </article>\n )\n}\n","import * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport type { SubmitClockifyActionRequest, SubmitClockifyActionResponse } from \"../../api/deliveryGraph.js\"\nimport type { EntityId } from \"../../domain/identifiers.js\"\nimport { makeAuthenticatedMutationClient } from \"../authenticatedMutationClient.js\"\n\nexport type ClockifyActionSubmissionState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"submitting\" }\n | { readonly _tag: \"succeeded\"; readonly result: SubmitClockifyActionResponse }\n | { readonly _tag: \"failed\" }\n\nexport interface ClockifyActionSubmissionTransport {\n readonly submit: (\n entityId: EntityId,\n request: SubmitClockifyActionRequest,\n signal: AbortSignal\n ) => Promise<SubmitClockifyActionResponse>\n}\n\n/** Generated-client transport carrying the authenticated mutation proof. */\nexport const browserClockifyActionSubmissionTransport: ClockifyActionSubmissionTransport = {\n submit: (entityId, request, signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeAuthenticatedMutationClient\n return yield* request._tag === \"correct-association\"\n ? client.deliveryGraph.submitClockifyAction({\n params: { entityId },\n payload: request\n })\n : client.deliveryGraph.submitClockifyAction({\n params: { entityId },\n payload: request\n })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Submit one human-confirmed Clockify action and retain its durable result. */\nexport const useClockifyActionSubmission = (\n entityId: EntityId,\n sessionKey: string | null,\n onSessionExpired: (sessionKey: string) => void,\n onSucceeded: () => void,\n transport: ClockifyActionSubmissionTransport = browserClockifyActionSubmissionTransport\n) => {\n const [state, setState] = useState<ClockifyActionSubmissionState>({ _tag: \"idle\" })\n const active = useRef<AbortController | null>(null)\n useEffect(() => {\n active.current?.abort()\n active.current = null\n setState({ _tag: \"idle\" })\n return () => {\n active.current?.abort()\n active.current = null\n }\n }, [entityId, sessionKey])\n return {\n state,\n submit: useCallback((request: SubmitClockifyActionRequest) => {\n if (sessionKey === null || active.current !== null) return\n const abort = new AbortController()\n active.current = abort\n setState({ _tag: \"submitting\" })\n transport.submit(entityId, request, abort.signal).then(\n (result) => {\n if (active.current !== abort) return\n active.current = null\n setState({ _tag: \"succeeded\", result })\n onSucceeded()\n },\n (error) => {\n if (active.current !== abort) return\n active.current = null\n if (Predicate.isTagged(\"UnauthorizedApiError\")(error)) onSessionExpired(sessionKey)\n if (!abort.signal.aborted) setState({ _tag: \"failed\" })\n }\n )\n }, [entityId, onSessionExpired, onSucceeded, sessionKey, transport])\n }\n}\n","import * as BrowserCrypto from \"@effect/platform-browser/BrowserCrypto\"\nimport * as Clock from \"effect/Clock\"\nimport * as Crypto from \"effect/Crypto\"\nimport * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport type { PluginSynchronizationState } from \"../../api/plugins.js\"\nimport type { PluginConnectionId } from \"../../domain/identifiers.js\"\nimport { browserConnectionTestTransport } from \"../services/connectionTestTransport.js\"\n\nexport const OPEN_CONFLUENCE_SYNC_INTERVAL = \"15 seconds\"\nconst OPEN_CONFLUENCE_SYNC_INTERVAL_MILLIS = 15_000\nconst OPEN_CONFLUENCE_SYNC_MAX_FORWARD_SKEW_MILLIS = 1_000\nconst OPEN_CONFLUENCE_SYNC_LEASE_MILLIS = 15 * 60_000\n\nexport type OpenConfluenceSynchronizationState = \"idle\" | \"syncing\" | \"synchronized\" | \"failed\"\n\nexport interface OpenConfluenceSynchronizationTransport {\n readonly synchronize: (\n pluginConnectionId: PluginConnectionId,\n signal: AbortSignal\n ) => Promise<PluginSynchronizationState>\n}\n\ninterface ActiveSynchronization {\n readonly abort: AbortController\n readonly completion: Promise<void>\n}\n\nconst browserOpenConfluenceSynchronizationTransport: OpenConfluenceSynchronizationTransport = {\n synchronize: (pluginConnectionId, signal) => {\n const synchronize = browserConnectionTestTransport.synchronize\n return synchronize === undefined\n ? Promise.reject(new Error(\"Confluence synchronization is unavailable\"))\n : synchronize(pluginConnectionId, signal)\n }\n}\n\ninterface AutomaticSynchronizationParticipant {\n readonly lifetime: AbortSignal\n readonly onSessionExpired: () => void\n readonly onSynchronized: () => void\n readonly ownerKey: string\n readonly sessionKey: string\n readonly setState: (state: OpenConfluenceSynchronizationState) => void\n readonly transport: OpenConfluenceSynchronizationTransport\n readonly verifySynchronized: (signal: AbortSignal) => Promise<boolean>\n}\n\ninterface AutomaticSynchronizationGroup {\n active: ActiveSynchronization | null\n readonly participants: Map<symbol, AutomaticSynchronizationParticipant>\n}\n\nconst CrossTabAutomaticSynchronization = Schema.Struct({\n ownerKey: Schema.String,\n recordedAt: Schema.Number,\n sessionExpired: Schema.Boolean,\n state: Schema.Literals([\"syncing\", \"synchronized\", \"failed\"])\n})\n\ntype CrossTabAutomaticSynchronization = typeof CrossTabAutomaticSynchronization.Type\n\nconst automaticSynchronizationGroups = new Map<PluginConnectionId, AutomaticSynchronizationGroup>()\nconst automaticSynchronizationCleanup = new WeakMap<AutomaticSynchronizationGroup, () => void>()\nconst automaticSynchronizationOwnerKeys = new Map<string, string>()\nconst makeAutomaticSynchronizationOwnerKey = Effect.gen(function*() {\n const cryptoService = yield* Crypto.Crypto\n return yield* cryptoService.randomUUIDv4\n}).pipe(Effect.provide(BrowserCrypto.layer))\n\nconst automaticSynchronizationOwnerKey = (sessionKey: string): string => {\n const existing = automaticSynchronizationOwnerKeys.get(sessionKey)\n if (existing !== undefined) return existing\n const ownerKey = Effect.runSync(makeAutomaticSynchronizationOwnerKey)\n automaticSynchronizationOwnerKeys.set(sessionKey, ownerKey)\n return ownerKey\n}\n\nconst automaticSynchronizationStorageKey = (pluginConnectionId: PluginConnectionId): string =>\n `control-center:confluence-sync:${pluginConnectionId}`\n\nconst readCrossTabSynchronization = (key: string): CrossTabAutomaticSynchronization | null => {\n try {\n const value = localStorage.getItem(key)\n if (value === null) return null\n return Result.getOrNull(\n Schema.decodeUnknownResult(Schema.fromJsonString(CrossTabAutomaticSynchronization))(value)\n )\n } catch {\n return null\n }\n}\n\nconst writeCrossTabSynchronization = (\n key: string,\n synchronization: CrossTabAutomaticSynchronization\n): void => {\n try {\n localStorage.setItem(\n key,\n Schema.encodeSync(Schema.fromJsonString(CrossTabAutomaticSynchronization))(synchronization)\n )\n } catch {\n // Storage can be unavailable in a restricted browser context; the in-document coordinator remains active.\n }\n}\n\nconst clearCrossTabSynchronization = (\n key: string,\n expected: CrossTabAutomaticSynchronization\n): void => {\n const current = readCrossTabSynchronization(key)\n if (\n current?.state !== \"syncing\" ||\n current.ownerKey !== expected.ownerKey ||\n current.recordedAt !== expected.recordedAt\n ) return\n try {\n localStorage.removeItem(key)\n } catch {\n // Storage can be unavailable in a restricted browser context; the in-document coordinator remains active.\n }\n}\n\nconst applyAutomaticSynchronization = async (\n group: AutomaticSynchronizationGroup,\n synchronization: CrossTabAutomaticSynchronization\n): Promise<boolean> => {\n let requiresSessionRetry = false\n await Promise.all(Array.from(group.participants.values(), async (participant) => {\n if (participant.lifetime.aborted) return\n if (synchronization.sessionExpired && synchronization.ownerKey !== participant.ownerKey) {\n requiresSessionRetry = true\n return\n }\n if (synchronization.state !== \"synchronized\") {\n participant.setState(synchronization.state)\n if (synchronization.sessionExpired) participant.onSessionExpired()\n return\n }\n participant.setState(\"syncing\")\n try {\n const verified = await participant.verifySynchronized(participant.lifetime)\n if (participant.lifetime.aborted) return\n participant.setState(verified ? \"synchronized\" : \"idle\")\n if (verified) participant.onSynchronized()\n } catch (failure) {\n if (participant.lifetime.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) participant.onSessionExpired()\n participant.setState(\"failed\")\n }\n }))\n return requiresSessionRetry\n}\n\nconst synchronizeAutomatically = (\n pluginConnectionId: PluginConnectionId,\n group: AutomaticSynchronizationGroup,\n force = false\n): Promise<void> => {\n if (group.active !== null) return group.active.completion\n const abort = new AbortController()\n const requestedAt = Effect.runPromise(Clock.currentTimeMillis)\n const storageKey = automaticSynchronizationStorageKey(pluginConnectionId)\n let retryAfterCompletion = false\n const synchronizeWithLease = async (): Promise<void> => {\n const requestStartedAt = await requestedAt\n const recordedAt = await Effect.runPromise(Clock.currentTimeMillis)\n const source = group.participants.values().next().value\n if (source === undefined || abort.signal.aborted) return\n const recent = readCrossTabSynchronization(storageKey)\n const recentAge = recent === null ? null : recordedAt - recent.recordedAt\n if (\n recent !== null &&\n recentAge !== null &&\n recent.recordedAt <= recordedAt + OPEN_CONFLUENCE_SYNC_MAX_FORWARD_SKEW_MILLIS &&\n (!recent.sessionExpired || recent.ownerKey === source.ownerKey) &&\n (recent.state === \"syncing\"\n ? recentAge < OPEN_CONFLUENCE_SYNC_LEASE_MILLIS\n : !force &&\n (recent.recordedAt >= requestStartedAt || recentAge < OPEN_CONFLUENCE_SYNC_INTERVAL_MILLIS))\n ) {\n if (recent.state !== \"syncing\") retryAfterCompletion = await applyAutomaticSynchronization(group, recent)\n return\n }\n const syncing = {\n ownerKey: source.ownerKey,\n recordedAt,\n sessionExpired: false,\n state: \"syncing\"\n } satisfies CrossTabAutomaticSynchronization\n writeCrossTabSynchronization(storageKey, syncing)\n retryAfterCompletion = await applyAutomaticSynchronization(group, syncing)\n const releaseSyncingRecord = (): void => clearCrossTabSynchronization(storageKey, syncing)\n abort.signal.addEventListener(\"abort\", releaseSyncingRecord, { once: true })\n try {\n const result = await source.transport.synchronize(pluginConnectionId, abort.signal)\n if (abort.signal.aborted) return releaseSyncingRecord()\n const completed = {\n ownerKey: source.ownerKey,\n recordedAt: await Effect.runPromise(Clock.currentTimeMillis),\n sessionExpired: false,\n state: result.result === \"synchronized\" ? \"synchronized\" : \"failed\"\n } satisfies CrossTabAutomaticSynchronization\n writeCrossTabSynchronization(storageKey, completed)\n retryAfterCompletion = await applyAutomaticSynchronization(group, completed)\n } catch (failure) {\n if (abort.signal.aborted) return releaseSyncingRecord()\n const failed = {\n ownerKey: source.ownerKey,\n recordedAt: await Effect.runPromise(Clock.currentTimeMillis),\n sessionExpired: Predicate.isTagged(\"UnauthorizedApiError\")(failure),\n state: \"failed\"\n } satisfies CrossTabAutomaticSynchronization\n writeCrossTabSynchronization(storageKey, failed)\n retryAfterCompletion = await applyAutomaticSynchronization(group, failed)\n } finally {\n abort.signal.removeEventListener(\"abort\", releaseSyncingRecord)\n }\n }\n const lockManager = \"locks\" in navigator ? navigator.locks : null\n const completion = (\n lockManager === null\n ? synchronizeWithLease()\n : lockManager.request(\n `control-center:confluence-sync:${pluginConnectionId}`,\n { signal: abort.signal },\n () => synchronizeWithLease()\n )\n ).catch(async <UnparsedInput>(failure: UnparsedInput) => {\n const source = group.participants.values().next().value\n if (!abort.signal.aborted && source !== undefined) {\n const failed = {\n ownerKey: source.ownerKey,\n recordedAt: 0,\n sessionExpired: Predicate.isTagged(\"UnauthorizedApiError\")(failure),\n state: \"failed\"\n } satisfies CrossTabAutomaticSynchronization\n retryAfterCompletion = await applyAutomaticSynchronization(group, failed)\n }\n }).finally(() => {\n if (group.active?.abort === abort) group.active = null\n if (retryAfterCompletion && document.visibilityState === \"visible\") {\n void synchronizeAutomatically(pluginConnectionId, group, true)\n }\n })\n group.active = { abort, completion }\n return completion\n}\n\nconst startAutomaticSynchronization = (\n pluginConnectionId: PluginConnectionId,\n group: AutomaticSynchronizationGroup\n): () => void => {\n let cadence: AbortController | null = null\n let generation = 0\n let stopped = false\n const schedule = (currentGeneration: number): void => {\n if (stopped || currentGeneration !== generation) return\n const nextCadence = new AbortController()\n cadence = nextCadence\n void Effect.runPromise(Effect.sleep(OPEN_CONFLUENCE_SYNC_INTERVAL), { signal: nextCadence.signal }).then(\n () => synchronizeAndSchedule(),\n <UnparsedInput>(_failure: UnparsedInput) => {\n if (!nextCadence.signal.aborted) {\n for (const participant of group.participants.values()) participant.setState(\"failed\")\n }\n }\n )\n }\n const synchronizeAndSchedule = (): void => {\n generation += 1\n const currentGeneration = generation\n cadence?.abort()\n cadence = null\n const completion = document.visibilityState === \"visible\"\n ? synchronizeAutomatically(pluginConnectionId, group)\n : Promise.resolve()\n void completion.finally(() => schedule(currentGeneration))\n }\n const synchronizeWhenVisible = (): void => {\n if (document.visibilityState === \"visible\") {\n generation += 1\n const currentGeneration = generation\n cadence?.abort()\n cadence = null\n void synchronizeAutomatically(pluginConnectionId, group, true).finally(() => schedule(currentGeneration))\n }\n }\n const synchronizeFromAnotherTab = (event: StorageEvent): void => {\n if (event.key !== automaticSynchronizationStorageKey(pluginConnectionId) || event.newValue === null) return\n const synchronization = Result.getOrNull(\n Schema.decodeUnknownResult(Schema.fromJsonString(CrossTabAutomaticSynchronization))(event.newValue)\n )\n if (synchronization === null) return\n void applyAutomaticSynchronization(group, synchronization).then((requiresSessionRetry) => {\n if (requiresSessionRetry && document.visibilityState === \"visible\") {\n void synchronizeAutomatically(pluginConnectionId, group, true)\n }\n })\n }\n document.addEventListener(\"visibilitychange\", synchronizeWhenVisible)\n window.addEventListener(\"storage\", synchronizeFromAnotherTab)\n synchronizeAndSchedule()\n return () => {\n stopped = true\n generation += 1\n cadence?.abort()\n cadence = null\n group.active?.abort.abort()\n group.active = null\n document.removeEventListener(\"visibilitychange\", synchronizeWhenVisible)\n window.removeEventListener(\"storage\", synchronizeFromAnotherTab)\n }\n}\n\nconst registerAutomaticSynchronization = (\n pluginConnectionId: PluginConnectionId,\n participant: AutomaticSynchronizationParticipant\n): () => void => {\n const participantId = Symbol()\n const existing = automaticSynchronizationGroups.get(pluginConnectionId)\n const group = existing ?? { active: null, participants: new Map() }\n group.participants.set(participantId, participant)\n if (existing === undefined) {\n automaticSynchronizationGroups.set(pluginConnectionId, group)\n automaticSynchronizationCleanup.set(group, startAutomaticSynchronization(pluginConnectionId, group))\n }\n return () => {\n group.participants.delete(participantId)\n if (group.participants.size !== 0) return\n automaticSynchronizationCleanup.get(group)?.()\n automaticSynchronizationCleanup.delete(group)\n if (automaticSynchronizationGroups.get(pluginConnectionId) === group) {\n automaticSynchronizationGroups.delete(pluginConnectionId)\n }\n }\n}\n\nconst activeCrossTabSynchronizationLease = async (\n storageKey: string\n): Promise<{ readonly remainingMillis: number; readonly synchronization: CrossTabAutomaticSynchronization } | null> => {\n const synchronization = readCrossTabSynchronization(storageKey)\n if (synchronization?.state !== \"syncing\") return null\n const now = await Effect.runPromise(Clock.currentTimeMillis)\n if (synchronization.recordedAt > now + OPEN_CONFLUENCE_SYNC_MAX_FORWARD_SKEW_MILLIS) return null\n const remainingMillis = synchronization.recordedAt + OPEN_CONFLUENCE_SYNC_LEASE_MILLIS - now\n return remainingMillis <= 0 ? null : { remainingMillis, synchronization }\n}\n\nconst waitForCrossTabSynchronization = async (\n pluginConnectionId: PluginConnectionId,\n registrationLifetime: AbortSignal\n): Promise<void> => {\n const storageKey = automaticSynchronizationStorageKey(pluginConnectionId)\n while (true) {\n if (registrationLifetime.aborted) return\n const lease = await activeCrossTabSynchronizationLease(storageKey)\n if (lease === null) return\n const lifetime = new AbortController()\n await new Promise<void>((resolve) => {\n let finished = false\n const finish = (): void => {\n if (finished) return\n finished = true\n lifetime.abort()\n window.removeEventListener(\"storage\", storageChanged)\n registrationLifetime.removeEventListener(\"abort\", finish)\n resolve()\n }\n const storageChanged = (event: StorageEvent): void => {\n if (event.key === storageKey) finish()\n }\n window.addEventListener(\"storage\", storageChanged)\n registrationLifetime.addEventListener(\"abort\", finish, { once: true })\n if (registrationLifetime.aborted) finish()\n const current = readCrossTabSynchronization(storageKey)\n if (\n current?.state !== \"syncing\" ||\n current.ownerKey !== lease.synchronization.ownerKey ||\n current.recordedAt !== lease.synchronization.recordedAt\n ) finish()\n void Effect.runPromise(Effect.sleep(lease.remainingMillis), { signal: lifetime.signal }).then(\n finish,\n <UnparsedInput>(_failure: UnparsedInput) => {\n if (!lifetime.signal.aborted) finish()\n }\n )\n })\n }\n}\n\n/** Keep an open Confluence page fresh without polling while its browser tab is hidden. */\nexport const useOpenConfluenceSynchronization = ({\n enabled,\n onSessionExpired,\n onSynchronized,\n pluginConnectionId,\n readSynchronizationRevision,\n sessionKey,\n synchronizationRevision,\n transport = browserOpenConfluenceSynchronizationTransport\n}: {\n readonly enabled: boolean\n readonly onSessionExpired: (sessionKey: string) => void\n readonly onSynchronized: () => void\n readonly pluginConnectionId: PluginConnectionId | null\n readonly readSynchronizationRevision: (signal: AbortSignal) => Promise<number | null>\n readonly sessionKey: string | null\n readonly synchronizationRevision: number | null\n readonly transport?: OpenConfluenceSynchronizationTransport\n}) => {\n const [state, setState] = useState<OpenConfluenceSynchronizationState>(\"idle\")\n const registrationLifetime = useRef<AbortController | null>(null)\n const sessionExpired = useRef(onSessionExpired)\n const synchronized = useRef(onSynchronized)\n const revisionReader = useRef(readSynchronizationRevision)\n const knownRevision = useRef({ pluginConnectionId, sessionKey, value: synchronizationRevision })\n sessionExpired.current = onSessionExpired\n synchronized.current = onSynchronized\n revisionReader.current = readSynchronizationRevision\n if (\n knownRevision.current.pluginConnectionId !== pluginConnectionId ||\n knownRevision.current.sessionKey !== sessionKey\n ) {\n knownRevision.current = { pluginConnectionId, sessionKey, value: synchronizationRevision }\n } else if (\n synchronizationRevision !== null &&\n (knownRevision.current.value === null || synchronizationRevision > knownRevision.current.value)\n ) {\n knownRevision.current.value = synchronizationRevision\n }\n const verifySynchronized = useCallback(async (signal: AbortSignal): Promise<boolean> => {\n const currentRevision = await revisionReader.current(signal)\n const previousRevision = knownRevision.current.value\n if (currentRevision === null || previousRevision === null || currentRevision <= previousRevision) return false\n knownRevision.current.value = currentRevision\n return true\n }, [])\n\n const synchronize = useCallback((): Promise<void> => {\n if (!enabled || pluginConnectionId === null || sessionKey === null) return Promise.resolve()\n const group = automaticSynchronizationGroups.get(pluginConnectionId)\n return group === undefined ? Promise.resolve() : synchronizeAutomatically(pluginConnectionId, group, true)\n }, [enabled, pluginConnectionId, sessionKey])\n\n const synchronizeWhenReady = useCallback((): void => {\n const lifetime = registrationLifetime.current?.signal\n if (lifetime === undefined || lifetime.aborted) return\n const inFlight = pluginConnectionId === null\n ? undefined\n : automaticSynchronizationGroups.get(pluginConnectionId)?.active?.completion\n ?? waitForCrossTabSynchronization(pluginConnectionId, lifetime)\n if (inFlight === undefined) void synchronize()\n else {\n void inFlight.then(() => {\n if (!lifetime.aborted) void synchronize()\n })\n }\n }, [pluginConnectionId, synchronize])\n\n useEffect(() => {\n setState(\"idle\")\n if (!enabled || pluginConnectionId === null || sessionKey === null) return\n const lifetime = new AbortController()\n registrationLifetime.current = lifetime\n const unregister = registerAutomaticSynchronization(pluginConnectionId, {\n lifetime: lifetime.signal,\n onSessionExpired: () => sessionExpired.current(sessionKey),\n onSynchronized: () => synchronized.current(),\n ownerKey: automaticSynchronizationOwnerKey(sessionKey),\n sessionKey,\n setState,\n transport,\n verifySynchronized\n })\n return () => {\n lifetime.abort()\n if (registrationLifetime.current === lifetime) registrationLifetime.current = null\n unregister()\n }\n }, [enabled, pluginConnectionId, sessionKey, transport, verifySynchronized])\n\n return {\n state,\n synchronizeAfterMutation: synchronizeWhenReady,\n synchronizeNow: synchronizeWhenReady\n }\n}\n","import { Button, Field, StatePanel, Text } from \"@knpkv/rly/primitives\"\nimport { memo, type ReactElement, useEffect, useRef, useState } from \"react\"\n\nimport type { EntityId, ReleaseId } from \"../../domain/identifiers.js\"\nimport { confluenceTaskSummary, setConfluenceTaskChecked } from \"../../domain/confluenceTasks.js\"\nimport { Revision } from \"../../domain/sourceRevision.js\"\nimport { submitBrowserReleasePublication } from \"../releases/releaseAgentTransport.js\"\nimport type { WorkspaceConfluencePagePresentation } from \"./presentWorkspaceConfluencePage.js\"\nimport { WorkspaceRichText } from \"./WorkspaceRichText.js\"\nimport styles from \"./WorkspaceConfluencePageDetails.module.css\"\nimport * as Predicate from \"effect/Predicate\"\n\ntype EditorState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"editing\" }\n | { readonly _tag: \"saving\" }\n | { readonly _tag: \"saved\" }\n | { readonly _tag: \"failed\" }\n\nconst markdownEscape = (value: string): string => value.replace(/([\\\\`*_[\\]<>])/gu, \"\\\\$1\")\nconst isElementNode = (node: Node): node is Element => node.nodeType === Node.ELEMENT_NODE\nconst isCheckboxInput = (node: Element): node is Element & { readonly checked: boolean } =>\n node.tagName.toLocaleLowerCase(\"en-US\") === \"input\" &&\n \"type\" in node &&\n node.type === \"checkbox\" &&\n \"checked\" in node &&\n Predicate.isBoolean(node.checked)\n\nconst inlineMarkdown = (node: Node): string => {\n if (node.nodeType === Node.TEXT_NODE) return markdownEscape(node.textContent ?? \"\")\n if (!isElementNode(node)) return \"\"\n const content = [...node.childNodes].map(inlineMarkdown).join(\"\")\n switch (node.tagName.toLocaleLowerCase(\"en-US\")) {\n case \"strong\":\n case \"b\":\n return `**${content}**`\n case \"em\":\n case \"i\":\n return `*${content}*`\n case \"s\":\n case \"del\":\n return `~~${content}~~`\n case \"code\":\n return `\\`${(node.textContent ?? \"\").replace(/`/gu, \"\\\\`\")}\\``\n case \"a\": {\n const href = node.getAttribute(\"href\")\n return href === null ? content : `[${content}](${href.replace(/\\)/gu, \"\\\\)\")})`\n }\n case \"br\":\n return \" \\n\"\n default:\n return content\n }\n}\n\nconst listMarkdown = (element: Element, ordered: boolean, depth = 0): string =>\n [...element.children]\n .filter((child) => child.tagName.toLocaleLowerCase(\"en-US\") === \"li\")\n .map((child, index) => {\n const task = [...child.children].find(isCheckboxInput)\n const marker = task === undefined ? \"\" : `[${task.checked ? \"x\" : \" \"}] `\n const nestedLists = [...child.children].filter((node) => /^(?:ol|ul)$/u.test(node.tagName.toLowerCase()))\n const label = [...child.childNodes]\n .filter((node) => !isElementNode(node) || !/^(?:ol|ul)$/u.test(node.tagName.toLowerCase()))\n .map(inlineMarkdown)\n .join(\"\")\n .trim()\n const indent = \" \".repeat(depth)\n const nested = nestedLists.map((node) => listMarkdown(node, node.tagName.toLowerCase() === \"ol\", depth + 1))\n return [\n `${indent}${ordered ? `${String(index + 1)}.` : \"-\"} ${task === undefined ? \"\" : marker}${label}`,\n ...nested\n ].join(\"\\n\")\n })\n .join(\"\\n\")\n\nconst blockMarkdown = (node: Node): string => {\n if (node.nodeType === Node.TEXT_NODE) return markdownEscape(node.textContent ?? \"\")\n if (!isElementNode(node)) return \"\"\n const tag = node.tagName.toLocaleLowerCase(\"en-US\")\n switch (tag) {\n case \"h1\":\n case \"h2\":\n case \"h3\":\n case \"h4\":\n case \"h5\":\n case \"h6\":\n return `${\"#\".repeat(Number(tag.slice(1)))} ${inlineMarkdown(node).trim()}`\n case \"ul\":\n return listMarkdown(node, false)\n case \"ol\":\n return listMarkdown(node, true)\n case \"blockquote\":\n return inlineMarkdown(node)\n .trim()\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\")\n case \"pre\": {\n const content = node.textContent ?? \"\"\n const longestFence = Math.max(0, ...[...content.matchAll(/`+/gu)].map(([marker]) => marker.length))\n const fence = \"`\".repeat(Math.max(3, longestFence + 1))\n return `${fence}\\n${content}\\n${fence}`\n }\n case \"hr\":\n return \"---\"\n case \"p\":\n case \"div\":\n case \"section\":\n case \"article\": {\n const blockChildren = [...node.children].some((child) =>\n /^(?:article|blockquote|div|h[1-6]|hr|ol|p|pre|section|ul)$/u.test(child.tagName.toLocaleLowerCase(\"en-US\"))\n )\n return blockChildren\n ? [...node.childNodes]\n .map(blockMarkdown)\n .filter((part) => part.trim().length > 0)\n .join(\"\\n\\n\")\n : inlineMarkdown(node).trim()\n }\n default:\n return inlineMarkdown(node).trim()\n }\n}\n\n/** Serialize only the semantic subset rendered by WorkspaceRichText; provider HTML never crosses this boundary. */\nexport const confluenceEditorMarkdown = (root: HTMLElement): string =>\n [...root.childNodes]\n .map(blockMarkdown)\n .filter((part) => part.trim().length > 0)\n .join(\"\\n\\n\")\n .replace(/\\n{3,}/gu, \"\\n\\n\")\n .trim()\n\nconst runEditorCommand = (command: string, value?: string): void => {\n document.execCommand(command, false, value)\n}\n\n/** Accept only ordinary web links from the visual-editor prompt. */\nexport const safeConfluenceEditorLinkHref = (href: string): string | null => {\n const parsed = URL.parse(href)\n return parsed !== null && (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") ? parsed.href : null\n}\n\nexport const releasePublicationSucceeded = (state: string): boolean => state === \"succeeded\"\n\nconst InitialEditorBody = memo(\n ({ markdown }: { readonly markdown: string }): ReactElement => <WorkspaceRichText value={markdown} />,\n () => true\n)\n\nexport interface WorkspaceConfluenceVisualEditorProps {\n readonly canEdit: boolean\n readonly entityId: EntityId\n readonly onAskAgent: () => void\n readonly onSaved: () => void\n readonly page: WorkspaceConfluencePagePresentation\n readonly releaseId: ReleaseId | null\n readonly submitPublication?: typeof submitBrowserReleasePublication\n readonly title: string\n}\n\n/** In-place, revision-guarded visual editing for one synchronized Confluence page. */\nexport const WorkspaceConfluenceVisualEditor = ({\n canEdit,\n entityId,\n onAskAgent,\n onSaved,\n page,\n releaseId,\n submitPublication = submitBrowserReleasePublication,\n title\n}: WorkspaceConfluenceVisualEditorProps): ReactElement => {\n const [state, setState] = useState<EditorState>({ _tag: \"idle\" })\n const [taskLineSaving, setTaskLineSaving] = useState<number | null>(null)\n const [taskSaveFailed, setTaskSaveFailed] = useState(false)\n const [draftTitle, setDraftTitle] = useState(title)\n const editorRef = useRef<HTMLDivElement>(null)\n const editing = state._tag !== \"idle\" && state._tag !== \"saved\"\n const busy = state._tag === \"saving\"\n const taskSummary = confluenceTaskSummary(page.content ?? \"\")\n\n useEffect(() => {\n setDraftTitle(title)\n setState({ _tag: \"idle\" })\n setTaskLineSaving(null)\n setTaskSaveFailed(false)\n }, [page.revision, title])\n\n const setTaskChecked = (lineIndex: number, checked: boolean): void => {\n if (!canEdit || !page.taskUpdatesSafe || releaseId === null || page.content === null || taskLineSaving !== null) {\n return\n }\n const updatedMarkdown = setConfluenceTaskChecked(page.content, lineIndex, checked)\n if (updatedMarkdown === null) return\n setTaskLineSaving(lineIndex)\n setTaskSaveFailed(false)\n submitPublication({\n releaseId,\n provider: \"confluence\",\n title,\n markdown: updatedMarkdown,\n targetEntityId: entityId,\n targetRevision: Revision.make(page.revision),\n signal: AbortSignal.timeout(30_000)\n })\n .then(\n (result) => {\n if (releasePublicationSucceeded(result.state)) onSaved()\n else setTaskSaveFailed(true)\n },\n () => setTaskSaveFailed(true)\n )\n .finally(() => setTaskLineSaving(null))\n }\n\n const save = (): void => {\n const editor = editorRef.current\n if (editor === null || releaseId === null || busy) return\n const markdown = confluenceEditorMarkdown(editor)\n const normalizedTitle = draftTitle.trim()\n if (normalizedTitle.length === 0 || markdown.length === 0) {\n setState({ _tag: \"failed\" })\n return\n }\n setState({ _tag: \"saving\" })\n submitPublication({\n releaseId,\n provider: \"confluence\",\n title: normalizedTitle,\n markdown,\n targetEntityId: entityId,\n targetRevision: Revision.make(page.revision),\n signal: AbortSignal.timeout(30_000)\n }).then(\n (result) => {\n if (releasePublicationSucceeded(result.state)) {\n setState({ _tag: \"saved\" })\n onSaved()\n } else {\n setState({ _tag: \"failed\" })\n }\n },\n () => setState({ _tag: \"failed\" })\n )\n }\n\n if (!editing) {\n return (\n <div className={styles.documentRead}>\n {page.contentState === \"loaded\" && page.content !== null ? (\n <WorkspaceRichText className={styles.richText} value={page.content} />\n ) : (\n <div className={styles.contentState} data-content-state={page.contentState}>\n <strong>\n {page.contentState === \"lazy\" ? \"Content has not been loaded\" : \"No readable body was returned\"}\n </strong>\n <Text tone=\"secondary\">\n Open the authenticated Confluence source to read it now, or synchronize the connection before editing so\n Relay never replaces an unseen document.\n </Text>\n </div>\n )}\n {taskSummary.total === 0 ? null : (\n <section aria-labelledby=\"confluence-release-tasks\" className={styles.releaseTasks}>\n <div className={styles.releaseTaskHeading}>\n <Text as=\"h3\" id=\"confluence-release-tasks\" variant=\"card-title\">\n Release tasks\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {taskSummary.completed} of {taskSummary.total} complete\n </Text>\n </div>\n <ul className={styles.releaseTaskList}>\n {taskSummary.tasks.map((task) => (\n <li key={`${String(task.lineIndex)}-${task.label}`}>\n <label>\n <input\n checked={task.checked}\n disabled={!canEdit || !page.taskUpdatesSafe || releaseId === null || taskLineSaving !== null}\n onChange={(event) => setTaskChecked(task.lineIndex, event.target.checked)}\n type=\"checkbox\"\n />\n <span>{task.label}</span>\n </label>\n {taskLineSaving === task.lineIndex ? <Text variant=\"meta\">Saving…</Text> : null}\n </li>\n ))}\n </ul>\n {taskSummary.outstanding === 0 ? (\n <Text>All Confluence tasks are complete.</Text>\n ) : (\n <Text tone=\"secondary\">\n {taskSummary.outstanding} task{taskSummary.outstanding === 1 ? \"\" : \"s\"} block release publication.\n </Text>\n )}\n {!page.taskUpdatesSafe ? (\n <Text tone=\"secondary\">\n Task-only updates are unavailable because this safe page projection cannot prove a lossless ADF round\n trip. Review a complete replacement before changing these tasks.\n </Text>\n ) : null}\n {taskSaveFailed ? (\n <StatePanel\n description=\"Refresh the latest Confluence revision, then tick the task again.\"\n title=\"The task was not updated\"\n tone=\"critical\"\n />\n ) : null}\n </section>\n )}\n <div className={styles.editorEntry}>\n <Button disabled={!canEdit || releaseId === null} onClick={() => setState({ _tag: \"editing\" })}>\n {page.contentState === \"loaded\" && page.content !== null\n ? \"Edit on this page\"\n : \"Write a complete replacement\"}\n </Button>\n <Button onClick={onAskAgent} variant=\"secondary\">\n Ask Relay to edit\n </Button>\n {state._tag === \"saved\" ? <Text>Saved to Confluence.</Text> : null}\n {!canEdit ? (\n <Text tone=\"secondary\">Current source data and workspace-owner access are required to edit.</Text>\n ) : null}\n {canEdit && releaseId === null ? (\n <Text tone=\"secondary\">Link this page to a release before editing it in Relay.</Text>\n ) : null}\n </div>\n </div>\n )\n }\n\n return (\n <div className={styles.visualEditor} data-confluence-visual-editor>\n <div className={styles.editorHeading}>\n <div>\n <Text as=\"strong\">Editing revision {page.revision}</Text>\n <Text tone=\"secondary\" variant=\"meta\">\n Save creates the next Confluence revision after an explicit owner confirmation.\n </Text>\n </div>\n <div className={styles.editorActions}>\n <Button disabled={busy} onClick={onAskAgent} variant=\"secondary\">\n Ask Relay\n </Button>\n <Button disabled={busy} onClick={() => setState({ _tag: \"idle\" })} variant=\"secondary\">\n Cancel\n </Button>\n <Button disabled={busy} loading={busy} onClick={save}>\n Save to Confluence\n </Button>\n </div>\n </div>\n {page.contentState !== \"loaded\" || page.content === null ? (\n <StatePanel\n description=\"The existing body is not synchronized. Saving this draft replaces the complete Confluence page body at the displayed revision.\"\n title=\"Complete replacement\"\n tone=\"caution\"\n />\n ) : null}\n <Field label=\"Page title\">\n {(controlProps) => (\n <input\n {...controlProps}\n disabled={busy}\n maxLength={500}\n onChange={(event) => setDraftTitle(event.target.value)}\n value={draftTitle}\n />\n )}\n </Field>\n <div\n aria-label=\"Document formatting\"\n className={styles.editorToolbar}\n onMouseDown={(event) => event.preventDefault()}\n role=\"toolbar\"\n >\n <button onClick={() => runEditorCommand(\"formatBlock\", \"p\")} type=\"button\">\n Paragraph\n </button>\n <button onClick={() => runEditorCommand(\"formatBlock\", \"h2\")} type=\"button\">\n Heading 2\n </button>\n <button onClick={() => runEditorCommand(\"formatBlock\", \"h3\")} type=\"button\">\n Heading 3\n </button>\n <button aria-label=\"Bold\" onClick={() => runEditorCommand(\"bold\")} type=\"button\">\n <strong>B</strong>\n </button>\n <button aria-label=\"Italic\" onClick={() => runEditorCommand(\"italic\")} type=\"button\">\n <em>I</em>\n </button>\n <button onClick={() => runEditorCommand(\"insertUnorderedList\")} type=\"button\">\n Bullets\n </button>\n <button onClick={() => runEditorCommand(\"insertOrderedList\")} type=\"button\">\n Numbered\n </button>\n <button\n onClick={() => {\n const href = window.prompt(\"Link address\")\n const safeHref = href === null ? null : safeConfluenceEditorLinkHref(href)\n if (safeHref !== null) runEditorCommand(\"createLink\", safeHref)\n }}\n type=\"button\"\n >\n Link\n </button>\n </div>\n <div\n aria-label=\"Confluence page body\"\n aria-multiline=\"true\"\n className={`${styles.editorCanvas} ${styles.richText}`}\n contentEditable={!busy}\n ref={editorRef}\n role=\"textbox\"\n suppressContentEditableWarning\n >\n <InitialEditorBody markdown={page.content ?? \"\"} />\n </div>\n {state._tag === \"failed\" ? (\n <StatePanel\n description=\"Keep a non-empty title and document body, refresh the latest revision, then try again.\"\n title=\"The page was not saved\"\n tone=\"critical\"\n />\n ) : null}\n </div>\n )\n}\n","import { PeopleStrip } from \"@knpkv/rly/patterns\"\nimport { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport { type ReactElement, type ReactNode, useState } from \"react\"\n\nimport type { WorkspaceConfluencePagePresentation } from \"./presentWorkspaceConfluencePage.js\"\nimport styles from \"./WorkspaceConfluencePageDetails.module.css\"\nimport {\n WorkspaceConfluenceVisualEditor,\n type WorkspaceConfluenceVisualEditorProps\n} from \"./WorkspaceConfluenceVisualEditor.js\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n </header>\n {children}\n </section>\n)\n\n/** Render one canonical Confluence page without exposing provider media or write controls. */\nexport const WorkspaceConfluencePageDetails = ({\n editor,\n page\n}: {\n readonly editor: Omit<WorkspaceConfluenceVisualEditorProps, \"page\">\n readonly page: WorkspaceConfluencePagePresentation\n}): ReactElement => {\n const [peopleExpanded, setPeopleExpanded] = useState(false)\n return (\n <article className={styles.document} data-workspace-confluence-page-detail>\n <section aria-label=\"Document identity\" className={styles.folio}>\n <div className={styles.revision}>\n <span>Revision</span>\n <strong>{page.revision}</strong>\n </div>\n <div className={styles.folioMeta}>\n <StateLabel\n label={page.status}\n tone={page.status === \"Superseded\" ? \"caution\" : page.status === \"Current\" ? \"positive\" : \"neutral\"}\n />\n <dl>\n <div>\n <dt>Space</dt>\n <dd>{page.sourceSpaceId}</dd>\n </div>\n <div>\n <dt>Updated</dt>\n <dd>\n {page.updatedAt === null ? (\n \"Not synchronized\"\n ) : (\n <time dateTime={page.updatedAt.dateTime}>{page.updatedAt.label}</time>\n )}\n </dd>\n </div>\n <div>\n <dt>Created</dt>\n <dd>\n {page.createdAt === null ? (\n \"Not synchronized\"\n ) : (\n <time dateTime={page.createdAt.dateTime}>{page.createdAt.label}</time>\n )}\n </dd>\n </div>\n </dl>\n </div>\n </section>\n\n <Section heading=\"Document\" meta=\"Safely converted text; raw provider markup and media stay outside this view\">\n <WorkspaceConfluenceVisualEditor {...editor} page={page} />\n </Section>\n\n <Section heading=\"People\" meta={page.watcherInventoryLabel}>\n {page.contributors.length === 0 ? (\n <Text tone=\"secondary\">No owner, contributor, or watcher identity was synchronized.</Text>\n ) : (\n <PeopleStrip\n aria-label=\"Page collaborators\"\n expanded={peopleExpanded}\n limit={4}\n onExpandedChange={setPeopleExpanded}\n people={page.contributors}\n />\n )}\n </Section>\n\n <div className={styles.collections}>\n <Section heading=\"Revision history\" meta={page.historyInventoryLabel}>\n {page.versions.length === 0 ? (\n <Text tone=\"secondary\">No revision history was synchronized.</Text>\n ) : (\n <ol className={styles.versions}>\n {page.versions.map((version) => (\n <li key={`${String(version.number)}-${version.createdAt.dateTime}`}>\n <strong>v{version.number}</strong>\n <span>{version.message}</span>\n <small>\n {version.author} · <time dateTime={version.createdAt.dateTime}>{version.createdAt.label}</time>\n {version.minorEdit ? \" · Minor edit\" : \"\"}\n </small>\n </li>\n ))}\n </ol>\n )}\n </Section>\n\n <Section heading=\"Attachments\" meta={page.attachmentInventoryLabel}>\n {page.attachments.length === 0 ? (\n <Text tone=\"secondary\">No attachment metadata was synchronized.</Text>\n ) : (\n <ul className={styles.attachments}>\n {page.attachments.map((attachment) => (\n <li key={attachment.id}>\n <strong>{attachment.title}</strong>\n <span>\n {attachment.mediaType} · {attachment.fileSize} · {attachment.version}\n </span>\n <small>Metadata only · authenticated proxy required</small>\n </li>\n ))}\n </ul>\n )}\n </Section>\n </div>\n\n <Section heading=\"Runbook evidence\" meta=\"Immutable delivery evidence around this page\">\n <div className={styles.evidenceCount}>\n <strong>{page.runbookEvidenceCount}</strong>\n <span>evidence item{page.runbookEvidenceCount === 1 ? \"\" : \"s\"} in the current bounded graph</span>\n </div>\n </Section>\n </article>\n )\n}\n","import { Person } from \"@knpkv/rly/patterns\"\nimport { Text } from \"@knpkv/rly/primitives\"\nimport type { ReactElement, ReactNode } from \"react\"\n\nimport type { WorkspaceIssuePresentation } from \"./presentWorkspaceIssue.js\"\nimport styles from \"./WorkspaceIssueDetails.module.css\"\nimport { WorkspaceRichText } from \"./WorkspaceRichText.js\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta?: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n {meta === undefined ? null : (\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n )}\n </header>\n {children}\n </section>\n)\n\nconst RichText = ({ empty, value }: { readonly empty: string; readonly value: string | null }): ReactElement =>\n value === null ? (\n <Text tone=\"secondary\">{empty}</Text>\n ) : (\n <WorkspaceRichText className={styles.richText} value={value} />\n )\n\n/** Render a complete, read-only synchronized issue as a quiet working document. */\nexport const WorkspaceIssueDetails = ({ issue }: { readonly issue: WorkspaceIssuePresentation }): ReactElement => (\n <article className={styles.document} data-workspace-issue-detail>\n {issue.truncationMessage === null ? null : (\n <Text className={styles.boundaryNotice} tone=\"secondary\">\n {issue.truncationMessage}\n </Text>\n )}\n\n <Section heading=\"Description\" meta=\"What changes and why\">\n <RichText empty=\"No description was synchronized from Jira.\" value={issue.description} />\n </Section>\n\n <Section heading=\"Acceptance criteria\" meta=\"The finish line\">\n <div className={styles.criteria}>\n <RichText empty=\"No acceptance criteria were synchronized.\" value={issue.acceptanceCriteria} />\n </div>\n </Section>\n\n {issue.environment === null ? null : (\n <Section heading=\"Environment\" meta=\"Where this applies\">\n <RichText empty=\"No environment was synchronized.\" value={issue.environment} />\n </Section>\n )}\n\n <Section heading=\"People\" meta={`${String(issue.collaborators.length)} collaborators`}>\n {issue.collaborators.length === 0 ? (\n <Text tone=\"secondary\">No Jira collaborator was synchronized for this issue.</Text>\n ) : (\n <ul className={styles.people}>\n {issue.collaborators.map((person) => (\n <li key={person.id}>\n <Person person={person} />\n </li>\n ))}\n </ul>\n )}\n </Section>\n\n <Section heading=\"Issue details\" meta=\"Synchronized fields\">\n <dl className={styles.metadata}>\n {issue.metadata.map((field) => (\n <div key={field.label}>\n <dt>{field.label}</dt>\n <dd>{field.value}</dd>\n </div>\n ))}\n </dl>\n </Section>\n\n {issue.parent === null && issue.subtasks.length === 0 ? null : (\n <Section heading=\"Related Jira work\" meta=\"Source hierarchy\">\n <div className={styles.related}>\n {issue.parent === null ? null : (\n <div>\n <Text tone=\"secondary\" variant=\"meta\">\n Parent\n </Text>\n {issue.parent.href === null ? (\n <strong>{issue.parent.key}</strong>\n ) : (\n <a href={issue.parent.href} rel=\"noreferrer\" target=\"_blank\">\n {issue.parent.key}\n </a>\n )}\n <span>{issue.parent.summary}</span>\n <small>{issue.parent.status}</small>\n </div>\n )}\n {issue.subtasks.map((subtask) => (\n <div key={subtask.key}>\n <Text tone=\"secondary\" variant=\"meta\">\n Subtask\n </Text>\n {subtask.href === null ? (\n <strong>{subtask.key}</strong>\n ) : (\n <a href={subtask.href} rel=\"noreferrer\" target=\"_blank\">\n {subtask.key}\n </a>\n )}\n <span>{subtask.summary}</span>\n <small>{subtask.status}</small>\n </div>\n ))}\n </div>\n </Section>\n )}\n\n <Section heading=\"Comments\" meta={`${String(issue.commentCount)} comments`}>\n {issue.commentBodiesTruncated ? (\n <Text className={styles.collectionNotice} tone=\"secondary\">\n Jira shortened comment bodies to keep this synchronized view bounded.\n </Text>\n ) : null}\n {issue.commentsTruncated ? (\n <Text className={styles.collectionNotice} tone=\"secondary\">\n Only the newest synchronized comments are shown.\n </Text>\n ) : null}\n {issue.comments.length === 0 ? (\n <Text tone=\"secondary\">No comment was synchronized for this issue.</Text>\n ) : (\n <ol className={styles.conversation}>\n {issue.comments.map((comment) => (\n <li key={comment.id}>\n <div className={styles.attribution}>\n <Person person={comment.author} size=\"compact\" />\n {comment.time === null ? null : <time>{comment.time}</time>}\n </div>\n <WorkspaceRichText className={styles.commentBody} value={comment.body ?? \"Comment body unavailable.\"} />\n </li>\n ))}\n </ol>\n )}\n </Section>\n\n <Section heading=\"History\" meta={`${String(issue.historyCount)} changes`}>\n {issue.historyTruncated ? (\n <Text className={styles.collectionNotice} tone=\"secondary\">\n Only the newest synchronized history is shown.\n </Text>\n ) : null}\n {issue.history.length === 0 ? (\n <Text tone=\"secondary\">No field history was synchronized for this issue.</Text>\n ) : (\n <ol className={styles.history}>\n {issue.history.map((entry) => (\n <li key={entry.id}>\n <div className={styles.attribution}>\n <Person person={entry.actor} size=\"compact\" />\n {entry.time === null ? null : <time>{entry.time}</time>}\n </div>\n <dl>\n {entry.changes.map((change, index) => (\n <div key={`${change.field}:${String(index)}`}>\n <dt>{change.field}</dt>\n <dd>{change.transition}</dd>\n </div>\n ))}\n </dl>\n </li>\n ))}\n </ol>\n )}\n </Section>\n </article>\n)\n","import { StageRail } from \"@knpkv/rly/patterns\"\nimport { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport type { ReactElement, ReactNode } from \"react\"\n\nimport type { WorkspacePipelineExecutionPresentation } from \"./presentWorkspacePipelineExecution.js\"\nimport styles from \"./WorkspacePipelineExecutionDetails.module.css\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n </header>\n {children}\n </section>\n)\n\nconst Timestamp = ({ value }: { readonly value: WorkspacePipelineExecutionPresentation[\"startedAt\"] }): ReactElement =>\n value === null ? <>Not synchronized</> : <time dateTime={value.dateTime}>{value.label}</time>\n\n/** Render one immutable CodePipeline execution as an operator-readable flight recorder. */\nexport const WorkspacePipelineExecutionDetails = ({\n pipeline\n}: {\n readonly pipeline: WorkspacePipelineExecutionPresentation\n}): ReactElement => (\n <article className={styles.document} data-workspace-pipeline-execution-detail>\n <section aria-label=\"Execution identity\" className={styles.hero}>\n <div className={styles.heroHeading}>\n <span>Execution</span>\n <strong>{pipeline.executionId}</strong>\n <StateLabel\n label={pipeline.status}\n tone={\n pipeline.status === \"Succeeded\"\n ? \"positive\"\n : pipeline.status === \"Failed\"\n ? \"critical\"\n : pipeline.status === \"Running\"\n ? \"progress\"\n : pipeline.status === \"Stopped\"\n ? \"caution\"\n : \"neutral\"\n }\n />\n </div>\n {pipeline.statusSummary === null ? null : <p className={styles.summary}>{pipeline.statusSummary}</p>}\n <dl className={styles.heroFacts}>\n <div>\n <dt>Why</dt>\n <dd>\n {pipeline.triggerType}\n <small>{pipeline.triggerDetail}</small>\n </dd>\n </div>\n <div>\n <dt>Revision</dt>\n <dd>\n <code>{pipeline.triggerRevision}</code>\n </dd>\n </div>\n <div>\n <dt>Where</dt>\n <dd>{pipeline.targetEnvironment}</dd>\n </div>\n <div>\n <dt>Duration</dt>\n <dd>{pipeline.duration}</dd>\n </div>\n </dl>\n <dl className={styles.executionMeta}>\n <div>\n <dt>Pipeline</dt>\n <dd>\n {pipeline.pipelineName} · {pipeline.pipelineVersion}\n </dd>\n </div>\n <div>\n <dt>Started</dt>\n <dd>\n <Timestamp value={pipeline.startedAt} />\n </dd>\n </div>\n <div>\n <dt>Updated</dt>\n <dd>\n <Timestamp value={pipeline.updatedAt} />\n </dd>\n </div>\n <div>\n <dt>Mode</dt>\n <dd>{pipeline.executionMode}</dd>\n </div>\n </dl>\n </section>\n\n <StageRail\n className={styles.stageRail}\n emptyLabel=\"No stage detail was synchronized for this execution.\"\n heading=\"Execution path\"\n stages={pipeline.stages}\n />\n\n <Section heading=\"People\" meta=\"Provider identities that operated or approved this run\">\n <div className={styles.peopleLanes}>\n <div>\n <small>Operators</small>\n <strong>{pipeline.operators.join(\" · \") || \"Not synchronized\"}</strong>\n </div>\n <div>\n <small>Approvers</small>\n <strong>{pipeline.approvers.join(\" · \") || \"No approval recorded\"}</strong>\n </div>\n </div>\n </Section>\n\n <Section\n heading=\"Actions\"\n meta={`${pipeline.actionCountLabel} actions · ${String(pipeline.pagesRead)} bounded pages read`}\n >\n {pipeline.actionsTruncated ? (\n <p className={styles.partial}>This is a bounded view. Additional action detail exists in CodePipeline.</p>\n ) : null}\n {pipeline.actions.length === 0 ? (\n <Text tone=\"secondary\">No action detail was synchronized for this execution.</Text>\n ) : (\n <ol className={styles.actions}>\n {pipeline.actions.map((action) => (\n <li data-tone={action.tone} key={action.id}>\n <header>\n <span>\n <small>{action.stageName}</small>\n <strong>{action.name}</strong>\n </span>\n <StateLabel label={action.status} tone={action.tone} />\n </header>\n <dl>\n <div>\n <dt>Provider</dt>\n <dd>{action.provider}</dd>\n </div>\n <div>\n <dt>Duration</dt>\n <dd>{action.duration}</dd>\n </div>\n <div>\n <dt>Actor</dt>\n <dd>{action.actor ?? \"Not synchronized\"}</dd>\n </div>\n <div>\n <dt>Region</dt>\n <dd>{action.region ?? \"Not synchronized\"}</dd>\n </div>\n </dl>\n {action.summary === null ? null : <p>{action.summary}</p>}\n {action.error === null ? null : <p className={styles.error}>{action.error}</p>}\n {action.artifacts.length === 0 ? null : (\n <ul className={styles.artifacts}>\n {action.artifacts.map((artifact, index) => (\n <li key={`${artifact.direction}-${artifact.name}-${String(index)}`}>\n <span>{artifact.direction}</span>\n <strong>{artifact.name}</strong>\n <small>{artifact.accessLabel}</small>\n </li>\n ))}\n </ul>\n )}\n </li>\n ))}\n </ol>\n )}\n </Section>\n\n <Section heading=\"Source artifacts\" meta=\"Metadata only; content stays behind the authenticated proxy\">\n {pipeline.sourceArtifacts.length === 0 ? (\n <Text tone=\"secondary\">No source artifact metadata was synchronized.</Text>\n ) : (\n <ul className={styles.sourceArtifacts}>\n {pipeline.sourceArtifacts.map((artifact) => (\n <li key={`${artifact.name}-${artifact.revision}`}>\n <span>\n <strong>{artifact.name}</strong>\n <code>{artifact.revision}</code>\n </span>\n <span>\n {artifact.summary ?? \"No summary\"}\n <small>{artifact.accessLabel}</small>\n </span>\n </li>\n ))}\n </ul>\n )}\n </Section>\n\n <Section heading=\"Delivery evidence\" meta=\"Current accepted relationships around this exact run\">\n <dl className={styles.deliveryCounts}>\n <div>\n <dt>Releases</dt>\n <dd>{pipeline.releaseCountLabel}</dd>\n </div>\n <div>\n <dt>Pull requests</dt>\n <dd>{pipeline.pullRequestCountLabel}</dd>\n </div>\n <div>\n <dt>Runbooks</dt>\n <dd>{pipeline.runbookCountLabel}</dd>\n </div>\n </dl>\n <Text tone=\"secondary\">\n Use the delivery relationships below to open each connected object and inspect its evidence.\n </Text>\n </Section>\n </article>\n)\n","/** Browser-safe provider-neutral review contracts. @module */\nimport * as Schema from \"effect/Schema\";\nconst boundedIdentifier = (maximumLength) => Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(maximumLength), Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._:/-]*$/u));\nexport const ReviewKind = Schema.Literals([\"review\", \"security\", \"tests\", \"explain\"]);\nexport const ReviewExecutionProfile = Schema.Struct({\n id: boundedIdentifier(128),\n name: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(200)),\n kind: ReviewKind,\n provider: boundedIdentifier(128),\n harness: boundedIdentifier(128),\n model: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(200)),\n skillIds: Schema.Array(boundedIdentifier(256)).check(Schema.isMaxLength(24), Schema.isUnique())\n});\nexport const ReviewThreadIdentity = Schema.Struct({\n namespace: boundedIdentifier(128),\n subjectId: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(1_024)),\n revisionId: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(1_024)),\n baseRevision: Schema.NullOr(Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(1_024))),\n headRevision: Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(1_024))\n});\n/** Stable local key. Provider locators and credentials must not enter this browser-safe identity. */\nexport const reviewThreadKey = (identity) => JSON.stringify([\n identity.namespace,\n identity.subjectId,\n identity.revisionId,\n identity.baseRevision,\n identity.headRevision\n]);\nexport const sameReviewThread = (left, right) => reviewThreadKey(left) === reviewThreadKey(right);\n//# sourceMappingURL=model.js.map","import { sameReviewThread } from \"@knpkv/review\"\nimport * as Data from \"effect/Data\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Duration from \"effect/Duration\"\nimport * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\"\n\nimport type {\n AgentProviderCatalog,\n AgentProviderCatalogEntry,\n DurableAgentPrompt,\n PublishedReviewComment,\n PullRequestReviewState,\n PullRequestReviewThreadPage,\n ReleaseAgentThreadCursor,\n ReviewSuggestionPublicationContent,\n ReviewSuggestionPublicationOperation,\n ReviewSuggestionPublicationPreview,\n ReviewSuggestionPublicationSelection\n} from \"../../api/agent.js\"\nimport type { RateLimitedApiError } from \"../../api/errors.js\"\nimport type { EntityId, JobId, PrReviewSuggestionRevisionId } from \"../../domain/identifiers.js\"\nimport type { PrReviewSuggestionId } from \"../../domain/prReview.js\"\nimport type { PrReviewSuggestionRevisionSequence } from \"../../domain/prReviewRevision.js\"\nimport {\n isRecoverablePullRequestReviewFailure,\n isUnauthorizedPullRequestReviewFailure\n} from \"./pullRequestReviewFailures.js\"\nimport type { PullRequestReviewThread } from \"./pullRequestReviewThreadReplay.js\"\nimport { controlCenterReviewThread } from \"./reviewPlatformAdapter.js\"\n\nconst pullRequestReviewBrowser = import(\"./pullRequestReviewThreadReplay.js\")\nconst generatedClientTransport = pullRequestReviewBrowser.then(\n ({ generatedClientPullRequestReviewTransport }) => generatedClientPullRequestReviewTransport\n)\n\nconst isRateLimitedReviewFailure = <UnparsedInput>(\n failure: UnparsedInput\n): failure is UnparsedInput & RateLimitedApiError => Predicate.isTagged(failure, \"RateLimitedApiError\")\n\nconst waitBeforeAutomaticReviewRetry = <UnparsedInput>(failure?: UnparsedInput): Effect.Effect<void> => {\n if (!isRateLimitedReviewFailure(failure)) return Effect.sleep(Duration.seconds(1))\n const retryAt = failure.retryAt\n if (retryAt === null) return Effect.sleep(Duration.seconds(2))\n return Effect.flatMap(DateTime.now, (now) =>\n Effect.sleep(\n Duration.millis(\n Math.max(0, DateTime.toEpochMillis(retryAt) - DateTime.toEpochMillis(now))\n )\n ))\n}\n\ninterface ReviewProviderSelection {\n readonly displayName?: NonNullable<AgentProviderCatalogEntry[\"displayName\"]>\n readonly model: AgentProviderCatalogEntry[\"models\"][number]\n readonly providerId: AgentProviderCatalogEntry[\"providerId\"]\n readonly reviewProfile: NonNullable<AgentProviderCatalogEntry[\"reviewProfile\"]>\n}\n\nexport interface PullRequestReviewScope {\n readonly baseRevision: string | null\n readonly entityId: EntityId\n readonly headRevision: string\n readonly sessionKey: string\n}\n\n/** Browser selection resolved to an exact revision before publication preview. */\nexport type ReviewSuggestionPublicationTarget = Pick<\n ReviewSuggestionPublicationSelection,\n \"jobId\" | \"revisionId\" | \"suggestionId\"\n>\n\n/** Exact immutable revision selected for one targeted agent operation. */\nexport type ReviewSuggestionTarget = {\n readonly expectedRevisionId: PrReviewSuggestionRevisionId\n readonly expectedSequence: PrReviewSuggestionRevisionSequence\n readonly intent: \"suggestion-edit\" | \"suggestion-revalidation\"\n readonly jobId: JobId\n readonly suggestionId: PrReviewSuggestionId\n}\n\nexport type PullRequestReviewControllerState =\n | { readonly _tag: \"idle\" }\n | ({ readonly _tag: \"loading\" } & PullRequestReviewScope)\n | ({ readonly _tag: \"failed\" } & PullRequestReviewScope)\n | ({\n readonly _tag: \"ready\"\n readonly action: \"idle\" | \"starting\" | \"failed\"\n readonly historyAction: \"idle\" | \"loading\" | \"failed\"\n readonly provider: ReviewProviderSelection | null\n /** Ordered launch presets; `provider` remains the default for older callers. */\n readonly providerPresets?: ReadonlyArray<ReviewProviderSelection>\n readonly review: PullRequestReviewState\n readonly thread?: PullRequestReviewThread\n } & PullRequestReviewScope)\n\nexport type PullRequestReviewPublicationState =\n | { readonly _tag: \"idle\" }\n | {\n readonly _tag: \"previewing\"\n readonly selection: ReviewSuggestionPublicationTarget\n }\n | {\n readonly _tag: \"preview\"\n readonly preview: ReviewSuggestionPublicationPreview\n }\n | {\n readonly _tag: \"publishing\"\n readonly preview: ReviewSuggestionPublicationPreview\n }\n | {\n readonly _tag: \"published\"\n readonly headSuperseded: boolean\n readonly preview: ReviewSuggestionPublicationPreview\n readonly publication: PublishedReviewComment\n }\n | {\n readonly _tag: \"receipt-conflict\"\n readonly preview: ReviewSuggestionPublicationPreview\n readonly publication: PublishedReviewComment\n }\n | {\n readonly _tag: \"failed\"\n readonly preview: ReviewSuggestionPublicationPreview | null\n readonly selection: ReviewSuggestionPublicationTarget\n }\n\n/** Browser boundary for immutable pull-request review reads and mutations. */\nexport interface PullRequestReviewTransport {\n readonly enqueue: (\n entityId: EntityId,\n provider: ReviewProviderSelection,\n prompt: DurableAgentPrompt | undefined,\n signal: AbortSignal\n ) => Promise<PullRequestReviewState>\n readonly cancel?: (entityId: EntityId, jobId: JobId, signal: AbortSignal) => Promise<PullRequestReviewState>\n readonly extendBudget?: (entityId: EntityId, jobId: JobId, signal: AbortSignal) => Promise<PullRequestReviewState>\n readonly load: (entityId: EntityId, signal: AbortSignal) => Promise<PullRequestReviewState>\n readonly loadThread: (\n entityId: EntityId,\n cursor: ReleaseAgentThreadCursor | null,\n signal: AbortSignal,\n direction?: \"after\" | \"before\"\n ) => Promise<PullRequestReviewThreadPage>\n readonly previewPublication: (\n entityId: EntityId,\n selection: ReviewSuggestionPublicationTarget,\n signal: AbortSignal,\n operation?: ReviewSuggestionPublicationOperation,\n commentId?: string\n ) => Promise<ReviewSuggestionPublicationPreview>\n readonly providers: (signal: AbortSignal) => Promise<AgentProviderCatalog>\n readonly publishSuggestion: (\n entityId: EntityId,\n selection: ReviewSuggestionPublicationSelection,\n finalContent: ReviewSuggestionPublicationContent,\n authorityBinding: ReviewSuggestionPublicationPreview[\"authorityBinding\"],\n signal: AbortSignal,\n operation?: ReviewSuggestionPublicationOperation,\n commentId?: string\n ) => Promise<PublishedReviewComment>\n readonly targetSuggestion?: (\n entityId: EntityId,\n target: ReviewSuggestionTarget,\n provider: ReviewProviderSelection,\n signal: AbortSignal\n ) => Promise<PullRequestReviewState>\n}\n\nexport class PullRequestReviewRequestAborted extends Data.TaggedError(\"PullRequestReviewRequestAborted\")<{}> {}\n\nconst eligibleProviders = (catalog: AgentProviderCatalog): ReadonlyArray<ReviewProviderSelection> => {\n const eligible = new Array<ReviewProviderSelection>()\n for (const provider of catalog.providers) {\n const model = provider.models[0]\n if (\n provider.health === \"available\" &&\n provider.capabilities.includes(\"pr-review\") &&\n provider.reviewProfile !== undefined &&\n model !== undefined\n ) {\n eligible.push({\n providerId: provider.providerId,\n model,\n reviewProfile: provider.reviewProfile,\n ...(!(provider.displayName === undefined) && { displayName: provider.displayName })\n })\n }\n }\n return eligible\n}\n\n/** Generated-client transport for the authenticated immutable-review contract. */\nexport const browserPullRequestReviewTransport: PullRequestReviewTransport = {\n enqueue: (...args) => generatedClientTransport.then((transport) => transport.enqueue(...args)),\n cancel: (...args) => generatedClientTransport.then((transport) => transport.cancel!(...args)),\n extendBudget: (...args) => generatedClientTransport.then((transport) => transport.extendBudget!(...args)),\n load: (...args) => generatedClientTransport.then((transport) => transport.load(...args)),\n loadThread: (...args) => generatedClientTransport.then((transport) => transport.loadThread(...args)),\n previewPublication: (...args) => generatedClientTransport.then((transport) => transport.previewPublication(...args)),\n providers: (...args) => generatedClientTransport.then((transport) => transport.providers(...args)),\n publishSuggestion: (...args) => generatedClientTransport.then((transport) => transport.publishSuggestion(...args)),\n targetSuggestion: (...args) => generatedClientTransport.then((transport) => transport.targetSuggestion!(...args))\n}\n\nconst sameReviewScope = (\n left: PullRequestReviewScope,\n right: PullRequestReviewScope\n): boolean => sameReviewThread(controlCenterReviewThread(left), controlCenterReviewThread(right))\n\n/** Observe the lazy history boundary so a missing browser chunk remains retryable. */\nexport const observePullRequestReviewHistoryLoad = (\n task: Promise<void>,\n signal: AbortSignal,\n current: PullRequestReviewControllerState & PullRequestReviewScope,\n latestScope: { readonly current: PullRequestReviewScope | null },\n setState: (\n update: (state: PullRequestReviewControllerState) => PullRequestReviewControllerState\n ) => void\n): void => {\n task.catch(<UnparsedInput>(failure: UnparsedInput) => {\n if (\n signal.aborted ||\n latestScope.current === null ||\n !sameReviewScope(latestScope.current, current)\n ) return\n Effect.runFork(Effect.logError(\"Pull-request review history boundary failed\", failure))\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, historyAction: \"failed\" }\n : latest\n )\n })\n}\n\n/** Publish the shared merged replay, not an older async caller snapshot. */\nexport const publishNewestPullRequestReviewThread = (\n candidate: PullRequestReviewThread,\n signal: AbortSignal,\n current: PullRequestReviewScope,\n latestScope: { readonly current: PullRequestReviewScope | null },\n latestThread: { readonly current: PullRequestReviewThread | null },\n setState: (\n update: (state: PullRequestReviewControllerState) => PullRequestReviewControllerState\n ) => void\n): void => {\n if (\n signal.aborted ||\n latestScope.current === null ||\n !sameReviewScope(latestScope.current, current)\n ) return\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, thread: latestThread.current ?? candidate }\n : latest\n )\n}\n\nconst matchesScope = (\n review: PullRequestReviewState,\n scope: PullRequestReviewScope\n): boolean =>\n review._tag === \"unavailable\" ||\n (\n review.subject.baseRevision === scope.baseRevision &&\n review.subject.headRevision === scope.headRevision\n )\n\n/** Keep review state scoped to the exact entity and authenticated browser session. */\nexport const usePullRequestReview = (\n entityId: EntityId,\n baseRevision: string | null,\n headRevision: string | null,\n sessionKey: string | null,\n canEnqueue: boolean,\n onSessionExpired: (sessionKey: string) => void,\n transport: PullRequestReviewTransport = browserPullRequestReviewTransport\n) => {\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<PullRequestReviewControllerState>({ _tag: \"idle\" })\n const [publication, setPublication] = useState<PullRequestReviewPublicationState>({ _tag: \"idle\" })\n const historyAbort = useRef<AbortController | null>(null)\n const mutationAbort = useRef<AbortController | null>(null)\n const publicationAbort = useRef<AbortController | null>(null)\n const automaticRetryScope = useRef<PullRequestReviewScope | null>(null)\n const latestScope = useRef<PullRequestReviewScope | null>(null)\n const latestThread = useRef<PullRequestReviewThread | null>(null)\n const scope = useMemo(\n () =>\n sessionKey === null || headRevision === null\n ? null\n : { baseRevision, entityId, headRevision, sessionKey },\n [baseRevision, entityId, headRevision, sessionKey]\n )\n useLayoutEffect(() => {\n latestScope.current = scope\n }, [scope])\n useLayoutEffect(() => {\n latestThread.current = null\n }, [entityId, sessionKey])\n\n useEffect(() => {\n if (sessionKey === null || headRevision === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const scope = { baseRevision, entityId, headRevision, sessionKey } satisfies PullRequestReviewScope\n const previousThread = latestThread.current ?? undefined\n const abort = new AbortController()\n const scheduleAutomaticRetry = <UnparsedInput>(message: string, failure?: UnparsedInput): boolean => {\n if (\n automaticRetryScope.current !== null &&\n sameReviewScope(automaticRetryScope.current, scope)\n ) return false\n automaticRetryScope.current = scope\n Effect.runFork(Effect.logWarning(message, failure))\n Effect.runPromise(waitBeforeAutomaticReviewRetry(failure), { signal: abort.signal }).then(\n () => {\n if (!abort.signal.aborted) setRequestRevision((revision) => revision + 1)\n },\n <UnparsedInput>(_retryFailure: UnparsedInput) => {\n if (!abort.signal.aborted) setState({ _tag: \"failed\", ...scope })\n }\n )\n return true\n }\n setState((current) =>\n current._tag === \"ready\" && sameReviewScope(current, scope)\n ? current\n : { _tag: \"loading\", ...scope }\n )\n pullRequestReviewBrowser.then(\n ({ loadPullRequestReviewSnapshot }) =>\n loadPullRequestReviewSnapshot(\n transport,\n entityId,\n canEnqueue,\n abort.signal,\n previousThread,\n latestThread\n )\n ).then(\n ({ catalog, catalogNeedsRetry, review, thread }) => {\n if (!abort.signal.aborted) {\n if (!catalogNeedsRetry) automaticRetryScope.current = null\n const providerPresets = eligibleProviders(catalog)\n setState(\n matchesScope(review, scope)\n ? {\n _tag: \"ready\",\n ...scope,\n action: \"idle\",\n historyAction: \"idle\",\n provider: providerPresets[0] ?? null,\n providerPresets,\n review,\n thread\n }\n : { _tag: \"failed\", ...scope }\n )\n if (catalogNeedsRetry) {\n scheduleAutomaticRetry(\"Pull-request review provider catalog unavailable; retrying once\")\n }\n }\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) {\n onSessionExpired(sessionKey)\n setState({ _tag: \"failed\", ...scope })\n return\n }\n if (\n isRecoverablePullRequestReviewFailure(failure) &&\n scheduleAutomaticRetry(\n \"Pull-request review snapshot load failed; retrying once\",\n failure\n )\n ) {\n return\n }\n setState({ _tag: \"failed\", ...scope })\n }\n )\n return () => abort.abort()\n }, [\n baseRevision,\n canEnqueue,\n entityId,\n headRevision,\n onSessionExpired,\n requestRevision,\n sessionKey,\n transport\n ])\n\n useEffect(() => {\n if (state._tag !== \"ready\" || state.review._tag !== \"pending\") return\n const abort = new AbortController()\n Effect.runPromise(Effect.sleep(\"2 seconds\"), { signal: abort.signal }).then(\n () => {\n if (!abort.signal.aborted) setRequestRevision((revision) => revision + 1)\n },\n <UnparsedInput>(_failure: UnparsedInput) => {\n if (!abort.signal.aborted) {\n setState({\n _tag: \"failed\",\n baseRevision: state.baseRevision,\n entityId: state.entityId,\n headRevision: state.headRevision,\n sessionKey: state.sessionKey\n })\n }\n }\n )\n return () => abort.abort()\n }, [state])\n\n useEffect(\n () => () => {\n historyAbort.current?.abort()\n mutationAbort.current?.abort()\n publicationAbort.current?.abort()\n },\n []\n )\n useEffect(() => {\n historyAbort.current?.abort()\n historyAbort.current = null\n mutationAbort.current?.abort()\n mutationAbort.current = null\n publicationAbort.current?.abort()\n publicationAbort.current = null\n setPublication({ _tag: \"idle\" })\n }, [entityId, sessionKey])\n useLayoutEffect(() => {\n mutationAbort.current?.abort()\n mutationAbort.current = null\n setPublication((current) => current._tag === \"publishing\" ? current : { _tag: \"idle\" })\n }, [baseRevision, headRevision])\n\n const refreshThread = useCallback((\n refreshScope: PullRequestReviewScope,\n signal: AbortSignal\n ): void => {\n const previous = latestThread.current ?? undefined\n pullRequestReviewBrowser.then(\n ({ refreshPullRequestReviewThread }) =>\n refreshPullRequestReviewThread(\n transport,\n refreshScope.entityId,\n signal,\n previous,\n latestThread\n )\n ).then(\n (thread) => {\n publishNewestPullRequestReviewThread(\n thread,\n signal,\n refreshScope,\n latestScope,\n latestThread,\n setState\n )\n },\n () => undefined\n )\n }, [transport])\n\n const loadEarlier = useCallback(() => {\n if (\n state._tag !== \"ready\" ||\n state.historyAction === \"loading\" ||\n state.thread === undefined ||\n !state.thread.hasEarlier\n ) return\n const current = state\n const currentThread = state.thread\n historyAbort.current?.abort()\n const abort = new AbortController()\n historyAbort.current = abort\n setState({ ...current, historyAction: \"loading\" })\n observePullRequestReviewHistoryLoad(\n pullRequestReviewBrowser.then(\n ({ loadEarlierPullRequestReviewThreadIntoState }) =>\n loadEarlierPullRequestReviewThreadIntoState(\n transport,\n current,\n currentThread,\n abort.signal,\n latestScope,\n latestThread,\n onSessionExpired,\n setState\n )\n ),\n abort.signal,\n current,\n latestScope,\n setState\n )\n }, [onSessionExpired, state, transport])\n\n const startAwaitable = useCallback((\n prompt?: DurableAgentPrompt,\n providerId?: ReviewProviderSelection[\"providerId\"]\n ): Promise<void> => {\n if (state._tag !== \"ready\" || state.review._tag === \"unavailable\") return Promise.resolve()\n const provider = providerId === undefined\n ? state.provider\n : state.providerPresets?.find((candidate) => candidate.providerId === providerId) ?? null\n if (provider === null) return Promise.resolve()\n const current = state\n mutationAbort.current?.abort()\n const abort = new AbortController()\n mutationAbort.current = abort\n setState({ ...current, action: \"starting\" })\n return transport.enqueue(entityId, provider, prompt, abort.signal).then(\n (review) => {\n if (abort.signal.aborted) return Promise.reject(new PullRequestReviewRequestAborted())\n setState((latest) =>\n latest._tag === \"ready\" &&\n sameReviewScope(latest, current) &&\n matchesScope(review, current)\n ? { ...latest, action: \"idle\", review }\n : latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? {\n _tag: \"failed\",\n baseRevision: current.baseRevision,\n entityId: current.entityId,\n headRevision: current.headRevision,\n sessionKey: current.sessionKey\n }\n : latest\n )\n },\n (failure) => {\n if (abort.signal.aborted) return Promise.reject(new PullRequestReviewRequestAborted())\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, action: \"failed\" }\n : latest\n )\n return Promise.reject(failure)\n }\n )\n }, [entityId, onSessionExpired, state, transport])\n\n const start = useCallback((\n prompt?: DurableAgentPrompt,\n providerId?: ReviewProviderSelection[\"providerId\"]\n ): void => {\n void startAwaitable(prompt, providerId).catch(<UnparsedInput>(failure: UnparsedInput) => {\n if (Predicate.isTagged(failure, \"PullRequestReviewRequestAborted\")) return\n Effect.runFork(Effect.logError(\"Pull-request review enqueue failed\", failure))\n })\n }, [startAwaitable])\n\n const mutatePendingReview = useCallback((\n operation: (jobId: JobId, signal: AbortSignal) => Promise<PullRequestReviewState>\n ) => {\n if (state._tag !== \"ready\") return\n const review = state.review\n if (review._tag !== \"pending\") return\n const current = state\n mutationAbort.current?.abort()\n const abort = new AbortController()\n mutationAbort.current = abort\n operation(review.jobId, abort.signal).then(\n (review) => {\n if (abort.signal.aborted) return\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current) && matchesScope(review, current)\n ? { ...latest, review }\n : latest\n )\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n }\n )\n }, [onSessionExpired, state])\n\n const previewPublication = useCallback((selection: ReviewSuggestionPublicationTarget) => {\n if (\n state._tag !== \"ready\" ||\n state.review._tag !== \"completed\" ||\n state.review.jobId !== selection.jobId ||\n !state.review.report.suggestions.some(\n ({ suggestionId }) => suggestionId === selection.suggestionId\n )\n ) return\n const current = state\n mutationAbort.current?.abort()\n const abort = new AbortController()\n mutationAbort.current = abort\n setPublication({ _tag: \"previewing\", selection })\n transport.previewPublication(entityId, selection, abort.signal).then(\n (preview) => {\n if (abort.signal.aborted) return\n setPublication(\n preview.subject.headRevision === current.headRevision\n ? { _tag: \"preview\", preview }\n : { _tag: \"failed\", preview: null, selection }\n )\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setPublication({ _tag: \"failed\", preview: null, selection })\n }\n )\n }, [entityId, onSessionExpired, state, transport])\n\n const publishSuggestion = useCallback((finalContent: ReviewSuggestionPublicationContent) => {\n if (state._tag !== \"ready\") return\n const preview = publication._tag === \"preview\"\n ? publication.preview\n : publication._tag === \"failed\"\n ? publication.preview\n : null\n if (preview === null) return\n const current = state\n const selection = {\n jobId: preview.jobId,\n suggestionId: preview.suggestionId,\n revisionId: preview.revisionId\n }\n publicationAbort.current?.abort()\n const abort = new AbortController()\n publicationAbort.current = abort\n setPublication({ _tag: \"publishing\", preview })\n transport.publishSuggestion(\n entityId,\n selection,\n finalContent,\n preview.authorityBinding,\n abort.signal\n ).then(\n (published) => {\n if (abort.signal.aborted) return\n const receiptMatches = published.suggestionRevision.reviewedHead ===\n preview.suggestionRevision.reviewedHead\n if (receiptMatches) {\n setState((latest) =>\n latest._tag === \"ready\" && latest.review._tag === \"completed\" &&\n latest.review.jobId === published.jobId\n ? {\n ...latest,\n review: {\n ...latest.review,\n report: {\n ...latest.review.report,\n suggestions: latest.review.report.suggestions.map((suggestion) => {\n if (suggestion.suggestionId !== published.suggestionId) return suggestion\n const transitioned: typeof suggestion = { ...suggestion, state: \"published\" }\n return transitioned\n })\n }\n }\n }\n : latest\n )\n }\n setPublication(\n receiptMatches\n ? {\n _tag: \"published\",\n headSuperseded: latestScope.current === null ||\n published.subject.baseRevision !== latestScope.current.baseRevision ||\n published.subject.headRevision !== latestScope.current.headRevision,\n preview,\n publication: published\n }\n : { _tag: \"receipt-conflict\", preview, publication: published }\n )\n const activeScope = latestScope.current\n if (\n activeScope !== null &&\n activeScope.entityId === current.entityId &&\n activeScope.sessionKey === current.sessionKey\n ) refreshThread(activeScope, abort.signal)\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setPublication({ _tag: \"failed\", preview, selection })\n }\n )\n }, [entityId, onSessionExpired, publication, refreshThread, state, transport])\n\n const targetSuggestion = useCallback((target: ReviewSuggestionTarget) => {\n if (\n state._tag !== \"ready\" ||\n state.review._tag !== \"completed\" ||\n state.review.jobId !== target.jobId ||\n state.provider === null ||\n !state.review.report.suggestions.some(({ suggestionId }) => suggestionId === target.suggestionId)\n ) return\n if (transport.targetSuggestion === undefined) return\n const current = state\n mutationAbort.current?.abort()\n const abort = new AbortController()\n mutationAbort.current = abort\n setState({ ...current, action: \"starting\" })\n transport.targetSuggestion(entityId, target, state.provider, abort.signal).then(\n (review) => {\n if (abort.signal.aborted) return\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current) && matchesScope(review, current)\n ? { ...latest, action: \"idle\", review }\n : latest\n )\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, action: \"failed\" }\n : latest\n )\n }\n )\n }, [entityId, onSessionExpired, state, transport])\n\n const currentState: PullRequestReviewControllerState = scope === null\n ? { _tag: \"idle\" }\n : state._tag !== \"idle\" && sameReviewScope(state, scope)\n ? state\n : { _tag: \"loading\", ...scope }\n\n return {\n cancel: useCallback(() => {\n if (transport.cancel === undefined) return\n mutatePendingReview((jobId, signal) => transport.cancel!(entityId, jobId, signal))\n }, [entityId, mutatePendingReview, transport]),\n cancelPublication: useCallback(() => {\n mutationAbort.current?.abort()\n mutationAbort.current = null\n publicationAbort.current?.abort()\n publicationAbort.current = null\n setPublication({ _tag: \"idle\" })\n }, []),\n extendBudget: useCallback(() => {\n if (transport.extendBudget === undefined) return\n mutatePendingReview((jobId, signal) => transport.extendBudget!(entityId, jobId, signal))\n }, [entityId, mutatePendingReview, transport]),\n loadEarlier,\n previewPublication,\n publication,\n publishSuggestion,\n targetSuggestion,\n retry: useCallback(() => {\n automaticRetryScope.current = null\n setRequestRevision((revision) => revision + 1)\n }, []),\n start,\n startAwaitable,\n state: currentState\n }\n}\n","import { LinkProvider } from \"@knpkv/rly/foundations\"\nimport {\n AgentContextButton,\n CollaboratorGroup,\n EntityShell,\n EvidenceStamp,\n RelationshipChain,\n RelationshipTable,\n ServiceMark,\n TimelineRow,\n type RlyCollaboratorCategory\n} from \"@knpkv/rly/patterns\"\nimport { Button, Skeleton, StatePanel, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport { type ReactElement, lazy, Suspense, useCallback, useEffect, useRef, useState } from \"react\"\nimport { Link, useLocation, useNavigate, useOutletContext, useParams } from \"react-router\"\n\nimport type { DurableAgentPrompt } from \"../../api/agent.js\"\nimport type { SubmitClockifyActionRequest } from \"../../api/deliveryGraph.js\"\nimport type { EntityId as EntityIdType, WorkspaceId as WorkspaceIdType } from \"../../domain/identifiers.js\"\nimport { browserReadableSessionKey, useBrowserSession } from \"../BrowserSession.js\"\nimport { ControlCenterRelayThread } from \"../controlCenterRelayThread.js\"\nimport {\n decodeEntityRouteId,\n resolveWorkspaceEntityOrigin,\n type WorkspaceEntityOrigin,\n workspaceEntityAgentPath,\n workspaceEntityOriginHref,\n workspaceEntityParentPath\n} from \"../items/workspaceEntityRoutes.js\"\nimport type { WorkspaceReleaseOutletContext } from \"../releases/WorkspaceReleaseLayout.js\"\nimport { presentWorkspaceEntity, type WorkspaceEntityPresentation } from \"./presentWorkspaceEntity.js\"\nimport { WorkspaceEntityLink } from \"./WorkspaceEntityLink.js\"\nimport styles from \"./WorkspaceEntityRoute.module.css\"\nimport { WorkspaceClockifyTimeEntryDetails } from \"./WorkspaceClockifyTimeEntryDetails.js\"\nimport { type ClockifyActionSubmissionState, useClockifyActionSubmission } from \"./useClockifyActionSubmission.js\"\nimport {\n type OpenConfluenceSynchronizationState,\n useOpenConfluenceSynchronization\n} from \"./useOpenConfluenceSynchronization.js\"\nimport { WorkspaceConfluencePageDetails } from \"./WorkspaceConfluencePageDetails.js\"\nimport type { WorkspaceConfluenceVisualEditorProps } from \"./WorkspaceConfluenceVisualEditor.js\"\nimport { WorkspaceIssueDetails } from \"./WorkspaceIssueDetails.js\"\nimport { WorkspacePipelineExecutionDetails } from \"./WorkspacePipelineExecutionDetails.js\"\nimport {\n usePullRequestReview,\n type PullRequestReviewControllerState,\n type PullRequestReviewPublicationState,\n type ReviewSuggestionPublicationTarget,\n type ReviewSuggestionTarget\n} from \"./usePullRequestReview.js\"\nimport type { ReviewSuggestionRevisionTransport } from \"./useReviewSuggestionRevisions.js\"\nimport { browserWorkspaceEntityTransport, useWorkspaceEntity, type WorkspaceEntityState } from \"./useWorkspaceEntity.js\"\n\nconst WorkspacePullRequestDetails = lazy(() =>\n import(\"./WorkspacePullRequestDetails.js\").then((module) => ({\n default: module.WorkspacePullRequestDetails\n }))\n)\n\nconst originLabel = (href: string, workspaceId: WorkspaceIdType): string => {\n const pathname = href.split(/[?#]/u, 1)[0] ?? \"\"\n if (pathname === workspaceEntityParentPath(workspaceId)) return \"Back to items\"\n if (pathname.includes(\"/releases/\")) return \"Back to release\"\n if (pathname.endsWith(\"/work\")) return \"Back to active work\"\n if (pathname.endsWith(\"/timeline\")) return \"Back to timeline\"\n return \"Back to workspace\"\n}\n\nconst RouteState = ({\n action,\n description,\n title,\n tone = \"neutral\"\n}: {\n readonly action?: ReactElement\n readonly description: string\n readonly title: string\n readonly tone?: \"critical\" | \"neutral\" | \"progress\"\n}): ReactElement => {\n const ref = useRef<HTMLElement>(null)\n useEffect(() => ref.current?.focus(), [])\n return (\n <section className={styles.state} data-workspace-entity-state={tone} ref={ref} tabIndex={-1}>\n <StatePanel action={action} description={description} title={title} tone={tone} />\n </section>\n )\n}\n\nconst LoadingEntity = (): ReactElement => (\n <section aria-label=\"Loading canonical entity\" className={styles.loading}>\n <Skeleton decorative={false} height=\"12rem\" label=\"Loading canonical entity\" variant=\"block\" />\n <div className={styles.loadingColumns}>\n <Skeleton height=\"20rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </div>\n </section>\n)\n\nconst PrincipalAction = ({\n action\n}: {\n readonly action: WorkspaceEntityPresentation[\"primaryAction\"]\n}): ReactElement => {\n if (action.href === null) {\n return (\n <Button disabled size=\"principal\" stretch variant=\"primary\">\n {action.label}\n </Button>\n )\n }\n return action.external ? (\n <a className={styles.principalAction} href={action.href} rel=\"noreferrer\" target=\"_blank\">\n {action.label}\n </a>\n ) : (\n <Link className={styles.principalAction} to={action.href}>\n {action.label}\n </Link>\n )\n}\n\n/** Derive Confluence's authenticated editor only from one canonical same-page source link. */\nexport const confluenceEditHref = (sourceHref: string | null, pageId: string): string | null => {\n if (sourceHref === null) return null\n const source = URL.parse(sourceHref)\n if (source === null || source.protocol !== \"https:\") return null\n const match = /^\\/wiki\\/spaces\\/([^/]+)\\/pages\\/([^/]+)(?:\\/|$)/u.exec(source.pathname)\n if (match?.[1] === undefined || match[2] !== encodeURIComponent(pageId)) return null\n source.pathname = `/wiki/spaces/${match[1]}/pages/edit-v2/${encodeURIComponent(pageId)}`\n source.search = \"\"\n source.hash = \"\"\n return source.href\n}\n\nconst EntityActions = ({\n onConfluenceSynchronize,\n presentation,\n synchronizationState\n}: {\n readonly onConfluenceSynchronize: () => void\n readonly presentation: WorkspaceEntityPresentation\n readonly synchronizationState: OpenConfluenceSynchronizationState | null\n}): ReactElement => {\n const editHref =\n presentation.confluencePage === null\n ? null\n : confluenceEditHref(presentation.primaryAction.href, presentation.displayKey)\n return (\n <div className={styles.entityActions}>\n <PrincipalAction action={presentation.primaryAction} />\n {editHref === null ? null : (\n <a className={styles.secondaryAction} href={editHref} rel=\"noreferrer\" target=\"_blank\">\n Edit in Confluence\n </a>\n )}\n {presentation.confluencePage === null || synchronizationState === null ? null : (\n <div className={styles.pageSynchronization}>\n <Button\n disabled={synchronizationState === \"syncing\"}\n loading={synchronizationState === \"syncing\"}\n onClick={onConfluenceSynchronize}\n variant=\"secondary\"\n >\n Sync now\n </Button>\n <Text tone=\"secondary\" variant=\"meta\">\n {synchronizationState === \"failed\"\n ? \"Sync failed. Try again.\"\n : synchronizationState === \"synchronized\"\n ? \"Up to date · live sync every 15 seconds while visible\"\n : \"Live sync every 15 seconds while visible\"}\n </Text>\n </div>\n )}\n </div>\n )\n}\n\nconst DeliveryPath = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-path\" className={styles.deliveryPath}>\n <div className={styles.sectionHeading}>\n <Text as=\"h2\" id=\"workspace-entity-path\" variant=\"section-title\">\n Delivery path\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n Where this work lives\n </Text>\n </div>\n <div className={styles.pathRail}>\n <div className={styles.pathNode}>\n <ServiceMark service={presentation.service} size=\"compact\" />\n <span>\n <strong>{presentation.serviceName}</strong>\n <code>{presentation.displayKey}</code>\n </span>\n </div>\n {presentation.releases.length === 0 ? (\n <div className={styles.pathEmpty}>No release membership yet</div>\n ) : (\n <ol className={styles.releasePath}>\n {presentation.releases.map((release) => (\n <li key={release.id}>\n <Link to={release.href}>{release.label}</Link>\n </li>\n ))}\n </ol>\n )}\n </div>\n <Text tone=\"secondary\">{presentation.contentSummary}</Text>\n </section>\n)\n\nconst EntityFacts = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-facts\" className={styles.facts}>\n <Text as=\"h2\" id=\"workspace-entity-facts\" variant=\"card-title\">\n At a glance\n </Text>\n <dl>\n {presentation.facts.map((fact) => (\n <div key={fact.label}>\n <dt>{fact.label}</dt>\n <dd>{fact.value}</dd>\n </div>\n ))}\n </dl>\n </section>\n)\n\nconst EntityEvidence = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-evidence\" className={styles.evidence}>\n <Text as=\"h2\" id=\"workspace-entity-evidence\" variant=\"card-title\">\n Provenance\n </Text>\n <EvidenceStamp\n freshness={presentation.evidence.freshness}\n freshnessDateTime={presentation.evidence.freshnessDateTime}\n freshnessTime={presentation.evidence.freshnessTime}\n reference={presentation.evidence.reference}\n service={presentation.service}\n />\n <Text tone=\"secondary\" variant=\"meta\">\n {presentation.evidence.itemCount} evidence item{presentation.evidence.itemCount === 1 ? \"\" : \"s\"} ·{\" \"}\n {presentation.evidence.claimCount} claim{presentation.evidence.claimCount === 1 ? \"\" : \"s\"}\n </Text>\n </section>\n)\n\nconst EntityCollaborators = ({\n presentation\n}: {\n readonly presentation: WorkspaceEntityPresentation\n}): ReactElement => {\n const [expanded, setExpanded] = useState<ReadonlyArray<RlyCollaboratorCategory>>(\n presentation.collaborators.expandedCategories\n )\n return (\n <div className={styles.workingCircle}>\n <CollaboratorGroup\n approvers={presentation.collaborators.approvers}\n authors={presentation.collaborators.authors}\n emptyLabel={presentation.collaborators.emptyLabel}\n expandedCategories={expanded}\n heading=\"Working circle\"\n limit={3}\n onCategoryExpandedChange={(category, nextExpanded) => {\n setExpanded((current) =>\n nextExpanded ? [...new Set([...current, category])] : current.filter((candidate) => candidate !== category)\n )\n }}\n operators={presentation.collaborators.operators}\n owners={presentation.collaborators.owners}\n reviewers={presentation.collaborators.reviewers}\n size=\"compact\"\n />\n </div>\n )\n}\n\nconst EntityRelationships = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement =>\n presentation.relationships.length <= 4 ? (\n <RelationshipChain\n emptyLabel={presentation.relationshipEmptyLabel}\n heading=\"Delivery relationships\"\n relationships={presentation.relationships}\n />\n ) : (\n <RelationshipTable\n emptyLabel={presentation.relationshipEmptyLabel}\n heading=\"Delivery relationships\"\n relationships={presentation.relationships}\n />\n )\n\nconst EntityActivity = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-activity\" className={styles.activity}>\n <div className={styles.sectionHeading}>\n <Text as=\"h2\" id=\"workspace-entity-activity\" variant=\"section-title\">\n Activity\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n Quiet, attributable history\n </Text>\n </div>\n {presentation.activity.length === 0 ? (\n <Text tone=\"secondary\">{presentation.activityEmptyLabel}</Text>\n ) : (\n <ol className={styles.timeline}>\n {presentation.activity.map((event, index) => (\n <TimelineRow continued={index < presentation.activity.length - 1} event={event} key={event.id} />\n ))}\n </ol>\n )}\n </section>\n)\n\nconst staleMessage = (state: Extract<WorkspaceEntityState, { readonly _tag: \"stale\" }>): string => {\n switch (state.reason) {\n case \"refreshing\":\n return \"Refreshing from the connected service. The last complete inspection remains visible.\"\n case \"refresh-failed\":\n return \"The latest refresh failed. The last complete inspection remains visible and may be out of date.\"\n case \"source-stale\":\n return \"The connected service reported stale source data. Confirm current state before acting.\"\n }\n}\n\nconst EntityContent = ({\n clockifyActionCanApprove,\n clockifyActionCanCorrect,\n clockifyActionState,\n clockifyActionSubmit,\n confluenceEditor,\n onSessionExpired,\n presentation,\n retry,\n reviewCanEnqueue,\n reviewCancel,\n reviewExtendBudget,\n reviewLoadEarlier,\n reviewPublication,\n reviewPublicationCancel,\n reviewPublicationPreview,\n reviewRetry,\n reviewStart,\n reviewState,\n reviewSuggestionPublish,\n reviewSuggestionRevisionTransport,\n reviewTargetSuggestion,\n sessionKey,\n stale\n}: {\n readonly clockifyActionCanApprove: boolean\n readonly clockifyActionCanCorrect: boolean\n readonly clockifyActionState: ClockifyActionSubmissionState\n readonly clockifyActionSubmit: (request: SubmitClockifyActionRequest) => void\n readonly confluenceEditor: Omit<WorkspaceConfluenceVisualEditorProps, \"page\">\n readonly onSessionExpired: (sessionKey: string) => void\n readonly presentation: WorkspaceEntityPresentation\n readonly reviewCanEnqueue: boolean\n readonly reviewCancel: () => void\n readonly reviewExtendBudget: () => void\n readonly reviewPublication: PullRequestReviewPublicationState\n readonly reviewPublicationCancel: () => void\n readonly reviewLoadEarlier: () => void\n readonly reviewPublicationPreview: (selection: ReviewSuggestionPublicationTarget) => void\n readonly reviewRetry: () => void\n readonly reviewSuggestionRevisionTransport?: ReviewSuggestionRevisionTransport\n readonly reviewSuggestionPublish: (finalContent: string) => void\n readonly reviewTargetSuggestion: (target: ReviewSuggestionTarget) => void\n readonly reviewStart: (prompt?: DurableAgentPrompt) => void\n readonly reviewState: PullRequestReviewControllerState\n readonly retry: () => void\n readonly sessionKey: string | null\n readonly stale: Extract<WorkspaceEntityState, { readonly _tag: \"stale\" }> | null\n}): ReactElement => (\n <div className={styles.content}>\n {stale === null ? null : (\n <StatePanel\n action={stale.reason === \"refreshing\" ? undefined : <Button onClick={retry}>Retry refresh</Button>}\n announce={stale.reason === \"refresh-failed\" ? \"polite\" : \"off\"}\n description={staleMessage(stale)}\n title={stale.reason === \"refreshing\" ? \"Refreshing source\" : \"Showing retained source data\"}\n tone=\"caution\"\n />\n )}\n {presentation.partialMessages.map((message) => (\n <StatePanel description={message} key={message} title=\"Partial canonical view\" tone=\"caution\" />\n ))}\n {presentation.clockifyTimeEntry === null ? null : (\n <WorkspaceClockifyTimeEntryDetails\n canApprove={clockifyActionCanApprove}\n canCorrect={clockifyActionCanCorrect}\n onSubmit={clockifyActionSubmit}\n submission={clockifyActionState}\n timeEntry={presentation.clockifyTimeEntry}\n />\n )}\n {presentation.issue === null ? null : <WorkspaceIssueDetails issue={presentation.issue} />}\n {presentation.confluencePage === null ? null : (\n <WorkspaceConfluencePageDetails editor={confluenceEditor} page={presentation.confluencePage} />\n )}\n {presentation.pipelineExecution === null ? null : (\n <WorkspacePipelineExecutionDetails pipeline={presentation.pipelineExecution} />\n )}\n {presentation.pullRequest === null ? null : (\n <Suspense fallback={<Skeleton decorative={false} height=\"20rem\" label=\"Loading pull request\" variant=\"block\" />}>\n <WorkspacePullRequestDetails\n approvers={presentation.collaborators.approvers}\n onSessionExpired={onSessionExpired}\n onReviewCancel={reviewCancel}\n onReviewExtendBudget={reviewExtendBudget}\n onReviewLoadEarlier={reviewLoadEarlier}\n onReviewPublicationCancel={reviewPublicationCancel}\n onReviewPublicationPreview={reviewPublicationPreview}\n onReviewRetry={reviewRetry}\n onReviewSuggestionPublish={reviewSuggestionPublish}\n onReviewTargetSuggestion={reviewTargetSuggestion}\n onReviewStart={reviewStart}\n pullRequest={presentation.pullRequest}\n reviewCanEnqueue={reviewCanEnqueue}\n reviewPublication={reviewPublication}\n {...(reviewSuggestionRevisionTransport === undefined ? {} : { reviewSuggestionRevisionTransport })}\n reviewState={reviewState}\n reviewers={presentation.collaborators.reviewers}\n sessionKey={sessionKey}\n />\n </Suspense>\n )}\n <DeliveryPath presentation={presentation} />\n </div>\n)\n\ninterface WorkspaceEntityViewProps {\n readonly clockifyActionCanApprove?: boolean\n readonly clockifyActionCanCorrect?: boolean\n readonly clockifyActionState?: ClockifyActionSubmissionState\n readonly clockifyActionSubmit?: (request: SubmitClockifyActionRequest) => void\n readonly confluenceCanEdit?: boolean\n readonly confluenceSynchronizationState?: OpenConfluenceSynchronizationState | null\n readonly onConfluenceSaved?: () => void\n readonly onConfluenceSynchronize?: () => void\n readonly onAskAgent: () => void\n readonly onSessionExpired?: (sessionKey: string) => void\n readonly originHref: string\n readonly originLabel: string\n readonly originState: WorkspaceEntityOrigin[\"state\"]\n readonly retry: () => void\n readonly reviewCanEnqueue?: boolean\n readonly reviewCancel?: () => void\n readonly reviewExtendBudget?: () => void\n readonly reviewLoadEarlier?: () => void\n readonly reviewPublication?: PullRequestReviewPublicationState\n readonly reviewPublicationCancel?: () => void\n readonly reviewPublicationPreview?: (selection: ReviewSuggestionPublicationTarget) => void\n readonly reviewRetry?: () => void\n readonly reviewSuggestionRevisionTransport?: ReviewSuggestionRevisionTransport\n readonly reviewSuggestionPublish?: (finalContent: string) => void\n readonly reviewTargetSuggestion?: (target: ReviewSuggestionTarget) => void\n readonly reviewStart?: (prompt?: DurableAgentPrompt) => void\n readonly reviewState?: PullRequestReviewControllerState\n readonly state: WorkspaceEntityState\n readonly sessionKey?: string | null\n readonly workspaceId: WorkspaceIdType\n}\n\nconst ignoreSessionExpiration = (_sessionKey: string): void => undefined\nconst ignoreAction = (): void => undefined\n\n/** Pure state renderer for the canonical entity route. */\nexport const WorkspaceEntityView = ({\n clockifyActionCanApprove = false,\n clockifyActionCanCorrect = false,\n clockifyActionState = { _tag: \"idle\" },\n clockifyActionSubmit = ignoreAction,\n confluenceCanEdit = false,\n confluenceSynchronizationState = null,\n onAskAgent,\n onConfluenceSaved,\n onConfluenceSynchronize = ignoreAction,\n onSessionExpired = ignoreSessionExpiration,\n originHref,\n originLabel: backLabel,\n originState,\n retry,\n reviewCanEnqueue = false,\n reviewCancel = ignoreAction,\n reviewExtendBudget = ignoreAction,\n reviewLoadEarlier = ignoreAction,\n reviewPublication = { _tag: \"idle\" },\n reviewPublicationCancel = ignoreAction,\n reviewPublicationPreview = ignoreAction,\n reviewRetry = ignoreAction,\n reviewStart = ignoreAction,\n reviewState = { _tag: \"idle\" },\n reviewSuggestionPublish = ignoreAction,\n reviewSuggestionRevisionTransport,\n reviewTargetSuggestion = ignoreAction,\n sessionKey = null,\n state,\n workspaceId\n}: WorkspaceEntityViewProps): ReactElement => {\n const focusRef = useRef<HTMLElement>(null)\n const visibleEntityId =\n state._tag === \"ready\" || state._tag === \"stale\" ? state.inspection.entity.projection.entityId : state._tag\n useEffect(() => focusRef.current?.focus(), [visibleEntityId])\n\n if (state._tag === \"idle\") {\n return (\n <RouteState\n action={\n <Link state={originState} to={originHref}>\n {backLabel}\n </Link>\n }\n description=\"A readable workspace session is required before this object can be loaded.\"\n title=\"Entity unavailable\"\n />\n )\n }\n if (state._tag === \"loading\") return <LoadingEntity />\n if (state._tag === \"not-found\") {\n return (\n <RouteState\n action={\n <Link state={originState} to={originHref}>\n {backLabel}\n </Link>\n }\n description=\"This object is not in this workspace. It may have been deleted, disconnected, or the address may be wrong.\"\n title=\"Object not found\"\n />\n )\n }\n if (state._tag === \"failed\") {\n return (\n <RouteState\n action={<Button onClick={retry}>Retry entity</Button>}\n description=\"The canonical object could not be loaded. Your current workspace location is preserved.\"\n title=\"Could not load object\"\n tone=\"critical\"\n />\n )\n }\n\n const presentation = presentWorkspaceEntity(workspaceId, state.inspection)\n const clockifyActionsCurrent =\n state._tag === \"ready\" && state.inspection.isSourceCurrent && state.inspection.sourceActionsAvailable\n const afterConfluenceSave = onConfluenceSaved ?? retry\n return (\n <LinkProvider component={WorkspaceEntityLink}>\n <EntityShell\n actions={\n <EntityActions\n onConfluenceSynchronize={onConfluenceSynchronize}\n presentation={presentation}\n synchronizationState={confluenceSynchronizationState}\n />\n }\n activity={<EntityActivity presentation={presentation} />}\n agentEntry={\n <AgentContextButton\n actionLabel={presentation.confluencePage === null ? \"Ask about this object\" : \"Draft with Relay\"}\n agentName=\"Relay\"\n context={presentation.agentContext}\n onClick={onAskAgent}\n />\n }\n collaborators={\n <EntityCollaborators key={state.inspection.entity.projection.entityId} presentation={presentation} />\n }\n className={styles.shell}\n content={\n <EntityContent\n clockifyActionCanApprove={clockifyActionsCurrent && clockifyActionCanApprove}\n clockifyActionCanCorrect={clockifyActionsCurrent && clockifyActionCanCorrect}\n clockifyActionState={clockifyActionState}\n clockifyActionSubmit={clockifyActionSubmit}\n confluenceEditor={{\n canEdit:\n confluenceCanEdit &&\n state._tag === \"ready\" &&\n state.inspection.isSourceCurrent &&\n state.inspection.sourceActionsAvailable,\n entityId: state.inspection.entity.projection.entityId,\n onAskAgent,\n onSaved: afterConfluenceSave,\n releaseId: state.inspection.entity.canonicalReleaseId,\n title: presentation.title\n }}\n onSessionExpired={onSessionExpired}\n presentation={presentation}\n reviewCanEnqueue={reviewCanEnqueue}\n reviewCancel={reviewCancel}\n reviewExtendBudget={reviewExtendBudget}\n reviewPublication={reviewPublication}\n reviewPublicationCancel={reviewPublicationCancel}\n reviewLoadEarlier={reviewLoadEarlier}\n reviewPublicationPreview={reviewPublicationPreview}\n reviewRetry={reviewRetry}\n {...(reviewSuggestionRevisionTransport === undefined ? {} : { reviewSuggestionRevisionTransport })}\n reviewSuggestionPublish={reviewSuggestionPublish}\n reviewTargetSuggestion={reviewTargetSuggestion}\n reviewStart={reviewStart}\n reviewState={reviewState}\n retry={retry}\n sessionKey={sessionKey}\n stale={state._tag === \"stale\" ? state : null}\n />\n }\n data-service={presentation.service}\n data-workspace-entity-id={state.inspection.entity.projection.entityId}\n evidence={<EntityEvidence presentation={presentation} />}\n facts={<EntityFacts presentation={presentation} />}\n freshness={presentation.freshness}\n freshnessDateTime={presentation.freshnessDateTime}\n freshnessTime={presentation.freshnessTime}\n navigation={\n <Link className={styles.back} state={originState} to={originHref}>\n {backLabel}\n </Link>\n }\n reason={`${presentation.displayKey} is ${presentation.verdict.toLocaleLowerCase(\"en-US\")} in ${presentation.serviceName}.`}\n ref={focusRef}\n relationships={<EntityRelationships presentation={presentation} />}\n service={presentation.service}\n tabIndex={-1}\n title={presentation.title}\n tone={presentation.tone}\n verdict={presentation.verdict}\n />\n </LinkProvider>\n )\n}\n\nconst ConnectedWorkspaceEntity = ({\n entityId,\n workspaceId\n}: {\n readonly entityId: EntityIdType\n readonly workspaceId: WorkspaceIdType\n}): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const browserSession = useBrowserSession()\n const location = useLocation()\n const navigate = useNavigate()\n const refreshKey =\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.generatedAt : \"pending\"\n const sessionKey = browserReadableSessionKey(browserSession.state)\n const controller = useWorkspaceEntity(workspaceId, entityId, refreshKey, sessionKey, browserSession.invalidateSession)\n const confluencePluginConnectionId =\n (controller.state._tag === \"ready\" || controller.state._tag === \"stale\") &&\n controller.state.inspection.entity.projection.details._tag === \"page\"\n ? controller.state.inspection.source.pluginConnectionId\n : null\n const canSynchronizeConfluence =\n confluencePluginConnectionId !== null &&\n (controller.state._tag === \"ready\" || controller.state._tag === \"stale\") &&\n controller.state.inspection.sourceSynchronizationAvailable &&\n browserSession.state._tag === \"authenticated\" &&\n browserSession.state.session.permission === \"workspace-owner\"\n const confluenceSynchronizedAt =\n confluencePluginConnectionId !== null && (controller.state._tag === \"ready\" || controller.state._tag === \"stale\")\n ? DateTime.toEpochMillis(controller.state.inspection.source.synchronizedAt)\n : null\n const readConfluenceSynchronizationRevision = useCallback(\n async (signal: AbortSignal): Promise<number | null> => {\n if (confluencePluginConnectionId === null) return null\n const current = await browserWorkspaceEntityTransport.load(entityId, signal)\n return current.entity.projection.entityId === entityId &&\n current.source.pluginConnectionId === confluencePluginConnectionId\n ? DateTime.toEpochMillis(current.source.synchronizedAt)\n : null\n },\n [confluencePluginConnectionId, entityId]\n )\n const confluenceSynchronization = useOpenConfluenceSynchronization({\n enabled: canSynchronizeConfluence,\n onSessionExpired: browserSession.invalidateSession,\n onSynchronized: controller.retry,\n pluginConnectionId: confluencePluginConnectionId,\n readSynchronizationRevision: readConfluenceSynchronizationRevision,\n sessionKey,\n synchronizationRevision: confluenceSynchronizedAt\n })\n const clockifyActions = useClockifyActionSubmission(\n entityId,\n sessionKey,\n browserSession.invalidateSession,\n controller.retry\n )\n const reviewCanEnqueue =\n browserSession.state._tag === \"authenticated\" && browserSession.state.session.permission === \"workspace-owner\"\n const reviewSubject =\n (controller.state._tag === \"ready\" || controller.state._tag === \"stale\") &&\n controller.state.inspection.entity.projection.details._tag === \"pull-request\"\n ? {\n baseRevision: controller.state.inspection.entity.projection.details.baseRevision ?? null,\n headRevision: controller.state.inspection.entity.projection.details.headRevision\n }\n : null\n const reviewController = usePullRequestReview(\n entityId,\n reviewSubject?.baseRevision ?? null,\n reviewSubject?.headRevision ?? null,\n sessionKey,\n reviewCanEnqueue,\n browserSession.invalidateSession\n )\n const resolvedOrigin = resolveWorkspaceEntityOrigin(location.state, workspaceId, entityId)\n const resolvedOriginHref = workspaceEntityOriginHref(resolvedOrigin.origin)\n const releaseContext =\n controller.state._tag === \"ready\" || controller.state._tag === \"stale\"\n ? controller.state.inspection.entity\n : { canonicalReleaseId: null, releaseIds: [], releaseMembershipsTruncated: false }\n const routableReleaseIds = new Set(\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.releases.map(({ id }) => id) : []\n )\n const agentPath = workspaceEntityAgentPath(\n resolvedOrigin.origin,\n workspaceId,\n location,\n releaseContext,\n routableReleaseIds\n )\n return (\n <>\n {(controller.state._tag === \"ready\" || controller.state._tag === \"stale\") &&\n controller.state.inspection.entity.projection.details._tag === \"pull-request\" ? (\n <ControlCenterRelayThread\n canEnqueue={reviewCanEnqueue}\n entityId={entityId}\n inspection={controller.state.inspection}\n reviewState={reviewController.state}\n startReview={reviewController.startAwaitable}\n workspaceId={workspaceId}\n />\n ) : null}\n <WorkspaceEntityView\n clockifyActionCanApprove={\n browserSession.state._tag === \"authenticated\" &&\n (browserSession.state.session.permission === \"workspace-owner\" ||\n browserSession.state.session.permission === \"workspace-approver\")\n }\n clockifyActionCanCorrect={\n browserSession.state._tag === \"authenticated\" && browserSession.state.session.permission === \"workspace-owner\"\n }\n clockifyActionState={clockifyActions.state}\n clockifyActionSubmit={clockifyActions.submit}\n confluenceCanEdit={\n browserSession.state._tag === \"authenticated\" && browserSession.state.session.permission === \"workspace-owner\"\n }\n confluenceSynchronizationState={canSynchronizeConfluence ? confluenceSynchronization.state : null}\n onAskAgent={() => navigate(agentPath, { state: location.state })}\n onConfluenceSaved={confluenceSynchronization.synchronizeAfterMutation}\n onConfluenceSynchronize={confluenceSynchronization.synchronizeNow}\n onSessionExpired={browserSession.invalidateSession}\n originHref={resolvedOriginHref}\n originLabel={originLabel(resolvedOriginHref, workspaceId)}\n originState={resolvedOrigin.origin.state}\n retry={controller.retry}\n reviewCanEnqueue={reviewCanEnqueue}\n reviewCancel={reviewController.cancel}\n reviewExtendBudget={reviewController.extendBudget}\n reviewPublication={reviewController.publication}\n reviewPublicationCancel={reviewController.cancelPublication}\n reviewLoadEarlier={reviewController.loadEarlier}\n reviewPublicationPreview={reviewController.previewPublication}\n reviewRetry={reviewController.retry}\n reviewSuggestionPublish={reviewController.publishSuggestion}\n reviewTargetSuggestion={reviewController.targetSuggestion}\n reviewStart={reviewController.start}\n reviewState={reviewController.state}\n state={controller.state}\n sessionKey={sessionKey}\n workspaceId={workspaceId}\n />\n </>\n )\n}\n\n/** Load and render one exact normalized object at its canonical full-page route. */\nexport const WorkspaceEntityRoute = (): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const params = useParams()\n const entityId = decodeEntityRouteId(params.entityId)\n return entityId === null ? (\n <RouteState\n action={<Link to={workspaceEntityParentPath(context.workspaceId)}>Back to items</Link>}\n description=\"The object address is not a canonical entity identifier.\"\n title=\"Object not found\"\n />\n ) : (\n <ConnectedWorkspaceEntity entityId={entityId} workspaceId={context.workspaceId} />\n )\n}\n"],"file":"WorkspaceEntityRoute-uUK6vwM_.js"}