@hienlh/ppm 0.22.3 → 0.22.4

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 (269) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/cli-reference.md +4 -4
  4. package/assets/skills/ppm/references/http-api.md +1 -1
  5. package/dist/web/assets/{accounts-settings-section-DbJ7QQg4.js → accounts-settings-section-BdUSroB_.js} +1 -1
  6. package/dist/web/assets/accounts-settings-section-BdUSroB_.js.br +0 -0
  7. package/dist/web/assets/accounts-settings-section-BdUSroB_.js.gz +0 -0
  8. package/dist/web/assets/{ai-resource-editor-B24DvHYZ.js → ai-resource-editor-UMbGL_jd.js} +1 -1
  9. package/dist/web/assets/ai-resource-editor-UMbGL_jd.js.br +0 -0
  10. package/dist/web/assets/ai-resource-editor-UMbGL_jd.js.gz +0 -0
  11. package/dist/web/assets/{ai-settings-section-Bq1-gIlM.js → ai-settings-section-DIb_MwDG.js} +1 -1
  12. package/dist/web/assets/ai-settings-section-DIb_MwDG.js.br +0 -0
  13. package/dist/web/assets/ai-settings-section-DIb_MwDG.js.gz +0 -0
  14. package/dist/web/assets/{ai-settings-section-BgEN9JJn.js → ai-settings-section-DXD90Oed.js} +1 -1
  15. package/dist/web/assets/{appearance-settings-section-DEPNZnJ2.js → appearance-settings-section-cnAoZk5I.js} +1 -1
  16. package/dist/web/assets/appearance-settings-section-cnAoZk5I.js.br +0 -0
  17. package/dist/web/assets/appearance-settings-section-cnAoZk5I.js.gz +0 -0
  18. package/dist/web/assets/{branch-review-tab-ruiWErmR.js → branch-review-tab-zZcw_Z9A.js} +1 -1
  19. package/dist/web/assets/branch-review-tab-zZcw_Z9A.js.br +0 -0
  20. package/dist/web/assets/branch-review-tab-zZcw_Z9A.js.gz +0 -0
  21. package/dist/web/assets/chat-tab-Bb6Wx_9W.js +15 -0
  22. package/dist/web/assets/chat-tab-Bb6Wx_9W.js.br +0 -0
  23. package/dist/web/assets/chat-tab-Bb6Wx_9W.js.gz +0 -0
  24. package/dist/web/assets/{code-editor-C7XqHn9o.js → code-editor-DT7ra7LE.js} +3 -3
  25. package/dist/web/assets/code-editor-DT7ra7LE.js.br +0 -0
  26. package/dist/web/assets/code-editor-DT7ra7LE.js.gz +0 -0
  27. package/dist/web/assets/{codex-daily-guard-DetGq_en.js → codex-daily-guard-BTimXxlM.js} +1 -1
  28. package/dist/web/assets/codex-daily-guard-BTimXxlM.js.br +0 -0
  29. package/dist/web/assets/codex-daily-guard-BTimXxlM.js.gz +0 -0
  30. package/dist/web/assets/{conflict-editor-DHUpVDGB.js → conflict-editor-Cu9DCNow.js} +1 -1
  31. package/dist/web/assets/conflict-editor-Cu9DCNow.js.br +0 -0
  32. package/dist/web/assets/conflict-editor-Cu9DCNow.js.gz +0 -0
  33. package/dist/web/assets/{csv-preview-DXGt24yG.js → csv-preview-BpKdfkoD.js} +1 -1
  34. package/dist/web/assets/csv-preview-BpKdfkoD.js.br +0 -0
  35. package/dist/web/assets/csv-preview-BpKdfkoD.js.gz +0 -0
  36. package/dist/web/assets/{database-viewer-zMGckF4c.js → database-viewer-CFWSVJ6D.js} +1 -1
  37. package/dist/web/assets/database-viewer-CFWSVJ6D.js.br +0 -0
  38. package/dist/web/assets/database-viewer-CFWSVJ6D.js.gz +0 -0
  39. package/dist/web/assets/{diff-viewer-D8ORwKJO.js → diff-viewer-DfjjKjgw.js} +1 -1
  40. package/dist/web/assets/diff-viewer-DfjjKjgw.js.br +0 -0
  41. package/dist/web/assets/diff-viewer-DfjjKjgw.js.gz +0 -0
  42. package/dist/web/assets/{editor-language-service-DlXOJKTM.js → editor-language-service-DN1yAn4G.js} +1 -1
  43. package/dist/web/assets/editor-language-service-DN1yAn4G.js.br +0 -0
  44. package/dist/web/assets/editor-language-service-DN1yAn4G.js.gz +0 -0
  45. package/dist/web/assets/{explorer-body-CvLKavSL.js → explorer-body-DWyFKpWw.js} +1 -1
  46. package/dist/web/assets/explorer-body-DWyFKpWw.js.br +0 -0
  47. package/dist/web/assets/explorer-body-DWyFKpWw.js.gz +0 -0
  48. package/dist/web/assets/{explorer-window-content-DLPV_kMF.js → explorer-window-content-CgtS3nhS.js} +1 -1
  49. package/dist/web/assets/explorer-window-content-CgtS3nhS.js.br +0 -0
  50. package/dist/web/assets/explorer-window-content-CgtS3nhS.js.gz +0 -0
  51. package/dist/web/assets/{extension-manager-section-CAy3LVt7.js → extension-manager-section-D7syyPQv.js} +1 -1
  52. package/dist/web/assets/extension-manager-section-D7syyPQv.js.br +0 -0
  53. package/dist/web/assets/extension-manager-section-D7syyPQv.js.gz +0 -0
  54. package/dist/web/assets/{extension-webview-BHg6PTCh.js → extension-webview-BkU4LB87.js} +1 -1
  55. package/dist/web/assets/extension-webview-BkU4LB87.js.br +0 -0
  56. package/dist/web/assets/extension-webview-BkU4LB87.js.gz +0 -0
  57. package/dist/web/assets/{files-settings-section-ND3D08W7.js → files-settings-section-BnQqhnUX.js} +1 -1
  58. package/dist/web/assets/files-settings-section-BnQqhnUX.js.br +0 -0
  59. package/dist/web/assets/files-settings-section-BnQqhnUX.js.gz +0 -0
  60. package/dist/web/assets/{general-settings-section-SJbTkh0b.js → general-settings-section-Chg1cFnJ.js} +1 -1
  61. package/dist/web/assets/general-settings-section-Chg1cFnJ.js.br +0 -0
  62. package/dist/web/assets/general-settings-section-Chg1cFnJ.js.gz +0 -0
  63. package/dist/web/assets/{git-log-panel-_yL7W4EQ.js → git-log-panel-DoYx7qpu.js} +1 -1
  64. package/dist/web/assets/git-log-panel-DoYx7qpu.js.br +0 -0
  65. package/dist/web/assets/git-log-panel-DoYx7qpu.js.gz +0 -0
  66. package/dist/web/assets/{glide-data-grid-CfH4uK1t.js → glide-data-grid-DzHd1zUz.js} +1 -1
  67. package/dist/web/assets/glide-data-grid-DzHd1zUz.js.br +0 -0
  68. package/dist/web/assets/glide-data-grid-DzHd1zUz.js.gz +0 -0
  69. package/dist/web/assets/{group-chat-tab-CprxuYA-.js → group-chat-tab-DPbPLDNH.js} +1 -1
  70. package/dist/web/assets/group-chat-tab-DPbPLDNH.js.br +0 -0
  71. package/dist/web/assets/group-chat-tab-DPbPLDNH.js.gz +0 -0
  72. package/dist/web/assets/{index-8M7JWSZx.js → index-Dh3WkQrC.js} +4 -4
  73. package/dist/web/assets/index-Dh3WkQrC.js.br +0 -0
  74. package/dist/web/assets/index-Dh3WkQrC.js.gz +0 -0
  75. package/dist/web/assets/{jira-watcher-section-_pTAalcO.js → jira-watcher-section-DhcwaPyZ.js} +1 -1
  76. package/dist/web/assets/jira-watcher-section-DhcwaPyZ.js.br +0 -0
  77. package/dist/web/assets/jira-watcher-section-DhcwaPyZ.js.gz +0 -0
  78. package/dist/web/assets/{keybindings-store-BwDohs5S.js → keybindings-store-BTDoQ-9J.js} +1 -1
  79. package/dist/web/assets/{keyboard-shortcuts-section-DpW1qIXk.js → keyboard-shortcuts-section-DQitR9HX.js} +1 -1
  80. package/dist/web/assets/keyboard-shortcuts-section-DQitR9HX.js.br +0 -0
  81. package/dist/web/assets/keyboard-shortcuts-section-DQitR9HX.js.gz +0 -0
  82. package/dist/web/assets/{markdown-renderer-BzkIv5_4.js → markdown-renderer-2son_wrq.js} +1 -1
  83. package/dist/web/assets/{markdown-renderer-CjEg_HGP.js → markdown-renderer-CpWOpNyX.js} +1 -1
  84. package/dist/web/assets/markdown-renderer-CpWOpNyX.js.br +0 -0
  85. package/dist/web/assets/{markdown-renderer-CjEg_HGP.js.gz → markdown-renderer-CpWOpNyX.js.gz} +0 -0
  86. package/dist/web/assets/{mobile-explorer-sheet-DjeEB2i8.js → mobile-explorer-sheet-CPUuOwTi.js} +1 -1
  87. package/dist/web/assets/mobile-explorer-sheet-CPUuOwTi.js.br +0 -0
  88. package/dist/web/assets/mobile-explorer-sheet-CPUuOwTi.js.gz +0 -0
  89. package/dist/web/assets/{notification-store-D8VycLI7.js → notification-store-CLD8V5pA.js} +1 -1
  90. package/dist/web/assets/{ppmbot-settings-section-ByROaaIk.js → ppmbot-settings-section-B8gDeE7h.js} +1 -1
  91. package/dist/web/assets/ppmbot-settings-section-B8gDeE7h.js.br +0 -0
  92. package/dist/web/assets/ppmbot-settings-section-B8gDeE7h.js.gz +0 -0
  93. package/dist/web/assets/{problems-panel-D-iHH0j8.js → problems-panel-CmkeR-bD.js} +1 -1
  94. package/dist/web/assets/problems-panel-CmkeR-bD.js.br +0 -0
  95. package/dist/web/assets/problems-panel-CmkeR-bD.js.gz +0 -0
  96. package/dist/web/assets/{process-table-CSgGG2La.js → process-table-DxrXd89K.js} +1 -1
  97. package/dist/web/assets/process-table-DxrXd89K.js.br +0 -0
  98. package/dist/web/assets/process-table-DxrXd89K.js.gz +0 -0
  99. package/dist/web/assets/{proxy-settings-section-Cz98fxZn.js → proxy-settings-section-8pLlN7YT.js} +1 -1
  100. package/dist/web/assets/proxy-settings-section-8pLlN7YT.js.br +0 -0
  101. package/dist/web/assets/proxy-settings-section-8pLlN7YT.js.gz +0 -0
  102. package/dist/web/assets/{remote-desktop-clipboard-notice-fjTRSMfw.js → remote-desktop-clipboard-notice-CKucNCju.js} +1 -1
  103. package/dist/web/assets/remote-desktop-clipboard-notice-CKucNCju.js.br +0 -0
  104. package/dist/web/assets/remote-desktop-clipboard-notice-CKucNCju.js.gz +0 -0
  105. package/dist/web/assets/{remote-desktop-mobile-sheet-BGzXIOnN.js → remote-desktop-mobile-sheet-CiGcUiO6.js} +2 -2
  106. package/dist/web/assets/remote-desktop-mobile-sheet-CiGcUiO6.js.br +0 -0
  107. package/dist/web/assets/remote-desktop-mobile-sheet-CiGcUiO6.js.gz +0 -0
  108. package/dist/web/assets/{remote-desktop-mobile-view-DC-_I2st.js → remote-desktop-mobile-view-Czubv7hF.js} +1 -1
  109. package/dist/web/assets/remote-desktop-mobile-view-Czubv7hF.js.br +0 -0
  110. package/dist/web/assets/remote-desktop-mobile-view-Czubv7hF.js.gz +0 -0
  111. package/dist/web/assets/{remote-desktop-readiness-gate-BBFhTM_C.js → remote-desktop-readiness-gate-CnRhTEwk.js} +1 -1
  112. package/dist/web/assets/remote-desktop-readiness-gate-CnRhTEwk.js.br +0 -0
  113. package/dist/web/assets/remote-desktop-readiness-gate-CnRhTEwk.js.gz +0 -0
  114. package/dist/web/assets/{remote-desktop-window-content-S1LNG0iM.js → remote-desktop-window-content-ZiRNL4Io.js} +1 -1
  115. package/dist/web/assets/remote-desktop-window-content-ZiRNL4Io.js.br +0 -0
  116. package/dist/web/assets/remote-desktop-window-content-ZiRNL4Io.js.gz +0 -0
  117. package/dist/web/assets/{schedules-settings-section-BERxYmYn.js → schedules-settings-section-Dq5Kn6Q8.js} +1 -1
  118. package/dist/web/assets/schedules-settings-section-Dq5Kn6Q8.js.br +0 -0
  119. package/dist/web/assets/schedules-settings-section-Dq5Kn6Q8.js.gz +0 -0
  120. package/dist/web/assets/{settings-body-C31PdcMj.js → settings-body-CYBJZti2.js} +2 -2
  121. package/dist/web/assets/settings-body-CYBJZti2.js.br +0 -0
  122. package/dist/web/assets/settings-body-CYBJZti2.js.gz +0 -0
  123. package/dist/web/assets/{settings-tab-D6QZSBqI.js → settings-tab-50Q5rjMo.js} +1 -1
  124. package/dist/web/assets/{settings-window-content-DLLcDkV0.js → settings-window-content-C_AGP_Go.js} +1 -1
  125. package/dist/web/assets/{sql-query-editor-BXaAQmLJ.js → sql-query-editor-DmqbSfHi.js} +1 -1
  126. package/dist/web/assets/sql-query-editor-DmqbSfHi.js.br +0 -0
  127. package/dist/web/assets/sql-query-editor-DmqbSfHi.js.gz +0 -0
  128. package/dist/web/assets/{sqlite-viewer-DWpzKvve.js → sqlite-viewer-CAX-LlOl.js} +1 -1
  129. package/dist/web/assets/sqlite-viewer-CAX-LlOl.js.br +0 -0
  130. package/dist/web/assets/sqlite-viewer-CAX-LlOl.js.gz +0 -0
  131. package/dist/web/assets/{system-monitor-body-CKoLYd_G.js → system-monitor-body-DcjbfTwC.js} +2 -2
  132. package/dist/web/assets/system-monitor-body-DcjbfTwC.js.br +0 -0
  133. package/dist/web/assets/system-monitor-body-DcjbfTwC.js.gz +0 -0
  134. package/dist/web/assets/{system-monitor-tab-CerUeEbU.js → system-monitor-tab-B5ctYgFG.js} +1 -1
  135. package/dist/web/assets/{system-monitor-window-content-CYFnoCgb.js → system-monitor-window-content-DsgNoxTw.js} +1 -1
  136. package/dist/web/assets/{tab-host-window-content-CloVeb9a.js → tab-host-window-content-0fmkEEGB.js} +1 -1
  137. package/dist/web/assets/tab-host-window-content-0fmkEEGB.js.br +0 -0
  138. package/dist/web/assets/tab-host-window-content-0fmkEEGB.js.gz +0 -0
  139. package/dist/web/assets/{team-member-sheet-BXmTXQCt.js → team-member-sheet-B-7tQLyM.js} +2 -2
  140. package/dist/web/assets/team-member-sheet-B-7tQLyM.js.br +0 -0
  141. package/dist/web/assets/team-member-sheet-B-7tQLyM.js.gz +0 -0
  142. package/dist/web/assets/{team-member-window-content-BST7Cs5l.js → team-member-window-content-Bb3ssjGY.js} +1 -1
  143. package/dist/web/assets/team-member-window-content-Bb3ssjGY.js.br +0 -0
  144. package/dist/web/assets/team-member-window-content-Bb3ssjGY.js.gz +0 -0
  145. package/dist/web/assets/{terminal-tab-BVZhZnTh.js → terminal-tab-Dilre-Mk.js} +1 -1
  146. package/dist/web/assets/terminal-tab-Dilre-Mk.js.br +0 -0
  147. package/dist/web/assets/terminal-tab-Dilre-Mk.js.gz +0 -0
  148. package/dist/web/assets/{tool-cards-F7hDZH6M.js → tool-cards-C-YxPo3q.js} +2 -2
  149. package/dist/web/assets/tool-cards-C-YxPo3q.js.br +0 -0
  150. package/dist/web/assets/tool-cards-C-YxPo3q.js.gz +0 -0
  151. package/dist/web/assets/{use-inline-blame-BmY9SN79.js → use-inline-blame-Co4lggO_.js} +1 -1
  152. package/dist/web/assets/use-inline-blame-Co4lggO_.js.br +0 -0
  153. package/dist/web/assets/use-inline-blame-Co4lggO_.js.gz +0 -0
  154. package/dist/web/assets/{use-lsp-CEq09fZR.js → use-lsp-D_2UVnaV.js} +1 -1
  155. package/dist/web/assets/use-lsp-D_2UVnaV.js.br +0 -0
  156. package/dist/web/assets/use-lsp-D_2UVnaV.js.gz +0 -0
  157. package/dist/web/assets/{use-monaco-theme-CBB5mAYT.js → use-monaco-theme-BFp0c8RX.js} +1 -1
  158. package/dist/web/assets/{use-websocket-BfuA8Guj.js → use-websocket-DXdXq2qa.js} +1 -1
  159. package/dist/web/assets/{video-preview-C9Aqfcru.js → video-preview-DMWtzyhn.js} +1 -1
  160. package/dist/web/assets/video-preview-DMWtzyhn.js.br +0 -0
  161. package/dist/web/assets/video-preview-DMWtzyhn.js.gz +0 -0
  162. package/dist/web/index.html +1 -1
  163. package/dist/web/index.html.br +0 -0
  164. package/dist/web/index.html.gz +0 -0
  165. package/dist/web/sw.js +1 -1
  166. package/dist/web/sw.js.br +0 -0
  167. package/dist/web/sw.js.gz +0 -0
  168. package/package.json +1 -1
  169. package/src/server/ws/chat.ts +19 -6
  170. package/src/types/api.ts +5 -3
  171. package/src/web/hooks/use-chat.ts +55 -6
  172. package/dist/web/assets/accounts-settings-section-DbJ7QQg4.js.br +0 -0
  173. package/dist/web/assets/accounts-settings-section-DbJ7QQg4.js.gz +0 -0
  174. package/dist/web/assets/ai-resource-editor-B24DvHYZ.js.br +0 -0
  175. package/dist/web/assets/ai-resource-editor-B24DvHYZ.js.gz +0 -0
  176. package/dist/web/assets/ai-settings-section-Bq1-gIlM.js.br +0 -0
  177. package/dist/web/assets/ai-settings-section-Bq1-gIlM.js.gz +0 -0
  178. package/dist/web/assets/appearance-settings-section-DEPNZnJ2.js.br +0 -0
  179. package/dist/web/assets/appearance-settings-section-DEPNZnJ2.js.gz +0 -0
  180. package/dist/web/assets/branch-review-tab-ruiWErmR.js.br +0 -0
  181. package/dist/web/assets/branch-review-tab-ruiWErmR.js.gz +0 -0
  182. package/dist/web/assets/chat-tab-BeBe2z3X.js +0 -15
  183. package/dist/web/assets/chat-tab-BeBe2z3X.js.br +0 -0
  184. package/dist/web/assets/chat-tab-BeBe2z3X.js.gz +0 -0
  185. package/dist/web/assets/code-editor-C7XqHn9o.js.br +0 -0
  186. package/dist/web/assets/code-editor-C7XqHn9o.js.gz +0 -0
  187. package/dist/web/assets/codex-daily-guard-DetGq_en.js.br +0 -0
  188. package/dist/web/assets/codex-daily-guard-DetGq_en.js.gz +0 -0
  189. package/dist/web/assets/conflict-editor-DHUpVDGB.js.br +0 -0
  190. package/dist/web/assets/conflict-editor-DHUpVDGB.js.gz +0 -0
  191. package/dist/web/assets/csv-preview-DXGt24yG.js.br +0 -0
  192. package/dist/web/assets/csv-preview-DXGt24yG.js.gz +0 -0
  193. package/dist/web/assets/database-viewer-zMGckF4c.js.br +0 -0
  194. package/dist/web/assets/database-viewer-zMGckF4c.js.gz +0 -0
  195. package/dist/web/assets/diff-viewer-D8ORwKJO.js.br +0 -0
  196. package/dist/web/assets/diff-viewer-D8ORwKJO.js.gz +0 -0
  197. package/dist/web/assets/editor-language-service-DlXOJKTM.js.br +0 -0
  198. package/dist/web/assets/editor-language-service-DlXOJKTM.js.gz +0 -0
  199. package/dist/web/assets/explorer-body-CvLKavSL.js.br +0 -0
  200. package/dist/web/assets/explorer-body-CvLKavSL.js.gz +0 -0
  201. package/dist/web/assets/explorer-window-content-DLPV_kMF.js.br +0 -0
  202. package/dist/web/assets/explorer-window-content-DLPV_kMF.js.gz +0 -0
  203. package/dist/web/assets/extension-manager-section-CAy3LVt7.js.br +0 -0
  204. package/dist/web/assets/extension-manager-section-CAy3LVt7.js.gz +0 -0
  205. package/dist/web/assets/extension-webview-BHg6PTCh.js.br +0 -0
  206. package/dist/web/assets/extension-webview-BHg6PTCh.js.gz +0 -0
  207. package/dist/web/assets/files-settings-section-ND3D08W7.js.br +0 -0
  208. package/dist/web/assets/files-settings-section-ND3D08W7.js.gz +0 -0
  209. package/dist/web/assets/general-settings-section-SJbTkh0b.js.br +0 -0
  210. package/dist/web/assets/general-settings-section-SJbTkh0b.js.gz +0 -0
  211. package/dist/web/assets/git-log-panel-_yL7W4EQ.js.br +0 -0
  212. package/dist/web/assets/git-log-panel-_yL7W4EQ.js.gz +0 -0
  213. package/dist/web/assets/glide-data-grid-CfH4uK1t.js.br +0 -0
  214. package/dist/web/assets/glide-data-grid-CfH4uK1t.js.gz +0 -0
  215. package/dist/web/assets/group-chat-tab-CprxuYA-.js.br +0 -0
  216. package/dist/web/assets/group-chat-tab-CprxuYA-.js.gz +0 -0
  217. package/dist/web/assets/index-8M7JWSZx.js.br +0 -0
  218. package/dist/web/assets/index-8M7JWSZx.js.gz +0 -0
  219. package/dist/web/assets/jira-watcher-section-_pTAalcO.js.br +0 -0
  220. package/dist/web/assets/jira-watcher-section-_pTAalcO.js.gz +0 -0
  221. package/dist/web/assets/keyboard-shortcuts-section-DpW1qIXk.js.br +0 -0
  222. package/dist/web/assets/keyboard-shortcuts-section-DpW1qIXk.js.gz +0 -0
  223. package/dist/web/assets/markdown-renderer-CjEg_HGP.js.br +0 -0
  224. package/dist/web/assets/mobile-explorer-sheet-DjeEB2i8.js.br +0 -0
  225. package/dist/web/assets/mobile-explorer-sheet-DjeEB2i8.js.gz +0 -0
  226. package/dist/web/assets/ppmbot-settings-section-ByROaaIk.js.br +0 -0
  227. package/dist/web/assets/ppmbot-settings-section-ByROaaIk.js.gz +0 -0
  228. package/dist/web/assets/problems-panel-D-iHH0j8.js.br +0 -0
  229. package/dist/web/assets/problems-panel-D-iHH0j8.js.gz +0 -0
  230. package/dist/web/assets/process-table-CSgGG2La.js.br +0 -0
  231. package/dist/web/assets/process-table-CSgGG2La.js.gz +0 -0
  232. package/dist/web/assets/proxy-settings-section-Cz98fxZn.js.br +0 -0
  233. package/dist/web/assets/proxy-settings-section-Cz98fxZn.js.gz +0 -0
  234. package/dist/web/assets/remote-desktop-clipboard-notice-fjTRSMfw.js.br +0 -0
  235. package/dist/web/assets/remote-desktop-clipboard-notice-fjTRSMfw.js.gz +0 -0
  236. package/dist/web/assets/remote-desktop-mobile-sheet-BGzXIOnN.js.br +0 -0
  237. package/dist/web/assets/remote-desktop-mobile-sheet-BGzXIOnN.js.gz +0 -0
  238. package/dist/web/assets/remote-desktop-mobile-view-DC-_I2st.js.br +0 -0
  239. package/dist/web/assets/remote-desktop-mobile-view-DC-_I2st.js.gz +0 -0
  240. package/dist/web/assets/remote-desktop-readiness-gate-BBFhTM_C.js.br +0 -0
  241. package/dist/web/assets/remote-desktop-readiness-gate-BBFhTM_C.js.gz +0 -0
  242. package/dist/web/assets/remote-desktop-window-content-S1LNG0iM.js.br +0 -0
  243. package/dist/web/assets/remote-desktop-window-content-S1LNG0iM.js.gz +0 -0
  244. package/dist/web/assets/schedules-settings-section-BERxYmYn.js.br +0 -0
  245. package/dist/web/assets/schedules-settings-section-BERxYmYn.js.gz +0 -0
  246. package/dist/web/assets/settings-body-C31PdcMj.js.br +0 -0
  247. package/dist/web/assets/settings-body-C31PdcMj.js.gz +0 -0
  248. package/dist/web/assets/sql-query-editor-BXaAQmLJ.js.br +0 -0
  249. package/dist/web/assets/sql-query-editor-BXaAQmLJ.js.gz +0 -0
  250. package/dist/web/assets/sqlite-viewer-DWpzKvve.js.br +0 -0
  251. package/dist/web/assets/sqlite-viewer-DWpzKvve.js.gz +0 -0
  252. package/dist/web/assets/system-monitor-body-CKoLYd_G.js.br +0 -0
  253. package/dist/web/assets/system-monitor-body-CKoLYd_G.js.gz +0 -0
  254. package/dist/web/assets/tab-host-window-content-CloVeb9a.js.br +0 -0
  255. package/dist/web/assets/tab-host-window-content-CloVeb9a.js.gz +0 -0
  256. package/dist/web/assets/team-member-sheet-BXmTXQCt.js.br +0 -0
  257. package/dist/web/assets/team-member-sheet-BXmTXQCt.js.gz +0 -0
  258. package/dist/web/assets/team-member-window-content-BST7Cs5l.js.br +0 -0
  259. package/dist/web/assets/team-member-window-content-BST7Cs5l.js.gz +0 -0
  260. package/dist/web/assets/terminal-tab-BVZhZnTh.js.br +0 -0
  261. package/dist/web/assets/terminal-tab-BVZhZnTh.js.gz +0 -0
  262. package/dist/web/assets/tool-cards-F7hDZH6M.js.br +0 -0
  263. package/dist/web/assets/tool-cards-F7hDZH6M.js.gz +0 -0
  264. package/dist/web/assets/use-inline-blame-BmY9SN79.js.br +0 -0
  265. package/dist/web/assets/use-inline-blame-BmY9SN79.js.gz +0 -0
  266. package/dist/web/assets/use-lsp-CEq09fZR.js.br +0 -0
  267. package/dist/web/assets/use-lsp-CEq09fZR.js.gz +0 -0
  268. package/dist/web/assets/video-preview-C9Aqfcru.js.br +0 -0
  269. package/dist/web/assets/video-preview-C9Aqfcru.js.gz +0 -0
@@ -1,4 +1,4 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import{n,s as r}from"./api-client-Jn3njtNw.js";import{i}from"./project-store-hNvwfqX3.js";import{Dt as a,en as o}from"./index-8M7JWSZx.js";`0`.repeat(40);function s(e){return/^0+$/.test(e)}function c(e,t=Date.now()){if(!e)return``;if(s(e.hash))return`You, uncommitted changes`;let n=e.author||`Unknown`,r=e.authorTime>0?l(e.authorTime*1e3,t):``,i=r?`${n}, ${r}`:n;return e.summary?`${i} • ${e.summary}`:i}function l(e,t=Date.now()){let n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return`just now`;for(let[e,t,r]of[[3600,60,`minute`],[86400,3600,`hour`],[2592e3,86400,`day`],[31536e3,2592e3,`month`],[1/0,31536e3,`year`]])if(n<e){let e=Math.floor(n/t);return`${e} ${r}${e===1?``:`s`} ago`}return`just now`}function u(e){let t=new Date(e),n=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],r=t.getDate(),i=t.getHours()%12||12,a=String(t.getMinutes()).padStart(2,`0`),o=t.getHours()<12?`AM`:`PM`;return`${n[t.getMonth()]} ${r}${d(r)}, ${t.getFullYear()} ${i}:${a} ${o}`}function d(e){return e%100>=11&&e%100<=13?`th`:[`th`,`st`,`nd`,`rd`][e%10]??`th`}var f=[`ppm.blame.copySha`,`ppm.blame.fileHistory`,`ppm.blame.blameFile`,`ppm.blame.showInGraph`],p=7;function m(e){return e.replace(/[\\`*_{}[\]()#+\-!<>]/g,e=>`\\${e}`)}function h(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?`?`:(t[0][0]+(t.length>1?t[t.length-1][0]:``)).toUpperCase()}var g=[`4E79A7`,`F28E2B`,`E15759`,`76B7B2`,`59A14F`,`AF7AA1`,`9C755F`,`B07AA1`];function _(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)|0;return g[Math.abs(t)%g.length]}function v(e){let t=`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="8" cy="8" r="8" fill="#${_(e)}"/><text x="8" y="11.5" font-family="sans-serif" font-size="7" font-weight="700" fill="#ffffff" text-anchor="middle">${y(h(e))}</text></svg>`;return`data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`}function y(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function b(e,t){return`command:${e}?${encodeURIComponent(JSON.stringify(t))}`}function x(e){let{commit:t,detail:n,filePath:r,projectPath:i,now:a=Date.now()}=e;if(s(t.hash))return null;let o=t.author||`Unknown`,c=t.hash.slice(0,p),d=[],h=t.authorTime>0?`${l(t.authorTime*1e3,a)} (${u(t.authorTime*1e3)})`:``;d.push(`![](${v(o)}) **${m(o)}**${h?` &nbsp;$(history) ${m(h)}`:``}`);let g=n?.message||t.summary;g&&(d.push(``),d.push(m(g).split(`
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import{n,s as r}from"./api-client-Jn3njtNw.js";import{i}from"./project-store-hNvwfqX3.js";import{Dt as a,en as o}from"./index-Dh3WkQrC.js";`0`.repeat(40);function s(e){return/^0+$/.test(e)}function c(e,t=Date.now()){if(!e)return``;if(s(e.hash))return`You, uncommitted changes`;let n=e.author||`Unknown`,r=e.authorTime>0?l(e.authorTime*1e3,t):``,i=r?`${n}, ${r}`:n;return e.summary?`${i} • ${e.summary}`:i}function l(e,t=Date.now()){let n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return`just now`;for(let[e,t,r]of[[3600,60,`minute`],[86400,3600,`hour`],[2592e3,86400,`day`],[31536e3,2592e3,`month`],[1/0,31536e3,`year`]])if(n<e){let e=Math.floor(n/t);return`${e} ${r}${e===1?``:`s`} ago`}return`just now`}function u(e){let t=new Date(e),n=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],r=t.getDate(),i=t.getHours()%12||12,a=String(t.getMinutes()).padStart(2,`0`),o=t.getHours()<12?`AM`:`PM`;return`${n[t.getMonth()]} ${r}${d(r)}, ${t.getFullYear()} ${i}:${a} ${o}`}function d(e){return e%100>=11&&e%100<=13?`th`:[`th`,`st`,`nd`,`rd`][e%10]??`th`}var f=[`ppm.blame.copySha`,`ppm.blame.fileHistory`,`ppm.blame.blameFile`,`ppm.blame.showInGraph`],p=7;function m(e){return e.replace(/[\\`*_{}[\]()#+\-!<>]/g,e=>`\\${e}`)}function h(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?`?`:(t[0][0]+(t.length>1?t[t.length-1][0]:``)).toUpperCase()}var g=[`4E79A7`,`F28E2B`,`E15759`,`76B7B2`,`59A14F`,`AF7AA1`,`9C755F`,`B07AA1`];function _(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)|0;return g[Math.abs(t)%g.length]}function v(e){let t=`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="8" cy="8" r="8" fill="#${_(e)}"/><text x="8" y="11.5" font-family="sans-serif" font-size="7" font-weight="700" fill="#ffffff" text-anchor="middle">${y(h(e))}</text></svg>`;return`data:image/svg+xml;charset=utf-8,${encodeURIComponent(t)}`}function y(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function b(e,t){return`command:${e}?${encodeURIComponent(JSON.stringify(t))}`}function x(e){let{commit:t,detail:n,filePath:r,projectPath:i,now:a=Date.now()}=e;if(s(t.hash))return null;let o=t.author||`Unknown`,c=t.hash.slice(0,p),d=[],h=t.authorTime>0?`${l(t.authorTime*1e3,a)} (${u(t.authorTime*1e3)})`:``;d.push(`![](${v(o)}) **${m(o)}**${h?` &nbsp;$(history) ${m(h)}`:``}`);let g=n?.message||t.summary;g&&(d.push(``),d.push(m(g).split(`
2
2
  `).join(`
3
3
  `)));let _=[``,`---`,``],y=[`[$(git-commit) ${c}](${b(`ppm.blame.copySha`,[t.hash])} "Copy commit hash")`];i&&y.push(`[$(history) File History](${b(`ppm.blame.fileHistory`,[i,r])} "Open the file's history")`,`[$(users) Blame](${b(`ppm.blame.blameFile`,[i,r])} "Open the blame view")`,`[$(git-branch) Graph](${b(`ppm.blame.showInGraph`,[i])} "Open the commit graph")`),d.push(..._),d.push(y.join(` &nbsp; `));let x=[...(n?.removed??[]).map(e=>`-${e}`),...(n?.added??[]).map(e=>`+${e}`)];if(x.length>0){d.push(..._),d.push("```diff"),d.push(...x),d.push("```"),d.push(``);let e=(n?.removed.length??0)===0?`added in`:`in`;d.push(`Changes ${e} \`${c}\``)}return{value:d.join(`
4
4
  `),isTrusted:{enabledCommands:[...f]},supportThemeIcons:!0}}var S=!1;function C(e,t){window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:t}}))}function w(e){return typeof e==`string`&&/^[0-9a-f]{7,40}$/.test(e)?e:null}function T(e){return typeof e==`string`&&e.length>0?e:null}function E(e,t,n){let r=T(t),i=T(n);!r||!i||C(e,[r,i])}function D(e){S||(S=!0,e.editor.registerCommand(`ppm.blame.copySha`,(e,t)=>{let n=w(t);n&&o(n).then(e=>{r[e?`success`:`error`](e?`Copied ${n.slice(0,7)}`:`Could not copy`)})}),e.editor.registerCommand(`ppm.blame.fileHistory`,(e,t,n)=>{E(`git-graph.fileHistory`,t,n)}),e.editor.registerCommand(`ppm.blame.blameFile`,(e,t,n)=>{E(`git-graph.blame`,t,n)}),e.editor.registerCommand(`ppm.blame.showInGraph`,(e,t)=>{let n=T(t);n&&C(`git-graph.view`,[n])}))}var O=`diff`,k=!1;function A(e){if(!k){if(e.languages.getLanguages().some(e=>e.id===`diff`)){k=!0;return}e.languages.register({id:O,aliases:[`Diff`,`patch`],extensions:[`.diff`,`.patch`]}),e.languages.setMonarchTokensProvider(O,{tokenizer:{root:[[/^diff .*$/,`meta.diff.header`],[/^(index|similarity index|rename from|rename to|new file mode|deleted file mode|old mode|new mode) .*$/,`meta.diff.header`],[/^(\+\+\+|---) .*$/,`meta.diff.header`],[/^@@.*$/,`meta.diff.range`],[/^\+.*$/,`inserted`],[/^-.*$/,`deleted`],[/^\\ .*$/,`meta.diff.header`],[/^.*$/,``]]}}),k=!0}}var j=e(t(),1),M=`inline-blame-styles`,N=`
@@ -1,4 +1,4 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-DmZ-Mb-H.js";import{i as n,n as r}from"./api-client-Jn3njtNw.js";import"./ws-auth-BG-cdrQ8.js";import{S as i,a}from"./index-8M7JWSZx.js";var o=e(t(),1),s=15e3;function c(e){clearTimeout(e.timer),e.detach?.()}var l=class{ws;docs=new Map;pending=new Map;notificationListeners=new Set;statusListeners=new Set;nextId=1;constructor(e){this.projectName=e,this.ws=new a(`/ws/project/${encodeURIComponent(e)}/lsp`),this.ws.onMessage(e=>this.receive(e)),this.ws.connect()}open(e,t){this.docs.set(e,{source:t,status:{state:`opening`}}),this.setStatus(e,{state:`opening`}),this.sendOpen(e)}sendOpen(e){let t=this.docs.get(e);t&&this.send({t:`open`,path:e,version:t.source.getVersion(),text:t.source.getText(),clientUri:t.source.clientUri})}close(e){this.docs.delete(e)&&this.send({t:`close`,path:e})}change(e,t,n){this.docs.has(e)&&this.send({t:`change`,path:e,version:t,changes:n})}save(e,t){this.docs.has(e)&&this.send({t:`save`,path:e,text:t})}statusOf(e){return this.docs.get(e)?.status}request(e,t,n,r={}){let i=this.docs.get(e);if(!i||i.status.state!==`ready`)return Promise.reject(Error(`No language server is ready for ${e}`));let{timeoutMs:a=s,signal:o}=r;if(o?.aborted)return Promise.reject(Error(`${t} was cancelled`));let c=this.nextId++;return new Promise((r,i)=>{let s=setTimeout(()=>{this.pending.delete(c),this.send({t:`cancel`,id:c}),i(Error(`${t} timed out`))},a),l=()=>{this.pending.delete(c)&&(clearTimeout(s),this.send({t:`cancel`,id:c}),i(Error(`${t} was cancelled`)))};o?.addEventListener(`abort`,l,{once:!0}),this.pending.set(c,{resolve:r,reject:i,timer:s,detach:o?()=>o.removeEventListener(`abort`,l):void 0}),this.send({t:`request`,id:c,path:e,method:t,params:n})})}onNotification(e){return this.notificationListeners.add(e),()=>this.notificationListeners.delete(e)}onStatus(e){return this.statusListeners.add(e),()=>this.statusListeners.delete(e)}send(e){this.ws.send(JSON.stringify(e))}receive(e){let t;try{t=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}switch(t.t){case`hello`:for(let e of this.docs.keys())this.sendOpen(e);break;case`ready`:this.setStatus(String(t.path),{state:`ready`,languageId:String(t.languageId),server:t.server,projectPath:String(t.projectPath??``),capabilities:t.capabilities??{}});break;case`unavailable`:this.setStatus(String(t.path),{state:`unavailable`,reason:String(t.reason),server:t.server??null,message:String(t.message)});break;case`resync`:{let e=String(t.path),n=this.docs.get(e);n&&this.send({t:`change`,path:e,version:n.source.getVersion(),text:n.source.getText()});break}case`response`:{let e=this.pending.get(Number(t.id));if(!e)return;c(e),this.pending.delete(Number(t.id)),e.resolve(t.result);break}case`error`:{let e=this.pending.get(Number(t.id));if(!e)return;c(e),this.pending.delete(Number(t.id)),e.reject(Error(String(t.message)));break}case`notification`:for(let e of this.notificationListeners)e(String(t.method),t.params);break}}setStatus(e,t){let n=this.docs.get(e);n&&(n.status=t);for(let n of this.statusListeners)n(e,t)}dispose(){for(let e of this.pending.values())c(e),e.reject(Error(`The language server connection was closed`));this.pending.clear(),this.docs.clear(),this.notificationListeners.clear(),this.statusListeners.clear(),this.ws.disconnect()}},u=new Map;function d(e){let t=u.get(e);if(t)return t.holders++,t.connection;let n=new l(e);return u.set(e,{connection:n,holders:1}),n}function f(e){let t=u.get(e);return!t||(t.holders--,t.holders>0)?!1:(u.delete(e),t.connection.dispose(),!0)}var p=new Map;function ee(e,t){p.set(e.uri.toString(),t)}function m(e){p.delete(e.uri.toString())}function h(e){return p.get(e.uri.toString())}function g(e){if(!e.startsWith(`file:`))return null;let t=e.slice(5),n=``;if(t.startsWith(`//`)){t=t.slice(2);let e=t.indexOf(`/`);n=e<0?t:t.slice(0,e),t=e<0?``:t.slice(e)}let r=t.split(`/`).map(_).join(`/`);return/^\/[A-Za-z]:/.test(r)?r.slice(1):n?`//${_(n)}${r}`:r}function _(e){try{return decodeURIComponent(e)}catch{return e}}var te=40,v=500,y=3,ne=6,b=new Map,x=new Map;function re(e){return(x.get(e)??0)>=y}function S(e){w(e,(x.get(e)??0)+1)}function C(e){w(e,y)}function w(e,t){for(x.delete(e),x.set(e,t);x.size>v;){let e=x.keys().next().value;if(e===void 0)return;x.delete(e)}}function T(e){x.delete(e)}async function ie(e,t,n){let r=0,i=Array.from({length:Math.min(t,e.length)},async()=>{for(;;){let t=r++;if(t>=e.length)return;await n(e[t])}});await Promise.all(i)}function ae(e,t){let n=e.replace(/\\/g,`/`).replace(/\/+$/,``),r=t.replace(/\\/g,`/`),i=n+`/`,a=/^[A-Za-z]:\//.test(i),o=r.slice(0,i.length);return(a?o.toLowerCase()!==i.toLowerCase():o!==i)?null:r.slice(i.length)}async function oe(e,t,i,a){if(!i)return;let o=new Set,s=[...new Set(a)].filter(t=>{if(re(t))return!1;let n=b.get(t);return n&&(b.delete(t),!n.isDisposed())?(b.set(t,n),o.add(t),!1):t.startsWith(`file:`)&&!e.editor.getModel(e.Uri.parse(t))});s.length!==0&&(await ie(s,ne,async a=>{try{let s=g(a),c=s?ae(i,s):null;if(!c){C(a);return}let l=(await r.get(`${n(t)}/files/read?path=${encodeURIComponent(c)}`))?.content;if(typeof l!=`string`){S(a);return}T(a);let u=e.Uri.parse(a);if(e.editor.getModel(u)){o.add(a);return}b.set(a,e.editor.createModel(l,void 0,u)),o.add(a)}catch{S(a)}}),se(o))}function se(e){for(let t of[...b.keys()]){if(b.size<=te)return;if(e.has(t))continue;let n=b.get(t);b.delete(t);try{n?.dispose()}catch{}}}function ce(){for(let e of b.values())try{e.dispose()}catch{}b.clear(),x.clear()}function E(e){if(!e)return;let t=new AbortController;return e.isCancellationRequested?t.abort():e.onCancellationRequested(()=>t.abort()),t.signal}function D(e){return{line:e.lineNumber-1,character:e.column-1}}function le(e){return{lineNumber:e.line+1,column:e.character+1}}function O(e){return{start:{line:e.startLineNumber-1,character:e.startColumn-1},end:{line:e.endLineNumber-1,character:e.endColumn-1}}}function k(e){return{startLineNumber:e.start.line+1,startColumn:e.start.character+1,endLineNumber:e.end.line+1,endColumn:e.end.character+1}}var ue={1:`Text`,2:`Method`,3:`Function`,4:`Constructor`,5:`Field`,6:`Variable`,7:`Class`,8:`Interface`,9:`Module`,10:`Property`,11:`Unit`,12:`Value`,13:`Enum`,14:`Keyword`,15:`Snippet`,16:`Color`,17:`File`,18:`Reference`,19:`Folder`,20:`EnumMember`,21:`Constant`,22:`Struct`,23:`Event`,24:`Operator`,25:`TypeParameter`},A={1:`File`,2:`Module`,3:`Namespace`,4:`Package`,5:`Class`,6:`Method`,7:`Property`,8:`Field`,9:`Constructor`,10:`Enum`,11:`Interface`,12:`Function`,13:`Variable`,14:`Constant`,15:`String`,16:`Number`,17:`Boolean`,18:`Array`,19:`Object`,20:`Key`,21:`Null`,22:`EnumMember`,23:`Struct`,24:`Event`,25:`Operator`,26:`TypeParameter`},j={1:`Error`,2:`Warning`,3:`Info`,4:`Hint`},M={1:`Text`,2:`Read`,3:`Write`};function N(e,t){let n=ue[t??0];return e.languages.CompletionItemKind[n??`Text`]}function P(e,t){let n=A[t??0];return e.languages.SymbolKind[n??`Variable`]}function F(e,t){let n=j[t??0];return e.MarkerSeverity[n??`Warning`]}function I(e,t){let n=M[t??0];return e.languages.DocumentHighlightKind[n??`Text`]}function L(e){if(e!=null){if(Array.isArray(e)){let t=e.map(L).filter(e=>!!e?.value);return t.length===0?void 0:{value:t.map(e=>e.value).join(`
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-DmZ-Mb-H.js";import{i as n,n as r}from"./api-client-Jn3njtNw.js";import"./ws-auth-BG-cdrQ8.js";import{S as i,a}from"./index-Dh3WkQrC.js";var o=e(t(),1),s=15e3;function c(e){clearTimeout(e.timer),e.detach?.()}var l=class{ws;docs=new Map;pending=new Map;notificationListeners=new Set;statusListeners=new Set;nextId=1;constructor(e){this.projectName=e,this.ws=new a(`/ws/project/${encodeURIComponent(e)}/lsp`),this.ws.onMessage(e=>this.receive(e)),this.ws.connect()}open(e,t){this.docs.set(e,{source:t,status:{state:`opening`}}),this.setStatus(e,{state:`opening`}),this.sendOpen(e)}sendOpen(e){let t=this.docs.get(e);t&&this.send({t:`open`,path:e,version:t.source.getVersion(),text:t.source.getText(),clientUri:t.source.clientUri})}close(e){this.docs.delete(e)&&this.send({t:`close`,path:e})}change(e,t,n){this.docs.has(e)&&this.send({t:`change`,path:e,version:t,changes:n})}save(e,t){this.docs.has(e)&&this.send({t:`save`,path:e,text:t})}statusOf(e){return this.docs.get(e)?.status}request(e,t,n,r={}){let i=this.docs.get(e);if(!i||i.status.state!==`ready`)return Promise.reject(Error(`No language server is ready for ${e}`));let{timeoutMs:a=s,signal:o}=r;if(o?.aborted)return Promise.reject(Error(`${t} was cancelled`));let c=this.nextId++;return new Promise((r,i)=>{let s=setTimeout(()=>{this.pending.delete(c),this.send({t:`cancel`,id:c}),i(Error(`${t} timed out`))},a),l=()=>{this.pending.delete(c)&&(clearTimeout(s),this.send({t:`cancel`,id:c}),i(Error(`${t} was cancelled`)))};o?.addEventListener(`abort`,l,{once:!0}),this.pending.set(c,{resolve:r,reject:i,timer:s,detach:o?()=>o.removeEventListener(`abort`,l):void 0}),this.send({t:`request`,id:c,path:e,method:t,params:n})})}onNotification(e){return this.notificationListeners.add(e),()=>this.notificationListeners.delete(e)}onStatus(e){return this.statusListeners.add(e),()=>this.statusListeners.delete(e)}send(e){this.ws.send(JSON.stringify(e))}receive(e){let t;try{t=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}switch(t.t){case`hello`:for(let e of this.docs.keys())this.sendOpen(e);break;case`ready`:this.setStatus(String(t.path),{state:`ready`,languageId:String(t.languageId),server:t.server,projectPath:String(t.projectPath??``),capabilities:t.capabilities??{}});break;case`unavailable`:this.setStatus(String(t.path),{state:`unavailable`,reason:String(t.reason),server:t.server??null,message:String(t.message)});break;case`resync`:{let e=String(t.path),n=this.docs.get(e);n&&this.send({t:`change`,path:e,version:n.source.getVersion(),text:n.source.getText()});break}case`response`:{let e=this.pending.get(Number(t.id));if(!e)return;c(e),this.pending.delete(Number(t.id)),e.resolve(t.result);break}case`error`:{let e=this.pending.get(Number(t.id));if(!e)return;c(e),this.pending.delete(Number(t.id)),e.reject(Error(String(t.message)));break}case`notification`:for(let e of this.notificationListeners)e(String(t.method),t.params);break}}setStatus(e,t){let n=this.docs.get(e);n&&(n.status=t);for(let n of this.statusListeners)n(e,t)}dispose(){for(let e of this.pending.values())c(e),e.reject(Error(`The language server connection was closed`));this.pending.clear(),this.docs.clear(),this.notificationListeners.clear(),this.statusListeners.clear(),this.ws.disconnect()}},u=new Map;function d(e){let t=u.get(e);if(t)return t.holders++,t.connection;let n=new l(e);return u.set(e,{connection:n,holders:1}),n}function f(e){let t=u.get(e);return!t||(t.holders--,t.holders>0)?!1:(u.delete(e),t.connection.dispose(),!0)}var p=new Map;function ee(e,t){p.set(e.uri.toString(),t)}function m(e){p.delete(e.uri.toString())}function h(e){return p.get(e.uri.toString())}function g(e){if(!e.startsWith(`file:`))return null;let t=e.slice(5),n=``;if(t.startsWith(`//`)){t=t.slice(2);let e=t.indexOf(`/`);n=e<0?t:t.slice(0,e),t=e<0?``:t.slice(e)}let r=t.split(`/`).map(_).join(`/`);return/^\/[A-Za-z]:/.test(r)?r.slice(1):n?`//${_(n)}${r}`:r}function _(e){try{return decodeURIComponent(e)}catch{return e}}var te=40,v=500,y=3,ne=6,b=new Map,x=new Map;function re(e){return(x.get(e)??0)>=y}function S(e){w(e,(x.get(e)??0)+1)}function C(e){w(e,y)}function w(e,t){for(x.delete(e),x.set(e,t);x.size>v;){let e=x.keys().next().value;if(e===void 0)return;x.delete(e)}}function T(e){x.delete(e)}async function ie(e,t,n){let r=0,i=Array.from({length:Math.min(t,e.length)},async()=>{for(;;){let t=r++;if(t>=e.length)return;await n(e[t])}});await Promise.all(i)}function ae(e,t){let n=e.replace(/\\/g,`/`).replace(/\/+$/,``),r=t.replace(/\\/g,`/`),i=n+`/`,a=/^[A-Za-z]:\//.test(i),o=r.slice(0,i.length);return(a?o.toLowerCase()!==i.toLowerCase():o!==i)?null:r.slice(i.length)}async function oe(e,t,i,a){if(!i)return;let o=new Set,s=[...new Set(a)].filter(t=>{if(re(t))return!1;let n=b.get(t);return n&&(b.delete(t),!n.isDisposed())?(b.set(t,n),o.add(t),!1):t.startsWith(`file:`)&&!e.editor.getModel(e.Uri.parse(t))});s.length!==0&&(await ie(s,ne,async a=>{try{let s=g(a),c=s?ae(i,s):null;if(!c){C(a);return}let l=(await r.get(`${n(t)}/files/read?path=${encodeURIComponent(c)}`))?.content;if(typeof l!=`string`){S(a);return}T(a);let u=e.Uri.parse(a);if(e.editor.getModel(u)){o.add(a);return}b.set(a,e.editor.createModel(l,void 0,u)),o.add(a)}catch{S(a)}}),se(o))}function se(e){for(let t of[...b.keys()]){if(b.size<=te)return;if(e.has(t))continue;let n=b.get(t);b.delete(t);try{n?.dispose()}catch{}}}function ce(){for(let e of b.values())try{e.dispose()}catch{}b.clear(),x.clear()}function E(e){if(!e)return;let t=new AbortController;return e.isCancellationRequested?t.abort():e.onCancellationRequested(()=>t.abort()),t.signal}function D(e){return{line:e.lineNumber-1,character:e.column-1}}function le(e){return{lineNumber:e.line+1,column:e.character+1}}function O(e){return{start:{line:e.startLineNumber-1,character:e.startColumn-1},end:{line:e.endLineNumber-1,character:e.endColumn-1}}}function k(e){return{startLineNumber:e.start.line+1,startColumn:e.start.character+1,endLineNumber:e.end.line+1,endColumn:e.end.character+1}}var ue={1:`Text`,2:`Method`,3:`Function`,4:`Constructor`,5:`Field`,6:`Variable`,7:`Class`,8:`Interface`,9:`Module`,10:`Property`,11:`Unit`,12:`Value`,13:`Enum`,14:`Keyword`,15:`Snippet`,16:`Color`,17:`File`,18:`Reference`,19:`Folder`,20:`EnumMember`,21:`Constant`,22:`Struct`,23:`Event`,24:`Operator`,25:`TypeParameter`},A={1:`File`,2:`Module`,3:`Namespace`,4:`Package`,5:`Class`,6:`Method`,7:`Property`,8:`Field`,9:`Constructor`,10:`Enum`,11:`Interface`,12:`Function`,13:`Variable`,14:`Constant`,15:`String`,16:`Number`,17:`Boolean`,18:`Array`,19:`Object`,20:`Key`,21:`Null`,22:`EnumMember`,23:`Struct`,24:`Event`,25:`Operator`,26:`TypeParameter`},j={1:`Error`,2:`Warning`,3:`Info`,4:`Hint`},M={1:`Text`,2:`Read`,3:`Write`};function N(e,t){let n=ue[t??0];return e.languages.CompletionItemKind[n??`Text`]}function P(e,t){let n=A[t??0];return e.languages.SymbolKind[n??`Variable`]}function F(e,t){let n=j[t??0];return e.MarkerSeverity[n??`Warning`]}function I(e,t){let n=M[t??0];return e.languages.DocumentHighlightKind[n??`Text`]}function L(e){if(e!=null){if(Array.isArray(e)){let t=e.map(L).filter(e=>!!e?.value);return t.length===0?void 0:{value:t.map(e=>e.value).join(`
2
2
 
3
3
  ---
4
4
 
@@ -1 +1 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import{t as n}from"./settings-store-DhU2tx3Y.js";import{r,t as i}from"./apply-theme-CbR31K6I.js";import{t as a}from"./resolve-theme-B_ukrg_8.js";import{s as o}from"./index-8M7JWSZx.js";var s=e(t(),1);function c(){let e=n(e=>e.themeStyle),t=n(e=>e.themeMode),c=n(e=>e.customThemeId),l=n(e=>e.customThemes),u=()=>o(r()??a(e,t,l,c)),[d,f]=(0,s.useState)(u);return(0,s.useEffect)(()=>{f(u());let e=()=>f(u());return window.addEventListener(i,e),()=>window.removeEventListener(i,e)},[e,t,c,l]),d}export{c as t};
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import{t as n}from"./settings-store-DhU2tx3Y.js";import{r,t as i}from"./apply-theme-CbR31K6I.js";import{t as a}from"./resolve-theme-B_ukrg_8.js";import{s as o}from"./index-Dh3WkQrC.js";var s=e(t(),1);function c(){let e=n(e=>e.themeStyle),t=n(e=>e.themeMode),c=n(e=>e.customThemeId),l=n(e=>e.customThemes),u=()=>o(r()??a(e,t,l,c)),[d,f]=(0,s.useState)(u);return(0,s.useEffect)(()=>{f(u());let e=()=>f(u());return window.addEventListener(i,e),()=>window.removeEventListener(i,e)},[e,t,c,l]),d}export{c as t};
@@ -1 +1 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import{a as n}from"./index-8M7JWSZx.js";var r=e(t(),1);function i({url:e,onMessage:t,autoConnect:i=!0,idleTimeoutMs:a,onConnectionChange:o}){let s=(0,r.useRef)(null),c=(0,r.useRef)(t),l=(0,r.useRef)(o);return c.current=t,l.current=o,(0,r.useEffect)(()=>{let t=!0,r=new n(e,{idleTimeoutMs:a,onConnectionChange:e=>{t&&l.current?.(e)}});return s.current=r,r.onMessage(e=>c.current?.(e)),i&&r.connect(),()=>{t=!1,r.disconnect(),s.current=null}},[e,i,a]),{send:(0,r.useCallback)(e=>{s.current?.send(e)},[]),connect:(0,r.useCallback)(()=>{s.current?.connect()},[]),disconnect:(0,r.useCallback)(()=>{s.current?.disconnect()},[])}}export{i as t};
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t}from"./vendor-markdown-CuWCHIVb.js";import{a as n}from"./index-Dh3WkQrC.js";var r=e(t(),1);function i({url:e,onMessage:t,autoConnect:i=!0,idleTimeoutMs:a,onConnectionChange:o}){let s=(0,r.useRef)(null),c=(0,r.useRef)(t),l=(0,r.useRef)(o);return c.current=t,l.current=o,(0,r.useEffect)(()=>{let t=!0,r=new n(e,{idleTimeoutMs:a,onConnectionChange:e=>{t&&l.current?.(e)}});return s.current=r,r.onMessage(e=>c.current?.(e)),i&&r.connect(),()=>{t=!1,r.disconnect(),s.current=null}},[e,i,a]),{send:(0,r.useCallback)(e=>{s.current?.send(e)},[]),connect:(0,r.useCallback)(()=>{s.current?.connect()},[]),disconnect:(0,r.useCallback)(()=>{s.current?.disconnect()},[])}}export{i as t};
@@ -1 +1 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t,S as n}from"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-DmZ-Mb-H.js";import{$n as r,Ct as i,Dr as a,Fr as o,Gn as s,Ir as c,Pr as l,Tt as u,er as d,ln as f,mn as p,or as m,st as h,xn as g,yt as _,zn as v}from"./icons-DQjqk0lJ.js";import"./api-client-Jn3njtNw.js";import"./portal-container-context-BarKmT4S.js";import{t as y}from"./button-B9CTrsEf.js";import{Bt as b,Gt as x,Ht as S,Kt as C,Ut as w,Wt as T,Zt as E,qt as D}from"./index-8M7JWSZx.js";import{o as O}from"./can-open-in-ppm-cv5--yHX.js";import{a as k,i as A,n as j,r as M,t as ee}from"./media-url-BmIBOO3z.js";var N=e(t(),1),P={rotation:0,flipH:!1,flipV:!1};function F(e){return{...e,rotation:(e.rotation+90)%360}}function te(e){return{...e,rotation:(e.rotation+270)%360}}function I(e){return e.rotation===0&&!e.flipH&&!e.flipV}function ne(e){let t=[];return e.rotation&&t.push(`rotate(${e.rotation}deg)`),e.flipH&&t.push(`scaleX(-1)`),e.flipV&&t.push(`scaleY(-1)`),t.length?t.join(` `):`none`}function re(e,t){return e.rotation===90||e.rotation===270?{maxWidth:t.height,maxHeight:t.width}:{maxWidth:t.width,maxHeight:t.height}}var L=[[`Space / K`,`Play / pause`],[`← / →`,`Seek 5s`],[`J / L or Shift+← / →`,`Seek 10s`],[`↑ / ↓`,`Volume`],[`M`,`Mute`],[`F`,`Fullscreen`],[`< / >`,`Speed`],[`R / Shift+R`,`Rotate`]];function R(e){return(0,N.useCallback)(t=>{let n=t.target;if(n.tagName===`INPUT`||n.tagName===`TEXTAREA`||n.isContentEditable||t.ctrlKey||t.metaKey||t.altKey)return;let r=!0;switch(t.key){case` `:case`k`:case`K`:e.togglePlay();break;case`ArrowLeft`:e.seekBy(t.shiftKey?-10:-5);break;case`ArrowRight`:e.seekBy(t.shiftKey?10:5);break;case`j`:case`J`:e.seekBy(-10);break;case`l`:case`L`:e.seekBy(10);break;case`ArrowUp`:e.volumeBy(.1);break;case`ArrowDown`:e.volumeBy(-.1);break;case`m`:case`M`:e.toggleMute();break;case`f`:case`F`:e.toggleFullscreen();break;case`<`:case`,`:e.speedStep(-1);break;case`>`:case`.`:e.speedStep(1);break;case`r`:e.rotate(1);break;case`R`:e.rotate(-1);break;default:r=!1}r&&t.preventDefault()},[e])}var z=n(),B=[.25,.5,.75,1,1.25,1.5,2,3];function V({speed:e,onSpeed:t,transform:n,onRotate:o,onFlipH:s,onFlipV:c,onResetTransform:l}){return(0,z.jsxs)(b,{children:[(0,z.jsx)(E,{asChild:!0,children:(0,z.jsxs)(y,{variant:`ghost`,size:`icon`,className:`size-11 shrink-0 relative`,"aria-label":`Playback settings`,children:[(0,z.jsx)(m,{className:`size-5`}),e!==1&&(0,z.jsxs)(`span`,{className:`absolute -top-0.5 -right-0.5 text-[10px] leading-none px-1 rounded bg-primary text-primary-foreground tabular-nums`,children:[e,`x`]})]})}),(0,z.jsxs)(S,{align:`end`,className:`w-60 max-h-[70vh] overflow-y-auto`,children:[(0,z.jsx)(T,{children:`Speed`}),(0,z.jsx)(x,{value:String(e),onValueChange:e=>t(Number(e)),children:(0,z.jsx)(`div`,{className:`grid grid-cols-4 gap-1 px-1 pb-1`,children:B.map(e=>(0,z.jsxs)(C,{value:String(e),className:`justify-center pl-2 min-h-11 text-xs tabular-nums data-[state=checked]:bg-accent [&>span:first-child]:hidden`,children:[e,`x`]},e))})}),(0,z.jsx)(D,{}),(0,z.jsx)(T,{children:`Orientation`}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),o(1)},children:[(0,z.jsx)(d,{className:`size-4`}),` Rotate right `,(0,z.jsx)(`span`,{className:`ml-auto text-xs text-text-subtle`,children:`R`})]}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),o(-1)},children:[(0,z.jsx)(r,{className:`size-4`}),` Rotate left `,(0,z.jsx)(`span`,{className:`ml-auto text-xs text-text-subtle`,children:`⇧R`})]}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),s()},children:[(0,z.jsx)(i,{className:`size-4`}),` Flip horizontal `,n.flipH&&(0,z.jsx)(`span`,{className:`ml-auto text-xs`,children:`✓`})]}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),c()},children:[(0,z.jsx)(u,{className:`size-4`}),` Flip vertical `,n.flipV&&(0,z.jsx)(`span`,{className:`ml-auto text-xs`,children:`✓`})]}),!I(n)&&(0,z.jsxs)(w,{className:`min-h-11`,onSelect:l,children:[(0,z.jsx)(a,{className:`size-4`}),` Reset orientation`]}),(0,z.jsx)(D,{}),(0,z.jsx)(T,{children:`Keyboard`}),(0,z.jsx)(`div`,{className:`px-2 pb-2 grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-xs text-text-secondary`,children:L.map(([e,t])=>(0,z.jsxs)(`div`,{className:`contents`,children:[(0,z.jsx)(`kbd`,{className:`font-mono text-text-subtle whitespace-nowrap`,children:e}),(0,z.jsx)(`span`,{children:t})]},e))})]})]})}function ie(e){let t=e.muted||e.volume===0?c:e.volume<.5?l:o,n=t=>e.onSeek(Number(t.target.value));return(0,z.jsxs)(`div`,{className:`flex items-center gap-1 px-2 py-1 bg-surface border-t border-border`,children:[(0,z.jsx)(y,{variant:`ghost`,size:`icon`,className:`size-11 shrink-0`,onClick:e.onTogglePlay,"aria-label":e.playing?`Pause`:`Play`,children:e.playing?(0,z.jsx)(v,{className:`size-5`}):(0,z.jsx)(s,{className:`size-5`})}),(0,z.jsxs)(`span`,{className:`text-xs tabular-nums text-text-secondary shrink-0 min-w-[4.5rem] text-center`,children:[H(e.position),e.duration?` / ${H(e.duration)}`:``]}),e.duration?(0,z.jsx)(`input`,{type:`range`,min:0,max:e.duration,step:.1,value:Math.min(e.position,e.duration),"aria-label":`Seek`,className:`flex-1 h-11 accent-primary cursor-pointer min-w-0`,onChange:t=>e.onScrub(Number(t.target.value)),onPointerUp:n,onKeyUp:n,onTouchEnd:n}):(0,z.jsx)(`div`,{className:`flex-1`}),(0,z.jsxs)(`div`,{className:`flex items-center shrink-0`,children:[(0,z.jsx)(y,{variant:`ghost`,size:`icon`,className:`size-11`,onClick:e.onToggleMute,"aria-label":e.muted?`Unmute`:`Mute`,children:(0,z.jsx)(t,{className:`size-5`})}),(0,z.jsx)(`input`,{type:`range`,min:0,max:1,step:.05,value:e.muted?0:e.volume,"aria-label":`Volume`,className:`hidden sm:block w-20 h-11 accent-primary cursor-pointer`,onChange:t=>e.onVolume(Number(t.target.value))})]}),(0,z.jsx)(V,{speed:e.speed,onSpeed:e.onSpeed,transform:e.transform,onRotate:e.onRotate,onFlipH:e.onFlipH,onFlipV:e.onFlipV,onResetTransform:e.onResetTransform}),(0,z.jsx)(y,{variant:`ghost`,size:`icon`,className:`size-11 shrink-0`,onClick:e.onToggleFullscreen,"aria-label":e.fullscreen?`Exit fullscreen`:`Fullscreen`,children:e.fullscreen?(0,z.jsx)(g,{className:`size-5`}):(0,z.jsx)(p,{className:`size-5`})})]})}function H(e){let t=Math.max(0,Math.floor(Number.isFinite(e)?e:0)),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=n?String(r).padStart(2,`0`):String(r);return`${n?`${n}:`:``}${a}:${String(i).padStart(2,`0`)}`}function U({filePath:e,projectName:t,mode:n,probeDuration:r=null,onNativeError:i}){let a=(0,N.useRef)(null),o=(0,N.useRef)(null),s=(0,N.useRef)(null),c=(0,N.useRef)(!0),[l]=(0,N.useState)(ee),[u,d]=(0,N.useState)(0),[p,m]=(0,N.useState)(0),[h,g]=(0,N.useState)(null),[_,v]=(0,N.useState)(!1),[b,x]=(0,N.useState)(!0),[S,C]=(0,N.useState)(null),[w,T]=(0,N.useState)(1),[E,D]=(0,N.useState)(!1),[O,j]=(0,N.useState)(1),[I,L]=(0,N.useState)(P),[V,H]=(0,N.useState)(!1),[U,W]=(0,N.useState)({width:0,height:0}),[G,K]=(0,N.useState)(null),q=n===`transcode`,J=q?k(e,t,u,l):M(e,t),Y=q?r:h,X=S??(q?u+p:p);(0,N.useEffect)(()=>{m(0),x(!0),K(null)},[J]),(0,N.useEffect)(()=>{d(0),g(null),L(P)},[e,n]),(0,N.useEffect)(()=>{let e=s.current;e&&(e.volume=w,e.muted=E)},[w,E]),(0,N.useEffect)(()=>{let e=s.current;e&&(e.playbackRate=O)},[O,J]),(0,N.useEffect)(()=>{let n=s.current,r=()=>{q&&A(e,t,l)};return window.addEventListener(`pagehide`,r),()=>{window.removeEventListener(`pagehide`,r),n&&!n.isConnected&&(n.pause(),n.removeAttribute(`src`),n.load(),r())}},[e,t,q,l]),(0,N.useEffect)(()=>{let e=()=>H(document.fullscreenElement===a.current);return document.addEventListener(`fullscreenchange`,e),()=>document.removeEventListener(`fullscreenchange`,e)},[]),(0,N.useEffect)(()=>{let e=o.current;if(!e)return;let t=new ResizeObserver(()=>W({width:e.clientWidth,height:e.clientHeight}));return t.observe(e),()=>t.disconnect()},[]);let Z=(0,N.useCallback)(e=>{let t=s.current,n=Math.max(0,Y?Math.min(e,Y-.5):e);if(C(null),!q){t&&(t.currentTime=n);return}Math.abs(n-(u+(t?.currentTime??0)))<.5||d(n)},[Y,q,u]),Q=(0,N.useMemo)(()=>({togglePlay:()=>{let e=s.current;e&&(c.current=e.paused,e.paused?e.play().catch(()=>{}):e.pause())},seekBy:e=>Z((q?u:0)+(s.current?.currentTime??0)+e),toggleFullscreen:()=>{document.fullscreenElement?document.exitFullscreen():a.current?.requestFullscreen?.()},toggleMute:()=>D(e=>!e),volumeBy:e=>{D(!1),T(t=>Math.min(1,Math.max(0,Math.round((t+e)*100)/100)))},speedStep:e=>j(t=>{let n=B.indexOf(t);return B[Math.min(B.length-1,Math.max(0,(n===-1?3:n)+e))]??1}),rotate:e=>L(t=>e===1?F(t):te(t))}),[Z,q,u]),ae=R(Q),$=re(I,U),oe=()=>{K(null),d(e=>e+.001)};return(0,z.jsxs)(`div`,{ref:a,"data-testid":`video-player`,tabIndex:0,onKeyDown:ae,className:`flex flex-col h-full bg-black outline-none focus-visible:ring-1 focus-visible:ring-primary/60`,children:[(0,z.jsxs)(`div`,{ref:o,className:`relative flex-1 min-h-0 flex items-center justify-center overflow-hidden`,onClick:e=>{a.current?.focus(),e.detail===1&&Q.togglePlay()},onDoubleClick:Q.toggleFullscreen,children:[(0,z.jsx)(`video`,{ref:s,src:J,autoPlay:!0,playsInline:!0,preload:q?`auto`:`metadata`,style:{transform:ne(I),maxWidth:$.maxWidth||void 0,maxHeight:$.maxHeight||void 0},onLoadedMetadata:e=>{let t=e.currentTarget;t.playbackRate=O,t.volume=w,t.muted=E,!q&&Number.isFinite(t.duration)&&g(t.duration),q&&!c.current&&t.pause()},onPlay:()=>v(!0),onPause:()=>v(!1),onWaiting:()=>x(!0),onPlaying:()=>x(!1),onCanPlay:()=>x(!1),onTimeUpdate:e=>m(e.currentTarget.currentTime),onEnded:()=>{v(!1),c.current=!1},onError:()=>{q?K(`Transcoding failed. ffmpeg may have stopped or the file is corrupt.`):i?.()}}),b&&!G&&(0,z.jsx)(f,{className:`absolute size-8 animate-spin text-white/80 pointer-events-none`}),G&&(0,z.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center gap-3 bg-black/85 text-text-secondary p-4 text-center`,onClick:e=>e.stopPropagation(),onDoubleClick:e=>e.stopPropagation(),children:[(0,z.jsx)(`p`,{className:`text-sm`,children:G}),(0,z.jsx)(y,{variant:`outline`,size:`sm`,className:`h-11 px-4`,onClick:oe,children:`Retry`})]})]}),(0,z.jsx)(ie,{playing:_,position:X,duration:Y,volume:w,muted:E,speed:O,transform:I,fullscreen:V,onTogglePlay:Q.togglePlay,onScrub:C,onSeek:Z,onVolume:e=>{T(e),D(e===0)},onToggleMute:Q.toggleMute,onSpeed:j,onRotate:Q.rotate,onFlipH:()=>L(e=>({...e,flipH:!e.flipH})),onFlipV:()=>L(e=>({...e,flipV:!e.flipV})),onResetTransform:()=>L(P),onToggleFullscreen:Q.toggleFullscreen})]})}var W=new Set([`mp4`,`m4v`,`webm`,`ogg`,`ogv`,`mov`]);function G({filePath:e,projectName:t}){let n=O(e),[r,i]=(0,N.useState)(()=>W.has(n)?{kind:`native`}:{kind:`probing`});return(0,N.useEffect)(()=>{i(W.has(O(e))?{kind:`native`}:{kind:`probing`})},[e]),(0,N.useEffect)(()=>{if(r.kind!==`probing`)return;let n=!1;return j(e,t).then(e=>{n||i(e.transcodable?{kind:`transcode`,probe:e}:{kind:`unsupported`,probe:e})}).catch(()=>{n||i({kind:`unsupported`,probe:null})}),()=>{n=!0}},[r.kind,e,t]),r.kind===`probing`?(0,z.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,z.jsx)(f,{className:`size-5 animate-spin text-text-subtle`})}):r.kind===`transcode`?(0,z.jsx)(U,{filePath:e,projectName:t,mode:`transcode`,probeDuration:r.probe.duration}):r.kind===`unsupported`?(0,z.jsx)(K,{filePath:e,projectName:t,probe:r.probe}):(0,z.jsx)(U,{filePath:e,projectName:t,mode:`native`,onNativeError:()=>i({kind:`probing`})})}function K({filePath:e,projectName:t,probe:n}){let r=[n?.video?.codec,n?.audio?.codec].filter(Boolean).join(` + `);return(0,z.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary p-6 text-center`,children:[(0,z.jsx)(_,{className:`size-10 text-text-subtle`}),(0,z.jsxs)(`p`,{className:`text-sm`,children:[`This video cannot be played in the browser`,r?` (${r})`:``,`.`]}),(0,z.jsxs)(`p`,{className:`text-xs text-text-subtle max-w-sm`,children:[`Install `,(0,z.jsx)(`code`,{children:`ffmpeg`}),` on the PPM server (e.g. `,(0,z.jsx)(`code`,{children:`winget install ffmpeg`}),`, `,(0,z.jsx)(`code`,{children:`brew install ffmpeg`}),`,`,` `,(0,z.jsx)(`code`,{children:`apt install ffmpeg`}),`) and restart PPM to transcode it on the fly.`]}),(0,z.jsx)(y,{asChild:!0,variant:`outline`,size:`sm`,className:`h-11 px-4`,children:(0,z.jsxs)(`a`,{href:`${M(e,t)}&download=true`,download:!0,children:[(0,z.jsx)(h,{className:`size-4 mr-2`}),` Download file`]})})]})}export{G as VideoPreview};
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t,S as n}from"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-DmZ-Mb-H.js";import{$n as r,Ct as i,Dr as a,Fr as o,Gn as s,Ir as c,Pr as l,Tt as u,er as d,ln as f,mn as p,or as m,st as h,xn as g,yt as _,zn as v}from"./icons-DQjqk0lJ.js";import"./api-client-Jn3njtNw.js";import"./portal-container-context-BarKmT4S.js";import{t as y}from"./button-B9CTrsEf.js";import{Bt as b,Gt as x,Ht as S,Kt as C,Ut as w,Wt as T,Zt as E,qt as D}from"./index-Dh3WkQrC.js";import{o as O}from"./can-open-in-ppm-cv5--yHX.js";import{a as k,i as A,n as j,r as M,t as ee}from"./media-url-BmIBOO3z.js";var N=e(t(),1),P={rotation:0,flipH:!1,flipV:!1};function F(e){return{...e,rotation:(e.rotation+90)%360}}function te(e){return{...e,rotation:(e.rotation+270)%360}}function I(e){return e.rotation===0&&!e.flipH&&!e.flipV}function ne(e){let t=[];return e.rotation&&t.push(`rotate(${e.rotation}deg)`),e.flipH&&t.push(`scaleX(-1)`),e.flipV&&t.push(`scaleY(-1)`),t.length?t.join(` `):`none`}function re(e,t){return e.rotation===90||e.rotation===270?{maxWidth:t.height,maxHeight:t.width}:{maxWidth:t.width,maxHeight:t.height}}var L=[[`Space / K`,`Play / pause`],[`← / →`,`Seek 5s`],[`J / L or Shift+← / →`,`Seek 10s`],[`↑ / ↓`,`Volume`],[`M`,`Mute`],[`F`,`Fullscreen`],[`< / >`,`Speed`],[`R / Shift+R`,`Rotate`]];function R(e){return(0,N.useCallback)(t=>{let n=t.target;if(n.tagName===`INPUT`||n.tagName===`TEXTAREA`||n.isContentEditable||t.ctrlKey||t.metaKey||t.altKey)return;let r=!0;switch(t.key){case` `:case`k`:case`K`:e.togglePlay();break;case`ArrowLeft`:e.seekBy(t.shiftKey?-10:-5);break;case`ArrowRight`:e.seekBy(t.shiftKey?10:5);break;case`j`:case`J`:e.seekBy(-10);break;case`l`:case`L`:e.seekBy(10);break;case`ArrowUp`:e.volumeBy(.1);break;case`ArrowDown`:e.volumeBy(-.1);break;case`m`:case`M`:e.toggleMute();break;case`f`:case`F`:e.toggleFullscreen();break;case`<`:case`,`:e.speedStep(-1);break;case`>`:case`.`:e.speedStep(1);break;case`r`:e.rotate(1);break;case`R`:e.rotate(-1);break;default:r=!1}r&&t.preventDefault()},[e])}var z=n(),B=[.25,.5,.75,1,1.25,1.5,2,3];function V({speed:e,onSpeed:t,transform:n,onRotate:o,onFlipH:s,onFlipV:c,onResetTransform:l}){return(0,z.jsxs)(b,{children:[(0,z.jsx)(E,{asChild:!0,children:(0,z.jsxs)(y,{variant:`ghost`,size:`icon`,className:`size-11 shrink-0 relative`,"aria-label":`Playback settings`,children:[(0,z.jsx)(m,{className:`size-5`}),e!==1&&(0,z.jsxs)(`span`,{className:`absolute -top-0.5 -right-0.5 text-[10px] leading-none px-1 rounded bg-primary text-primary-foreground tabular-nums`,children:[e,`x`]})]})}),(0,z.jsxs)(S,{align:`end`,className:`w-60 max-h-[70vh] overflow-y-auto`,children:[(0,z.jsx)(T,{children:`Speed`}),(0,z.jsx)(x,{value:String(e),onValueChange:e=>t(Number(e)),children:(0,z.jsx)(`div`,{className:`grid grid-cols-4 gap-1 px-1 pb-1`,children:B.map(e=>(0,z.jsxs)(C,{value:String(e),className:`justify-center pl-2 min-h-11 text-xs tabular-nums data-[state=checked]:bg-accent [&>span:first-child]:hidden`,children:[e,`x`]},e))})}),(0,z.jsx)(D,{}),(0,z.jsx)(T,{children:`Orientation`}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),o(1)},children:[(0,z.jsx)(d,{className:`size-4`}),` Rotate right `,(0,z.jsx)(`span`,{className:`ml-auto text-xs text-text-subtle`,children:`R`})]}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),o(-1)},children:[(0,z.jsx)(r,{className:`size-4`}),` Rotate left `,(0,z.jsx)(`span`,{className:`ml-auto text-xs text-text-subtle`,children:`⇧R`})]}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),s()},children:[(0,z.jsx)(i,{className:`size-4`}),` Flip horizontal `,n.flipH&&(0,z.jsx)(`span`,{className:`ml-auto text-xs`,children:`✓`})]}),(0,z.jsxs)(w,{className:`min-h-11`,onSelect:e=>{e.preventDefault(),c()},children:[(0,z.jsx)(u,{className:`size-4`}),` Flip vertical `,n.flipV&&(0,z.jsx)(`span`,{className:`ml-auto text-xs`,children:`✓`})]}),!I(n)&&(0,z.jsxs)(w,{className:`min-h-11`,onSelect:l,children:[(0,z.jsx)(a,{className:`size-4`}),` Reset orientation`]}),(0,z.jsx)(D,{}),(0,z.jsx)(T,{children:`Keyboard`}),(0,z.jsx)(`div`,{className:`px-2 pb-2 grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-xs text-text-secondary`,children:L.map(([e,t])=>(0,z.jsxs)(`div`,{className:`contents`,children:[(0,z.jsx)(`kbd`,{className:`font-mono text-text-subtle whitespace-nowrap`,children:e}),(0,z.jsx)(`span`,{children:t})]},e))})]})]})}function ie(e){let t=e.muted||e.volume===0?c:e.volume<.5?l:o,n=t=>e.onSeek(Number(t.target.value));return(0,z.jsxs)(`div`,{className:`flex items-center gap-1 px-2 py-1 bg-surface border-t border-border`,children:[(0,z.jsx)(y,{variant:`ghost`,size:`icon`,className:`size-11 shrink-0`,onClick:e.onTogglePlay,"aria-label":e.playing?`Pause`:`Play`,children:e.playing?(0,z.jsx)(v,{className:`size-5`}):(0,z.jsx)(s,{className:`size-5`})}),(0,z.jsxs)(`span`,{className:`text-xs tabular-nums text-text-secondary shrink-0 min-w-[4.5rem] text-center`,children:[H(e.position),e.duration?` / ${H(e.duration)}`:``]}),e.duration?(0,z.jsx)(`input`,{type:`range`,min:0,max:e.duration,step:.1,value:Math.min(e.position,e.duration),"aria-label":`Seek`,className:`flex-1 h-11 accent-primary cursor-pointer min-w-0`,onChange:t=>e.onScrub(Number(t.target.value)),onPointerUp:n,onKeyUp:n,onTouchEnd:n}):(0,z.jsx)(`div`,{className:`flex-1`}),(0,z.jsxs)(`div`,{className:`flex items-center shrink-0`,children:[(0,z.jsx)(y,{variant:`ghost`,size:`icon`,className:`size-11`,onClick:e.onToggleMute,"aria-label":e.muted?`Unmute`:`Mute`,children:(0,z.jsx)(t,{className:`size-5`})}),(0,z.jsx)(`input`,{type:`range`,min:0,max:1,step:.05,value:e.muted?0:e.volume,"aria-label":`Volume`,className:`hidden sm:block w-20 h-11 accent-primary cursor-pointer`,onChange:t=>e.onVolume(Number(t.target.value))})]}),(0,z.jsx)(V,{speed:e.speed,onSpeed:e.onSpeed,transform:e.transform,onRotate:e.onRotate,onFlipH:e.onFlipH,onFlipV:e.onFlipV,onResetTransform:e.onResetTransform}),(0,z.jsx)(y,{variant:`ghost`,size:`icon`,className:`size-11 shrink-0`,onClick:e.onToggleFullscreen,"aria-label":e.fullscreen?`Exit fullscreen`:`Fullscreen`,children:e.fullscreen?(0,z.jsx)(g,{className:`size-5`}):(0,z.jsx)(p,{className:`size-5`})})]})}function H(e){let t=Math.max(0,Math.floor(Number.isFinite(e)?e:0)),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=n?String(r).padStart(2,`0`):String(r);return`${n?`${n}:`:``}${a}:${String(i).padStart(2,`0`)}`}function U({filePath:e,projectName:t,mode:n,probeDuration:r=null,onNativeError:i}){let a=(0,N.useRef)(null),o=(0,N.useRef)(null),s=(0,N.useRef)(null),c=(0,N.useRef)(!0),[l]=(0,N.useState)(ee),[u,d]=(0,N.useState)(0),[p,m]=(0,N.useState)(0),[h,g]=(0,N.useState)(null),[_,v]=(0,N.useState)(!1),[b,x]=(0,N.useState)(!0),[S,C]=(0,N.useState)(null),[w,T]=(0,N.useState)(1),[E,D]=(0,N.useState)(!1),[O,j]=(0,N.useState)(1),[I,L]=(0,N.useState)(P),[V,H]=(0,N.useState)(!1),[U,W]=(0,N.useState)({width:0,height:0}),[G,K]=(0,N.useState)(null),q=n===`transcode`,J=q?k(e,t,u,l):M(e,t),Y=q?r:h,X=S??(q?u+p:p);(0,N.useEffect)(()=>{m(0),x(!0),K(null)},[J]),(0,N.useEffect)(()=>{d(0),g(null),L(P)},[e,n]),(0,N.useEffect)(()=>{let e=s.current;e&&(e.volume=w,e.muted=E)},[w,E]),(0,N.useEffect)(()=>{let e=s.current;e&&(e.playbackRate=O)},[O,J]),(0,N.useEffect)(()=>{let n=s.current,r=()=>{q&&A(e,t,l)};return window.addEventListener(`pagehide`,r),()=>{window.removeEventListener(`pagehide`,r),n&&!n.isConnected&&(n.pause(),n.removeAttribute(`src`),n.load(),r())}},[e,t,q,l]),(0,N.useEffect)(()=>{let e=()=>H(document.fullscreenElement===a.current);return document.addEventListener(`fullscreenchange`,e),()=>document.removeEventListener(`fullscreenchange`,e)},[]),(0,N.useEffect)(()=>{let e=o.current;if(!e)return;let t=new ResizeObserver(()=>W({width:e.clientWidth,height:e.clientHeight}));return t.observe(e),()=>t.disconnect()},[]);let Z=(0,N.useCallback)(e=>{let t=s.current,n=Math.max(0,Y?Math.min(e,Y-.5):e);if(C(null),!q){t&&(t.currentTime=n);return}Math.abs(n-(u+(t?.currentTime??0)))<.5||d(n)},[Y,q,u]),Q=(0,N.useMemo)(()=>({togglePlay:()=>{let e=s.current;e&&(c.current=e.paused,e.paused?e.play().catch(()=>{}):e.pause())},seekBy:e=>Z((q?u:0)+(s.current?.currentTime??0)+e),toggleFullscreen:()=>{document.fullscreenElement?document.exitFullscreen():a.current?.requestFullscreen?.()},toggleMute:()=>D(e=>!e),volumeBy:e=>{D(!1),T(t=>Math.min(1,Math.max(0,Math.round((t+e)*100)/100)))},speedStep:e=>j(t=>{let n=B.indexOf(t);return B[Math.min(B.length-1,Math.max(0,(n===-1?3:n)+e))]??1}),rotate:e=>L(t=>e===1?F(t):te(t))}),[Z,q,u]),ae=R(Q),$=re(I,U),oe=()=>{K(null),d(e=>e+.001)};return(0,z.jsxs)(`div`,{ref:a,"data-testid":`video-player`,tabIndex:0,onKeyDown:ae,className:`flex flex-col h-full bg-black outline-none focus-visible:ring-1 focus-visible:ring-primary/60`,children:[(0,z.jsxs)(`div`,{ref:o,className:`relative flex-1 min-h-0 flex items-center justify-center overflow-hidden`,onClick:e=>{a.current?.focus(),e.detail===1&&Q.togglePlay()},onDoubleClick:Q.toggleFullscreen,children:[(0,z.jsx)(`video`,{ref:s,src:J,autoPlay:!0,playsInline:!0,preload:q?`auto`:`metadata`,style:{transform:ne(I),maxWidth:$.maxWidth||void 0,maxHeight:$.maxHeight||void 0},onLoadedMetadata:e=>{let t=e.currentTarget;t.playbackRate=O,t.volume=w,t.muted=E,!q&&Number.isFinite(t.duration)&&g(t.duration),q&&!c.current&&t.pause()},onPlay:()=>v(!0),onPause:()=>v(!1),onWaiting:()=>x(!0),onPlaying:()=>x(!1),onCanPlay:()=>x(!1),onTimeUpdate:e=>m(e.currentTarget.currentTime),onEnded:()=>{v(!1),c.current=!1},onError:()=>{q?K(`Transcoding failed. ffmpeg may have stopped or the file is corrupt.`):i?.()}}),b&&!G&&(0,z.jsx)(f,{className:`absolute size-8 animate-spin text-white/80 pointer-events-none`}),G&&(0,z.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center gap-3 bg-black/85 text-text-secondary p-4 text-center`,onClick:e=>e.stopPropagation(),onDoubleClick:e=>e.stopPropagation(),children:[(0,z.jsx)(`p`,{className:`text-sm`,children:G}),(0,z.jsx)(y,{variant:`outline`,size:`sm`,className:`h-11 px-4`,onClick:oe,children:`Retry`})]})]}),(0,z.jsx)(ie,{playing:_,position:X,duration:Y,volume:w,muted:E,speed:O,transform:I,fullscreen:V,onTogglePlay:Q.togglePlay,onScrub:C,onSeek:Z,onVolume:e=>{T(e),D(e===0)},onToggleMute:Q.toggleMute,onSpeed:j,onRotate:Q.rotate,onFlipH:()=>L(e=>({...e,flipH:!e.flipH})),onFlipV:()=>L(e=>({...e,flipV:!e.flipV})),onResetTransform:()=>L(P),onToggleFullscreen:Q.toggleFullscreen})]})}var W=new Set([`mp4`,`m4v`,`webm`,`ogg`,`ogv`,`mov`]);function G({filePath:e,projectName:t}){let n=O(e),[r,i]=(0,N.useState)(()=>W.has(n)?{kind:`native`}:{kind:`probing`});return(0,N.useEffect)(()=>{i(W.has(O(e))?{kind:`native`}:{kind:`probing`})},[e]),(0,N.useEffect)(()=>{if(r.kind!==`probing`)return;let n=!1;return j(e,t).then(e=>{n||i(e.transcodable?{kind:`transcode`,probe:e}:{kind:`unsupported`,probe:e})}).catch(()=>{n||i({kind:`unsupported`,probe:null})}),()=>{n=!0}},[r.kind,e,t]),r.kind===`probing`?(0,z.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,z.jsx)(f,{className:`size-5 animate-spin text-text-subtle`})}):r.kind===`transcode`?(0,z.jsx)(U,{filePath:e,projectName:t,mode:`transcode`,probeDuration:r.probe.duration}):r.kind===`unsupported`?(0,z.jsx)(K,{filePath:e,projectName:t,probe:r.probe}):(0,z.jsx)(U,{filePath:e,projectName:t,mode:`native`,onNativeError:()=>i({kind:`probing`})})}function K({filePath:e,projectName:t,probe:n}){let r=[n?.video?.codec,n?.audio?.codec].filter(Boolean).join(` + `);return(0,z.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary p-6 text-center`,children:[(0,z.jsx)(_,{className:`size-10 text-text-subtle`}),(0,z.jsxs)(`p`,{className:`text-sm`,children:[`This video cannot be played in the browser`,r?` (${r})`:``,`.`]}),(0,z.jsxs)(`p`,{className:`text-xs text-text-subtle max-w-sm`,children:[`Install `,(0,z.jsx)(`code`,{children:`ffmpeg`}),` on the PPM server (e.g. `,(0,z.jsx)(`code`,{children:`winget install ffmpeg`}),`, `,(0,z.jsx)(`code`,{children:`brew install ffmpeg`}),`,`,` `,(0,z.jsx)(`code`,{children:`apt install ffmpeg`}),`) and restart PPM to transcode it on the fly.`]}),(0,z.jsx)(y,{asChild:!0,variant:`outline`,size:`sm`,className:`h-11 px-4`,children:(0,z.jsxs)(`a`,{href:`${M(e,t)}&download=true`,download:!0,children:[(0,z.jsx)(h,{className:`size-4 mr-2`}),` Download file`]})})]})}export{G as VideoPreview};
@@ -9,7 +9,7 @@
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com" />
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
11
  <link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600;700&family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
12
- <script type="module" crossorigin src="/assets/index-8M7JWSZx.js"></script>
12
+ <script type="module" crossorigin src="/assets/index-Dh3WkQrC.js"></script>
13
13
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-FhOqtrmT.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-BitiXJlL.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/vendor-markdown-CuWCHIVb.js">
Binary file
Binary file
package/dist/web/sw.js CHANGED
@@ -1 +1 @@
1
- try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}var B=`-precache-`,V=async(e,t=B)=>{let n=(await self.caches.keys()).filter(n=>n.includes(t)&&n.includes(self.registration.scope)&&n!==e);return await Promise.all(n.map(e=>self.caches.delete(e))),n};function H(){self.addEventListener(`activate`,(e=>{let t=a.getPrecacheName();e.waitUntil(V(t).then(e=>{}))}))}function U(e){O().precache(e)}function W(e,t){U(e),z(t)}var G=class extends w{async _handle(e,n){let r=await n.cacheMatch(e),i;if(!r)try{r=await n.fetchAndCachePut(e)}catch(e){e instanceof Error&&(i=e)}if(!r)throw new t(`no-response`,{url:e.url,error:i});return r}};W([{"revision":"804a5c60d7798b266ab577754b149c86","url":"index.html"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":null,"url":"assets/index-CWL5emyr.css"},{"revision":null,"url":"assets/index-8M7JWSZx.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"}]),H();var K=e=>(e.headers.get(`content-type`)??``).startsWith(`text/html`);F(({url:e})=>e.pathname.startsWith(`/assets/`),new G({cacheName:`ppm-assets`,plugins:[{cacheWillUpdate:async({response:e})=>K(e)?null:e,cachedResponseWillBeUsed:async({cachedResponse:e})=>e&&K(e)?null:e}]})),self.skipWaiting(),self.addEventListener(`activate`,()=>{self.clients.claim()});
1
+ try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}var B=`-precache-`,V=async(e,t=B)=>{let n=(await self.caches.keys()).filter(n=>n.includes(t)&&n.includes(self.registration.scope)&&n!==e);return await Promise.all(n.map(e=>self.caches.delete(e))),n};function H(){self.addEventListener(`activate`,(e=>{let t=a.getPrecacheName();e.waitUntil(V(t).then(e=>{}))}))}function U(e){O().precache(e)}function W(e,t){U(e),z(t)}var G=class extends w{async _handle(e,n){let r=await n.cacheMatch(e),i;if(!r)try{r=await n.fetchAndCachePut(e)}catch(e){e instanceof Error&&(i=e)}if(!r)throw new t(`no-response`,{url:e.url,error:i});return r}};W([{"revision":"2f6e0a7b6320b1fcab16c65ce3a51298","url":"index.html"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":null,"url":"assets/index-Dh3WkQrC.js"},{"revision":null,"url":"assets/index-CWL5emyr.css"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"}]),H();var K=e=>(e.headers.get(`content-type`)??``).startsWith(`text/html`);F(({url:e})=>e.pathname.startsWith(`/assets/`),new G({cacheName:`ppm-assets`,plugins:[{cacheWillUpdate:async({response:e})=>K(e)?null:e,cachedResponseWillBeUsed:async({cachedResponse:e})=>e&&K(e)?null:e}]})),self.skipWaiting(),self.addEventListener(`activate`,()=>{self.clients.claim()});
package/dist/web/sw.js.br CHANGED
Binary file
package/dist/web/sw.js.gz CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.22.3",
3
+ "version": "0.22.4",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -48,7 +48,7 @@ function resolveSessionThinkingEnabled(sessionId: string): boolean {
48
48
  );
49
49
  }
50
50
 
51
- const PING_INTERVAL_MS = 15_000; // 15s keepalive
51
+ const PING_INTERVAL_MS = 5_000; // Detect an active stream gap promptly through a tunnel.
52
52
  /**
53
53
  * When an abandoned session's entry is dropped.
54
54
  *
@@ -120,6 +120,8 @@ interface SessionEntry {
120
120
  backgroundToolUseIds?: Set<string>;
121
121
  /** Nested-agent children buffered into turnEvents this turn (see MAX_NESTED_TURN_EVENTS) */
122
122
  nestedBuffered?: number;
123
+ /** Monotonic sequence for streamed events, used to detect a downstream content gap. */
124
+ streamSeq: number;
123
125
  /** When the last client left, for evicting the least recently used warm subprocess */
124
126
  idleSince?: number;
125
127
  /** When the last turn completed — the moment this session's prompt cache was last written */
@@ -320,9 +322,12 @@ function bufferAndBroadcast(sessionId: string, event: unknown): void {
320
322
  const entry = activeSessions.get(sessionId);
321
323
  if (!entry) return;
322
324
  const evType = (event as any)?.type;
325
+ const streamed = evType && BUFFERABLE_TYPES.has(evType)
326
+ ? { ...(event as Record<string, unknown>), streamSeq: ++entry.streamSeq }
327
+ : event;
323
328
  if (evType && BUFFERABLE_TYPES.has(evType)) {
324
329
  if (entry.turnEvents.length < MAX_TURN_EVENTS) {
325
- entry.turnEvents.push({ ...(event as Record<string, unknown>) });
330
+ entry.turnEvents.push(streamed);
326
331
  }
327
332
  // Enrich: embed tool_result onto matching tool_use for reconnect reliability.
328
333
  // Reconnecting clients may miss separate tool_result events — this ensures
@@ -340,7 +345,7 @@ function bufferAndBroadcast(sessionId: string, event: unknown): void {
340
345
  }
341
346
  }
342
347
  }
343
- broadcast(sessionId, event);
348
+ broadcast(sessionId, streamed);
344
349
  }
345
350
 
346
351
  /**
@@ -453,11 +458,18 @@ function setPhase(sessionId: string, phase: SessionPhase, elapsed?: number): voi
453
458
  function sendTurnEvents(sessionId: string, ws: ChatWsSocket): void {
454
459
  const entry = activeSessions.get(sessionId);
455
460
  if (!entry || entry.turnEvents.length === 0) return;
461
+ const lastBufferedSeq = (entry.turnEvents[entry.turnEvents.length - 1] as { streamSeq?: number } | undefined)?.streamSeq ?? 0;
462
+ const truncated = lastBufferedSeq < entry.streamSeq;
456
463
  try {
457
464
  ws.send(JSON.stringify({
458
465
  type: "turn_events",
459
466
  events: entry.turnEvents,
460
467
  userMessage: entry.currentUserMessage ?? null,
468
+ // This is an authoritative full snapshot, not a delta. `truncated` tells
469
+ // the client it must wait for the normal idle history reload to recover
470
+ // frames beyond the bounded replay buffer.
471
+ streamSeq: entry.streamSeq,
472
+ ...(truncated ? { truncated: true } : {}),
461
473
  }));
462
474
  } catch (e) {
463
475
  console.warn(`[chat] session=${sessionId} sendTurnEvents failed: ${(e as Error).message}`);
@@ -467,7 +479,7 @@ function sendTurnEvents(sessionId: string, ws: ChatWsSocket): void {
467
479
  /** Set up per-client application-level ping */
468
480
  function setupClientPing(entry: SessionEntry, ws: ChatWsSocket): void {
469
481
  const interval = setInterval(() => {
470
- try { ws.send(JSON.stringify({ type: "ping" })); } catch { /* ws may be closed */ }
482
+ try { ws.send(JSON.stringify({ type: "ping", streamSeq: entry.streamSeq })); } catch { /* ws may be closed */ }
471
483
  }, PING_INTERVAL_MS);
472
484
  entry.pingIntervals.set(ws, interval);
473
485
  }
@@ -1033,6 +1045,7 @@ export const chatWebSocket = {
1033
1045
  phase: "idle",
1034
1046
  turnEvents: [],
1035
1047
  isStreamingActive: false,
1048
+ streamSeq: 0,
1036
1049
  teamWatchers: new Map(),
1037
1050
  teamNames: new Set(),
1038
1051
  compactStatus: null,
@@ -1093,7 +1106,7 @@ export const chatWebSocket = {
1093
1106
  if (pn) { try { pp = resolveProjectPath(pn); } catch { /* ignore */ } }
1094
1107
  const newEntry: SessionEntry = {
1095
1108
  providerId: pid, clients: new Set([ws]), projectPath: pp, projectName: pn,
1096
- pingIntervals: new Map(), phase: "idle", turnEvents: [], isStreamingActive: false,
1109
+ pingIntervals: new Map(), phase: "idle", turnEvents: [], isStreamingActive: false, streamSeq: 0,
1097
1110
  teamWatchers: new Map(), teamNames: new Set(), compactStatus: null,
1098
1111
  model: getSessionModel(sessionId) ?? undefined,
1099
1112
  };
@@ -1113,7 +1126,7 @@ export const chatWebSocket = {
1113
1126
  // Client-initiated handshake — FE sends "ready" after onopen.
1114
1127
  // Re-send status so tunnel connections (Cloudflare) that missed the
1115
1128
  // open-handler message still get connected/status confirmation.
1116
- if (parsed.type === "ready") {
1129
+ if (parsed.type === "ready" || parsed.type === "resync") {
1117
1130
  ws.send(JSON.stringify({
1118
1131
  type: "session_state",
1119
1132
  sessionId,
package/src/types/api.ts CHANGED
@@ -32,7 +32,9 @@ export type ChatWsClientMessage =
32
32
  | { type: "set_thinking"; enabled: boolean }
33
33
  | { type: "approval_response"; requestId: string; approved: boolean; reason?: string; data?: unknown }
34
34
  | { type: "kill_background_shell"; shellId: string }
35
- | { type: "ready" };
35
+ | { type: "ready" }
36
+ /** Replay an in-progress turn after a downstream WebSocket content gap. */
37
+ | { type: "resync" };
36
38
 
37
39
  /** A background command (SDK Bash run_in_background) tracked for the current session. */
38
40
  export interface BackgroundShell {
@@ -72,8 +74,8 @@ export type ChatWsServerMessage =
72
74
  | { type: "account_info"; accountId: string; accountLabel: string }
73
75
  | { type: "phase_changed"; phase: SessionPhase; elapsed?: number }
74
76
  | { type: "session_state"; sessionId: string; phase: SessionPhase; pendingApproval: { requestId: string; tool: string; input: unknown } | null; sessionTitle: string | null; model?: string; effort?: string; thinking?: boolean }
75
- | { type: "turn_events"; events: unknown[] }
77
+ | { type: "turn_events"; events: unknown[]; streamSeq?: number; truncated?: boolean }
76
78
  | { type: "user_message"; content: string; imageCount?: number; timestamp?: string }
77
79
  | { type: "title_updated"; title: string }
78
80
  | { type: "compact_status"; status: "compacting" | "done" }
79
- | { type: "ping" };
81
+ | { type: "ping"; streamSeq?: number };
@@ -199,6 +199,12 @@ export function useChat(
199
199
  const turnFinalizedRef = useRef(false);
200
200
  const historyRequestRef = useRef<AbortController | null>(null);
201
201
  const queuedReplayMessagesRef = useRef<MessageEvent[]>([]);
202
+ /** Highest streamed event sequence received from the server for this session. */
203
+ const streamSeqRef = useRef(0);
204
+ /** A full replay is already on its way; do not flood snapshots for one gap. */
205
+ const resyncInFlightRef = useRef(false);
206
+ /** The bounded server replay omitted an old prefix; idle history reload repairs it. */
207
+ const replayTruncatedRef = useRef(false);
202
208
  const handleMessageRef = useRef<((event: MessageEvent) => void) | null>(null);
203
209
  /** True while replaying turn_events — suppresses setPendingApproval */
204
210
  const isReplayingRef = useRef(false);
@@ -777,14 +783,41 @@ export function useChat(
777
783
  return;
778
784
  }
779
785
 
780
- // Ignore keepalive pings
781
- if ((data as any).type === "ping") return;
782
-
783
786
  if (isReplayingRef.current) {
784
787
  queuedReplayMessagesRef.current.push(event);
785
788
  return;
786
789
  }
787
790
 
791
+ // A ping carries the latest stream sequence. If it is ahead of what the tab
792
+ // has seen, request the server's in-flight buffer immediately. This catches
793
+ // a tunnel that keeps heartbeats alive while dropping content frames.
794
+ if ((data as any).type === "ping") {
795
+ const serverSeq = (data as any).streamSeq;
796
+ if (typeof serverSeq === "number" && serverSeq > streamSeqRef.current
797
+ && !resyncInFlightRef.current && !replayTruncatedRef.current) {
798
+ resyncInFlightRef.current = true;
799
+ sendRef.current(JSON.stringify({ type: "resync" }));
800
+ }
801
+ return;
802
+ }
803
+
804
+ // Live stream frames must be contiguous. A higher number is evidence that
805
+ // a tunnel/proxy skipped a content frame; request one full snapshot and let
806
+ // the replay establish the authoritative cursor below.
807
+ const streamSeq = (data as any).streamSeq;
808
+ if (typeof streamSeq === "number") {
809
+ if (replayTruncatedRef.current) {
810
+ // The prefix is unavailable from the bounded buffer. Continue showing
811
+ // fresh frames and let the normal idle transcript reload fill the gap.
812
+ streamSeqRef.current = Math.max(streamSeqRef.current, streamSeq);
813
+ } else if (streamSeq === streamSeqRef.current + 1) {
814
+ streamSeqRef.current = streamSeq;
815
+ } else if (streamSeq > streamSeqRef.current && !resyncInFlightRef.current) {
816
+ resyncInFlightRef.current = true;
817
+ sendRef.current(JSON.stringify({ type: "resync" }));
818
+ }
819
+ }
820
+
788
821
  // file:changed, session:unread_changed and jira:* are app-wide and now arrive
789
822
  // on the global bus (`use-global-events.ts`) instead of here — a chat socket is
790
823
  // not guaranteed to exist since chat tabs mount lazily.
@@ -860,11 +893,14 @@ export function useChat(
860
893
  // Safety: idle phase means no turn running — ensure compact indicator does not linger.
861
894
  // BE should broadcast compact_status=done too, but this is a belt-and-braces clear.
862
895
  if (p === "idle") {
896
+ const replayWasTruncated = replayTruncatedRef.current;
897
+ resyncInFlightRef.current = false;
898
+ replayTruncatedRef.current = false;
863
899
  setCompactStatus(null);
864
900
  setStatusMessage(null);
865
901
  // Completion can arrive after lost content/done frames. Reconcile once
866
902
  // the turn is idle so the answer appears without a manual reload.
867
- if (wasActive && !turnFinalizedRef.current) refetchRef.current?.();
903
+ if (replayWasTruncated || (wasActive && !turnFinalizedRef.current)) refetchRef.current?.();
868
904
  }
869
905
  return;
870
906
  }
@@ -921,8 +957,11 @@ export function useChat(
921
957
  // connects right after the mount fetch and this refetch would re-download
922
958
  // the entire history (and remount every transcript image) for no reason.
923
959
  if (p === "idle") {
960
+ const replayWasTruncated = replayTruncatedRef.current;
961
+ resyncInFlightRef.current = false;
962
+ replayTruncatedRef.current = false;
924
963
  const historyFresh = Date.now() - historyLoadedAtRef.current < 5000;
925
- if (!(wasIdle && historyFresh)) refetchRef.current?.();
964
+ if (replayWasTruncated || !(wasIdle && historyFresh)) refetchRef.current?.();
926
965
  setIsReconnecting(false);
927
966
  }
928
967
  // If streaming, turn_events message will follow
@@ -997,6 +1036,13 @@ export function useChat(
997
1036
  } else {
998
1037
  replayRafRef.current = 0;
999
1038
  isReplayingRef.current = false;
1039
+ const snapshotSeq = (data as any).streamSeq;
1040
+ const truncated = (data as any).truncated === true;
1041
+ replayTruncatedRef.current = truncated;
1042
+ if (!truncated && typeof snapshotSeq === "number") {
1043
+ streamSeqRef.current = snapshotSeq;
1044
+ }
1045
+ resyncInFlightRef.current = false;
1000
1046
  setIsReconnecting(false);
1001
1047
  // Preserve websocket order: live text/done must follow the snapshot,
1002
1048
  // even when rebuilding a large snapshot takes several frames.
@@ -1021,7 +1067,7 @@ export function useChat(
1021
1067
  url: wsUrl,
1022
1068
  onMessage: handleMessage,
1023
1069
  autoConnect: !!sessionId && !!projectName,
1024
- idleTimeoutMs: 45_000, // Server sends a heartbeat every 15 seconds.
1070
+ idleTimeoutMs: 45_000, // Server sends a heartbeat every 5 seconds.
1025
1071
  onConnectionChange: (connected) => {
1026
1072
  if (!connected) {
1027
1073
  attemptRef.current?.fail();
@@ -1042,6 +1088,9 @@ export function useChat(
1042
1088
  const historyReconciled = historyReconciledRef.current;
1043
1089
  turnFinalizedRef.current = false;
1044
1090
  historyActivityRef.current++;
1091
+ streamSeqRef.current = 0;
1092
+ resyncInFlightRef.current = false;
1093
+ replayTruncatedRef.current = false;
1045
1094
 
1046
1095
  // Keep the user's unconfirmed model/thinking picks across the draft→real transition
1047
1096
  // (null → id), but drop them when switching between two existing sessions so one