@hienlh/ppm 0.23.17 → 0.23.19

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 (437) hide show
  1. package/CHANGELOG.md +12 -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-BqsI4Ixj.js → accounts-settings-section-BTga1zwH.js} +1 -1
  6. package/dist/web/assets/accounts-settings-section-BTga1zwH.js.br +0 -0
  7. package/dist/web/assets/accounts-settings-section-BTga1zwH.js.gz +0 -0
  8. package/dist/web/assets/{agent-session-sheet-BmoNB8BG.js → agent-session-sheet-Q3kasbrZ.js} +2 -2
  9. package/dist/web/assets/agent-session-sheet-Q3kasbrZ.js.br +0 -0
  10. package/dist/web/assets/agent-session-sheet-Q3kasbrZ.js.gz +0 -0
  11. package/dist/web/assets/{agent-session-window-content-rlCrYBYv.js → agent-session-window-content-UNuEprIK.js} +1 -1
  12. package/dist/web/assets/agent-session-window-content-UNuEprIK.js.br +0 -0
  13. package/dist/web/assets/agent-session-window-content-UNuEprIK.js.gz +0 -0
  14. package/dist/web/assets/{ai-resource-editor-CUOR9Xtf.js → ai-resource-editor-BEwA6Do0.js} +1 -1
  15. package/dist/web/assets/ai-resource-editor-BEwA6Do0.js.br +0 -0
  16. package/dist/web/assets/ai-resource-editor-BEwA6Do0.js.gz +0 -0
  17. package/dist/web/assets/{ai-settings-section-CNdbcCaI.js → ai-settings-section-DVKJPM0n.js} +1 -1
  18. package/dist/web/assets/ai-settings-section-DVKJPM0n.js.br +0 -0
  19. package/dist/web/assets/ai-settings-section-DVKJPM0n.js.gz +0 -0
  20. package/dist/web/assets/{ai-settings-section-aXXTb0dN.js → ai-settings-section-DlfY5lFT.js} +1 -1
  21. package/dist/web/assets/{android-tab-BsuTMKJw.js → android-tab-BNa6R9fV.js} +1 -1
  22. package/dist/web/assets/android-tab-BNa6R9fV.js.br +0 -0
  23. package/dist/web/assets/android-tab-BNa6R9fV.js.gz +0 -0
  24. package/dist/web/assets/{appearance-settings-section-Dk6d_fTo.js → appearance-settings-section-CjWFwWNn.js} +1 -1
  25. package/dist/web/assets/appearance-settings-section-CjWFwWNn.js.br +0 -0
  26. package/dist/web/assets/appearance-settings-section-CjWFwWNn.js.gz +0 -0
  27. package/dist/web/assets/{apps-panel-C20ys4Cy.js → apps-panel-D4xjeMN9.js} +1 -1
  28. package/dist/web/assets/apps-panel-D4xjeMN9.js.br +0 -0
  29. package/dist/web/assets/apps-panel-D4xjeMN9.js.gz +0 -0
  30. package/dist/web/assets/{branch-review-tab-CcvkQMRA.js → branch-review-tab-BCW5294d.js} +1 -1
  31. package/dist/web/assets/branch-review-tab-BCW5294d.js.br +0 -0
  32. package/dist/web/assets/branch-review-tab-BCW5294d.js.gz +0 -0
  33. package/dist/web/assets/{chat-tab-BAh37UwG.js → chat-tab-BG0M1D3d.js} +1 -1
  34. package/dist/web/assets/chat-tab-BG0M1D3d.js.br +3 -0
  35. package/dist/web/assets/chat-tab-BG0M1D3d.js.gz +0 -0
  36. package/dist/web/assets/{chat-tab-D-cl4yMo.js → chat-tab-DsW93LTL.js} +3 -3
  37. package/dist/web/assets/chat-tab-DsW93LTL.js.br +0 -0
  38. package/dist/web/assets/chat-tab-DsW93LTL.js.gz +0 -0
  39. package/dist/web/assets/{code-editor-DIGsPNPS.js → code-editor-AxLIpK-b.js} +4 -4
  40. package/dist/web/assets/code-editor-AxLIpK-b.js.br +0 -0
  41. package/dist/web/assets/code-editor-AxLIpK-b.js.gz +0 -0
  42. package/dist/web/assets/{codex-reset-credit-button-C0a2svAw.js → codex-reset-credit-button-BnRmkBZu.js} +1 -1
  43. package/dist/web/assets/codex-reset-credit-button-BnRmkBZu.js.br +0 -0
  44. package/dist/web/assets/{codex-reset-credit-button-C0a2svAw.js.gz → codex-reset-credit-button-BnRmkBZu.js.gz} +0 -0
  45. package/dist/web/assets/{conflict-editor-zORSNMk6.js → conflict-editor-BwuNUPAK.js} +1 -1
  46. package/dist/web/assets/conflict-editor-BwuNUPAK.js.br +0 -0
  47. package/dist/web/assets/conflict-editor-BwuNUPAK.js.gz +0 -0
  48. package/dist/web/assets/{connection-form-tab-BkE7wACA.js → connection-form-tab-CM2o80eB.js} +1 -1
  49. package/dist/web/assets/connection-form-tab-CM2o80eB.js.br +0 -0
  50. package/dist/web/assets/connection-form-tab-CM2o80eB.js.gz +0 -0
  51. package/dist/web/assets/{csv-preview-CDUY0I94.js → csv-preview-C7ErHm4U.js} +1 -1
  52. package/dist/web/assets/csv-preview-C7ErHm4U.js.br +0 -0
  53. package/dist/web/assets/csv-preview-C7ErHm4U.js.gz +0 -0
  54. package/dist/web/assets/{db-tab-parts-tgVIgcs5.js → db-tab-parts-C8jbkfxO.js} +1 -1
  55. package/dist/web/assets/db-tab-parts-C8jbkfxO.js.br +0 -0
  56. package/dist/web/assets/db-tab-parts-C8jbkfxO.js.gz +0 -0
  57. package/dist/web/assets/{design-settings-section-CqFPwhis.js → design-settings-section-BcGEY4Zf.js} +1 -1
  58. package/dist/web/assets/design-settings-section-BcGEY4Zf.js.br +0 -0
  59. package/dist/web/assets/design-settings-section-BcGEY4Zf.js.gz +0 -0
  60. package/dist/web/assets/{design-tab-CVTzge3p.js → design-tab-BGPYNFvy.js} +1 -1
  61. package/dist/web/assets/design-tab-BGPYNFvy.js.br +0 -0
  62. package/dist/web/assets/design-tab-BGPYNFvy.js.gz +0 -0
  63. package/dist/web/assets/{designs-sidebar-panel-DKTSE1LS.js → designs-sidebar-panel-BgMj7xRm.js} +1 -1
  64. package/dist/web/assets/designs-sidebar-panel-BgMj7xRm.js.br +0 -0
  65. package/dist/web/assets/designs-sidebar-panel-BgMj7xRm.js.gz +0 -0
  66. package/dist/web/assets/{diff-viewer-3VDHcDag.js → diff-viewer-BKJkesHk.js} +1 -1
  67. package/dist/web/assets/diff-viewer-BKJkesHk.js.br +0 -0
  68. package/dist/web/assets/diff-viewer-BKJkesHk.js.gz +0 -0
  69. package/dist/web/assets/{docx-preview-FgE_WU6t.js → docx-preview-DD5oD_nL.js} +1 -1
  70. package/dist/web/assets/docx-preview-DD5oD_nL.js.br +0 -0
  71. package/dist/web/assets/docx-preview-DD5oD_nL.js.gz +0 -0
  72. package/dist/web/assets/{editor-dialog-BhK77FSu.js → editor-dialog--07lKJxl.js} +1 -1
  73. package/dist/web/assets/editor-dialog--07lKJxl.js.br +0 -0
  74. package/dist/web/assets/editor-dialog--07lKJxl.js.gz +0 -0
  75. package/dist/web/assets/{editor-language-service-BIN7M57r.js → editor-language-service-51xjO5d3.js} +1 -1
  76. package/dist/web/assets/editor-language-service-51xjO5d3.js.br +0 -0
  77. package/dist/web/assets/editor-language-service-51xjO5d3.js.gz +0 -0
  78. package/dist/web/assets/{explorer-body-DNsWiVO3.js → explorer-body-BXK5SjJQ.js} +1 -1
  79. package/dist/web/assets/explorer-body-BXK5SjJQ.js.br +0 -0
  80. package/dist/web/assets/explorer-body-BXK5SjJQ.js.gz +0 -0
  81. package/dist/web/assets/{explorer-window-content-DnOJYhRX.js → explorer-window-content-DKXcCmuX.js} +1 -1
  82. package/dist/web/assets/explorer-window-content-DKXcCmuX.js.br +0 -0
  83. package/dist/web/assets/explorer-window-content-DKXcCmuX.js.gz +0 -0
  84. package/dist/web/assets/{extension-manager-section-CJtRpUUs.js → extension-manager-section-CTpQP6te.js} +1 -1
  85. package/dist/web/assets/extension-manager-section-CTpQP6te.js.br +0 -0
  86. package/dist/web/assets/extension-manager-section-CTpQP6te.js.gz +0 -0
  87. package/dist/web/assets/{extension-webview-Bza7cPL1.js → extension-webview-COT-yLrM.js} +1 -1
  88. package/dist/web/assets/extension-webview-COT-yLrM.js.br +0 -0
  89. package/dist/web/assets/extension-webview-COT-yLrM.js.gz +0 -0
  90. package/dist/web/assets/{files-settings-section-8rWMj1Oi.js → files-settings-section-CgVR0fqi.js} +1 -1
  91. package/dist/web/assets/files-settings-section-CgVR0fqi.js.br +0 -0
  92. package/dist/web/assets/files-settings-section-CgVR0fqi.js.gz +0 -0
  93. package/dist/web/assets/{general-settings-section-joWQEgIn.js → general-settings-section-BEMIbE4Y.js} +1 -1
  94. package/dist/web/assets/general-settings-section-BEMIbE4Y.js.br +0 -0
  95. package/dist/web/assets/general-settings-section-BEMIbE4Y.js.gz +0 -0
  96. package/dist/web/assets/{git-log-panel-BxYYWEiU.js → git-log-panel-Cp2174iI.js} +1 -1
  97. package/dist/web/assets/git-log-panel-Cp2174iI.js.br +0 -0
  98. package/dist/web/assets/git-log-panel-Cp2174iI.js.gz +0 -0
  99. package/dist/web/assets/{git-review-tab-Btnvgk1e.js → git-review-tab-CpMJ0qDi.js} +1 -1
  100. package/dist/web/assets/git-review-tab-CpMJ0qDi.js.br +0 -0
  101. package/dist/web/assets/git-review-tab-CpMJ0qDi.js.gz +0 -0
  102. package/dist/web/assets/{glide-data-grid-lCwaM1Gy.js → glide-data-grid-BAhwWUhO.js} +1 -1
  103. package/dist/web/assets/glide-data-grid-BAhwWUhO.js.br +0 -0
  104. package/dist/web/assets/glide-data-grid-BAhwWUhO.js.gz +0 -0
  105. package/dist/web/assets/{grid-save-dialog-DoEEQ1vM.js → grid-save-dialog-DmJhaWOl.js} +1 -1
  106. package/dist/web/assets/grid-save-dialog-DmJhaWOl.js.br +0 -0
  107. package/dist/web/assets/grid-save-dialog-DmJhaWOl.js.gz +0 -0
  108. package/dist/web/assets/{group-chat-tab-B7Dwx9uL.js → group-chat-tab-Bq7-Yegf.js} +1 -1
  109. package/dist/web/assets/group-chat-tab-Bq7-Yegf.js.br +0 -0
  110. package/dist/web/assets/group-chat-tab-Bq7-Yegf.js.gz +0 -0
  111. package/dist/web/assets/{impexp-tab-BtEDbQSn.js → impexp-tab-COx3Cvs7.js} +1 -1
  112. package/dist/web/assets/impexp-tab-COx3Cvs7.js.br +0 -0
  113. package/dist/web/assets/impexp-tab-COx3Cvs7.js.gz +0 -0
  114. package/dist/web/assets/{index-CPBujJc_.js → index-BGk8EFQb.js} +5 -5
  115. package/dist/web/assets/index-BGk8EFQb.js.br +0 -0
  116. package/dist/web/assets/index-BGk8EFQb.js.gz +0 -0
  117. package/dist/web/assets/{jira-watcher-section-mnly-maX.js → jira-watcher-section-BEPbsi62.js} +1 -1
  118. package/dist/web/assets/{keybindings-store-BSPTMRiv.js → keybindings-store-DzcSIJUF.js} +1 -1
  119. package/dist/web/assets/{keyboard-shortcuts-section-DULhEWPg.js → keyboard-shortcuts-section-Bqg7AZiZ.js} +1 -1
  120. package/dist/web/assets/keyboard-shortcuts-section-Bqg7AZiZ.js.br +0 -0
  121. package/dist/web/assets/keyboard-shortcuts-section-Bqg7AZiZ.js.gz +0 -0
  122. package/dist/web/assets/{language-servers-section-CwBJsJ31.js → language-servers-section-CJ47DSIA.js} +2 -2
  123. package/dist/web/assets/language-servers-section-CJ47DSIA.js.br +0 -0
  124. package/dist/web/assets/language-servers-section-CJ47DSIA.js.gz +0 -0
  125. package/dist/web/assets/{logs-app-DatfI2Up.js → logs-app-BK-n-y_K.js} +1 -1
  126. package/dist/web/assets/logs-app-BK-n-y_K.js.br +0 -0
  127. package/dist/web/assets/logs-app-BK-n-y_K.js.gz +0 -0
  128. package/dist/web/assets/{logs-tab-an_9ujcz.js → logs-tab-B84EZJ1b.js} +1 -1
  129. package/dist/web/assets/{logs-window-content-Usr3JTmE.js → logs-window-content-B1uN_3pN.js} +1 -1
  130. package/dist/web/assets/{lsp-client-tCCcXWsR.js → lsp-client-DHSaAyJW.js} +1 -1
  131. package/dist/web/assets/lsp-client-DHSaAyJW.js.br +0 -0
  132. package/dist/web/assets/lsp-client-DHSaAyJW.js.gz +0 -0
  133. package/dist/web/assets/{markdown-renderer-DdzxNveP.js → markdown-renderer-BjDQUqT-.js} +1 -1
  134. package/dist/web/assets/{markdown-renderer-D0YUMQLE.js → markdown-renderer-CpxdNG0f.js} +1 -1
  135. package/dist/web/assets/markdown-renderer-CpxdNG0f.js.br +0 -0
  136. package/dist/web/assets/markdown-renderer-CpxdNG0f.js.gz +0 -0
  137. package/dist/web/assets/{mobile-explorer-sheet-Bo27IRye.js → mobile-explorer-sheet-BBwXGmXA.js} +1 -1
  138. package/dist/web/assets/mobile-explorer-sheet-BBwXGmXA.js.br +0 -0
  139. package/dist/web/assets/mobile-explorer-sheet-BBwXGmXA.js.gz +0 -0
  140. package/dist/web/assets/{new-design-dialog-DIOCWZW1.js → new-design-dialog-B_ZOvGhR.js} +1 -1
  141. package/dist/web/assets/new-design-dialog-B_ZOvGhR.js.br +0 -0
  142. package/dist/web/assets/new-design-dialog-B_ZOvGhR.js.gz +0 -0
  143. package/dist/web/assets/{notification-store-CRPOp-6B.js → notification-store-HuMqfadD.js} +1 -1
  144. package/dist/web/assets/{notifications-settings-section-DSSCTkfX.js → notifications-settings-section-D7fIVFHe.js} +1 -1
  145. package/dist/web/assets/notifications-settings-section-D7fIVFHe.js.br +0 -0
  146. package/dist/web/assets/notifications-settings-section-D7fIVFHe.js.gz +0 -0
  147. package/dist/web/assets/{ppmbot-settings-section-BIYSlZu5.js → ppmbot-settings-section-JDvyI-gZ.js} +1 -1
  148. package/dist/web/assets/ppmbot-settings-section-JDvyI-gZ.js.br +0 -0
  149. package/dist/web/assets/ppmbot-settings-section-JDvyI-gZ.js.gz +0 -0
  150. package/dist/web/assets/{problems-panel-CH-00nA7.js → problems-panel-Bsv_L6T2.js} +1 -1
  151. package/dist/web/assets/problems-panel-Bsv_L6T2.js.br +0 -0
  152. package/dist/web/assets/problems-panel-Bsv_L6T2.js.gz +0 -0
  153. package/dist/web/assets/{process-table-DQO0g5do.js → process-table-3kZyWOJx.js} +1 -1
  154. package/dist/web/assets/process-table-3kZyWOJx.js.br +0 -0
  155. package/dist/web/assets/process-table-3kZyWOJx.js.gz +0 -0
  156. package/dist/web/assets/{proxy-settings-section-Buo3hvQ4.js → proxy-settings-section-CYcmIp7W.js} +1 -1
  157. package/dist/web/assets/proxy-settings-section-CYcmIp7W.js.br +0 -0
  158. package/dist/web/assets/proxy-settings-section-CYcmIp7W.js.gz +0 -0
  159. package/dist/web/assets/{query-tab-CU0QVZpj.js → query-tab-CjrWnQUl.js} +1 -1
  160. package/dist/web/assets/query-tab-CjrWnQUl.js.br +0 -0
  161. package/dist/web/assets/query-tab-CjrWnQUl.js.gz +0 -0
  162. package/dist/web/assets/{remote-access-settings-section-vlHMJPdY.js → remote-access-settings-section-iQkakiVx.js} +1 -1
  163. package/dist/web/assets/remote-access-settings-section-iQkakiVx.js.br +0 -0
  164. package/dist/web/assets/remote-access-settings-section-iQkakiVx.js.gz +0 -0
  165. package/dist/web/assets/{remote-desktop-clipboard-notice-DNqX7d1L.js → remote-desktop-clipboard-notice-CFLnb7ML.js} +1 -1
  166. package/dist/web/assets/remote-desktop-clipboard-notice-CFLnb7ML.js.br +0 -0
  167. package/dist/web/assets/remote-desktop-clipboard-notice-CFLnb7ML.js.gz +0 -0
  168. package/dist/web/assets/{remote-desktop-mobile-sheet-Dz7tctpc.js → remote-desktop-mobile-sheet-C_-_-Nkz.js} +2 -2
  169. package/dist/web/assets/remote-desktop-mobile-sheet-C_-_-Nkz.js.br +0 -0
  170. package/dist/web/assets/remote-desktop-mobile-sheet-C_-_-Nkz.js.gz +0 -0
  171. package/dist/web/assets/{remote-desktop-mobile-view-BqhQdShH.js → remote-desktop-mobile-view-BnHSrind.js} +1 -1
  172. package/dist/web/assets/remote-desktop-mobile-view-BnHSrind.js.br +0 -0
  173. package/dist/web/assets/remote-desktop-mobile-view-BnHSrind.js.gz +0 -0
  174. package/dist/web/assets/{remote-desktop-readiness-gate-rnTq4ZQS.js → remote-desktop-readiness-gate-BGHJ7Sv6.js} +1 -1
  175. package/dist/web/assets/remote-desktop-readiness-gate-BGHJ7Sv6.js.br +0 -0
  176. package/dist/web/assets/remote-desktop-readiness-gate-BGHJ7Sv6.js.gz +0 -0
  177. package/dist/web/assets/{remote-desktop-window-content-TqjHt0_5.js → remote-desktop-window-content-BBm1YwM8.js} +1 -1
  178. package/dist/web/assets/remote-desktop-window-content-BBm1YwM8.js.br +0 -0
  179. package/dist/web/assets/remote-desktop-window-content-BBm1YwM8.js.gz +0 -0
  180. package/dist/web/assets/{rename-object-dialog-D0YpY40E.js → rename-object-dialog-BLnF9xyn.js} +1 -1
  181. package/dist/web/assets/rename-object-dialog-BLnF9xyn.js.br +0 -0
  182. package/dist/web/assets/rename-object-dialog-BLnF9xyn.js.gz +0 -0
  183. package/dist/web/assets/{review-code-DsF9921h.js → review-code-DG7sCIzr.js} +1 -1
  184. package/dist/web/assets/review-code-DG7sCIzr.js.br +0 -0
  185. package/dist/web/assets/review-code-DG7sCIzr.js.gz +0 -0
  186. package/dist/web/assets/{save-as-dialog-niU7kVMJ.js → save-as-dialog-KW7cErWh.js} +1 -1
  187. package/dist/web/assets/save-as-dialog-KW7cErWh.js.br +0 -0
  188. package/dist/web/assets/save-as-dialog-KW7cErWh.js.gz +0 -0
  189. package/dist/web/assets/{schedules-settings-section-Heuv2Kj4.js → schedules-settings-section-B4AV4ORv.js} +1 -1
  190. package/dist/web/assets/schedules-settings-section-B4AV4ORv.js.br +0 -0
  191. package/dist/web/assets/schedules-settings-section-B4AV4ORv.js.gz +0 -0
  192. package/dist/web/assets/{session-review-tab-Dob0FLvA.js → session-review-tab-C5nPyBzo.js} +1 -1
  193. package/dist/web/assets/session-review-tab-C5nPyBzo.js.br +0 -0
  194. package/dist/web/assets/session-review-tab-C5nPyBzo.js.gz +0 -0
  195. package/dist/web/assets/{settings-body-5t6SQbLx.js → settings-body-xWSmRXUD.js} +1 -1
  196. package/dist/web/assets/settings-body-xWSmRXUD.js.br +0 -0
  197. package/dist/web/assets/settings-body-xWSmRXUD.js.gz +0 -0
  198. package/dist/web/assets/{settings-rows-B0w15zot.js → settings-rows-ChKBHk07.js} +1 -1
  199. package/dist/web/assets/settings-rows-ChKBHk07.js.br +0 -0
  200. package/dist/web/assets/settings-rows-ChKBHk07.js.gz +0 -0
  201. package/dist/web/assets/settings-section-content-BOh2jaWV.js +1 -0
  202. package/dist/web/assets/{settings-section-content-D41IJ62x.js → settings-section-content-DdVdyPVX.js} +2 -2
  203. package/dist/web/assets/settings-section-content-DdVdyPVX.js.br +0 -0
  204. package/dist/web/assets/settings-section-content-DdVdyPVX.js.gz +0 -0
  205. package/dist/web/assets/{settings-tab-DGU5FVbO.js → settings-tab-CzaBBNoj.js} +1 -1
  206. package/dist/web/assets/{settings-window-content-Da5PY5MZ.js → settings-window-content-DAvWSu_O.js} +1 -1
  207. package/dist/web/assets/{slash-command-picker-DpZsPuNf.js → slash-command-picker-Cn2Fdz2p.js} +1 -1
  208. package/dist/web/assets/slash-command-picker-Cn2Fdz2p.js.br +0 -0
  209. package/dist/web/assets/slash-command-picker-Cn2Fdz2p.js.gz +0 -0
  210. package/dist/web/assets/{sql-object-tab-BTS8aHGO.js → sql-object-tab-_mPRCvD9.js} +1 -1
  211. package/dist/web/assets/sql-object-tab-_mPRCvD9.js.br +0 -0
  212. package/dist/web/assets/sql-object-tab-_mPRCvD9.js.gz +0 -0
  213. package/dist/web/assets/{sqlite-viewer-CVo5eqWj.js → sqlite-viewer-B8VZt-mA.js} +1 -1
  214. package/dist/web/assets/sqlite-viewer-B8VZt-mA.js.br +0 -0
  215. package/dist/web/assets/sqlite-viewer-B8VZt-mA.js.gz +0 -0
  216. package/dist/web/assets/{structure-save-dialog-B9Q-Rhgj.js → structure-save-dialog-Lcst7kAl.js} +1 -1
  217. package/dist/web/assets/structure-save-dialog-Lcst7kAl.js.br +0 -0
  218. package/dist/web/assets/structure-save-dialog-Lcst7kAl.js.gz +0 -0
  219. package/dist/web/assets/{structure-tab-_cQn0KG7.js → structure-tab-ljJCzxUe.js} +1 -1
  220. package/dist/web/assets/structure-tab-ljJCzxUe.js.br +0 -0
  221. package/dist/web/assets/structure-tab-ljJCzxUe.js.gz +0 -0
  222. package/dist/web/assets/{system-monitor-body-YS3i1PUs.js → system-monitor-body-CTi5xUZz.js} +2 -2
  223. package/dist/web/assets/system-monitor-body-CTi5xUZz.js.br +0 -0
  224. package/dist/web/assets/system-monitor-body-CTi5xUZz.js.gz +0 -0
  225. package/dist/web/assets/{system-monitor-tab-D63xmd8U.js → system-monitor-tab-DeL2YoXO.js} +1 -1
  226. package/dist/web/assets/{system-monitor-window-content-DkCsK8Ed.js → system-monitor-window-content-DK-rQIZh.js} +1 -1
  227. package/dist/web/assets/{tab-host-window-content-CrASOMX8.js → tab-host-window-content-CG0vPTc_.js} +1 -1
  228. package/dist/web/assets/tab-host-window-content-CG0vPTc_.js.br +0 -0
  229. package/dist/web/assets/tab-host-window-content-CG0vPTc_.js.gz +0 -0
  230. package/dist/web/assets/{table-tab-JlfqyPZR.js → table-tab-CTZ3nCWV.js} +1 -1
  231. package/dist/web/assets/table-tab-CTZ3nCWV.js.br +0 -0
  232. package/dist/web/assets/table-tab-CTZ3nCWV.js.gz +0 -0
  233. package/dist/web/assets/{telegram-bot-token-field-ctRa2529.js → telegram-bot-token-field-DF7zq7_h.js} +1 -1
  234. package/dist/web/assets/telegram-bot-token-field-DF7zq7_h.js.br +0 -0
  235. package/dist/web/assets/telegram-bot-token-field-DF7zq7_h.js.gz +0 -0
  236. package/dist/web/assets/{terminal-tab-BsXBBru0.js → terminal-tab-B_jECWTH.js} +1 -1
  237. package/dist/web/assets/terminal-tab-B_jECWTH.js.br +0 -0
  238. package/dist/web/assets/terminal-tab-B_jECWTH.js.gz +0 -0
  239. package/dist/web/assets/{tool-cards-BDzK03U4.js → tool-cards-CsD_VXcG.js} +2 -2
  240. package/dist/web/assets/tool-cards-CsD_VXcG.js.br +0 -0
  241. package/dist/web/assets/tool-cards-CsD_VXcG.js.gz +0 -0
  242. package/dist/web/assets/{tools-settings-section-DCG74pbd.js → tools-settings-section-DbBr0Hnr.js} +1 -1
  243. package/dist/web/assets/tools-settings-section-DbBr0Hnr.js.br +0 -0
  244. package/dist/web/assets/tools-settings-section-DbBr0Hnr.js.gz +0 -0
  245. package/dist/web/assets/{use-inline-blame-BOn_m8f-.js → use-inline-blame-BA2mrMxT.js} +1 -1
  246. package/dist/web/assets/use-inline-blame-BA2mrMxT.js.br +0 -0
  247. package/dist/web/assets/use-inline-blame-BA2mrMxT.js.gz +0 -0
  248. package/dist/web/assets/{use-lsp-D144ftsf.js → use-lsp-ChbrzwvS.js} +1 -1
  249. package/dist/web/assets/use-lsp-ChbrzwvS.js.br +0 -0
  250. package/dist/web/assets/use-lsp-ChbrzwvS.js.gz +0 -0
  251. package/dist/web/assets/{use-monaco-theme-ArU1f9T6.js → use-monaco-theme-C3_wfz5J.js} +1 -1
  252. package/dist/web/assets/{use-process-kill-BdmXHMFE.js → use-process-kill-C-YetnGd.js} +1 -1
  253. package/dist/web/assets/use-process-kill-C-YetnGd.js.br +0 -0
  254. package/dist/web/assets/use-process-kill-C-YetnGd.js.gz +0 -0
  255. package/dist/web/assets/{use-sql-schema-info-BQXSMw6p.js → use-sql-schema-info-pKwLD9wk.js} +1 -1
  256. package/dist/web/assets/use-sql-schema-info-pKwLD9wk.js.br +0 -0
  257. package/dist/web/assets/use-sql-schema-info-pKwLD9wk.js.gz +0 -0
  258. package/dist/web/assets/{use-websocket-rWdrMWa8.js → use-websocket-BFnUq0-x.js} +1 -1
  259. package/dist/web/assets/web-preview-tab-DGLPuZYM.js +1 -0
  260. package/dist/web/assets/web-preview-tab-DGLPuZYM.js.br +0 -0
  261. package/dist/web/assets/web-preview-tab-DGLPuZYM.js.gz +0 -0
  262. package/dist/web/index.html +1 -1
  263. package/dist/web/index.html.br +0 -0
  264. package/dist/web/index.html.gz +0 -0
  265. package/dist/web/sw.js +1 -1
  266. package/dist/web/sw.js.br +0 -0
  267. package/dist/web/sw.js.gz +0 -0
  268. package/docs/architecture/workspace-and-ui.md +11 -0
  269. package/package.json +1 -1
  270. package/src/services/port-forward/forward-hop.ts +20 -5
  271. package/src/services/port-forward/preview-navigation.ts +45 -0
  272. package/src/web/components/floating-window/floating-window.tsx +7 -1
  273. package/src/web/components/floating-window/use-window-body-element.ts +12 -5
  274. package/src/web/components/web-preview/web-preview-tab.tsx +38 -5
  275. package/dist/web/assets/accounts-settings-section-BqsI4Ixj.js.br +0 -0
  276. package/dist/web/assets/accounts-settings-section-BqsI4Ixj.js.gz +0 -0
  277. package/dist/web/assets/agent-session-sheet-BmoNB8BG.js.br +0 -0
  278. package/dist/web/assets/agent-session-sheet-BmoNB8BG.js.gz +0 -0
  279. package/dist/web/assets/agent-session-window-content-rlCrYBYv.js.br +0 -0
  280. package/dist/web/assets/agent-session-window-content-rlCrYBYv.js.gz +0 -0
  281. package/dist/web/assets/ai-resource-editor-CUOR9Xtf.js.br +0 -0
  282. package/dist/web/assets/ai-resource-editor-CUOR9Xtf.js.gz +0 -0
  283. package/dist/web/assets/ai-settings-section-CNdbcCaI.js.br +0 -0
  284. package/dist/web/assets/ai-settings-section-CNdbcCaI.js.gz +0 -0
  285. package/dist/web/assets/android-tab-BsuTMKJw.js.br +0 -0
  286. package/dist/web/assets/android-tab-BsuTMKJw.js.gz +0 -0
  287. package/dist/web/assets/appearance-settings-section-Dk6d_fTo.js.br +0 -0
  288. package/dist/web/assets/appearance-settings-section-Dk6d_fTo.js.gz +0 -0
  289. package/dist/web/assets/apps-panel-C20ys4Cy.js.br +0 -0
  290. package/dist/web/assets/apps-panel-C20ys4Cy.js.gz +0 -0
  291. package/dist/web/assets/branch-review-tab-CcvkQMRA.js.br +0 -0
  292. package/dist/web/assets/branch-review-tab-CcvkQMRA.js.gz +0 -0
  293. package/dist/web/assets/chat-tab-BAh37UwG.js.br +0 -0
  294. package/dist/web/assets/chat-tab-BAh37UwG.js.gz +0 -0
  295. package/dist/web/assets/chat-tab-D-cl4yMo.js.br +0 -0
  296. package/dist/web/assets/chat-tab-D-cl4yMo.js.gz +0 -0
  297. package/dist/web/assets/code-editor-DIGsPNPS.js.br +0 -0
  298. package/dist/web/assets/code-editor-DIGsPNPS.js.gz +0 -0
  299. package/dist/web/assets/codex-reset-credit-button-C0a2svAw.js.br +0 -0
  300. package/dist/web/assets/conflict-editor-zORSNMk6.js.br +0 -0
  301. package/dist/web/assets/conflict-editor-zORSNMk6.js.gz +0 -0
  302. package/dist/web/assets/connection-form-tab-BkE7wACA.js.br +0 -0
  303. package/dist/web/assets/connection-form-tab-BkE7wACA.js.gz +0 -0
  304. package/dist/web/assets/csv-preview-CDUY0I94.js.br +0 -0
  305. package/dist/web/assets/csv-preview-CDUY0I94.js.gz +0 -0
  306. package/dist/web/assets/db-tab-parts-tgVIgcs5.js.br +0 -0
  307. package/dist/web/assets/db-tab-parts-tgVIgcs5.js.gz +0 -0
  308. package/dist/web/assets/design-settings-section-CqFPwhis.js.br +0 -0
  309. package/dist/web/assets/design-settings-section-CqFPwhis.js.gz +0 -0
  310. package/dist/web/assets/design-tab-CVTzge3p.js.br +0 -0
  311. package/dist/web/assets/design-tab-CVTzge3p.js.gz +0 -0
  312. package/dist/web/assets/designs-sidebar-panel-DKTSE1LS.js.br +0 -0
  313. package/dist/web/assets/designs-sidebar-panel-DKTSE1LS.js.gz +0 -0
  314. package/dist/web/assets/diff-viewer-3VDHcDag.js.br +0 -0
  315. package/dist/web/assets/diff-viewer-3VDHcDag.js.gz +0 -0
  316. package/dist/web/assets/docx-preview-FgE_WU6t.js.br +0 -0
  317. package/dist/web/assets/docx-preview-FgE_WU6t.js.gz +0 -0
  318. package/dist/web/assets/editor-dialog-BhK77FSu.js.br +0 -0
  319. package/dist/web/assets/editor-dialog-BhK77FSu.js.gz +0 -0
  320. package/dist/web/assets/editor-language-service-BIN7M57r.js.br +0 -4
  321. package/dist/web/assets/editor-language-service-BIN7M57r.js.gz +0 -0
  322. package/dist/web/assets/explorer-body-DNsWiVO3.js.br +0 -0
  323. package/dist/web/assets/explorer-body-DNsWiVO3.js.gz +0 -0
  324. package/dist/web/assets/explorer-window-content-DnOJYhRX.js.br +0 -0
  325. package/dist/web/assets/explorer-window-content-DnOJYhRX.js.gz +0 -0
  326. package/dist/web/assets/extension-manager-section-CJtRpUUs.js.br +0 -0
  327. package/dist/web/assets/extension-manager-section-CJtRpUUs.js.gz +0 -0
  328. package/dist/web/assets/extension-webview-Bza7cPL1.js.br +0 -0
  329. package/dist/web/assets/extension-webview-Bza7cPL1.js.gz +0 -0
  330. package/dist/web/assets/files-settings-section-8rWMj1Oi.js.br +0 -0
  331. package/dist/web/assets/files-settings-section-8rWMj1Oi.js.gz +0 -0
  332. package/dist/web/assets/general-settings-section-joWQEgIn.js.br +0 -0
  333. package/dist/web/assets/general-settings-section-joWQEgIn.js.gz +0 -0
  334. package/dist/web/assets/git-log-panel-BxYYWEiU.js.br +0 -0
  335. package/dist/web/assets/git-log-panel-BxYYWEiU.js.gz +0 -0
  336. package/dist/web/assets/git-review-tab-Btnvgk1e.js.br +0 -0
  337. package/dist/web/assets/git-review-tab-Btnvgk1e.js.gz +0 -0
  338. package/dist/web/assets/glide-data-grid-lCwaM1Gy.js.br +0 -0
  339. package/dist/web/assets/glide-data-grid-lCwaM1Gy.js.gz +0 -0
  340. package/dist/web/assets/grid-save-dialog-DoEEQ1vM.js.br +0 -0
  341. package/dist/web/assets/grid-save-dialog-DoEEQ1vM.js.gz +0 -0
  342. package/dist/web/assets/group-chat-tab-B7Dwx9uL.js.br +0 -0
  343. package/dist/web/assets/group-chat-tab-B7Dwx9uL.js.gz +0 -0
  344. package/dist/web/assets/impexp-tab-BtEDbQSn.js.br +0 -0
  345. package/dist/web/assets/impexp-tab-BtEDbQSn.js.gz +0 -0
  346. package/dist/web/assets/index-CPBujJc_.js.br +0 -0
  347. package/dist/web/assets/index-CPBujJc_.js.gz +0 -0
  348. package/dist/web/assets/keyboard-shortcuts-section-DULhEWPg.js.br +0 -0
  349. package/dist/web/assets/keyboard-shortcuts-section-DULhEWPg.js.gz +0 -0
  350. package/dist/web/assets/language-servers-section-CwBJsJ31.js.br +0 -0
  351. package/dist/web/assets/language-servers-section-CwBJsJ31.js.gz +0 -0
  352. package/dist/web/assets/logs-app-DatfI2Up.js.br +0 -0
  353. package/dist/web/assets/logs-app-DatfI2Up.js.gz +0 -0
  354. package/dist/web/assets/lsp-client-tCCcXWsR.js.br +0 -0
  355. package/dist/web/assets/lsp-client-tCCcXWsR.js.gz +0 -0
  356. package/dist/web/assets/markdown-renderer-D0YUMQLE.js.br +0 -0
  357. package/dist/web/assets/markdown-renderer-D0YUMQLE.js.gz +0 -0
  358. package/dist/web/assets/mobile-explorer-sheet-Bo27IRye.js.br +0 -0
  359. package/dist/web/assets/mobile-explorer-sheet-Bo27IRye.js.gz +0 -0
  360. package/dist/web/assets/new-design-dialog-DIOCWZW1.js.br +0 -0
  361. package/dist/web/assets/new-design-dialog-DIOCWZW1.js.gz +0 -0
  362. package/dist/web/assets/notifications-settings-section-DSSCTkfX.js.br +0 -0
  363. package/dist/web/assets/notifications-settings-section-DSSCTkfX.js.gz +0 -0
  364. package/dist/web/assets/ppmbot-settings-section-BIYSlZu5.js.br +0 -0
  365. package/dist/web/assets/ppmbot-settings-section-BIYSlZu5.js.gz +0 -0
  366. package/dist/web/assets/problems-panel-CH-00nA7.js.br +0 -0
  367. package/dist/web/assets/problems-panel-CH-00nA7.js.gz +0 -0
  368. package/dist/web/assets/process-table-DQO0g5do.js.br +0 -0
  369. package/dist/web/assets/process-table-DQO0g5do.js.gz +0 -0
  370. package/dist/web/assets/proxy-settings-section-Buo3hvQ4.js.br +0 -0
  371. package/dist/web/assets/proxy-settings-section-Buo3hvQ4.js.gz +0 -0
  372. package/dist/web/assets/query-tab-CU0QVZpj.js.br +0 -0
  373. package/dist/web/assets/query-tab-CU0QVZpj.js.gz +0 -0
  374. package/dist/web/assets/remote-access-settings-section-vlHMJPdY.js.br +0 -0
  375. package/dist/web/assets/remote-access-settings-section-vlHMJPdY.js.gz +0 -0
  376. package/dist/web/assets/remote-desktop-clipboard-notice-DNqX7d1L.js.br +0 -0
  377. package/dist/web/assets/remote-desktop-clipboard-notice-DNqX7d1L.js.gz +0 -0
  378. package/dist/web/assets/remote-desktop-mobile-sheet-Dz7tctpc.js.br +0 -0
  379. package/dist/web/assets/remote-desktop-mobile-sheet-Dz7tctpc.js.gz +0 -0
  380. package/dist/web/assets/remote-desktop-mobile-view-BqhQdShH.js.br +0 -0
  381. package/dist/web/assets/remote-desktop-mobile-view-BqhQdShH.js.gz +0 -0
  382. package/dist/web/assets/remote-desktop-readiness-gate-rnTq4ZQS.js.br +0 -0
  383. package/dist/web/assets/remote-desktop-readiness-gate-rnTq4ZQS.js.gz +0 -0
  384. package/dist/web/assets/remote-desktop-window-content-TqjHt0_5.js.br +0 -0
  385. package/dist/web/assets/remote-desktop-window-content-TqjHt0_5.js.gz +0 -0
  386. package/dist/web/assets/rename-object-dialog-D0YpY40E.js.br +0 -0
  387. package/dist/web/assets/rename-object-dialog-D0YpY40E.js.gz +0 -0
  388. package/dist/web/assets/review-code-DsF9921h.js.br +0 -0
  389. package/dist/web/assets/review-code-DsF9921h.js.gz +0 -0
  390. package/dist/web/assets/save-as-dialog-niU7kVMJ.js.br +0 -0
  391. package/dist/web/assets/save-as-dialog-niU7kVMJ.js.gz +0 -0
  392. package/dist/web/assets/schedules-settings-section-Heuv2Kj4.js.br +0 -0
  393. package/dist/web/assets/schedules-settings-section-Heuv2Kj4.js.gz +0 -0
  394. package/dist/web/assets/session-review-tab-Dob0FLvA.js.br +0 -0
  395. package/dist/web/assets/session-review-tab-Dob0FLvA.js.gz +0 -0
  396. package/dist/web/assets/settings-body-5t6SQbLx.js.br +0 -0
  397. package/dist/web/assets/settings-body-5t6SQbLx.js.gz +0 -0
  398. package/dist/web/assets/settings-rows-B0w15zot.js.br +0 -0
  399. package/dist/web/assets/settings-rows-B0w15zot.js.gz +0 -0
  400. package/dist/web/assets/settings-section-content-D41IJ62x.js.br +0 -0
  401. package/dist/web/assets/settings-section-content-D41IJ62x.js.gz +0 -0
  402. package/dist/web/assets/settings-section-content-DuVO6erO.js +0 -1
  403. package/dist/web/assets/slash-command-picker-DpZsPuNf.js.br +0 -0
  404. package/dist/web/assets/slash-command-picker-DpZsPuNf.js.gz +0 -0
  405. package/dist/web/assets/sql-object-tab-BTS8aHGO.js.br +0 -0
  406. package/dist/web/assets/sql-object-tab-BTS8aHGO.js.gz +0 -0
  407. package/dist/web/assets/sqlite-viewer-CVo5eqWj.js.br +0 -0
  408. package/dist/web/assets/sqlite-viewer-CVo5eqWj.js.gz +0 -0
  409. package/dist/web/assets/structure-save-dialog-B9Q-Rhgj.js.br +0 -0
  410. package/dist/web/assets/structure-save-dialog-B9Q-Rhgj.js.gz +0 -0
  411. package/dist/web/assets/structure-tab-_cQn0KG7.js.br +0 -0
  412. package/dist/web/assets/structure-tab-_cQn0KG7.js.gz +0 -0
  413. package/dist/web/assets/system-monitor-body-YS3i1PUs.js.br +0 -0
  414. package/dist/web/assets/system-monitor-body-YS3i1PUs.js.gz +0 -0
  415. package/dist/web/assets/tab-host-window-content-CrASOMX8.js.br +0 -0
  416. package/dist/web/assets/tab-host-window-content-CrASOMX8.js.gz +0 -0
  417. package/dist/web/assets/table-tab-JlfqyPZR.js.br +0 -0
  418. package/dist/web/assets/table-tab-JlfqyPZR.js.gz +0 -0
  419. package/dist/web/assets/telegram-bot-token-field-ctRa2529.js.br +0 -0
  420. package/dist/web/assets/telegram-bot-token-field-ctRa2529.js.gz +0 -0
  421. package/dist/web/assets/terminal-tab-BsXBBru0.js.br +0 -0
  422. package/dist/web/assets/terminal-tab-BsXBBru0.js.gz +0 -0
  423. package/dist/web/assets/tool-cards-BDzK03U4.js.br +0 -0
  424. package/dist/web/assets/tool-cards-BDzK03U4.js.gz +0 -0
  425. package/dist/web/assets/tools-settings-section-DCG74pbd.js.br +0 -0
  426. package/dist/web/assets/tools-settings-section-DCG74pbd.js.gz +0 -0
  427. package/dist/web/assets/use-inline-blame-BOn_m8f-.js.br +0 -0
  428. package/dist/web/assets/use-inline-blame-BOn_m8f-.js.gz +0 -0
  429. package/dist/web/assets/use-lsp-D144ftsf.js.br +0 -0
  430. package/dist/web/assets/use-lsp-D144ftsf.js.gz +0 -0
  431. package/dist/web/assets/use-process-kill-BdmXHMFE.js.br +0 -0
  432. package/dist/web/assets/use-process-kill-BdmXHMFE.js.gz +0 -0
  433. package/dist/web/assets/use-sql-schema-info-BQXSMw6p.js.br +0 -0
  434. package/dist/web/assets/use-sql-schema-info-BQXSMw6p.js.gz +0 -0
  435. package/dist/web/assets/web-preview-tab-B2OSrnl9.js +0 -1
  436. package/dist/web/assets/web-preview-tab-B2OSrnl9.js.br +0 -0
  437. package/dist/web/assets/web-preview-tab-B2OSrnl9.js.gz +0 -0
@@ -1,2 +1,2 @@
1
- import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import{A as r,Ar as i,Hn as a,I as o,K as s,Kr as c,Mr as l,P as u,Vn as d,Xt as f,Yt as p,Z as m,Zr as h,_r as g,br as _,cr as v,er as y,gr as b,hr as x,li as S,lr as C,ni as w,nn as T,o as E,or as D,qr as O,ri as k,u as A,un as j,ut as M,xn as N,xr as P}from"./icons-BwyIKaTT.js";import{a as F,k as I,r as L}from"./api-client-xQDlhUTu.js";import{n as R}from"./utils-Bslrbb-G.js";import"./portal-container-context-NBi-KGK0.js";import"./window-store-DqX_qmkQ.js";import"./panel-store-BJhazigC.js";import{i as z}from"./project-store-BLGl9IAO.js";import"./project-framework-store-DwLxaRan.js";import"./session-list-sync-triggers-DtJI5KF0.js";import{t as B}from"./tab-store-D5I52eLN.js";import{n as ee}from"./use-is-mobile-VRV9eZy1.js";import{t as V}from"./button-C9ZXWb3b.js";import{a as H,n as U,o as W,r as te,t as ne}from"./dialog-Dn_2tuYa.js";import{i as G,m as re,r as ie,t as ae}from"./dropdown-menu-BQidk_OJ.js";import{t as K}from"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import{t as q}from"./input-C3oVNCMq.js";import"./start-ellipsis-CU8GkxaV.js";import{t as oe}from"./ws-auth-CbF6GqxP.js";import{Tr as J}from"./index-CPBujJc_.js";import{n as se,t as ce}from"./use-h264-canvas-decoder-_zqeiVx8.js";var Y=e(t(),1),le=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/;function ue(e){return le.test(e)?null:`use 1–63 letters, digits, dots, dashes or underscores, starting with a letter or digit`}var X={ramMb:{min:512,max:16*1024,default:2048},storageMb:{min:1024,max:128*1024,default:6144},sdCardMb:{min:0,max:32*1024,default:512}},Z=n(),de=[`phone`,`tablet`,`tv`,`wear`,`automotive`,`desktop`,`other`],fe={phone:`Phones`,tablet:`Tablets`,tv:`TV`,wear:`Wear`,automotive:`Automotive`,desktop:`Desktop`,other:`Other`},pe=e=>`${(e/1024**3).toFixed(1)} GB`;function me({open:e,onClose:t,existingNames:n,onCreated:r}){let a=ee(),[o,s]=(0,Y.useState)(null),[c,l]=(0,Y.useState)(null),[u,d]=(0,Y.useState)(null),[p,m]=(0,Y.useState)(``),[h,g]=(0,Y.useState)(``),[_,v]=(0,Y.useState)(``),[y,b]=(0,Y.useState)(String(X.ramMb.default)),[x,S]=(0,Y.useState)(String(X.storageMb.default)),[C,w]=(0,Y.useState)(!1),[T,E]=(0,Y.useState)(null);(0,Y.useEffect)(()=>{if(!e)return;let t=!0;return d(null),(async()=>{try{let[e,n]=await Promise.all([L.get(`/api/android/system-images`),L.get(`/api/android/device-profiles`)]);if(!t)return;s(e.images),l(n.profiles);let r=e.images.filter(e=>e.hostCompatible).slice().sort((e,t)=>(t.apiLevel??0)-(e.apiLevel??0))[0];r&&g(e=>e||r.id),n.profiles.some(e=>e.id===`pixel_9`)&&v(e=>e||`pixel_9`)}catch(e){t&&d(e.message)}})(),()=>{t=!1}},[e]);let D=(0,Y.useMemo)(()=>(o??[]).map(e=>({value:e.hostCompatible?e.id:``,label:`API ${e.apiLevel??`?`} · ${e.tagDisplay} · ${e.abi}`,group:e.hostCompatible?`Runs on this host`:`Wrong CPU for this host`,hint:e.hostCompatible?pe(e.bytes):`needs ${e.abi}`,title:e.id})),[o]),k=(0,Y.useMemo)(()=>{let e=c??[];return de.flatMap(t=>e.filter(e=>e.kind===t).map(e=>({value:e.id,label:e.name,group:fe[t],hint:e.oem})))},[c]),A=p.length===0?null:n.some(e=>e.toLowerCase()===p.toLowerCase())?`an AVD with that name already exists`:ue(p),j=Number(y),M=Number(x),P=Number.isFinite(j)&&j>=X.ramMb.min&&j<=X.ramMb.max?null:`RAM must be between ${X.ramMb.min} and ${X.ramMb.max} MB`,F=Number.isFinite(M)&&M>=X.storageMb.min&&M<=X.storageMb.max?null:`Storage must be between ${X.storageMb.min} and ${X.storageMb.max} MB`,I=p.length>0&&!A&&!P&&!F&&h!==``&&_!==``&&!C,R=()=>{m(``),E(null),w(!1),b(String(X.ramMb.default)),S(String(X.storageMb.default))},z=async()=>{if(I){w(!0),E(null);try{await L.post(`/api/android/avds`,{name:p,systemImage:h,deviceProfile:_,ramMb:j,storageMb:M}),r(p),R(),t()}catch(e){E(e.message),w(!1)}}},B=!u&&(o===null||c===null),G=(0,Z.jsxs)(`div`,{className:`space-y-4`,children:[u&&(0,Z.jsxs)(`p`,{className:`flex items-start gap-2 text-sm leading-relaxed text-destructive`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:u})]}),B&&(0,Z.jsxs)(`p`,{className:`flex items-center gap-2 py-6 text-sm text-muted-foreground`,children:[(0,Z.jsx)(N,{className:`size-4 animate-spin`}),` Reading the SDK…`]}),!B&&!u&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsx)(`label`,{htmlFor:`avd-name`,className:`text-sm font-medium`,children:`Name`}),(0,Z.jsx)(q,{id:`avd-name`,value:p,onChange:e=>m(e.target.value),placeholder:`Pixel_9_API_35`,autoComplete:`off`,spellCheck:!1,className:`h-11`}),A?(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-destructive`,children:A}):(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`This becomes a folder name, so no spaces.`})]}),(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium`,children:`System image`}),(0,Z.jsx)(J,{value:h,items:D,onChange:g,label:`System image`,searchPlaceholder:`Search images`,emptyText:`No system images are installed`,placeholder:`Pick an installed image`,icon:f,className:`h-11 w-full md:h-9`,modal:!a}),(0,Z.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`Only images already downloaded on this host. PPM never downloads one for you — use Android Studio's SDK Manager, or`,` `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 text-[11px]`,children:`sdkmanager`}),`.`]})]}),(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium`,children:`Device`}),(0,Z.jsx)(J,{value:_,items:k,onChange:v,label:`Device profile`,searchPlaceholder:`Search devices`,emptyText:`No device profiles`,placeholder:`Pick a device`,icon:i,className:`h-11 w-full md:h-9`,modal:!a}),(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`Sets the screen. Without one the emulator is 320x640.`})]}),(0,Z.jsxs)(`div`,{className:`flex gap-3`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1.5`,children:[(0,Z.jsx)(`label`,{htmlFor:`avd-ram`,className:`text-sm font-medium`,children:`RAM (MB)`}),(0,Z.jsx)(q,{id:`avd-ram`,inputMode:`numeric`,value:y,className:`h-11`,onChange:e=>b(e.target.value)})]}),(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1.5`,children:[(0,Z.jsx)(`label`,{htmlFor:`avd-storage`,className:`text-sm font-medium`,children:`Storage (MB)`}),(0,Z.jsx)(q,{id:`avd-storage`,inputMode:`numeric`,value:x,className:`h-11`,onChange:e=>S(e.target.value)})]})]}),(P||F)&&(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-destructive`,children:P??F}),(0,Z.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`PPM writes `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 text-[11px]`,children:`hw.keyboard=yes`}),` `,`into every AVD it creates — without it the emulator accepts key presses and shows nothing.`]})]}),T&&(0,Z.jsxs)(`p`,{className:`flex items-start gap-2 text-sm leading-relaxed text-destructive`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:T})]}),(0,Z.jsxs)(`div`,{className:`flex flex-col-reverse gap-2 pt-2 md:flex-row md:justify-end`,children:[(0,Z.jsx)(V,{variant:`outline`,className:`min-h-11`,onClick:()=>{R(),t()},children:`Cancel`}),(0,Z.jsx)(V,{className:`min-h-11`,disabled:!I,onClick:()=>void z(),children:C?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(N,{className:`animate-spin`}),` Creating…`]}):`Create device`})]})]});return e?a?(0,Z.jsx)(K,{open:!0,onClose:t,children:(0,Z.jsxs)(`div`,{className:`max-h-[80vh] overflow-y-auto px-4 pb-4`,children:[(0,Z.jsx)(`h2`,{className:`mb-3 text-base font-semibold`,children:`New Android device`}),G]})}):(0,Z.jsx)(ne,{open:!0,onOpenChange:e=>!e&&t(),children:(0,Z.jsxs)(U,{className:`sm:max-w-lg`,children:[(0,Z.jsxs)(H,{children:[(0,Z.jsx)(W,{children:`New Android device`}),(0,Z.jsx)(te,{children:`Built from a system image already installed on this host.`})]}),(0,Z.jsx)(`div`,{className:`max-h-[70vh] overflow-y-auto pr-1`,children:G})]})}):null}function he({action:e,avdId:t,deviceName:n,onCancel:r,onDone:i}){let a=ee(),[o,s]=(0,Y.useState)(``),[c,l]=(0,Y.useState)(!1),[u,d]=(0,Y.useState)(null);if((0,Y.useEffect)(()=>{s(``),d(null),l(!1)},[e,t]),!e)return null;let f=e===`delete`,p=f?`Delete this device`:`Wipe this device`,m=o===n&&!c,h=async()=>{if(m){l(!0),d(null);try{f?(await L.del(`/api/android/avds/${encodeURIComponent(t)}`,{confirmName:n}),i(`delete`,`Deleted ${n}`)):i(`wipe`,(await L.post(`/api/android/avds/${encodeURIComponent(t)}/wipe`,{confirmName:n})).message)}catch(e){d(e.message),l(!1)}}},g=(0,Z.jsxs)(`div`,{className:`space-y-4`,children:[(0,Z.jsx)(`p`,{className:`text-sm leading-relaxed`,children:f?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`span`,{className:`font-medium`,children:n}),` and everything in it will be removed from disk. The AVD, its settings and its installed apps are gone for good — this is not a recycle bin.`]}):(0,Z.jsxs)(Z.Fragment,{children:[`Everything inside `,(0,Z.jsx)(`span`,{className:`font-medium`,children:n}),` goes back to factory: installed apps, accounts, files and saved snapshots. The device itself and its settings stay, and the next start is a cold boot.`]})}),(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsxs)(`label`,{htmlFor:`avd-confirm`,className:`text-sm font-medium`,children:[`Type `,(0,Z.jsx)(`span`,{className:`font-mono`,children:n}),` to confirm`]}),(0,Z.jsx)(q,{id:`avd-confirm`,value:o,onChange:e=>s(e.target.value),autoComplete:`off`,spellCheck:!1,autoCapitalize:`off`,className:`h-11 font-mono`})]}),u&&(0,Z.jsxs)(`p`,{className:`flex items-start gap-2 text-sm leading-relaxed text-destructive`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:u})]}),(0,Z.jsxs)(`div`,{className:`flex flex-col-reverse gap-2 pt-2 md:flex-row md:justify-end`,children:[(0,Z.jsx)(V,{variant:`outline`,className:`min-h-11`,onClick:r,children:`Cancel`}),(0,Z.jsx)(V,{variant:`destructive`,className:`min-h-11`,autoFocus:!1,disabled:!m,onClick:()=>void h(),children:c?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(N,{className:`animate-spin`}),` `,f?`Deleting…`:`Wiping…`]}):f?`Delete device`:`Wipe data`})]})]});return a?(0,Z.jsx)(K,{open:!0,onClose:r,children:(0,Z.jsxs)(`div`,{className:`px-4 pb-4`,children:[(0,Z.jsx)(`h2`,{className:`mb-3 text-base font-semibold`,children:p}),g]})}):(0,Z.jsx)(ne,{open:!0,onOpenChange:e=>!e&&r(),children:(0,Z.jsxs)(U,{className:`sm:max-w-md`,children:[(0,Z.jsxs)(H,{children:[(0,Z.jsx)(W,{children:p}),(0,Z.jsx)(te,{children:f?`This cannot be undone.`:`A factory reset — the device itself stays.`})]}),g]})})}var ge=1500;function _e({onOpen:e}){let[t,n]=(0,Y.useState)(null),[o,s]=(0,Y.useState)([]),[u,d]=(0,Y.useState)(null),[f,p]=(0,Y.useState)({}),[m,h]=(0,Y.useState)(!1),[g,_]=(0,Y.useState)(null),y=(0,Y.useRef)(!0),S=(0,Y.useCallback)(async()=>{try{let e=await L.get(`/api/android/capabilities`);if(!y.current||(n(e),!e.enabled))return;let t=await L.get(`/api/android/devices`);if(!y.current)return;s(t.devices),d(null)}catch(e){y.current&&d(e.message)}},[]);(0,Y.useEffect)(()=>{y.current=!0,S();let e=setInterval(()=>void S(),ge*4);return()=>{y.current=!1,clearInterval(e)}},[S]);let C=(0,Y.useCallback)(async e=>{p(t=>({...t,[e.avdId]:`Starting…`}));try{let{operationId:t}=await L.post(`/api/android/avds/${encodeURIComponent(e.avdId)}/start`,{});for(;;){if(await new Promise(e=>setTimeout(e,ge)),!y.current)return;let n=await L.get(`/api/android/operations/${t}`);if(p(t=>({...t,[e.avdId]:n.detail??`Starting…`})),n.state===`succeeded`)break;if(n.state===`failed`||n.state===`cancelled`){d(n.error??`the emulator failed to start`);break}}}catch(e){y.current&&d(e.message)}finally{y.current&&(p(t=>{let n={...t};return delete n[e.avdId],n}),S())}},[S]),w=(0,Y.useCallback)(async e=>{if(e.runtime){p(t=>({...t,[e.avdId]:`Stopping…`}));try{await L.post(`/api/android/devices/${encodeURIComponent(e.runtime.deviceId)}/stop?generation=${e.runtime.generation}`,{})}catch(e){y.current&&d(e.message)}finally{y.current&&(p(t=>{let n={...t};return delete n[e.avdId],n}),S())}}},[S]);if(!t)return(0,Z.jsxs)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:[(0,Z.jsx)(N,{className:`mr-2 size-4 animate-spin`}),` Checking this host…`]});let T=t.requirements.filter(e=>!e.met);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 border-b px-4 py-3`,children:[(0,Z.jsx)(i,{className:`size-4 shrink-0 text-muted-foreground`}),(0,Z.jsx)(`h2`,{className:`min-w-0 flex-1 truncate text-sm font-medium`,children:`Android devices`}),t.canCreateAvd&&(0,Z.jsxs)(V,{size:`sm`,className:`h-10`,onClick:()=>h(!0),children:[(0,Z.jsx)(v,{}),` New device`]}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-10`,onClick:()=>void S(),title:`Refresh`,"aria-label":`Refresh`,children:(0,Z.jsx)(x,{})})]}),(0,Z.jsxs)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-4`,children:[u&&(0,Z.jsxs)(`div`,{className:`mb-4 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-destructive`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1 leading-relaxed`,children:u})]}),T.length>0&&(0,Z.jsxs)(`div`,{className:`mb-4 rounded-md border p-4`,children:[(0,Z.jsx)(`p`,{className:`text-sm font-medium`,children:`This host is not ready yet`}),(0,Z.jsx)(`ul`,{className:`mt-3 space-y-3`,children:t.requirements.map(e=>(0,Z.jsxs)(`li`,{className:`flex items-start gap-2 text-sm leading-relaxed`,children:[e.met?(0,Z.jsx)(r,{className:`mt-0.5 size-4 shrink-0 text-muted-foreground`}):(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-destructive`}),(0,Z.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`span`,{className:R(!e.met&&`font-medium`),children:e.label}),(0,Z.jsx)(`span`,{className:`block text-muted-foreground`,children:e.detail}),!e.met&&e.fix&&(0,Z.jsx)(`code`,{className:`mt-1 block overflow-x-auto rounded bg-muted px-2 py-1 text-xs`,children:e.fix})]})]},e.id))})]}),o.length===0&&T.length===0&&(0,Z.jsxs)(`div`,{className:`py-8 text-center`,children:[(0,Z.jsx)(`p`,{className:`text-sm leading-relaxed text-muted-foreground`,children:`No AVDs on this host yet.`}),t.canCreateAvd?(0,Z.jsxs)(V,{className:`mt-4 min-h-11`,onClick:()=>h(!0),children:[(0,Z.jsx)(v,{}),` New device`]}):(0,Z.jsxs)(`p`,{className:`mt-2 text-sm leading-relaxed text-muted-foreground`,children:[`Create one in Android Studio, or with`,` `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 text-xs`,children:`avdmanager create avd`}),`.`]})]}),(0,Z.jsx)(`ul`,{className:`space-y-2`,children:o.map(n=>{let r=n.runtime!==null,i=f[n.avdId];return(0,Z.jsxs)(`li`,{className:`flex flex-col gap-3 rounded-md border p-4 sm:flex-row sm:items-center`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`p`,{className:`truncate text-sm font-medium`,children:n.name}),(0,Z.jsx)(`p`,{className:`mt-0.5 text-xs leading-relaxed text-muted-foreground`,children:[n.apiLevel?`API ${n.apiLevel}`:null,n.abi,n.displayWidth&&n.displayHeight?`${n.displayWidth}x${n.displayHeight}`:null,r?n.runtime.ownedByPpm?`running (PPM)`:`running (external)`:null].filter(Boolean).join(` · `)}),n.lockedByAnotherProcess&&(0,Z.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-destructive`,children:`Locked by another process — it is probably open in Android Studio.`}),!n.hardwareKeyboard&&(0,Z.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`This AVD has no hardware keyboard, so typing will not reach it. Set`,` `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 text-[11px]`,children:`hw.keyboard=yes`}),` in its config.ini.`]})]}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[i&&(0,Z.jsxs)(`span`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,Z.jsx)(N,{className:`size-3.5 animate-spin`}),` `,i]}),r?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(V,{size:`sm`,className:`h-10`,onClick:()=>e(n),children:`View`}),n.runtime.ownedByPpm&&(0,Z.jsxs)(V,{size:`sm`,variant:`outline`,className:`h-10`,disabled:!!i,onClick:()=>void w(n),children:[(0,Z.jsx)(l,{}),` Stop`]})]}):(0,Z.jsxs)(V,{size:`sm`,className:`h-10`,disabled:!!i||n.lockedByAnotherProcess||!t.ready,onClick:()=>void C(n),children:[(0,Z.jsx)(D,{}),` Start`]}),(0,Z.jsxs)(ae,{children:[(0,Z.jsx)(re,{asChild:!0,children:(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-10`,title:`More for ${n.name}`,"aria-label":`More for ${n.name}`,children:(0,Z.jsx)(a,{})})}),(0,Z.jsxs)(ie,{align:`end`,children:[(0,Z.jsxs)(G,{className:`min-h-11 md:min-h-0`,disabled:r||n.lockedByAnotherProcess||!!i,onSelect:()=>_({action:`wipe`,device:n}),children:[(0,Z.jsx)(b,{}),` Wipe data`]}),(0,Z.jsxs)(G,{variant:`destructive`,className:`min-h-11 md:min-h-0`,disabled:r||n.lockedByAnotherProcess||!!i||!t.canCreateAvd,onSelect:()=>_({action:`delete`,device:n}),children:[(0,Z.jsx)(c,{}),` Delete device`]})]})]})]})]},n.avdId)})})]}),(0,Z.jsx)(me,{open:m,onClose:()=>h(!1),existingNames:o.map(e=>e.name),onCreated:e=>{I.success(`Created ${e}`),S()}}),(0,Z.jsx)(he,{action:g?.action??null,avdId:g?.device.avdId??``,deviceName:g?.device.name??``,onCancel:()=>_(null),onDone:(e,t)=>{_(null),I.success(t),S()}})]})}var ve={low:`Low`,balanced:`Balanced`,high:`High`};function ye(e){let{send:t,controller:n,rotation:r,quality:i,onQualityChange:a,onKeyboard:o,layout:c}=e,[u,f]=(0,Y.useState)(!1),p=c===`bar`,m=p?`size-11`:`size-9`,h=e=>()=>t({type:`hardware`,key:e});return(0,Z.jsxs)(`div`,{className:R(`flex items-center gap-2`,be(p)),children:[(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`back`),title:`Back`,"aria-label":`Back`,children:(0,Z.jsx)(A,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`home`),title:`Home`,"aria-label":`Home`,children:(0,Z.jsx)(s,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`recent`),title:`Recent apps`,"aria-label":`Recent apps`,children:(0,Z.jsx)(l,{})}),(0,Z.jsx)(`span`,{className:`mx-1 h-6 w-px shrink-0 bg-border`,"aria-hidden":!0}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:o,title:`Keyboard`,"aria-label":`Keyboard`,children:(0,Z.jsx)(j,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:()=>t({type:`rotate`,rotation:xe(r)}),title:`Rotate (now ${r}°)`,"aria-label":`Rotate`,children:(0,Z.jsx)(g,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:()=>f(e=>!e),title:`More keys`,"aria-label":`More keys`,"aria-expanded":u,children:(0,Z.jsx)(d,{})}),u&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`volume-up`),title:`Volume up`,"aria-label":`Volume up`,children:(0,Z.jsx)(k,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`volume-down`),title:`Volume down`,"aria-label":`Volume down`,children:(0,Z.jsx)(w,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`power`),title:`Power`,"aria-label":`Power`,children:(0,Z.jsx)(C,{})})]}),(0,Z.jsx)(`span`,{className:`flex-1`}),(0,Z.jsx)(`label`,{className:`sr-only`,htmlFor:`android-quality`,children:`Quality`}),(0,Z.jsx)(`select`,{id:`android-quality`,className:R(`rounded-md border bg-background px-2 text-sm`,p?`h-11`:`h-9`),value:i,disabled:!n,onChange:e=>a(e.target.value),children:Object.keys(ve).map(e=>(0,Z.jsx)(`option`,{value:e,children:ve[e]},e))})]})}function be(e){return e?`w-full justify-center border-t bg-background/95 px-3 py-2 backdrop-blur`:`px-2 py-1`}function xe(e){return(e+90)%360}function Se({deviceId:e}){let[t,n]=(0,Y.useState)(null),[i,a]=(0,Y.useState)(``),[o,s]=(0,Y.useState)(null),[c,l]=(0,Y.useState)(!1),[u,d]=(0,Y.useState)(null),f=(0,Y.useCallback)(async()=>{s(`read`),d(null);try{n((await L.get(`/api/android/devices/${encodeURIComponent(e)}/clipboard`)).text)}catch(e){d(e.message)}finally{s(null)}},[e]),p=(0,Y.useCallback)(async()=>{s(`write`),d(null);try{await L.post(`/api/android/devices/${encodeURIComponent(e)}/clipboard`,{text:i}),l(!0),setTimeout(()=>l(!1),1500)}catch(e){d(e.message)}finally{s(null)}},[e,i]);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col gap-4 overflow-auto p-3`,children:[(0,Z.jsxs)(`section`,{className:`flex flex-col gap-2`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(`h3`,{className:`flex-1 text-sm font-medium`,children:`From the device`}),(0,Z.jsxs)(V,{variant:`secondary`,className:`h-11 md:h-9`,onClick:()=>void f(),disabled:o!==null,children:[o===`read`?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(m,{}),` Read`]})]}),t!==null&&(0,Z.jsx)(`textarea`,{readOnly:!0,value:t,rows:3,placeholder:`(the device's clipboard is empty)`,className:`w-full resize-y rounded-md border bg-muted/40 p-2 font-mono text-xs`})]}),(0,Z.jsxs)(`section`,{className:`flex flex-col gap-2 border-t pt-3`,children:[(0,Z.jsx)(`h3`,{className:`text-sm font-medium`,children:`To the device`}),(0,Z.jsx)(`textarea`,{value:i,onChange:e=>a(e.target.value),rows:3,placeholder:`Text to put on the device's clipboard`,className:`w-full resize-y rounded-md border bg-background p-2 font-mono text-xs`}),(0,Z.jsxs)(V,{className:`h-11 self-start md:h-9`,onClick:()=>void p(),disabled:o!==null||i.length===0,children:[c?(0,Z.jsx)(r,{}):o===`write`?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(h,{}),c?`Sent`:`Send to device`]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Paste it in the guest with a long press, or with the keyboard's paste key.`})]}),u&&(0,Z.jsx)(`p`,{className:`text-sm text-destructive`,children:u})]})}function Ce(e,t,n){let r=new URLSearchParams({filename:t});return n&&r.set(`downgrade`,`1`),`/api/android/devices/${encodeURIComponent(e)}/apk?${r.toString()}`}function we(e,t){let n=null;try{n=JSON.parse(t)}catch{}let r=n;if(e>=200&&e<300&&r?.ok&&r.data?.operationId)return{operationId:r.data.operationId};throw Error(r?.error??(t.trim()||`the upload failed with HTTP ${e}`))}function Te(e){let t=new XMLHttpRequest,n=!1;return{done:new Promise((n,r)=>{t.open(`POST`,Ce(e.deviceId,e.file.name,e.allowDowngrade===!0)),e.token&&t.setRequestHeader(`Authorization`,`Bearer ${e.token}`),t.setRequestHeader(`Content-Type`,`application/vnd.android.package-archive`),t.setRequestHeader(`x-ppm-client`,`web`),t.upload.onprogress=t=>{t.lengthComputable&&e.onProgress&&e.onProgress(t.loaded/t.total)},t.onload=()=>{try{n(we(t.status,t.responseText).operationId)}catch(e){r(e)}},t.onerror=()=>r(Error(`the upload could not reach the server`)),t.onabort=()=>r(Error(`cancelled`)),t.send(e.file)}),cancel(){n||(n=!0,t.abort())}}}var Ee=800;function De({deviceId:e,deviceName:t}){let n=z(e=>e.projects),[r,i]=(0,Y.useState)(``),[a,o]=(0,Y.useState)(null),[s,c]=(0,Y.useState)(!1),[l,u]=(0,Y.useState)(!1),[d,f]=(0,Y.useState)({kind:`idle`}),p=(0,Y.useRef)(null),m=(0,Y.useRef)(null),g=(0,Y.useRef)(d);g.current=d;let _=d.kind===`uploading`||d.kind===`installing`,v=(0,Y.useCallback)(async(e,t)=>{for(;;){await new Promise(e=>setTimeout(e,Ee));let n=g.current;if(n.kind!==`installing`||n.operationId!==e)return;let r;try{r=await L.get(`/api/android/operations/${encodeURIComponent(e)}`)}catch(e){f({kind:`failed`,message:e.message});return}if(r.state===`succeeded`){f({kind:`done`,filename:t});return}if(r.state===`failed`){f({kind:`failed`,message:r.error??`the install failed`});return}if(r.state===`cancelled`){f({kind:`idle`});return}f({kind:`installing`,operationId:e,detail:r.detail,filename:t})}},[]),y=(0,Y.useCallback)(t=>{f({kind:`uploading`,fraction:0,filename:t.name});let n=Te({deviceId:e,file:t,allowDowngrade:l,token:F(),onProgress:e=>f({kind:`uploading`,fraction:e,filename:t.name})});m.current=n,n.done.then(e=>{m.current=null,f({kind:`installing`,operationId:e,detail:`installing…`,filename:t.name}),v(e,t.name)}).catch(e=>{m.current=null,f(e.message===`cancelled`?{kind:`idle`}:{kind:`failed`,message:e.message})})},[e,l,v]),b=(0,Y.useCallback)(async t=>{let n=t.split(`/`).pop()??t;f({kind:`installing`,operationId:``,detail:`starting…`,filename:n});try{let{operationId:i}=await L.post(`/api/android/devices/${encodeURIComponent(e)}/apk/project`,{project:r,path:t,downgrade:l});f({kind:`installing`,operationId:i,detail:`installing…`,filename:n}),v(i,n)}catch(e){f({kind:`failed`,message:e.message})}},[e,r,l,v]),S=(0,Y.useCallback)(()=>{if(d.kind===`uploading`){m.current?.cancel();return}d.kind===`installing`&&d.operationId&&(L.post(`/api/android/operations/${encodeURIComponent(d.operationId)}/cancel`,{}).catch(()=>{}),f({kind:`idle`}))},[d]),C=(0,Y.useCallback)(async e=>{if(!e){o(null);return}c(!0);try{o((await L.get(`/api/android/projects/${encodeURIComponent(e)}/apks`)).apks)}catch{o([])}finally{c(!1)}},[]);return(0,Y.useEffect)(()=>{C(r)},[r,C]),(0,Y.useEffect)(()=>()=>m.current?.cancel(),[]),(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col gap-3 overflow-auto p-3`,children:[(0,Z.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Installing on `,t,`.`]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`input`,{ref:p,type:`file`,accept:`.apk,application/vnd.android.package-archive`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,t&&y(t)}}),(0,Z.jsxs)(V,{className:`h-11 md:h-9`,disabled:_,onClick:()=>p.current?.click(),children:[(0,Z.jsx)(h,{}),` Choose an APK`]}),(0,Z.jsxs)(`label`,{className:`flex min-h-11 cursor-pointer items-center gap-2 text-sm md:min-h-9`,children:[(0,Z.jsx)(`input`,{type:`checkbox`,className:`size-4`,checked:l,disabled:_,onChange:e=>u(e.target.checked)}),`Allow downgrade`]})]}),(0,Z.jsx)(Oe,{phase:d,onCancel:S,onDismiss:()=>f({kind:`idle`})}),(0,Z.jsxs)(`div`,{className:`flex flex-col gap-2 border-t pt-3`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(`label`,{className:`text-sm`,htmlFor:`android-apk-project`,children:`From a project`}),(0,Z.jsxs)(`select`,{id:`android-apk-project`,className:`h-11 min-w-0 flex-1 rounded-md border bg-background px-2 text-sm md:h-9`,value:r,onChange:e=>i(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`Choose a project…`}),n.map(e=>(0,Z.jsx)(`option`,{value:e.name,children:e.name},e.name))]}),r&&(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,disabled:s,onClick:()=>void C(r),title:`Rescan`,"aria-label":`Rescan`,children:s?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(x,{})})]}),s&&(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Looking for APKs…`}),!s&&a?.length===0&&(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No .apk files in that project yet — build one and press rescan.`}),!s&&a&&a.length>0&&(0,Z.jsx)(`ul`,{className:`flex flex-col gap-1`,children:a.map(e=>(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{type:`button`,disabled:_,onClick:()=>void b(e.path),className:R(`flex min-h-11 w-full flex-col items-start rounded-md border px-3 py-2 text-left text-sm md:min-h-9`,_?`opacity-50`:`hover:bg-accent`),children:[(0,Z.jsx)(`span`,{dir:`rtl`,className:`w-full truncate`,children:(0,Z.jsx)(`bdi`,{children:e.path})}),(0,Z.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[ke(e.bytes),` · `,new Date(e.modifiedAt).toLocaleString()]})]})},e.path))})]})]})}function Oe({phase:e,onCancel:t,onDismiss:n}){if(e.kind===`idle`)return null;if(e.kind===`uploading`||e.kind===`installing`){let n=e.kind===`uploading`?Math.round(e.fraction*100):null,r=e.kind===`installing`?e.detail:``;return(0,Z.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-md border p-3`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[(0,Z.jsx)(N,{className:`size-4 shrink-0 animate-spin`}),(0,Z.jsx)(`span`,{dir:`rtl`,className:`min-w-0 flex-1 truncate`,children:(0,Z.jsx)(`bdi`,{children:e.filename})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-9`,onClick:t,title:`Cancel`,"aria-label":`Cancel`,children:(0,Z.jsx)(S,{})})]}),n===null?(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`div`,{className:`h-1.5 overflow-hidden rounded-full bg-muted`,children:(0,Z.jsx)(`div`,{className:`h-full bg-primary transition-[width]`,style:{width:`${n}%`}})}),(0,Z.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Uploading — `,n,`%`]})]})]})}return e.kind===`done`?(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-emerald-600/40 bg-emerald-600/10 p-3 text-sm`,children:[(0,Z.jsx)(r,{className:`size-4 shrink-0 text-emerald-600 dark:text-emerald-400`}),(0,Z.jsx)(`span`,{dir:`rtl`,className:`min-w-0 flex-1 truncate`,children:(0,Z.jsx)(`bdi`,{children:e.filename})}),(0,Z.jsx)(`span`,{className:`shrink-0 text-muted-foreground`,children:`installed`}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-9`,onClick:n,"aria-label":`Dismiss`,children:(0,Z.jsx)(S,{})})]}):(0,Z.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-destructive`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:e.message}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-9`,onClick:n,"aria-label":`Dismiss`,children:(0,Z.jsx)(S,{})})]})}function ke(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/1024/1024).toFixed(1)} MB`}var Ae=[`verbose`,`debug`,`info`,`warn`,`error`,`fatal`],je=new Map(Ae.map((e,t)=>[e,t]));function Me(e,t){return(je.get(e)??0)>=(je.get(t)??0)}var Ne={minimum:`verbose`,text:``,pid:0};function Pe(e,t){if(!Me(e.level,t.minimum)||t.pid!==0&&e.pid!==t.pid)return!1;let n=t.text.trim().toLowerCase();return n.length===0?!0:e.tag.toLowerCase().includes(n)||e.message.toLowerCase().includes(n)}function Fe(e,t,n){if(t.length===0)return e;let r=e.length>0?e[e.length-1].id:0,i=t[0].id>r?t:t.filter(e=>e.id>r);if(i.length===0)return e;let a=e.concat(i);return a.length>n?a.slice(a.length-n):a}function Ie(e){let t=new Date(e),n=(e,t=2)=>String(e).padStart(t,`0`);return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}.${n(t.getMilliseconds(),3)}`}function Le(e){let t={verbose:`V`,debug:`D`,info:`I`,warn:`W`,error:`E`,fatal:`F`};return e.map(e=>`${Ie(e.timestamp)} ${String(e.pid).padStart(5)} ${String(e.tid).padStart(5)} ${t[e.level]} ${e.tag}: ${e.message}`).join(`
1
+ import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import{A as r,Ar as i,Hn as a,I as o,K as s,Kr as c,Mr as l,P as u,Vn as d,Xt as f,Yt as p,Z as m,Zr as h,_r as g,br as _,cr as v,er as y,gr as b,hr as x,li as S,lr as C,ni as w,nn as T,o as E,or as D,qr as O,ri as k,u as A,un as j,ut as M,xn as N,xr as P}from"./icons-BwyIKaTT.js";import{a as F,k as I,r as L}from"./api-client-xQDlhUTu.js";import{n as R}from"./utils-Bslrbb-G.js";import"./portal-container-context-NBi-KGK0.js";import"./window-store-DqX_qmkQ.js";import"./panel-store-BJhazigC.js";import{i as z}from"./project-store-BLGl9IAO.js";import"./project-framework-store-DwLxaRan.js";import"./session-list-sync-triggers-DtJI5KF0.js";import{t as B}from"./tab-store-D5I52eLN.js";import{n as ee}from"./use-is-mobile-VRV9eZy1.js";import{t as V}from"./button-C9ZXWb3b.js";import{a as H,n as U,o as W,r as te,t as ne}from"./dialog-Dn_2tuYa.js";import{i as G,m as re,r as ie,t as ae}from"./dropdown-menu-BQidk_OJ.js";import{t as K}from"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import{t as q}from"./input-C3oVNCMq.js";import"./start-ellipsis-CU8GkxaV.js";import{t as oe}from"./ws-auth-CbF6GqxP.js";import{Tr as J}from"./index-BGk8EFQb.js";import{n as se,t as ce}from"./use-h264-canvas-decoder-_zqeiVx8.js";var Y=e(t(),1),le=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/;function ue(e){return le.test(e)?null:`use 1–63 letters, digits, dots, dashes or underscores, starting with a letter or digit`}var X={ramMb:{min:512,max:16*1024,default:2048},storageMb:{min:1024,max:128*1024,default:6144},sdCardMb:{min:0,max:32*1024,default:512}},Z=n(),de=[`phone`,`tablet`,`tv`,`wear`,`automotive`,`desktop`,`other`],fe={phone:`Phones`,tablet:`Tablets`,tv:`TV`,wear:`Wear`,automotive:`Automotive`,desktop:`Desktop`,other:`Other`},pe=e=>`${(e/1024**3).toFixed(1)} GB`;function me({open:e,onClose:t,existingNames:n,onCreated:r}){let a=ee(),[o,s]=(0,Y.useState)(null),[c,l]=(0,Y.useState)(null),[u,d]=(0,Y.useState)(null),[p,m]=(0,Y.useState)(``),[h,g]=(0,Y.useState)(``),[_,v]=(0,Y.useState)(``),[y,b]=(0,Y.useState)(String(X.ramMb.default)),[x,S]=(0,Y.useState)(String(X.storageMb.default)),[C,w]=(0,Y.useState)(!1),[T,E]=(0,Y.useState)(null);(0,Y.useEffect)(()=>{if(!e)return;let t=!0;return d(null),(async()=>{try{let[e,n]=await Promise.all([L.get(`/api/android/system-images`),L.get(`/api/android/device-profiles`)]);if(!t)return;s(e.images),l(n.profiles);let r=e.images.filter(e=>e.hostCompatible).slice().sort((e,t)=>(t.apiLevel??0)-(e.apiLevel??0))[0];r&&g(e=>e||r.id),n.profiles.some(e=>e.id===`pixel_9`)&&v(e=>e||`pixel_9`)}catch(e){t&&d(e.message)}})(),()=>{t=!1}},[e]);let D=(0,Y.useMemo)(()=>(o??[]).map(e=>({value:e.hostCompatible?e.id:``,label:`API ${e.apiLevel??`?`} · ${e.tagDisplay} · ${e.abi}`,group:e.hostCompatible?`Runs on this host`:`Wrong CPU for this host`,hint:e.hostCompatible?pe(e.bytes):`needs ${e.abi}`,title:e.id})),[o]),k=(0,Y.useMemo)(()=>{let e=c??[];return de.flatMap(t=>e.filter(e=>e.kind===t).map(e=>({value:e.id,label:e.name,group:fe[t],hint:e.oem})))},[c]),A=p.length===0?null:n.some(e=>e.toLowerCase()===p.toLowerCase())?`an AVD with that name already exists`:ue(p),j=Number(y),M=Number(x),P=Number.isFinite(j)&&j>=X.ramMb.min&&j<=X.ramMb.max?null:`RAM must be between ${X.ramMb.min} and ${X.ramMb.max} MB`,F=Number.isFinite(M)&&M>=X.storageMb.min&&M<=X.storageMb.max?null:`Storage must be between ${X.storageMb.min} and ${X.storageMb.max} MB`,I=p.length>0&&!A&&!P&&!F&&h!==``&&_!==``&&!C,R=()=>{m(``),E(null),w(!1),b(String(X.ramMb.default)),S(String(X.storageMb.default))},z=async()=>{if(I){w(!0),E(null);try{await L.post(`/api/android/avds`,{name:p,systemImage:h,deviceProfile:_,ramMb:j,storageMb:M}),r(p),R(),t()}catch(e){E(e.message),w(!1)}}},B=!u&&(o===null||c===null),G=(0,Z.jsxs)(`div`,{className:`space-y-4`,children:[u&&(0,Z.jsxs)(`p`,{className:`flex items-start gap-2 text-sm leading-relaxed text-destructive`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:u})]}),B&&(0,Z.jsxs)(`p`,{className:`flex items-center gap-2 py-6 text-sm text-muted-foreground`,children:[(0,Z.jsx)(N,{className:`size-4 animate-spin`}),` Reading the SDK…`]}),!B&&!u&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsx)(`label`,{htmlFor:`avd-name`,className:`text-sm font-medium`,children:`Name`}),(0,Z.jsx)(q,{id:`avd-name`,value:p,onChange:e=>m(e.target.value),placeholder:`Pixel_9_API_35`,autoComplete:`off`,spellCheck:!1,className:`h-11`}),A?(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-destructive`,children:A}):(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`This becomes a folder name, so no spaces.`})]}),(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium`,children:`System image`}),(0,Z.jsx)(J,{value:h,items:D,onChange:g,label:`System image`,searchPlaceholder:`Search images`,emptyText:`No system images are installed`,placeholder:`Pick an installed image`,icon:f,className:`h-11 w-full md:h-9`,modal:!a}),(0,Z.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`Only images already downloaded on this host. PPM never downloads one for you — use Android Studio's SDK Manager, or`,` `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 text-[11px]`,children:`sdkmanager`}),`.`]})]}),(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium`,children:`Device`}),(0,Z.jsx)(J,{value:_,items:k,onChange:v,label:`Device profile`,searchPlaceholder:`Search devices`,emptyText:`No device profiles`,placeholder:`Pick a device`,icon:i,className:`h-11 w-full md:h-9`,modal:!a}),(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`Sets the screen. Without one the emulator is 320x640.`})]}),(0,Z.jsxs)(`div`,{className:`flex gap-3`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1.5`,children:[(0,Z.jsx)(`label`,{htmlFor:`avd-ram`,className:`text-sm font-medium`,children:`RAM (MB)`}),(0,Z.jsx)(q,{id:`avd-ram`,inputMode:`numeric`,value:y,className:`h-11`,onChange:e=>b(e.target.value)})]}),(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1.5`,children:[(0,Z.jsx)(`label`,{htmlFor:`avd-storage`,className:`text-sm font-medium`,children:`Storage (MB)`}),(0,Z.jsx)(q,{id:`avd-storage`,inputMode:`numeric`,value:x,className:`h-11`,onChange:e=>S(e.target.value)})]})]}),(P||F)&&(0,Z.jsx)(`p`,{className:`text-xs leading-relaxed text-destructive`,children:P??F}),(0,Z.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`PPM writes `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 text-[11px]`,children:`hw.keyboard=yes`}),` `,`into every AVD it creates — without it the emulator accepts key presses and shows nothing.`]})]}),T&&(0,Z.jsxs)(`p`,{className:`flex items-start gap-2 text-sm leading-relaxed text-destructive`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:T})]}),(0,Z.jsxs)(`div`,{className:`flex flex-col-reverse gap-2 pt-2 md:flex-row md:justify-end`,children:[(0,Z.jsx)(V,{variant:`outline`,className:`min-h-11`,onClick:()=>{R(),t()},children:`Cancel`}),(0,Z.jsx)(V,{className:`min-h-11`,disabled:!I,onClick:()=>void z(),children:C?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(N,{className:`animate-spin`}),` Creating…`]}):`Create device`})]})]});return e?a?(0,Z.jsx)(K,{open:!0,onClose:t,children:(0,Z.jsxs)(`div`,{className:`max-h-[80vh] overflow-y-auto px-4 pb-4`,children:[(0,Z.jsx)(`h2`,{className:`mb-3 text-base font-semibold`,children:`New Android device`}),G]})}):(0,Z.jsx)(ne,{open:!0,onOpenChange:e=>!e&&t(),children:(0,Z.jsxs)(U,{className:`sm:max-w-lg`,children:[(0,Z.jsxs)(H,{children:[(0,Z.jsx)(W,{children:`New Android device`}),(0,Z.jsx)(te,{children:`Built from a system image already installed on this host.`})]}),(0,Z.jsx)(`div`,{className:`max-h-[70vh] overflow-y-auto pr-1`,children:G})]})}):null}function he({action:e,avdId:t,deviceName:n,onCancel:r,onDone:i}){let a=ee(),[o,s]=(0,Y.useState)(``),[c,l]=(0,Y.useState)(!1),[u,d]=(0,Y.useState)(null);if((0,Y.useEffect)(()=>{s(``),d(null),l(!1)},[e,t]),!e)return null;let f=e===`delete`,p=f?`Delete this device`:`Wipe this device`,m=o===n&&!c,h=async()=>{if(m){l(!0),d(null);try{f?(await L.del(`/api/android/avds/${encodeURIComponent(t)}`,{confirmName:n}),i(`delete`,`Deleted ${n}`)):i(`wipe`,(await L.post(`/api/android/avds/${encodeURIComponent(t)}/wipe`,{confirmName:n})).message)}catch(e){d(e.message),l(!1)}}},g=(0,Z.jsxs)(`div`,{className:`space-y-4`,children:[(0,Z.jsx)(`p`,{className:`text-sm leading-relaxed`,children:f?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`span`,{className:`font-medium`,children:n}),` and everything in it will be removed from disk. The AVD, its settings and its installed apps are gone for good — this is not a recycle bin.`]}):(0,Z.jsxs)(Z.Fragment,{children:[`Everything inside `,(0,Z.jsx)(`span`,{className:`font-medium`,children:n}),` goes back to factory: installed apps, accounts, files and saved snapshots. The device itself and its settings stay, and the next start is a cold boot.`]})}),(0,Z.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Z.jsxs)(`label`,{htmlFor:`avd-confirm`,className:`text-sm font-medium`,children:[`Type `,(0,Z.jsx)(`span`,{className:`font-mono`,children:n}),` to confirm`]}),(0,Z.jsx)(q,{id:`avd-confirm`,value:o,onChange:e=>s(e.target.value),autoComplete:`off`,spellCheck:!1,autoCapitalize:`off`,className:`h-11 font-mono`})]}),u&&(0,Z.jsxs)(`p`,{className:`flex items-start gap-2 text-sm leading-relaxed text-destructive`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:u})]}),(0,Z.jsxs)(`div`,{className:`flex flex-col-reverse gap-2 pt-2 md:flex-row md:justify-end`,children:[(0,Z.jsx)(V,{variant:`outline`,className:`min-h-11`,onClick:r,children:`Cancel`}),(0,Z.jsx)(V,{variant:`destructive`,className:`min-h-11`,autoFocus:!1,disabled:!m,onClick:()=>void h(),children:c?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(N,{className:`animate-spin`}),` `,f?`Deleting…`:`Wiping…`]}):f?`Delete device`:`Wipe data`})]})]});return a?(0,Z.jsx)(K,{open:!0,onClose:r,children:(0,Z.jsxs)(`div`,{className:`px-4 pb-4`,children:[(0,Z.jsx)(`h2`,{className:`mb-3 text-base font-semibold`,children:p}),g]})}):(0,Z.jsx)(ne,{open:!0,onOpenChange:e=>!e&&r(),children:(0,Z.jsxs)(U,{className:`sm:max-w-md`,children:[(0,Z.jsxs)(H,{children:[(0,Z.jsx)(W,{children:p}),(0,Z.jsx)(te,{children:f?`This cannot be undone.`:`A factory reset — the device itself stays.`})]}),g]})})}var ge=1500;function _e({onOpen:e}){let[t,n]=(0,Y.useState)(null),[o,s]=(0,Y.useState)([]),[u,d]=(0,Y.useState)(null),[f,p]=(0,Y.useState)({}),[m,h]=(0,Y.useState)(!1),[g,_]=(0,Y.useState)(null),y=(0,Y.useRef)(!0),S=(0,Y.useCallback)(async()=>{try{let e=await L.get(`/api/android/capabilities`);if(!y.current||(n(e),!e.enabled))return;let t=await L.get(`/api/android/devices`);if(!y.current)return;s(t.devices),d(null)}catch(e){y.current&&d(e.message)}},[]);(0,Y.useEffect)(()=>{y.current=!0,S();let e=setInterval(()=>void S(),ge*4);return()=>{y.current=!1,clearInterval(e)}},[S]);let C=(0,Y.useCallback)(async e=>{p(t=>({...t,[e.avdId]:`Starting…`}));try{let{operationId:t}=await L.post(`/api/android/avds/${encodeURIComponent(e.avdId)}/start`,{});for(;;){if(await new Promise(e=>setTimeout(e,ge)),!y.current)return;let n=await L.get(`/api/android/operations/${t}`);if(p(t=>({...t,[e.avdId]:n.detail??`Starting…`})),n.state===`succeeded`)break;if(n.state===`failed`||n.state===`cancelled`){d(n.error??`the emulator failed to start`);break}}}catch(e){y.current&&d(e.message)}finally{y.current&&(p(t=>{let n={...t};return delete n[e.avdId],n}),S())}},[S]),w=(0,Y.useCallback)(async e=>{if(e.runtime){p(t=>({...t,[e.avdId]:`Stopping…`}));try{await L.post(`/api/android/devices/${encodeURIComponent(e.runtime.deviceId)}/stop?generation=${e.runtime.generation}`,{})}catch(e){y.current&&d(e.message)}finally{y.current&&(p(t=>{let n={...t};return delete n[e.avdId],n}),S())}}},[S]);if(!t)return(0,Z.jsxs)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:[(0,Z.jsx)(N,{className:`mr-2 size-4 animate-spin`}),` Checking this host…`]});let T=t.requirements.filter(e=>!e.met);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 border-b px-4 py-3`,children:[(0,Z.jsx)(i,{className:`size-4 shrink-0 text-muted-foreground`}),(0,Z.jsx)(`h2`,{className:`min-w-0 flex-1 truncate text-sm font-medium`,children:`Android devices`}),t.canCreateAvd&&(0,Z.jsxs)(V,{size:`sm`,className:`h-10`,onClick:()=>h(!0),children:[(0,Z.jsx)(v,{}),` New device`]}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-10`,onClick:()=>void S(),title:`Refresh`,"aria-label":`Refresh`,children:(0,Z.jsx)(x,{})})]}),(0,Z.jsxs)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-4`,children:[u&&(0,Z.jsxs)(`div`,{className:`mb-4 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-destructive`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1 leading-relaxed`,children:u})]}),T.length>0&&(0,Z.jsxs)(`div`,{className:`mb-4 rounded-md border p-4`,children:[(0,Z.jsx)(`p`,{className:`text-sm font-medium`,children:`This host is not ready yet`}),(0,Z.jsx)(`ul`,{className:`mt-3 space-y-3`,children:t.requirements.map(e=>(0,Z.jsxs)(`li`,{className:`flex items-start gap-2 text-sm leading-relaxed`,children:[e.met?(0,Z.jsx)(r,{className:`mt-0.5 size-4 shrink-0 text-muted-foreground`}):(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-destructive`}),(0,Z.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`span`,{className:R(!e.met&&`font-medium`),children:e.label}),(0,Z.jsx)(`span`,{className:`block text-muted-foreground`,children:e.detail}),!e.met&&e.fix&&(0,Z.jsx)(`code`,{className:`mt-1 block overflow-x-auto rounded bg-muted px-2 py-1 text-xs`,children:e.fix})]})]},e.id))})]}),o.length===0&&T.length===0&&(0,Z.jsxs)(`div`,{className:`py-8 text-center`,children:[(0,Z.jsx)(`p`,{className:`text-sm leading-relaxed text-muted-foreground`,children:`No AVDs on this host yet.`}),t.canCreateAvd?(0,Z.jsxs)(V,{className:`mt-4 min-h-11`,onClick:()=>h(!0),children:[(0,Z.jsx)(v,{}),` New device`]}):(0,Z.jsxs)(`p`,{className:`mt-2 text-sm leading-relaxed text-muted-foreground`,children:[`Create one in Android Studio, or with`,` `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 py-0.5 text-xs`,children:`avdmanager create avd`}),`.`]})]}),(0,Z.jsx)(`ul`,{className:`space-y-2`,children:o.map(n=>{let r=n.runtime!==null,i=f[n.avdId];return(0,Z.jsxs)(`li`,{className:`flex flex-col gap-3 rounded-md border p-4 sm:flex-row sm:items-center`,children:[(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`p`,{className:`truncate text-sm font-medium`,children:n.name}),(0,Z.jsx)(`p`,{className:`mt-0.5 text-xs leading-relaxed text-muted-foreground`,children:[n.apiLevel?`API ${n.apiLevel}`:null,n.abi,n.displayWidth&&n.displayHeight?`${n.displayWidth}x${n.displayHeight}`:null,r?n.runtime.ownedByPpm?`running (PPM)`:`running (external)`:null].filter(Boolean).join(` · `)}),n.lockedByAnotherProcess&&(0,Z.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-destructive`,children:`Locked by another process — it is probably open in Android Studio.`}),!n.hardwareKeyboard&&(0,Z.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`This AVD has no hardware keyboard, so typing will not reach it. Set`,` `,(0,Z.jsx)(`code`,{className:`rounded bg-muted px-1 text-[11px]`,children:`hw.keyboard=yes`}),` in its config.ini.`]})]}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[i&&(0,Z.jsxs)(`span`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,Z.jsx)(N,{className:`size-3.5 animate-spin`}),` `,i]}),r?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(V,{size:`sm`,className:`h-10`,onClick:()=>e(n),children:`View`}),n.runtime.ownedByPpm&&(0,Z.jsxs)(V,{size:`sm`,variant:`outline`,className:`h-10`,disabled:!!i,onClick:()=>void w(n),children:[(0,Z.jsx)(l,{}),` Stop`]})]}):(0,Z.jsxs)(V,{size:`sm`,className:`h-10`,disabled:!!i||n.lockedByAnotherProcess||!t.ready,onClick:()=>void C(n),children:[(0,Z.jsx)(D,{}),` Start`]}),(0,Z.jsxs)(ae,{children:[(0,Z.jsx)(re,{asChild:!0,children:(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-10`,title:`More for ${n.name}`,"aria-label":`More for ${n.name}`,children:(0,Z.jsx)(a,{})})}),(0,Z.jsxs)(ie,{align:`end`,children:[(0,Z.jsxs)(G,{className:`min-h-11 md:min-h-0`,disabled:r||n.lockedByAnotherProcess||!!i,onSelect:()=>_({action:`wipe`,device:n}),children:[(0,Z.jsx)(b,{}),` Wipe data`]}),(0,Z.jsxs)(G,{variant:`destructive`,className:`min-h-11 md:min-h-0`,disabled:r||n.lockedByAnotherProcess||!!i||!t.canCreateAvd,onSelect:()=>_({action:`delete`,device:n}),children:[(0,Z.jsx)(c,{}),` Delete device`]})]})]})]})]},n.avdId)})})]}),(0,Z.jsx)(me,{open:m,onClose:()=>h(!1),existingNames:o.map(e=>e.name),onCreated:e=>{I.success(`Created ${e}`),S()}}),(0,Z.jsx)(he,{action:g?.action??null,avdId:g?.device.avdId??``,deviceName:g?.device.name??``,onCancel:()=>_(null),onDone:(e,t)=>{_(null),I.success(t),S()}})]})}var ve={low:`Low`,balanced:`Balanced`,high:`High`};function ye(e){let{send:t,controller:n,rotation:r,quality:i,onQualityChange:a,onKeyboard:o,layout:c}=e,[u,f]=(0,Y.useState)(!1),p=c===`bar`,m=p?`size-11`:`size-9`,h=e=>()=>t({type:`hardware`,key:e});return(0,Z.jsxs)(`div`,{className:R(`flex items-center gap-2`,be(p)),children:[(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`back`),title:`Back`,"aria-label":`Back`,children:(0,Z.jsx)(A,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`home`),title:`Home`,"aria-label":`Home`,children:(0,Z.jsx)(s,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`recent`),title:`Recent apps`,"aria-label":`Recent apps`,children:(0,Z.jsx)(l,{})}),(0,Z.jsx)(`span`,{className:`mx-1 h-6 w-px shrink-0 bg-border`,"aria-hidden":!0}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:o,title:`Keyboard`,"aria-label":`Keyboard`,children:(0,Z.jsx)(j,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:()=>t({type:`rotate`,rotation:xe(r)}),title:`Rotate (now ${r}°)`,"aria-label":`Rotate`,children:(0,Z.jsx)(g,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:()=>f(e=>!e),title:`More keys`,"aria-label":`More keys`,"aria-expanded":u,children:(0,Z.jsx)(d,{})}),u&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`volume-up`),title:`Volume up`,"aria-label":`Volume up`,children:(0,Z.jsx)(k,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`volume-down`),title:`Volume down`,"aria-label":`Volume down`,children:(0,Z.jsx)(w,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:m,disabled:!n,onClick:h(`power`),title:`Power`,"aria-label":`Power`,children:(0,Z.jsx)(C,{})})]}),(0,Z.jsx)(`span`,{className:`flex-1`}),(0,Z.jsx)(`label`,{className:`sr-only`,htmlFor:`android-quality`,children:`Quality`}),(0,Z.jsx)(`select`,{id:`android-quality`,className:R(`rounded-md border bg-background px-2 text-sm`,p?`h-11`:`h-9`),value:i,disabled:!n,onChange:e=>a(e.target.value),children:Object.keys(ve).map(e=>(0,Z.jsx)(`option`,{value:e,children:ve[e]},e))})]})}function be(e){return e?`w-full justify-center border-t bg-background/95 px-3 py-2 backdrop-blur`:`px-2 py-1`}function xe(e){return(e+90)%360}function Se({deviceId:e}){let[t,n]=(0,Y.useState)(null),[i,a]=(0,Y.useState)(``),[o,s]=(0,Y.useState)(null),[c,l]=(0,Y.useState)(!1),[u,d]=(0,Y.useState)(null),f=(0,Y.useCallback)(async()=>{s(`read`),d(null);try{n((await L.get(`/api/android/devices/${encodeURIComponent(e)}/clipboard`)).text)}catch(e){d(e.message)}finally{s(null)}},[e]),p=(0,Y.useCallback)(async()=>{s(`write`),d(null);try{await L.post(`/api/android/devices/${encodeURIComponent(e)}/clipboard`,{text:i}),l(!0),setTimeout(()=>l(!1),1500)}catch(e){d(e.message)}finally{s(null)}},[e,i]);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col gap-4 overflow-auto p-3`,children:[(0,Z.jsxs)(`section`,{className:`flex flex-col gap-2`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(`h3`,{className:`flex-1 text-sm font-medium`,children:`From the device`}),(0,Z.jsxs)(V,{variant:`secondary`,className:`h-11 md:h-9`,onClick:()=>void f(),disabled:o!==null,children:[o===`read`?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(m,{}),` Read`]})]}),t!==null&&(0,Z.jsx)(`textarea`,{readOnly:!0,value:t,rows:3,placeholder:`(the device's clipboard is empty)`,className:`w-full resize-y rounded-md border bg-muted/40 p-2 font-mono text-xs`})]}),(0,Z.jsxs)(`section`,{className:`flex flex-col gap-2 border-t pt-3`,children:[(0,Z.jsx)(`h3`,{className:`text-sm font-medium`,children:`To the device`}),(0,Z.jsx)(`textarea`,{value:i,onChange:e=>a(e.target.value),rows:3,placeholder:`Text to put on the device's clipboard`,className:`w-full resize-y rounded-md border bg-background p-2 font-mono text-xs`}),(0,Z.jsxs)(V,{className:`h-11 self-start md:h-9`,onClick:()=>void p(),disabled:o!==null||i.length===0,children:[c?(0,Z.jsx)(r,{}):o===`write`?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(h,{}),c?`Sent`:`Send to device`]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Paste it in the guest with a long press, or with the keyboard's paste key.`})]}),u&&(0,Z.jsx)(`p`,{className:`text-sm text-destructive`,children:u})]})}function Ce(e,t,n){let r=new URLSearchParams({filename:t});return n&&r.set(`downgrade`,`1`),`/api/android/devices/${encodeURIComponent(e)}/apk?${r.toString()}`}function we(e,t){let n=null;try{n=JSON.parse(t)}catch{}let r=n;if(e>=200&&e<300&&r?.ok&&r.data?.operationId)return{operationId:r.data.operationId};throw Error(r?.error??(t.trim()||`the upload failed with HTTP ${e}`))}function Te(e){let t=new XMLHttpRequest,n=!1;return{done:new Promise((n,r)=>{t.open(`POST`,Ce(e.deviceId,e.file.name,e.allowDowngrade===!0)),e.token&&t.setRequestHeader(`Authorization`,`Bearer ${e.token}`),t.setRequestHeader(`Content-Type`,`application/vnd.android.package-archive`),t.setRequestHeader(`x-ppm-client`,`web`),t.upload.onprogress=t=>{t.lengthComputable&&e.onProgress&&e.onProgress(t.loaded/t.total)},t.onload=()=>{try{n(we(t.status,t.responseText).operationId)}catch(e){r(e)}},t.onerror=()=>r(Error(`the upload could not reach the server`)),t.onabort=()=>r(Error(`cancelled`)),t.send(e.file)}),cancel(){n||(n=!0,t.abort())}}}var Ee=800;function De({deviceId:e,deviceName:t}){let n=z(e=>e.projects),[r,i]=(0,Y.useState)(``),[a,o]=(0,Y.useState)(null),[s,c]=(0,Y.useState)(!1),[l,u]=(0,Y.useState)(!1),[d,f]=(0,Y.useState)({kind:`idle`}),p=(0,Y.useRef)(null),m=(0,Y.useRef)(null),g=(0,Y.useRef)(d);g.current=d;let _=d.kind===`uploading`||d.kind===`installing`,v=(0,Y.useCallback)(async(e,t)=>{for(;;){await new Promise(e=>setTimeout(e,Ee));let n=g.current;if(n.kind!==`installing`||n.operationId!==e)return;let r;try{r=await L.get(`/api/android/operations/${encodeURIComponent(e)}`)}catch(e){f({kind:`failed`,message:e.message});return}if(r.state===`succeeded`){f({kind:`done`,filename:t});return}if(r.state===`failed`){f({kind:`failed`,message:r.error??`the install failed`});return}if(r.state===`cancelled`){f({kind:`idle`});return}f({kind:`installing`,operationId:e,detail:r.detail,filename:t})}},[]),y=(0,Y.useCallback)(t=>{f({kind:`uploading`,fraction:0,filename:t.name});let n=Te({deviceId:e,file:t,allowDowngrade:l,token:F(),onProgress:e=>f({kind:`uploading`,fraction:e,filename:t.name})});m.current=n,n.done.then(e=>{m.current=null,f({kind:`installing`,operationId:e,detail:`installing…`,filename:t.name}),v(e,t.name)}).catch(e=>{m.current=null,f(e.message===`cancelled`?{kind:`idle`}:{kind:`failed`,message:e.message})})},[e,l,v]),b=(0,Y.useCallback)(async t=>{let n=t.split(`/`).pop()??t;f({kind:`installing`,operationId:``,detail:`starting…`,filename:n});try{let{operationId:i}=await L.post(`/api/android/devices/${encodeURIComponent(e)}/apk/project`,{project:r,path:t,downgrade:l});f({kind:`installing`,operationId:i,detail:`installing…`,filename:n}),v(i,n)}catch(e){f({kind:`failed`,message:e.message})}},[e,r,l,v]),S=(0,Y.useCallback)(()=>{if(d.kind===`uploading`){m.current?.cancel();return}d.kind===`installing`&&d.operationId&&(L.post(`/api/android/operations/${encodeURIComponent(d.operationId)}/cancel`,{}).catch(()=>{}),f({kind:`idle`}))},[d]),C=(0,Y.useCallback)(async e=>{if(!e){o(null);return}c(!0);try{o((await L.get(`/api/android/projects/${encodeURIComponent(e)}/apks`)).apks)}catch{o([])}finally{c(!1)}},[]);return(0,Y.useEffect)(()=>{C(r)},[r,C]),(0,Y.useEffect)(()=>()=>m.current?.cancel(),[]),(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col gap-3 overflow-auto p-3`,children:[(0,Z.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Installing on `,t,`.`]}),(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`input`,{ref:p,type:`file`,accept:`.apk,application/vnd.android.package-archive`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,t&&y(t)}}),(0,Z.jsxs)(V,{className:`h-11 md:h-9`,disabled:_,onClick:()=>p.current?.click(),children:[(0,Z.jsx)(h,{}),` Choose an APK`]}),(0,Z.jsxs)(`label`,{className:`flex min-h-11 cursor-pointer items-center gap-2 text-sm md:min-h-9`,children:[(0,Z.jsx)(`input`,{type:`checkbox`,className:`size-4`,checked:l,disabled:_,onChange:e=>u(e.target.checked)}),`Allow downgrade`]})]}),(0,Z.jsx)(Oe,{phase:d,onCancel:S,onDismiss:()=>f({kind:`idle`})}),(0,Z.jsxs)(`div`,{className:`flex flex-col gap-2 border-t pt-3`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(`label`,{className:`text-sm`,htmlFor:`android-apk-project`,children:`From a project`}),(0,Z.jsxs)(`select`,{id:`android-apk-project`,className:`h-11 min-w-0 flex-1 rounded-md border bg-background px-2 text-sm md:h-9`,value:r,onChange:e=>i(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`Choose a project…`}),n.map(e=>(0,Z.jsx)(`option`,{value:e.name,children:e.name},e.name))]}),r&&(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,disabled:s,onClick:()=>void C(r),title:`Rescan`,"aria-label":`Rescan`,children:s?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(x,{})})]}),s&&(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Looking for APKs…`}),!s&&a?.length===0&&(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No .apk files in that project yet — build one and press rescan.`}),!s&&a&&a.length>0&&(0,Z.jsx)(`ul`,{className:`flex flex-col gap-1`,children:a.map(e=>(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{type:`button`,disabled:_,onClick:()=>void b(e.path),className:R(`flex min-h-11 w-full flex-col items-start rounded-md border px-3 py-2 text-left text-sm md:min-h-9`,_?`opacity-50`:`hover:bg-accent`),children:[(0,Z.jsx)(`span`,{dir:`rtl`,className:`w-full truncate`,children:(0,Z.jsx)(`bdi`,{children:e.path})}),(0,Z.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[ke(e.bytes),` · `,new Date(e.modifiedAt).toLocaleString()]})]})},e.path))})]})]})}function Oe({phase:e,onCancel:t,onDismiss:n}){if(e.kind===`idle`)return null;if(e.kind===`uploading`||e.kind===`installing`){let n=e.kind===`uploading`?Math.round(e.fraction*100):null,r=e.kind===`installing`?e.detail:``;return(0,Z.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-md border p-3`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[(0,Z.jsx)(N,{className:`size-4 shrink-0 animate-spin`}),(0,Z.jsx)(`span`,{dir:`rtl`,className:`min-w-0 flex-1 truncate`,children:(0,Z.jsx)(`bdi`,{children:e.filename})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-9`,onClick:t,title:`Cancel`,"aria-label":`Cancel`,children:(0,Z.jsx)(S,{})})]}),n===null?(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`div`,{className:`h-1.5 overflow-hidden rounded-full bg-muted`,children:(0,Z.jsx)(`div`,{className:`h-full bg-primary transition-[width]`,style:{width:`${n}%`}})}),(0,Z.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Uploading — `,n,`%`]})]})]})}return e.kind===`done`?(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-emerald-600/40 bg-emerald-600/10 p-3 text-sm`,children:[(0,Z.jsx)(r,{className:`size-4 shrink-0 text-emerald-600 dark:text-emerald-400`}),(0,Z.jsx)(`span`,{dir:`rtl`,className:`min-w-0 flex-1 truncate`,children:(0,Z.jsx)(`bdi`,{children:e.filename})}),(0,Z.jsx)(`span`,{className:`shrink-0 text-muted-foreground`,children:`installed`}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-9`,onClick:n,"aria-label":`Dismiss`,children:(0,Z.jsx)(S,{})})]}):(0,Z.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm`,children:[(0,Z.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-destructive`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1`,children:e.message}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-9`,onClick:n,"aria-label":`Dismiss`,children:(0,Z.jsx)(S,{})})]})}function ke(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/1024/1024).toFixed(1)} MB`}var Ae=[`verbose`,`debug`,`info`,`warn`,`error`,`fatal`],je=new Map(Ae.map((e,t)=>[e,t]));function Me(e,t){return(je.get(e)??0)>=(je.get(t)??0)}var Ne={minimum:`verbose`,text:``,pid:0};function Pe(e,t){if(!Me(e.level,t.minimum)||t.pid!==0&&e.pid!==t.pid)return!1;let n=t.text.trim().toLowerCase();return n.length===0?!0:e.tag.toLowerCase().includes(n)||e.message.toLowerCase().includes(n)}function Fe(e,t,n){if(t.length===0)return e;let r=e.length>0?e[e.length-1].id:0,i=t[0].id>r?t:t.filter(e=>e.id>r);if(i.length===0)return e;let a=e.concat(i);return a.length>n?a.slice(a.length-n):a}function Ie(e){let t=new Date(e),n=(e,t=2)=>String(e).padStart(t,`0`);return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}.${n(t.getMilliseconds(),3)}`}function Le(e){let t={verbose:`V`,debug:`D`,info:`I`,warn:`W`,error:`E`,fatal:`F`};return e.map(e=>`${Ie(e.timestamp)} ${String(e.pid).padStart(5)} ${String(e.tid).padStart(5)} ${t[e.level]} ${e.tag}: ${e.message}`).join(`
2
2
  `)}var Re=1e3,ze=400,Q={verbose:`text-muted-foreground`,debug:`text-muted-foreground`,info:`text-foreground`,warn:`text-amber-600 dark:text-amber-400`,error:`text-destructive`,fatal:`text-destructive font-semibold`},Be={verbose:`V`,debug:`D`,info:`I`,warn:`W`,error:`E`,fatal:`F`};function Ve({setLogcat:e,onLog:t}){let[n,i]=(0,Y.useState)([]),[a,o]=(0,Y.useState)(Ne),[s,l]=(0,Y.useState)(!1),[u,d]=(0,Y.useState)(!1),[f,p]=(0,Y.useState)(!0),m=(0,Y.useRef)(null),h=(0,Y.useRef)(!1);h.current=s,(0,Y.useEffect)(()=>(e(!0),()=>e(!1)),[e]),(0,Y.useEffect)(()=>t(e=>{h.current||i(t=>Fe(t,e,Re))}),[t]);let g=(0,Y.useMemo)(()=>{let e=n.filter(e=>Pe(e,a));return e.length>ze?e.slice(e.length-ze):e},[n,a]);(0,Y.useEffect)(()=>{if(!f)return;let e=m.current;e&&(e.scrollTop=e.scrollHeight)},[g,f]);let _=(0,Y.useCallback)(()=>{let e=m.current;e&&p(e.scrollHeight-e.scrollTop-e.clientHeight<24)},[]),v=(0,Y.useCallback)(async()=>{let e=Le(g);try{navigator.clipboard?.writeText?await navigator.clipboard.writeText(e):He(e),d(!0),setTimeout(()=>d(!1),1500)}catch{He(e)}},[g]);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col bg-background`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 border-b p-2`,children:[(0,Z.jsxs)(`div`,{className:`relative min-w-40 flex-1`,children:[(0,Z.jsx)(P,{className:`pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,Z.jsx)(q,{className:`h-11 pl-8 md:h-9`,placeholder:`Filter tag or message`,value:a.text,onChange:e=>o(t=>({...t,text:e.target.value}))})]}),(0,Z.jsx)(`label`,{className:`sr-only`,htmlFor:`android-log-level`,children:`Minimum level`}),(0,Z.jsx)(`select`,{id:`android-log-level`,className:`h-11 rounded-md border bg-background px-2 text-sm md:h-9`,value:a.minimum,onChange:e=>o(t=>({...t,minimum:e.target.value})),children:Ae.map(e=>(0,Z.jsx)(`option`,{value:e,children:e[0].toUpperCase()+e.slice(1)},e))}),(0,Z.jsx)(V,{variant:s?`default`:`ghost`,size:`icon`,className:`size-11 md:size-9`,onClick:()=>l(e=>!e),title:s?`Resume`:`Pause the view`,"aria-label":s?`Resume`:`Pause the view`,"aria-pressed":s,children:s?(0,Z.jsx)(D,{}):(0,Z.jsx)(y,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,onClick:()=>i([]),title:`Clear the view`,"aria-label":`Clear the view`,children:(0,Z.jsx)(c,{})}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,onClick:()=>void v(),title:`Copy what is shown`,"aria-label":`Copy what is shown`,children:u?(0,Z.jsx)(r,{}):(0,Z.jsx)(M,{})})]}),(0,Z.jsx)(`div`,{ref:m,onScroll:_,className:`min-h-0 flex-1 overflow-auto px-2 py-1 font-mono text-[11px] leading-[1.45]`,children:g.length===0?(0,Z.jsx)(`p`,{className:`px-2 py-6 text-center text-sm text-muted-foreground`,children:n.length===0?`Waiting for the device to log something…`:`Nothing matches that filter.`}):g.map(e=>(0,Z.jsxs)(`div`,{className:`flex gap-2 whitespace-pre-wrap break-words`,children:[(0,Z.jsx)(`span`,{className:`shrink-0 tabular-nums text-muted-foreground`,children:Ie(e.timestamp)}),(0,Z.jsx)(`span`,{className:R(`w-3 shrink-0 text-center font-semibold`,Q[e.level]),children:Be[e.level]}),e.tag&&(0,Z.jsx)(`button`,{type:`button`,className:`shrink-0 max-w-40 truncate text-left text-muted-foreground hover:underline`,title:`Filter by ${e.tag}`,onClick:()=>o(t=>({...t,text:e.tag})),children:e.tag}),(0,Z.jsx)(`span`,{className:R(`min-w-0`,Q[e.level]),children:e.message})]},e.id))}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 border-t px-2 py-1 text-xs text-muted-foreground`,children:[(0,Z.jsx)(`span`,{children:g.length===n.length?`${n.length} lines`:`${g.length} of ${n.length} lines`}),s&&(0,Z.jsx)(`span`,{className:`text-amber-600 dark:text-amber-400`,children:`paused`}),(0,Z.jsx)(`span`,{className:`flex-1`}),!f&&(0,Z.jsxs)(V,{variant:`ghost`,size:`sm`,className:`h-8`,onClick:()=>p(!0),children:[(0,Z.jsx)(E,{}),` Follow`]})]})]})}function He(e){let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.left=`-9999px`,t.setAttribute(`readonly`,``),document.body.appendChild(t);try{t.select(),document.execCommand(`copy`)}finally{t.remove()}}var Ue=[{id:`install`,label:`Install`,Icon:i},{id:`logs`,label:`Logs`,Icon:_},{id:`clipboard`,label:`Clipboard`,Icon:m}];function We(e){let{tool:t,onToolChange:n,onClose:r,deviceId:i,deviceName:a,setLogcat:o,onLog:s}=e;return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col border-t bg-background`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-1 border-b px-1`,children:[Ue.map(({id:e,label:r,Icon:i})=>(0,Z.jsxs)(`button`,{type:`button`,onClick:()=>n(e),"aria-current":t===e,className:R(`flex min-h-11 items-center gap-1.5 border-b-2 px-3 text-sm md:min-h-9`,t===e?`border-primary font-medium text-foreground`:`border-transparent text-muted-foreground hover:text-foreground`),children:[(0,Z.jsx)(i,{className:`size-4`}),r]},e)),(0,Z.jsx)(`span`,{className:`flex-1`}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,onClick:r,title:`Hide the tools`,"aria-label":`Hide the tools`,children:(0,Z.jsx)(u,{})})]}),(0,Z.jsxs)(`div`,{className:`min-h-0 flex-1`,children:[t===`install`&&(0,Z.jsx)(De,{deviceId:i,deviceName:a}),t===`logs`&&(0,Z.jsx)(Ve,{setLogcat:o,onLog:s}),t===`clipboard`&&(0,Z.jsx)(Se,{deviceId:i})]})]})}function Ge(e,t){if(!e)return t;let n=e.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);if(n?.[1])try{return decodeURIComponent(n[1].trim())||t}catch{}let r=(e.match(/filename\s*=\s*"([^"]*)"/i)??e.match(/filename\s*=\s*([^;]+)/i))?.[1]?.trim();return r&&r.length>0?r:t}function Ke(e){return`/api/android/devices/${encodeURIComponent(e)}/screenshot`}function qe(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,document.body.appendChild(r),r.click(),r.remove(),setTimeout(()=>URL.revokeObjectURL(n),1e4)}async function Je(e,t,n){let r=await fetch(Ke(e),{headers:t?{Authorization:`Bearer ${t}`,"x-ppm-client":`web`}:{"x-ppm-client":`web`}});if(!r.ok){let e=`the screenshot failed with HTTP ${r.status}`;try{let t=await r.json();t?.error&&(e=t.error)}catch{}throw Error(e)}qe(await r.blob(),Ge(r.headers.get(`content-disposition`),n))}var Ye={deleteContentBackward:`Backspace`,deleteContentForward:`Delete`,insertLineBreak:`Enter`,insertParagraph:`Enter`},Xe=new Set([`Enter`,`Backspace`,`Delete`,`Tab`,`Escape`,`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`,`Home`,`End`,`PageUp`,`PageDown`]);function Ze(e){let{geometry:t,enabled:n,send:r}=e,i=(0,Y.useRef)(null),a=(0,Y.useRef)(t);a.current=t;let o=(0,Y.useRef)(n);return o.current=n,(0,Y.useEffect)(()=>{let e=i.current;if(!e)return;let t=e=>{let t=e;if(!o.current)return;t.preventDefault();let n=Ye[t.inputType];if(n){let e=a.current;e&&r({type:`key`,geometryGeneration:e.generation,key:n,action:`press`});return}let i=t.data??t.dataTransfer?.getData(`text/plain`)??``;i&&r(t.inputType===`insertFromPaste`?{type:`paste`,text:i}:{type:`text`,text:i})},n=e=>{if(!o.current||!Xe.has(e.key))return;e.preventDefault();let t=a.current;t&&r({type:`key`,geometryGeneration:t.generation,key:e.key,action:`press`})};return e.addEventListener(`beforeinput`,t),e.addEventListener(`keydown`,n),()=>{e.removeEventListener(`beforeinput`,t),e.removeEventListener(`keydown`,n)}},[r]),{inputRef:i,focus:(0,Y.useCallback)(()=>i.current?.focus(),[]),blur:(0,Y.useCallback)(()=>i.current?.blur(),[])}}function Qe(e,t,n=`8081`){let r=oe(`/ws/android`),i=e.protocol===`https:`?`wss:`:`ws:`;return t&&e.protocol!==`https:`?`ws://${e.hostname}:${n}${r}`:`${i}//${e.host}${r}`}function $e(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);if(t.length<22)return null;let n=new DataView(t.buffer,t.byteOffset,t.byteLength),r=n.getUint8(1),i=n.getUint32(18,!0);return t.length-22===i?{header:{version:n.getUint8(0),keyframe:(r&1)!=0,codecConfig:(r&2)!=0,sessionGeneration:n.getUint16(2,!0),geometryGeneration:n.getUint16(4,!0),sequence:n.getUint32(6,!0),ptsMs:n.getFloat64(10,!0),payloadLength:i},payload:t.subarray(22)}:null}var et=5e3,$=[500,1e3,2e3,4e3,8e3];function tt(e){let{deviceId:t,quality:n,canvasRef:r,paused:i=!1}=e,[a,o]=(0,Y.useState)(`connecting`),[s,c]=(0,Y.useState)(null),[l,u]=(0,Y.useState)(null),[d,f]=(0,Y.useState)(!1),[p,m]=(0,Y.useState)(null),[h,g]=(0,Y.useState)(null),[_,v]=(0,Y.useState)(!1),y=se(r),b=(0,Y.useRef)(null),x=(0,Y.useRef)(0),S=(0,Y.useRef)(0),C=(0,Y.useRef)(null),w=(0,Y.useRef)(null),T=(0,Y.useRef)(n);T.current=n;let E=(0,Y.useRef)(!1),D=(0,Y.useRef)(new Set),O=(0,Y.useRef)(!1),k=(0,Y.useCallback)(e=>{let t=b.current;t?.readyState===WebSocket.OPEN&&t.send(JSON.stringify(e))},[]),A=(0,Y.useCallback)(()=>k({type:`take-control`}),[k]),j=(0,Y.useCallback)(e=>{switch(e.type){case`ready`:x.current=0,o(`live`),c(null),u(e.geometry),f(e.controller),m(null),g(e.encoder),e.codec&&(w.current=e.codec,y.configure(e.codec)),O.current&&k({type:`logcat`,subscribe:!0});return;case`log`:for(let t of D.current)t(e.entries);return;case`codec`:if(e.codec===w.current)return;w.current=e.codec,y.configure(e.codec);return;case`geometry`:u(e.geometry),y.reset(),v(!1);return;case`controller`:f(e.controller),m(e.reason??null);return;case`error`:c(e.message);return;default:return}},[y,k]),M=(0,Y.useCallback)(()=>{S.current+=1,C.current&&clearTimeout(C.current),C.current=null,b.current?.close(),b.current=null},[]),N=(0,Y.useCallback)(async()=>{M();let e=S.current,n=()=>S.current===e;c(null);let r;try{r=(await L.post(`/api/android/devices/${encodeURIComponent(t)}/sessions`,{})).nonce}catch(e){if(!n())return;c(e.message),o(`failed`);return}if(!n())return;let i=new WebSocket(Qe(window.location,!1));i.binaryType=`arraybuffer`,b.current=i,i.onopen=()=>{i.send(JSON.stringify({type:`auth`,nonce:r,quality:T.current}))},i.onmessage=e=>{if(!n())return;if(typeof e.data==`string`){try{j(JSON.parse(e.data))}catch{}return}let t=$e(e.data);!t||t.header.version!==1||ce(E.current,t.header.keyframe)&&(E.current=!0,v(!0),y.decodeAccessUnit(t.payload,t.header.keyframe))},i.onclose=()=>{if(!n())return;b.current=null;let e=$[Math.min(x.current,$.length-1)];x.current+=1,o(x.current>$.length?`failed`:`reconnecting`),E.current=!1,v(!1),y.reset(),w.current=null,C.current=setTimeout(()=>{N()},e)},i.onerror=()=>{}},[t,y,j,M]);(0,Y.useEffect)(()=>(N(),()=>{M(),y.reset()}),[t]),(0,Y.useEffect)(()=>{let e=setInterval(()=>k({type:`heartbeat`}),et);return()=>clearInterval(e)},[k]),(0,Y.useEffect)(()=>{k({type:`visibility`,visible:!i})},[i,k]),(0,Y.useEffect)(()=>{a===`live`&&k({type:`quality`,quality:n})},[n,a,k]);let P=(0,Y.useCallback)(e=>{O.current=e,k({type:`logcat`,subscribe:e})},[k]),F=(0,Y.useCallback)(e=>{let t=D.current;return t.add(e),()=>{t.delete(e)}},[]),I=(0,Y.useCallback)(()=>{x.current=0,o(`connecting`),N()},[N]);return{state:a,errorMessage:s??y.errorMessage,geometry:l,controller:d,controllerReason:p,encoder:h,hasPicture:_,send:k,takeControl:A,reconnect:I,setLogcat:P,onLog:F}}function nt(e,t,n){if(t<=0||n<=0||e.width<=0||e.height<=0)return{left:0,top:0,width:0,height:0,scale:0};let r=Math.min(e.width/t,e.height/n),i=t*r,a=n*r;return{left:(e.width-i)/2,top:(e.height-a)/2,width:i,height:a,scale:r}}function rt(e,t,n,r,i){let a=nt(e,t,n);if(a.scale<=0)return null;let o=(r-a.left)/a.scale,s=(i-a.top)/a.scale;return o<0||s<0||o>t||s>n?null:{x:Math.min(o,t-1),y:Math.min(s,n-1)}}function it(e,t){let{width:n,height:r,deviceWidth:i,deviceHeight:a,rotation:o}=t;if(n<=0||r<=0)return{x:0,y:0};let s=e.x/n,c=e.y/r,l,u;switch(o){case 90:l=1-c,u=s;break;case 180:l=1-s,u=1-c;break;case 270:l=c,u=1-s;break;default:l=s,u=c;break}return{x:Math.round(l*i),y:Math.round(u*a)}}function at(e,t,n,r){let i=rt(e,t.width,t.height,n,r);return i?it(i,t):null}var ot=1,st=10;function ct(e){let{canvasRef:t,geometry:n,enabled:r,send:i}=e,a=(0,Y.useRef)(new Map),o=(0,Y.useRef)(n);o.current=n;let s=(0,Y.useRef)(r);s.current=r;let c=(0,Y.useCallback)(e=>{let t=o.current;if(!t)return;let n=[...a.current.values()].map(e=>({x:e.x,y:e.y,id:e.slot,pressure:ot}));e&&n.push({x:e.x,y:e.y,id:e.slot,pressure:0}),n.length!==0&&i({type:`touch`,geometryGeneration:t.generation,touches:n})},[i]),l=(0,Y.useCallback)(e=>{let n=t.current,r=o.current;if(!n||!r)return null;let i=n.getBoundingClientRect();return at(i,r,e.clientX-i.left,e.clientY-i.top)},[t]),u=(0,Y.useCallback)(e=>{if(!s.current)return;let t=l(e);if(!t||a.current.size>=st)return;let n=new Set([...a.current.values()].map(e=>e.slot)),r=0;for(;n.has(r);)r++;a.current.set(e.pointerId,{slot:r,x:t.x,y:t.y});try{e.currentTarget.setPointerCapture(e.pointerId)}catch{}c()},[l,c]),d=(0,Y.useCallback)(e=>{let t=a.current.get(e.pointerId);if(!t||!s.current)return;let n=l(e);n&&(t.x=n.x,t.y=n.y),c()},[l,c]),f=(0,Y.useCallback)(e=>{let t=a.current.get(e.pointerId);if(t){a.current.delete(e.pointerId);try{e.currentTarget.releasePointerCapture(e.pointerId)}catch{}c(t)}},[c]);return(0,Y.useEffect)(()=>{let e=()=>{a.current.size!==0&&(a.current.clear(),i({type:`input-reset`}))};return window.addEventListener(`blur`,e),document.addEventListener(`visibilitychange`,e),()=>{window.removeEventListener(`blur`,e),document.removeEventListener(`visibilitychange`,e),e()}},[i]),{onPointerDown:u,onPointerMove:d,onPointerUp:f,onPointerCancel:f}}function lt({deviceId:e,deviceName:t,hidden:n=!1,onBack:r}){let i=(0,Y.useRef)(null),[a,s]=(0,Y.useState)(`balanced`),[c,l]=(0,Y.useState)(null),[u,d]=(0,Y.useState)(!1),[f,m]=(0,Y.useState)(null),h=tt({deviceId:e,quality:a,canvasRef:i,paused:n}),g=ct({canvasRef:i,geometry:h.geometry,enabled:h.controller,send:h.send}),_=Ze({geometry:h.geometry,enabled:h.controller,send:h.send});(0,Y.useEffect)(()=>{h.controller||_.blur()},[h.controller,_]);let v=h.geometry?.rotation??0,y=h.state===`connecting`||h.state===`reconnecting`,b=(0,Y.useCallback)(async()=>{d(!0),m(null);try{await Je(e,F(),`${t}.png`)}catch(e){m(e.message)}finally{d(!1)}},[e,t]);return(0,Z.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col bg-black`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-1 border-b bg-background px-1 py-1`,children:[r&&(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,onClick:r,title:`All devices`,"aria-label":`All devices`,children:(0,Z.jsx)(o,{})}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1 truncate px-1 text-sm font-medium`,children:t}),(0,Z.jsx)(V,{variant:`ghost`,size:`icon`,className:`size-11 md:size-9`,disabled:u,onClick:()=>void b(),title:`Save a screenshot`,"aria-label":`Save a screenshot`,children:u?(0,Z.jsx)(N,{className:`animate-spin`}):(0,Z.jsx)(T,{})}),Ue.map(({id:e,label:t,Icon:n})=>(0,Z.jsx)(V,{variant:c===e?`secondary`:`ghost`,size:`icon`,className:`size-11 md:size-9`,"aria-pressed":c===e,onClick:()=>l(t=>t===e?null:e),title:t,"aria-label":t,children:(0,Z.jsx)(n,{})},e))]}),f&&(0,Z.jsx)(`div`,{className:`bg-destructive/90 px-4 py-2 text-center text-sm text-white`,children:f}),!h.controller&&h.state===`live`&&(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 border-b bg-background px-4 py-2 text-sm`,children:[(0,Z.jsx)(p,{className:`size-4 shrink-0 text-muted-foreground`}),(0,Z.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground`,children:h.controllerReason??`Someone else is controlling this device.`}),(0,Z.jsx)(V,{size:`sm`,onClick:h.takeControl,children:`Take control`})]}),(0,Z.jsxs)(`div`,{className:`relative flex min-h-0 flex-1 items-center justify-center overflow-hidden`,children:[(0,Z.jsx)(`canvas`,{ref:i,className:R(`max-h-full max-w-full touch-none select-none object-contain`,h.controller?`cursor-crosshair`:`cursor-default`),onPointerDown:e=>{g.onPointerDown(e),_.focus()},onPointerMove:g.onPointerMove,onPointerUp:g.onPointerUp,onPointerCancel:g.onPointerCancel}),!h.hasPicture&&(0,Z.jsx)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center gap-3 text-sm text-white/70`,children:h.state===`failed`?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(O,{className:`size-6`}),(0,Z.jsx)(`p`,{className:`max-w-xs px-6 text-center`,children:h.errorMessage??`Could not connect.`}),(0,Z.jsxs)(V,{size:`sm`,variant:`secondary`,onClick:h.reconnect,children:[(0,Z.jsx)(x,{}),` Try again`]})]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(N,{className:`size-6 animate-spin`}),(0,Z.jsx)(`p`,{children:y?`Connecting to ${t}…`:`Waiting for the first frame…`})]})}),h.hasPicture&&h.errorMessage&&(0,Z.jsx)(`div`,{className:`absolute inset-x-0 top-0 bg-destructive/90 px-4 py-2 text-center text-sm text-white`,children:h.errorMessage})]}),(0,Z.jsx)(`textarea`,{ref:_.inputRef,className:`pointer-events-none absolute size-px opacity-0`,"aria-hidden":!0,tabIndex:-1,autoCapitalize:`off`,autoCorrect:`off`,autoComplete:`off`,spellCheck:!1,value:``,onChange:()=>{}}),c&&(0,Z.jsx)(`div`,{className:`h-[45%] min-h-0 shrink-0`,children:(0,Z.jsx)(We,{tool:c,onToolChange:l,onClose:()=>l(null),deviceId:e,deviceName:t,setLogcat:h.setLogcat,onLog:h.onLog})}),(0,Z.jsx)(ye,{layout:`bar`,send:h.send,controller:h.controller,rotation:v,quality:a,onQualityChange:s,onKeyboard:_.focus})]})}function ut({metadata:e,tabId:t}){let n=B(e=>e.updateTab),r=typeof e?.avdId==`string`?e.avdId:null,[i,a]=(0,Y.useState)(null),[o,s]=(0,Y.useState)(r!==null);(0,Y.useEffect)(()=>{if(!r){s(!1);return}let e=!1;return(async()=>{try{let{devices:t}=await L.get(`/api/android/devices`);if(e)return;a(t.find(e=>e.avdId===r&&e.runtime!==null)??null)}catch{e||a(null)}finally{e||s(!1)}})(),()=>{e=!0}},[r]);let c=(0,Y.useCallback)(r=>{a(r),t&&n(t,{title:r.name,metadata:{...e,avdId:r.avdId}})},[t,n,e]),l=(0,Y.useCallback)(()=>{a(null),t&&n(t,{title:`Android`,metadata:{...e,avdId:void 0}})},[t,n,e]);return o?(0,Z.jsx)(`div`,{className:`h-full`}):i?.runtime?(0,Z.jsx)(lt,{deviceId:i.runtime.deviceId,deviceName:i.name,onBack:l}):(0,Z.jsx)(_e,{onOpen:c})}export{ut as AndroidTab};
@@ -1 +1 @@
1
- import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import{c as r,l as i,s as a,u as o}from"./vendor-ui-BTSIXzhZ.js";import{A as s,Kr as c,cr as l,si as u}from"./icons-BwyIKaTT.js";import{k as d}from"./api-client-xQDlhUTu.js";import{t as f}from"./settings-store-B4mLp19V.js";import{n as p}from"./utils-Bslrbb-G.js";import"./portal-container-context-NBi-KGK0.js";import{n as m}from"./use-is-mobile-VRV9eZy1.js";import{r as h,t as g}from"./button-C9ZXWb3b.js";import{a as _,i as v,n as y,o as b,r as x,t as S}from"./dialog-Dn_2tuYa.js";import{t as C}from"./input-C3oVNCMq.js";import{n as w,r as T,t as E}from"./resolve-theme-BqoL27BW.js";import{Kn as D,lt as O,oi as k,ot as A}from"./index-CPBujJc_.js";import{t as j}from"./separator-DmU9aJwq.js";var M=n();function N(){let e=f(e=>e.themeStyle),t=f(e=>e.themeMode),n=f(e=>e.customThemeId),r=f(e=>e.customThemes),i=f(e=>e.setThemeStyle),a=f(e=>e.setThemeMode),o=E(e,t,r,n);return(0,M.jsx)(`div`,{className:`grid grid-cols-2 gap-2`,children:w.map(e=>{let t=T[e];if(!t)return null;let n=o.id===e;return(0,M.jsxs)(`button`,{onClick:()=>{i(t.style),a(t.mode)},className:p(`relative flex items-center gap-2 rounded-lg border p-2 text-left transition-colors min-h-11`,n?`border-primary ring-[3px] ring-accent-wash`:`border-border hover:bg-accent/40`),children:[(0,M.jsx)(O,{swatch:t.swatch}),(0,M.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,M.jsx)(`span`,{className:`block truncate text-xs font-medium text-text`,children:t.name.replace(/ (Dark|Light)$/,``)}),(0,M.jsx)(`span`,{className:`block text-[10px] text-text-3 capitalize`,children:t.mode})]}),n&&(0,M.jsx)(s,{className:`absolute top-1 right-1 size-3.5 text-primary`})]},e)})})}var P=e(t(),1);function F({className:e,orientation:t=`horizontal`,...n}){return(0,M.jsx)(i,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:p(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var I=h(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function L({className:e,variant:t=`default`,...n}){return(0,M.jsx)(r,{"data-slot":`tabs-list`,"data-variant":t,className:p(I({variant:t}),e),...n})}function R({className:e,...t}){return(0,M.jsx)(o,{"data-slot":`tabs-trigger`,className:p(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,e),...t})}function z({className:e,...t}){return(0,M.jsx)(a,{"data-slot":`tabs-content`,className:p(`flex-1 outline-none`,e),...t})}function B({open:e,onOpenChange:t}){let n=f(e=>e.importThemeFrom),r=f(e=>e.setCustomTheme),[i,a]=(0,P.useState)(`url`),[o,s]=(0,P.useState)(``),[c,l]=(0,P.useState)(``),[u,p]=(0,P.useState)(``),[m,h]=(0,P.useState)(!1),w=()=>{s(``),l(``),p(``),a(`url`)},T=async()=>{let e=i===`url`?o.trim():c.trim();if(!e){d.error(`Nothing to import`);return}h(!0);try{let a=await n({source:i===`url`?`url`:i===`upload`?`upload`:`json`,value:e,name:u.trim()||void 0});d.success(a.length>1?`Imported ${a.length} themes`:`Imported "${a[0]?.name}"`),a[0]&&r(a[0].id),w(),t(!1)}catch(e){d.error(e.message||`Import failed`)}finally{h(!1)}},E=async e=>{if(e)try{l(await e.text()),p(e.name.replace(/\.json$/i,``))}catch{d.error(`Could not read file`)}};return(0,M.jsx)(S,{open:e,onOpenChange:t,children:(0,M.jsxs)(y,{className:`max-w-md`,children:[(0,M.jsxs)(_,{children:[(0,M.jsx)(b,{children:`Import theme`}),(0,M.jsx)(x,{className:`text-text-3`,children:`Import a VSCode color theme. Single-mode themes apply to both dark and light.`})]}),(0,M.jsxs)(F,{value:i,onValueChange:e=>a(e),children:[(0,M.jsxs)(L,{className:`w-full`,children:[(0,M.jsx)(R,{value:`url`,className:`flex-1`,children:`URL`}),(0,M.jsx)(R,{value:`json`,className:`flex-1`,children:`Paste JSON`}),(0,M.jsx)(R,{value:`upload`,className:`flex-1`,children:`Upload`})]}),(0,M.jsxs)(z,{value:`url`,className:`space-y-2 pt-2`,children:[(0,M.jsx)(C,{placeholder:`https://…/theme.json or Marketplace .vsix URL`,value:o,onChange:e=>s(e.target.value)}),(0,M.jsx)(`p`,{className:`text-[11px] text-text-3`,children:`Only https URLs; private/internal addresses are blocked.`})]}),(0,M.jsx)(z,{value:`json`,className:`pt-2`,children:(0,M.jsx)(`textarea`,{className:`w-full h-40 rounded-md border border-border bg-surface p-2 text-xs font-mono text-text focus:outline-none focus:border-ring`,placeholder:`{ "name": "My Theme", "type": "dark", "colors": { … }, "tokenColors": [ … ] }`,value:c,onChange:e=>l(e.target.value)})}),(0,M.jsxs)(z,{value:`upload`,className:`space-y-2 pt-2`,children:[(0,M.jsx)(`input`,{type:`file`,accept:`.json,application/json`,onChange:e=>E(e.target.files?.[0]),className:`block w-full text-xs text-text-2 file:mr-3 file:rounded file:border file:border-border file:bg-panel-2 file:px-2 file:py-1 file:text-text`}),c&&(0,M.jsxs)(`p`,{className:`text-[11px] text-success`,children:[`File loaded (`,c.length,` chars)`]})]})]}),(0,M.jsx)(C,{placeholder:`Optional name`,value:u,onChange:e=>p(e.target.value)}),(0,M.jsxs)(v,{children:[(0,M.jsx)(g,{variant:`outline`,onClick:()=>t(!1),disabled:m,children:`Cancel`}),(0,M.jsx)(g,{onClick:T,disabled:m,children:m?`Importing…`:`Import`})]})]})})}function V(){let e=f(e=>e.customThemes),t=f(e=>e.themeStyle),n=f(e=>e.customThemeId),r=f(e=>e.setCustomTheme),i=f(e=>e.deleteCustomTheme),[a,o]=(0,P.useState)(!1);return(0,M.jsxs)(`section`,{className:`space-y-2`,children:[(0,M.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,M.jsx)(`h3`,{className:`text-xs font-medium text-muted-foreground`,children:`Imported themes`}),(0,M.jsxs)(g,{size:`sm`,variant:`outline`,className:`h-7 gap-1 text-xs`,onClick:()=>o(!0),children:[(0,M.jsx)(l,{className:`size-3.5`}),` Import`]})]}),e.length===0?(0,M.jsx)(`p`,{className:`text-[11px] text-text-3`,children:`No imported themes yet. Import a VSCode theme from a URL, .vsix, or JSON.`}):(0,M.jsx)(`ul`,{className:`space-y-1`,children:e.map(e=>{let a=t===`custom`&&n===e.id;return(0,M.jsxs)(`li`,{className:p(`flex items-center gap-2 rounded-md border px-2 py-1.5`,a?`border-primary bg-primary/10`:`border-border`),children:[(0,M.jsx)(O,{swatch:e.swatch}),(0,M.jsxs)(`button`,{className:`flex-1 min-w-0 text-left`,onClick:()=>r(e.id),children:[(0,M.jsx)(`span`,{className:`block truncate text-xs text-text`,children:e.name}),(0,M.jsx)(`span`,{className:`block text-[10px] text-text-3`,children:e.mode})]}),a&&(0,M.jsx)(s,{className:`size-4 text-primary shrink-0`}),(0,M.jsx)(`button`,{className:`text-text-3 hover:text-error transition-colors shrink-0`,title:`Delete`,onClick:()=>void i(e.id),children:(0,M.jsx)(c,{className:`size-3.5`})})]},e.id)})}),(0,M.jsx)(B,{open:a,onOpenChange:o})]})}var H=[{value:`default`,label:`Default`},{value:`boxed`,label:`Boxed`},{value:`pill`,label:`Pill`}],U=[{value:`auto`,label:`Auto`},{value:`windows`,label:`Windows`},{value:`macos`,label:`macOS`}];function W({options:e,value:t,onChange:n}){return(0,M.jsx)(`div`,{className:`flex gap-2`,children:e.map(e=>(0,M.jsx)(g,{variant:t===e.value?`default`:`outline`,onClick:()=>n(e.value),className:p(`flex-1 cursor-pointer`,t===e.value&&`ring-2 ring-primary`),children:e.label},e.value))})}function G(){let{theme:e,setTheme:t,tabWrap:n,toggleTabWrap:r,editorTabStyle:i,setEditorTabStyle:a,explorerSkin:o,setExplorerSkin:s}=f(k(e=>({theme:e.themeMode,setTheme:e.setThemeMode,tabWrap:e.tabWrap,toggleTabWrap:e.toggleTabWrap,editorTabStyle:e.editorTabStyle,setEditorTabStyle:e.setEditorTabStyle,explorerSkin:e.explorerSkin,setExplorerSkin:e.setExplorerSkin}))),{wordWrap:c,toggleWordWrap:l,mobileWordWrap:d,toggleMobileWordWrap:h}=f(k(e=>({wordWrap:e.wordWrap,toggleWordWrap:e.toggleWordWrap,mobileWordWrap:e.mobileWordWrap,toggleMobileWordWrap:e.toggleMobileWordWrap}))),_=m();return(0,M.jsxs)(`div`,{className:`space-y-6`,children:[(0,M.jsxs)(`section`,{className:`space-y-3`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Theme`}),(0,M.jsx)(N,{}),(0,M.jsx)(`div`,{className:`flex gap-2`,children:A.map(n=>{let r=n.icon;return(0,M.jsxs)(g,{variant:e===n.value?`default`:`outline`,onClick:()=>t(n.value),className:p(`flex-1 gap-2 cursor-pointer`,e===n.value&&`ring-2 ring-primary`),children:[(0,M.jsx)(r,{className:`size-4`}),n.label]},n.value)})})]}),(0,M.jsx)(j,{}),(0,M.jsx)(V,{}),(0,M.jsx)(j,{}),(0,M.jsxs)(`section`,{className:`flex items-center justify-between gap-4`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[(0,M.jsx)(u,{className:`size-4 text-muted-foreground shrink-0`}),(0,M.jsxs)(`div`,{className:`min-w-0`,children:[(0,M.jsx)(`p`,{className:`text-sm font-medium`,children:`Wrap Tabs`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Stack tabs in rows instead of scrolling`})]})]}),(0,M.jsx)(D,{checked:n,onCheckedChange:r})]}),(0,M.jsxs)(`section`,{className:`flex items-center justify-between gap-4`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[(0,M.jsx)(u,{className:`size-4 text-muted-foreground shrink-0`}),(0,M.jsxs)(`div`,{className:`min-w-0`,children:[(0,M.jsx)(`p`,{className:`text-sm font-medium`,children:`Word Wrap`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:_?`Wrap long lines instead of scrolling sideways (this device)`:`Wrap long lines in the editor (Alt+Z)`})]})]}),(0,M.jsx)(D,{checked:_?d:c,onCheckedChange:()=>_?h():l()})]}),(0,M.jsxs)(`section`,{className:`space-y-2`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Tab Style`}),(0,M.jsx)(W,{options:H,value:i,onChange:a})]}),(0,M.jsxs)(`section`,{className:`space-y-2`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Explorer Skin`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Chrome the OS File Explorer window wears. Auto follows the host platform.`}),(0,M.jsx)(W,{options:U,value:o,onChange:s})]})]})}export{G as AppearanceSettingsSection};
1
+ import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import{c as r,l as i,s as a,u as o}from"./vendor-ui-BTSIXzhZ.js";import{A as s,Kr as c,cr as l,si as u}from"./icons-BwyIKaTT.js";import{k as d}from"./api-client-xQDlhUTu.js";import{t as f}from"./settings-store-B4mLp19V.js";import{n as p}from"./utils-Bslrbb-G.js";import"./portal-container-context-NBi-KGK0.js";import{n as m}from"./use-is-mobile-VRV9eZy1.js";import{r as h,t as g}from"./button-C9ZXWb3b.js";import{a as _,i as v,n as y,o as b,r as x,t as S}from"./dialog-Dn_2tuYa.js";import{t as C}from"./input-C3oVNCMq.js";import{n as w,r as T,t as E}from"./resolve-theme-BqoL27BW.js";import{Kn as D,lt as O,oi as k,ot as A}from"./index-BGk8EFQb.js";import{t as j}from"./separator-DmU9aJwq.js";var M=n();function N(){let e=f(e=>e.themeStyle),t=f(e=>e.themeMode),n=f(e=>e.customThemeId),r=f(e=>e.customThemes),i=f(e=>e.setThemeStyle),a=f(e=>e.setThemeMode),o=E(e,t,r,n);return(0,M.jsx)(`div`,{className:`grid grid-cols-2 gap-2`,children:w.map(e=>{let t=T[e];if(!t)return null;let n=o.id===e;return(0,M.jsxs)(`button`,{onClick:()=>{i(t.style),a(t.mode)},className:p(`relative flex items-center gap-2 rounded-lg border p-2 text-left transition-colors min-h-11`,n?`border-primary ring-[3px] ring-accent-wash`:`border-border hover:bg-accent/40`),children:[(0,M.jsx)(O,{swatch:t.swatch}),(0,M.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[(0,M.jsx)(`span`,{className:`block truncate text-xs font-medium text-text`,children:t.name.replace(/ (Dark|Light)$/,``)}),(0,M.jsx)(`span`,{className:`block text-[10px] text-text-3 capitalize`,children:t.mode})]}),n&&(0,M.jsx)(s,{className:`absolute top-1 right-1 size-3.5 text-primary`})]},e)})})}var P=e(t(),1);function F({className:e,orientation:t=`horizontal`,...n}){return(0,M.jsx)(i,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:p(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var I=h(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function L({className:e,variant:t=`default`,...n}){return(0,M.jsx)(r,{"data-slot":`tabs-list`,"data-variant":t,className:p(I({variant:t}),e),...n})}function R({className:e,...t}){return(0,M.jsx)(o,{"data-slot":`tabs-trigger`,className:p(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,e),...t})}function z({className:e,...t}){return(0,M.jsx)(a,{"data-slot":`tabs-content`,className:p(`flex-1 outline-none`,e),...t})}function B({open:e,onOpenChange:t}){let n=f(e=>e.importThemeFrom),r=f(e=>e.setCustomTheme),[i,a]=(0,P.useState)(`url`),[o,s]=(0,P.useState)(``),[c,l]=(0,P.useState)(``),[u,p]=(0,P.useState)(``),[m,h]=(0,P.useState)(!1),w=()=>{s(``),l(``),p(``),a(`url`)},T=async()=>{let e=i===`url`?o.trim():c.trim();if(!e){d.error(`Nothing to import`);return}h(!0);try{let a=await n({source:i===`url`?`url`:i===`upload`?`upload`:`json`,value:e,name:u.trim()||void 0});d.success(a.length>1?`Imported ${a.length} themes`:`Imported "${a[0]?.name}"`),a[0]&&r(a[0].id),w(),t(!1)}catch(e){d.error(e.message||`Import failed`)}finally{h(!1)}},E=async e=>{if(e)try{l(await e.text()),p(e.name.replace(/\.json$/i,``))}catch{d.error(`Could not read file`)}};return(0,M.jsx)(S,{open:e,onOpenChange:t,children:(0,M.jsxs)(y,{className:`max-w-md`,children:[(0,M.jsxs)(_,{children:[(0,M.jsx)(b,{children:`Import theme`}),(0,M.jsx)(x,{className:`text-text-3`,children:`Import a VSCode color theme. Single-mode themes apply to both dark and light.`})]}),(0,M.jsxs)(F,{value:i,onValueChange:e=>a(e),children:[(0,M.jsxs)(L,{className:`w-full`,children:[(0,M.jsx)(R,{value:`url`,className:`flex-1`,children:`URL`}),(0,M.jsx)(R,{value:`json`,className:`flex-1`,children:`Paste JSON`}),(0,M.jsx)(R,{value:`upload`,className:`flex-1`,children:`Upload`})]}),(0,M.jsxs)(z,{value:`url`,className:`space-y-2 pt-2`,children:[(0,M.jsx)(C,{placeholder:`https://…/theme.json or Marketplace .vsix URL`,value:o,onChange:e=>s(e.target.value)}),(0,M.jsx)(`p`,{className:`text-[11px] text-text-3`,children:`Only https URLs; private/internal addresses are blocked.`})]}),(0,M.jsx)(z,{value:`json`,className:`pt-2`,children:(0,M.jsx)(`textarea`,{className:`w-full h-40 rounded-md border border-border bg-surface p-2 text-xs font-mono text-text focus:outline-none focus:border-ring`,placeholder:`{ "name": "My Theme", "type": "dark", "colors": { … }, "tokenColors": [ … ] }`,value:c,onChange:e=>l(e.target.value)})}),(0,M.jsxs)(z,{value:`upload`,className:`space-y-2 pt-2`,children:[(0,M.jsx)(`input`,{type:`file`,accept:`.json,application/json`,onChange:e=>E(e.target.files?.[0]),className:`block w-full text-xs text-text-2 file:mr-3 file:rounded file:border file:border-border file:bg-panel-2 file:px-2 file:py-1 file:text-text`}),c&&(0,M.jsxs)(`p`,{className:`text-[11px] text-success`,children:[`File loaded (`,c.length,` chars)`]})]})]}),(0,M.jsx)(C,{placeholder:`Optional name`,value:u,onChange:e=>p(e.target.value)}),(0,M.jsxs)(v,{children:[(0,M.jsx)(g,{variant:`outline`,onClick:()=>t(!1),disabled:m,children:`Cancel`}),(0,M.jsx)(g,{onClick:T,disabled:m,children:m?`Importing…`:`Import`})]})]})})}function V(){let e=f(e=>e.customThemes),t=f(e=>e.themeStyle),n=f(e=>e.customThemeId),r=f(e=>e.setCustomTheme),i=f(e=>e.deleteCustomTheme),[a,o]=(0,P.useState)(!1);return(0,M.jsxs)(`section`,{className:`space-y-2`,children:[(0,M.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,M.jsx)(`h3`,{className:`text-xs font-medium text-muted-foreground`,children:`Imported themes`}),(0,M.jsxs)(g,{size:`sm`,variant:`outline`,className:`h-7 gap-1 text-xs`,onClick:()=>o(!0),children:[(0,M.jsx)(l,{className:`size-3.5`}),` Import`]})]}),e.length===0?(0,M.jsx)(`p`,{className:`text-[11px] text-text-3`,children:`No imported themes yet. Import a VSCode theme from a URL, .vsix, or JSON.`}):(0,M.jsx)(`ul`,{className:`space-y-1`,children:e.map(e=>{let a=t===`custom`&&n===e.id;return(0,M.jsxs)(`li`,{className:p(`flex items-center gap-2 rounded-md border px-2 py-1.5`,a?`border-primary bg-primary/10`:`border-border`),children:[(0,M.jsx)(O,{swatch:e.swatch}),(0,M.jsxs)(`button`,{className:`flex-1 min-w-0 text-left`,onClick:()=>r(e.id),children:[(0,M.jsx)(`span`,{className:`block truncate text-xs text-text`,children:e.name}),(0,M.jsx)(`span`,{className:`block text-[10px] text-text-3`,children:e.mode})]}),a&&(0,M.jsx)(s,{className:`size-4 text-primary shrink-0`}),(0,M.jsx)(`button`,{className:`text-text-3 hover:text-error transition-colors shrink-0`,title:`Delete`,onClick:()=>void i(e.id),children:(0,M.jsx)(c,{className:`size-3.5`})})]},e.id)})}),(0,M.jsx)(B,{open:a,onOpenChange:o})]})}var H=[{value:`default`,label:`Default`},{value:`boxed`,label:`Boxed`},{value:`pill`,label:`Pill`}],U=[{value:`auto`,label:`Auto`},{value:`windows`,label:`Windows`},{value:`macos`,label:`macOS`}];function W({options:e,value:t,onChange:n}){return(0,M.jsx)(`div`,{className:`flex gap-2`,children:e.map(e=>(0,M.jsx)(g,{variant:t===e.value?`default`:`outline`,onClick:()=>n(e.value),className:p(`flex-1 cursor-pointer`,t===e.value&&`ring-2 ring-primary`),children:e.label},e.value))})}function G(){let{theme:e,setTheme:t,tabWrap:n,toggleTabWrap:r,editorTabStyle:i,setEditorTabStyle:a,explorerSkin:o,setExplorerSkin:s}=f(k(e=>({theme:e.themeMode,setTheme:e.setThemeMode,tabWrap:e.tabWrap,toggleTabWrap:e.toggleTabWrap,editorTabStyle:e.editorTabStyle,setEditorTabStyle:e.setEditorTabStyle,explorerSkin:e.explorerSkin,setExplorerSkin:e.setExplorerSkin}))),{wordWrap:c,toggleWordWrap:l,mobileWordWrap:d,toggleMobileWordWrap:h}=f(k(e=>({wordWrap:e.wordWrap,toggleWordWrap:e.toggleWordWrap,mobileWordWrap:e.mobileWordWrap,toggleMobileWordWrap:e.toggleMobileWordWrap}))),_=m();return(0,M.jsxs)(`div`,{className:`space-y-6`,children:[(0,M.jsxs)(`section`,{className:`space-y-3`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Theme`}),(0,M.jsx)(N,{}),(0,M.jsx)(`div`,{className:`flex gap-2`,children:A.map(n=>{let r=n.icon;return(0,M.jsxs)(g,{variant:e===n.value?`default`:`outline`,onClick:()=>t(n.value),className:p(`flex-1 gap-2 cursor-pointer`,e===n.value&&`ring-2 ring-primary`),children:[(0,M.jsx)(r,{className:`size-4`}),n.label]},n.value)})})]}),(0,M.jsx)(j,{}),(0,M.jsx)(V,{}),(0,M.jsx)(j,{}),(0,M.jsxs)(`section`,{className:`flex items-center justify-between gap-4`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[(0,M.jsx)(u,{className:`size-4 text-muted-foreground shrink-0`}),(0,M.jsxs)(`div`,{className:`min-w-0`,children:[(0,M.jsx)(`p`,{className:`text-sm font-medium`,children:`Wrap Tabs`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Stack tabs in rows instead of scrolling`})]})]}),(0,M.jsx)(D,{checked:n,onCheckedChange:r})]}),(0,M.jsxs)(`section`,{className:`flex items-center justify-between gap-4`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[(0,M.jsx)(u,{className:`size-4 text-muted-foreground shrink-0`}),(0,M.jsxs)(`div`,{className:`min-w-0`,children:[(0,M.jsx)(`p`,{className:`text-sm font-medium`,children:`Word Wrap`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:_?`Wrap long lines instead of scrolling sideways (this device)`:`Wrap long lines in the editor (Alt+Z)`})]})]}),(0,M.jsx)(D,{checked:_?d:c,onCheckedChange:()=>_?h():l()})]}),(0,M.jsxs)(`section`,{className:`space-y-2`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Tab Style`}),(0,M.jsx)(W,{options:H,value:i,onChange:a})]}),(0,M.jsxs)(`section`,{className:`space-y-2`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Explorer Skin`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Chrome the OS File Explorer window wears. Auto follows the host platform.`}),(0,M.jsx)(W,{options:U,value:o,onChange:s})]})]})}export{G as AppearanceSettingsSection};
@@ -1 +1 @@
1
- import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import{xr as r}from"./icons-BwyIKaTT.js";import{a as i}from"./api-client-xQDlhUTu.js";import{n as a}from"./utils-Bslrbb-G.js";import"./portal-container-context-NBi-KGK0.js";import"./context-menu-BCuZYfWC.js";import"./use-is-mobile-VRV9eZy1.js";import"./button-C9ZXWb3b.js";import"./dialog-Dn_2tuYa.js";import"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import{n as o,o as s,r as c,t as l,u}from"./adaptive-context-menu-C4jNSORA.js";import{r as d}from"./format-bytes-he3TR0bV.js";import{o as f}from"./process-row-format-CytRH7g2.js";import{n as p,r as m,t as h}from"./use-process-kill-BdmXHMFE.js";var g=e(t(),1);function _(e){let t=new Map;for(let n of e){let e=t.get(n.ppid);e?e.push(n.pid):t.set(n.ppid,[n.pid])}return t}function v(e,t,n=()=>!1){let r=new Set,i=[...e];for(;i.length>0;){let e=i.pop();if(!r.has(e)){r.add(e);for(let r of t.get(e)??[])n(r)||i.push(r)}}return[...r]}function y(e){let t=0,n=!1;for(let r of e)r!==void 0&&(n=!0,t+=r);return n?t:void 0}var b=e=>Math.round(e*10)/10;function x(e,t){let n=new Map(t.map(e=>[e.pid,e])),r=_(t),i=[],a=new Map;for(let t of e)for(let e of t.pids)a.set(e,t.id);for(let t of e){let e=v(t.pids,r,e=>{let n=a.get(e);return n!==void 0&&n!==t.id}).map(e=>n.get(e)).filter(e=>e!==void 0);e.length!==0&&i.push({id:t.id,name:t.name,icon:t.icon,pids:t.pids,memberPids:e.map(e=>e.pid),processCount:e.length,cpu:b(e.reduce((e,t)=>e+t.cpu,0)),ramMB:b(e.reduce((e,t)=>e+t.ramMB,0)),swapMB:y(e.map(e=>e.swapMB)),diskReadBps:y(e.map(e=>e.diskReadBps)),diskWriteBps:y(e.map(e=>e.diskWriteBps)),gpuPct:S(y(e.map(e=>e.gpuPct))),gpuMemMB:y(e.map(e=>e.gpuMemMB))})}return i}function S(e){return e===void 0?void 0:b(Math.min(100,Math.max(0,e)))}function C(e,t,n){let r=n===`asc`?1:-1;return[...e].sort((e,n)=>{if(t===`name`)return r*e.name.localeCompare(n.name);let i=t===`cpu`?e.cpu-n.cpu:e.ramMB-n.ramMB;return i===0?e.name.localeCompare(n.name):r*i})}function w(e,t){let n=t.trim().toLowerCase();return n?e.filter(e=>e.name.toLowerCase().includes(n)):[...e]}var T=n();function E(e){let t=i(),n=t?`?token=${encodeURIComponent(t)}`:``;return`/api/system/app-icon/${encodeURIComponent(e)}${n}`}function D(e){return e>80?`text-error`:e>50?`text-warning`:`text-text-secondary`}function O({app:e,endProtected:t,onEnd:n}){let[r,i]=(0,g.useState)(!1);return(0,T.jsxs)(l,{children:[(0,T.jsx)(u,{asChild:!0,children:(0,T.jsx)(`div`,{className:`select-none`,children:(0,T.jsxs)(`div`,{className:`w-full min-h-11 px-3 py-2 flex items-center gap-3 hover:bg-surface-hover transition-colors`,"data-testid":`sysmon-app-row`,"data-app-id":e.id,"data-cpu":e.cpu,children:[e.icon&&!r?(0,T.jsx)(`img`,{src:E(e.id),alt:``,width:24,height:24,className:`size-6 shrink-0 object-contain`,onError:()=>i(!0)}):(0,T.jsx)(`span`,{"aria-hidden":!0,className:`size-6 shrink-0 rounded bg-surface-hover grid place-items-center text-[11px] text-text-subtle`,children:e.name.slice(0,1).toUpperCase()}),(0,T.jsxs)(`span`,{className:`flex-1 min-w-0`,children:[(0,T.jsx)(`span`,{className:`block text-sm truncate`,children:e.name}),(0,T.jsxs)(`span`,{className:`block text-[11px] text-text-subtle`,children:[e.processCount,` process`,e.processCount===1?``:`es`]})]}),(0,T.jsxs)(`span`,{className:a(`w-14 text-right text-xs tabular-nums`,D(e.cpu)),children:[e.cpu.toFixed(1),`%`]}),(0,T.jsx)(`span`,{className:`w-16 text-right text-xs tabular-nums text-text-secondary`,children:d(e.ramMB)}),e.swapMB!==void 0&&(0,T.jsx)(`span`,{className:`hidden @xs:block w-16 text-right text-xs tabular-nums text-text-subtle`,children:f(e.swapMB)})]})})}),(0,T.jsxs)(o,{children:[(0,T.jsx)(c,{variant:`destructive`,disabled:t,onSelect:()=>{t||n(e)},children:`End application`}),t&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(s,{}),(0,T.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-text-subtle max-w-64`,children:`One of this app's processes is protected, so PPM will not end it.`})]})]})]})}var k=[{key:`cpu`,label:`CPU`},{key:`ram`,label:`Memory`},{key:`name`,label:`Name`}];function A(e){return{key:`app:${e.id}`,label:e.name,rootPid:null,cpu:e.cpu,ramMB:e.ramMB,count:e.processCount,ppm:!1,pids:e.memberPids}}function j({snapshot:e}){let[t,n]=(0,g.useState)(``),[i,o]=(0,g.useState)(`ram`),{pendingKill:s,requestKillGroup:c,confirmKill:l,cancelKill:u}=h(e),d=(0,g.useMemo)(()=>new Map(e.processes.map(e=>[e.pid,e])),[e.processes]),f=(0,g.useMemo)(()=>x(e.apps??[],e.processes),[e.apps,e.processes]),_=(0,g.useMemo)(()=>C(w(f,t),i,i===`name`?`asc`:`desc`),[f,t,i]),v=(0,g.useCallback)(e=>p(e.memberPids.map(e=>d.get(e)).filter(e=>e!==void 0)),[d]);return e.apps===void 0?(0,T.jsx)(`div`,{className:`p-4 text-sm text-text-subtle`,"data-testid":`sysmon-apps`,children:`This host does not list desktop applications.`}):(0,T.jsxs)(`div`,{className:`h-full flex flex-col min-h-0 @container`,"data-testid":`sysmon-apps`,"data-app-count":_.length,children:[(0,T.jsxs)(`div`,{className:`shrink-0 flex flex-wrap items-center gap-2 p-2 border-b border-border`,children:[(0,T.jsxs)(`div`,{className:`relative flex-1 min-w-[140px]`,children:[(0,T.jsx)(r,{className:`absolute left-2 top-1/2 -translate-y-1/2 size-3.5 text-text-subtle`}),(0,T.jsx)(`input`,{type:`text`,value:t,onChange:e=>n(e.target.value),placeholder:`Search applications`,"aria-label":`Search applications`,"data-testid":`sysmon-app-search`,className:`w-full min-h-11 md:min-h-8 pl-7 pr-2 text-sm rounded-md border border-border bg-transparent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`})]}),k.map(e=>(0,T.jsx)(`button`,{type:`button`,onClick:()=>o(e.key),"aria-pressed":i===e.key,"data-testid":`sysmon-app-sort-${e.key}`,className:a(`min-h-11 md:min-h-8 px-3 text-xs rounded-md border transition-colors`,i===e.key?`border-primary bg-primary/10 text-primary`:`border-border hover:bg-surface-hover`),children:e.label},e.key))]}),(0,T.jsxs)(`div`,{className:`flex-1 min-h-0 overflow-y-auto divide-y divide-border`,children:[_.length===0&&(0,T.jsx)(`p`,{className:`p-4 text-sm text-text-subtle`,children:f.length===0?`No desktop applications are running.`:`No applications match.`}),_.map(e=>(0,T.jsx)(O,{app:e,endProtected:v(e),onEnd:e=>c(A(e))},e.id))]}),(0,T.jsx)(m,{target:s,onConfirm:l,onCancel:u})]})}export{j as AppsPanel};
1
+ import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import{xr as r}from"./icons-BwyIKaTT.js";import{a as i}from"./api-client-xQDlhUTu.js";import{n as a}from"./utils-Bslrbb-G.js";import"./portal-container-context-NBi-KGK0.js";import"./context-menu-BCuZYfWC.js";import"./use-is-mobile-VRV9eZy1.js";import"./button-C9ZXWb3b.js";import"./dialog-Dn_2tuYa.js";import"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import{n as o,o as s,r as c,t as l,u}from"./adaptive-context-menu-C4jNSORA.js";import{r as d}from"./format-bytes-he3TR0bV.js";import{o as f}from"./process-row-format-CytRH7g2.js";import{n as p,r as m,t as h}from"./use-process-kill-C-YetnGd.js";var g=e(t(),1);function _(e){let t=new Map;for(let n of e){let e=t.get(n.ppid);e?e.push(n.pid):t.set(n.ppid,[n.pid])}return t}function v(e,t,n=()=>!1){let r=new Set,i=[...e];for(;i.length>0;){let e=i.pop();if(!r.has(e)){r.add(e);for(let r of t.get(e)??[])n(r)||i.push(r)}}return[...r]}function y(e){let t=0,n=!1;for(let r of e)r!==void 0&&(n=!0,t+=r);return n?t:void 0}var b=e=>Math.round(e*10)/10;function x(e,t){let n=new Map(t.map(e=>[e.pid,e])),r=_(t),i=[],a=new Map;for(let t of e)for(let e of t.pids)a.set(e,t.id);for(let t of e){let e=v(t.pids,r,e=>{let n=a.get(e);return n!==void 0&&n!==t.id}).map(e=>n.get(e)).filter(e=>e!==void 0);e.length!==0&&i.push({id:t.id,name:t.name,icon:t.icon,pids:t.pids,memberPids:e.map(e=>e.pid),processCount:e.length,cpu:b(e.reduce((e,t)=>e+t.cpu,0)),ramMB:b(e.reduce((e,t)=>e+t.ramMB,0)),swapMB:y(e.map(e=>e.swapMB)),diskReadBps:y(e.map(e=>e.diskReadBps)),diskWriteBps:y(e.map(e=>e.diskWriteBps)),gpuPct:S(y(e.map(e=>e.gpuPct))),gpuMemMB:y(e.map(e=>e.gpuMemMB))})}return i}function S(e){return e===void 0?void 0:b(Math.min(100,Math.max(0,e)))}function C(e,t,n){let r=n===`asc`?1:-1;return[...e].sort((e,n)=>{if(t===`name`)return r*e.name.localeCompare(n.name);let i=t===`cpu`?e.cpu-n.cpu:e.ramMB-n.ramMB;return i===0?e.name.localeCompare(n.name):r*i})}function w(e,t){let n=t.trim().toLowerCase();return n?e.filter(e=>e.name.toLowerCase().includes(n)):[...e]}var T=n();function E(e){let t=i(),n=t?`?token=${encodeURIComponent(t)}`:``;return`/api/system/app-icon/${encodeURIComponent(e)}${n}`}function D(e){return e>80?`text-error`:e>50?`text-warning`:`text-text-secondary`}function O({app:e,endProtected:t,onEnd:n}){let[r,i]=(0,g.useState)(!1);return(0,T.jsxs)(l,{children:[(0,T.jsx)(u,{asChild:!0,children:(0,T.jsx)(`div`,{className:`select-none`,children:(0,T.jsxs)(`div`,{className:`w-full min-h-11 px-3 py-2 flex items-center gap-3 hover:bg-surface-hover transition-colors`,"data-testid":`sysmon-app-row`,"data-app-id":e.id,"data-cpu":e.cpu,children:[e.icon&&!r?(0,T.jsx)(`img`,{src:E(e.id),alt:``,width:24,height:24,className:`size-6 shrink-0 object-contain`,onError:()=>i(!0)}):(0,T.jsx)(`span`,{"aria-hidden":!0,className:`size-6 shrink-0 rounded bg-surface-hover grid place-items-center text-[11px] text-text-subtle`,children:e.name.slice(0,1).toUpperCase()}),(0,T.jsxs)(`span`,{className:`flex-1 min-w-0`,children:[(0,T.jsx)(`span`,{className:`block text-sm truncate`,children:e.name}),(0,T.jsxs)(`span`,{className:`block text-[11px] text-text-subtle`,children:[e.processCount,` process`,e.processCount===1?``:`es`]})]}),(0,T.jsxs)(`span`,{className:a(`w-14 text-right text-xs tabular-nums`,D(e.cpu)),children:[e.cpu.toFixed(1),`%`]}),(0,T.jsx)(`span`,{className:`w-16 text-right text-xs tabular-nums text-text-secondary`,children:d(e.ramMB)}),e.swapMB!==void 0&&(0,T.jsx)(`span`,{className:`hidden @xs:block w-16 text-right text-xs tabular-nums text-text-subtle`,children:f(e.swapMB)})]})})}),(0,T.jsxs)(o,{children:[(0,T.jsx)(c,{variant:`destructive`,disabled:t,onSelect:()=>{t||n(e)},children:`End application`}),t&&(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(s,{}),(0,T.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-text-subtle max-w-64`,children:`One of this app's processes is protected, so PPM will not end it.`})]})]})]})}var k=[{key:`cpu`,label:`CPU`},{key:`ram`,label:`Memory`},{key:`name`,label:`Name`}];function A(e){return{key:`app:${e.id}`,label:e.name,rootPid:null,cpu:e.cpu,ramMB:e.ramMB,count:e.processCount,ppm:!1,pids:e.memberPids}}function j({snapshot:e}){let[t,n]=(0,g.useState)(``),[i,o]=(0,g.useState)(`ram`),{pendingKill:s,requestKillGroup:c,confirmKill:l,cancelKill:u}=h(e),d=(0,g.useMemo)(()=>new Map(e.processes.map(e=>[e.pid,e])),[e.processes]),f=(0,g.useMemo)(()=>x(e.apps??[],e.processes),[e.apps,e.processes]),_=(0,g.useMemo)(()=>C(w(f,t),i,i===`name`?`asc`:`desc`),[f,t,i]),v=(0,g.useCallback)(e=>p(e.memberPids.map(e=>d.get(e)).filter(e=>e!==void 0)),[d]);return e.apps===void 0?(0,T.jsx)(`div`,{className:`p-4 text-sm text-text-subtle`,"data-testid":`sysmon-apps`,children:`This host does not list desktop applications.`}):(0,T.jsxs)(`div`,{className:`h-full flex flex-col min-h-0 @container`,"data-testid":`sysmon-apps`,"data-app-count":_.length,children:[(0,T.jsxs)(`div`,{className:`shrink-0 flex flex-wrap items-center gap-2 p-2 border-b border-border`,children:[(0,T.jsxs)(`div`,{className:`relative flex-1 min-w-[140px]`,children:[(0,T.jsx)(r,{className:`absolute left-2 top-1/2 -translate-y-1/2 size-3.5 text-text-subtle`}),(0,T.jsx)(`input`,{type:`text`,value:t,onChange:e=>n(e.target.value),placeholder:`Search applications`,"aria-label":`Search applications`,"data-testid":`sysmon-app-search`,className:`w-full min-h-11 md:min-h-8 pl-7 pr-2 text-sm rounded-md border border-border bg-transparent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`})]}),k.map(e=>(0,T.jsx)(`button`,{type:`button`,onClick:()=>o(e.key),"aria-pressed":i===e.key,"data-testid":`sysmon-app-sort-${e.key}`,className:a(`min-h-11 md:min-h-8 px-3 text-xs rounded-md border transition-colors`,i===e.key?`border-primary bg-primary/10 text-primary`:`border-border hover:bg-surface-hover`),children:e.label},e.key))]}),(0,T.jsxs)(`div`,{className:`flex-1 min-h-0 overflow-y-auto divide-y divide-border`,children:[_.length===0&&(0,T.jsx)(`p`,{className:`p-4 text-sm text-text-subtle`,children:f.length===0?`No desktop applications are running.`:`No applications match.`}),_.map(e=>(0,T.jsx)(O,{app:e,endProtected:v(e),onEnd:e=>c(A(e))},e.id))]}),(0,T.jsx)(m,{target:s,onConfirm:l,onCancel:u})]})}export{j as AppsPanel};
@@ -1 +1 @@
1
- import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import{A as r,Et as i,L as a,P as o,_n as s,hr as c,m as l,xn as u}from"./icons-BwyIKaTT.js";import{r as d}from"./api-client-xQDlhUTu.js";import"./settings-store-B4mLp19V.js";import"./portal-container-context-NBi-KGK0.js";import"./project-store-BLGl9IAO.js";import"./project-framework-store-DwLxaRan.js";import{n as f}from"./use-is-mobile-VRV9eZy1.js";import"./git-repo-store-CKB5fdNP.js";import{t as p}from"./button-C9ZXWb3b.js";import{n as m}from"./file-icons-JInFtBVl.js";import{t as h}from"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import{t as g}from"./start-ellipsis-CU8GkxaV.js";import{t as _}from"./scroll-area-DOlQJGZp.js";import{Cr as ee,Sr as te,dr as ne,ii as re,ur as ie,wr as v,xr as ae}from"./index-CPBujJc_.js";import"./use-monaco-theme-ArU1f9T6.js";import"./use-inline-blame-BOn_m8f-.js";import{DiffViewer as y}from"./diff-viewer-3VDHcDag.js";var b=e(t(),1),x=`ppm:branch-review`,S=`${x}:recent`,C=20;function w(e,t,n){return`${x}:${e}:${t}:${n}`}function T(e,t){return e[t.path]===t.blob}function E(e,t){let n={...e};return T(e,t)?delete n[t.path]:n[t.path]=t.blob,n}function oe(e,t,n){if(!n)return{};let r={...e};for(let e of t)r[e.path]=e.blob;return r}function se(e,t){return t.reduce((t,n)=>t+(T(e,n)?1:0),0)}function D(e,t){let n=new Set(t.map(e=>e.path)),r={};for(let[t,i]of Object.entries(e))n.has(t)&&(r[t]=i);return r}function ce(e){return e.find(e=>!e.binary)??e[0]??null}function le(e,t,n){if(t.length===0)return null;let r=n?t.findIndex(e=>e.path===n)+1:0;for(let n=0;n<t.length;n++){let i=t[(r+n)%t.length];if(i&&!T(e,i))return i}return null}function ue(e){try{let t=localStorage.getItem(e);if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))return{};let r={};for(let[e,t]of Object.entries(n))typeof t==`string`&&(r[e]=t);return r}catch{return{}}}function O(e,t,n=C){let r=[t,...e.filter(e=>e!==t)];return{recent:r.slice(0,n),evicted:r.slice(n)}}function k(){try{let e=JSON.parse(localStorage.getItem(S)??`[]`);return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}catch{return[]}}function A(e,t){try{if(Object.keys(t).length===0){localStorage.removeItem(e);let t=k().filter(t=>t!==e);localStorage.setItem(S,JSON.stringify(t));return}localStorage.setItem(e,JSON.stringify(t));let{recent:n,evicted:r}=O(k(),e);for(let e of r)localStorage.removeItem(e);localStorage.setItem(S,JSON.stringify(n))}catch{}}var j=n(),M={M:`text-warning`,A:`text-success`,D:`text-error`,R:`text-primary`,C:`text-accent-2`,T:`text-text-3`};function N(e){let{node:t,depth:n,byPath:i,reviewed:s,selectedPath:c,collapsed:l,onToggleCollapse:u,onSelect:d,onToggleReviewed:f}=e,p=t.file?i.get(t.fullPath):void 0;if(!p){let r=l.has(t.fullPath);return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`button`,{type:`button`,"data-testid":`branch-review-folder`,className:`w-full flex items-center gap-1 px-2 py-1 text-xs min-h-11 md:min-h-0 hover:bg-surface-hover text-left`,style:{paddingLeft:n*14+8},onClick:()=>u(t.fullPath),children:[r?(0,j.jsx)(a,{className:`size-3 shrink-0`}):(0,j.jsx)(o,{className:`size-3 shrink-0`}),(0,j.jsx)(`span`,{className:`truncate text-text-2`,children:t.name})]}),!r&&t.children.map(t=>(0,j.jsx)(N,{...e,node:t,depth:n+1},t.fullPath))]})}let h=T(s,p),_=c===p.path;return(0,j.jsxs)(`div`,{className:`flex items-center gap-1.5 pr-2 py-1 text-xs cursor-pointer border-l-2 min-h-11 md:min-h-0 hover:bg-surface-hover ${_?`bg-primary/10 border-primary`:`border-transparent`}`,style:{paddingLeft:n*14+6},onClick:()=>d(p.path),"aria-current":_?`true`:void 0,"data-testid":`branch-review-file`,"data-path":p.path,"data-selected":_?`true`:`false`,"data-reviewed":h?`true`:`false`,children:[(0,j.jsx)(`button`,{type:`button`,"aria-label":h?`Mark ${p.path} unreviewed`:`Mark ${p.path} reviewed`,"data-testid":`branch-review-check`,className:`size-11 md:size-4 shrink-0 flex items-center justify-center`,onClick:e=>{e.stopPropagation(),f(p)},children:(0,j.jsx)(`span`,{"data-testid":`branch-review-check-box`,className:`size-4 rounded border flex items-center justify-center ${h?`bg-primary border-primary text-primary-foreground`:`border-border`}`,children:h&&(0,j.jsx)(r,{className:`size-3`})})}),(0,j.jsx)(m,{name:t.name,className:`size-3.5 shrink-0`}),(0,j.jsx)(g,{children:t.name}),(0,j.jsx)(`span`,{className:`shrink-0 font-mono ${M[p.status]}`,children:p.status}),p.binary?(0,j.jsx)(`span`,{className:`shrink-0 text-text-3 italic`,children:`bin`}):(0,j.jsxs)(`span`,{className:`shrink-0 tabular-nums text-[10px]`,children:[(0,j.jsxs)(`span`,{className:`text-success`,children:[`+`,p.additions]}),` `,(0,j.jsxs)(`span`,{className:`text-error`,children:[`-`,p.deletions]})]})]})}function P(e,t){let n=e.filter(e=>!e.remote&&e.name!==t);return n.find(e=>e.name===`main`)?.name??n.find(e=>e.name===`master`)?.name??n[0]?.name??``}function F({metadata:e}){let t=e?.projectName,n=re(t),r=f(),[a,o]=(0,b.useState)([]),[m,x]=(0,b.useState)(``),[S,C]=(0,b.useState)(``),[T,O]=(0,b.useState)(null),[k,M]=(0,b.useState)(null),[F,I]=(0,b.useState)({}),[de,L]=(0,b.useState)(new Set),[R,z]=(0,b.useState)(!1),[B,V]=(0,b.useState)(null),[fe,H]=(0,b.useState)(!1);(0,b.useEffect)(()=>{if(!t||!n.repo)return;let e=!1;return d.get(n.gitUrl(`/branches`)).then(t=>{if(e)return;o(t);let n=t.find(e=>e.current)?.name;C(e=>e||n||``),x(e=>e||P(t,n))}).catch(t=>!e&&V(t instanceof Error?t.message:`Could not list branches`)),()=>{e=!0}},[t,n]);let U=(0,b.useRef)(null),W=(0,b.useCallback)(async()=>{if(!t||!n.repo||!m||!S)return;U.current?.abort();let e=new AbortController;U.current=e,z(!0),V(null);try{let t=new URLSearchParams({base:m,head:S}),r=await d.get(n.gitUrl(`/branch-diff?${t}`),{signal:e.signal});if(e.signal.aborted)return;O(r),M(e=>e&&r.files.some(t=>t.path===e)?e:ce(r.files)?.path??null)}catch(t){if(e.signal.aborted)return;O(null),V(t instanceof Error?t.message:`Could not compare these branches`)}finally{e.signal.aborted||z(!1)}},[t,n,m,S]);(0,b.useEffect)(()=>(W(),()=>U.current?.abort()),[W]);let G=t&&m&&S?w(t,m,S):null;(0,b.useEffect)(()=>{L(new Set)},[G]),(0,b.useEffect)(()=>{I(G?ue(G):{})},[G]);let K=T&&T.base===m&&T.head===S?T:null;(0,b.useEffect)(()=>{!G||!K||I(e=>{let t=D(e,K.files);return Object.keys(t).length!==Object.keys(e).length&&A(G,t),t})},[G,K]);let q=(0,b.useCallback)(e=>{I(e),G&&A(G,e)},[G]),J=K?.files??[],Y=(0,b.useMemo)(()=>new Map(J.map(e=>[e.path,e])),[J]),X=(0,b.useMemo)(()=>se(F,J),[F,J]),pe=(0,b.useMemo)(()=>ne(ie(J.map(e=>({path:e.path,status:e.status===`T`?`M`:e.status})))),[J]),Z=k?Y.get(k)??null:null,Q=(0,b.useCallback)(()=>{let e=le(F,J,k);e&&(M(e.path),H(!1))},[F,J,k]);if(n.noRepo)return(0,j.jsx)(ae,{onReload:n.reload});if(n.needsPick)return(0,j.jsx)(ee,{repos:n.repos,onChoose:n.choose});let $=(0,j.jsx)(_,{className:`h-full`,children:(0,j.jsxs)(`div`,{className:`py-1`,children:[J.length===0&&!R&&(0,j.jsx)(`div`,{className:`px-3 py-6 text-center text-xs text-text-3`,children:B?`—`:`These branches have identical trees.`}),pe.map(e=>(0,j.jsx)(N,{node:e,depth:0,byPath:Y,reviewed:F,selectedPath:k,collapsed:de,onToggleCollapse:e=>L(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),onSelect:e=>{M(e),H(!1)},onToggleReviewed:e=>q(E(F,e))},e.fullPath)),!!K?.omitted&&(0,j.jsxs)(`div`,{className:`px-3 py-3 text-center text-xs text-text-3`,children:[K.omitted.toLocaleString(),` more `,K.omitted===1?`file`:`files`,` not listed.`]})]})});return(0,j.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden bg-bg`,children:[n.isNested&&n.repo&&(0,j.jsx)(te,{repo:n.repo,repos:n.repos,onChoose:n.choose}),(0,j.jsxs)(`div`,{className:`flex items-center gap-2 px-2 py-1.5 border-b border-border shrink-0 flex-wrap`,children:[(0,j.jsx)(v,{value:m,branches:a,onChange:x,label:`Base branch`,testId:`branch-review-base`,className:`max-w-[38%]`}),(0,j.jsx)(l,{className:`size-3.5 text-text-3 shrink-0`}),(0,j.jsx)(v,{value:S,branches:a,onChange:C,label:`Branch to review`,testId:`branch-review-head`,className:`max-w-[38%]`}),(0,j.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,j.jsxs)(`span`,{className:`text-xs text-text-2 tabular-nums`,"data-testid":`branch-review-progress`,children:[X,`/`,J.length,` reviewed`]}),(0,j.jsx)(p,{variant:`ghost`,size:`icon-xs`,title:X===J.length&&J.length>0?`Clear all`:`Mark all reviewed`,disabled:J.length===0,onClick:()=>q(oe(F,J,X!==J.length)),children:(0,j.jsx)(s,{className:`size-3.5`})}),(0,j.jsx)(p,{variant:`ghost`,size:`icon-xs`,title:`Reload`,onClick:()=>void W(),children:(0,j.jsx)(c,{className:R?`animate-spin`:``})})]})]}),B&&(0,j.jsx)(`div`,{className:`px-3 py-1.5 text-xs text-destructive bg-destructive/10 shrink-0`,children:B}),(0,j.jsxs)(`div`,{className:`flex-1 flex min-h-0`,children:[!r&&(0,j.jsx)(`div`,{className:`w-72 shrink-0 border-r border-border flex flex-col min-h-0`,children:$}),(0,j.jsx)(`div`,{className:`flex-1 min-w-0 flex flex-col`,children:Z?(0,j.jsx)(y,{metadata:{filePath:n.projectFile(Z.path),projectName:t,ref1:K?.mergeBase,ref2:K?.headCommit}},`${Z.path}:${K?.mergeBase}:${K?.headCommit}`):(0,j.jsx)(`div`,{className:`flex-1 flex items-center justify-center text-xs text-text-3`,children:R?(0,j.jsx)(u,{className:`size-4 animate-spin`}):`Nothing to review.`})})]}),r&&(0,j.jsxs)(`div`,{className:`flex items-center gap-2 border-t border-border p-2 shrink-0`,children:[(0,j.jsxs)(p,{variant:`secondary`,size:`sm`,className:`flex-1 min-h-11`,onClick:()=>H(!0),children:[(0,j.jsx)(i,{className:`size-4`}),J.length,` files`]}),(0,j.jsx)(p,{variant:`secondary`,size:`sm`,className:`flex-1 min-h-11`,onClick:Q,children:`Next unreviewed`})]}),r&&(0,j.jsx)(h,{open:fe,onClose:()=>H(!1),children:(0,j.jsx)(`div`,{className:`max-h-[70vh] overflow-hidden flex flex-col`,children:$})}),!r&&Z&&(0,j.jsxs)(`div`,{className:`flex items-center gap-2 border-t border-border px-2 py-1 shrink-0`,children:[(0,j.jsx)(g,{children:Z.path}),(0,j.jsx)(p,{variant:`ghost`,size:`xs`,onClick:Q,children:`Next unreviewed`})]})]})}export{F as BranchReviewTab};
1
+ import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import{A as r,Et as i,L as a,P as o,_n as s,hr as c,m as l,xn as u}from"./icons-BwyIKaTT.js";import{r as d}from"./api-client-xQDlhUTu.js";import"./settings-store-B4mLp19V.js";import"./portal-container-context-NBi-KGK0.js";import"./project-store-BLGl9IAO.js";import"./project-framework-store-DwLxaRan.js";import{n as f}from"./use-is-mobile-VRV9eZy1.js";import"./git-repo-store-CKB5fdNP.js";import{t as p}from"./button-C9ZXWb3b.js";import{n as m}from"./file-icons-JInFtBVl.js";import{t as h}from"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import{t as g}from"./start-ellipsis-CU8GkxaV.js";import{t as _}from"./scroll-area-DOlQJGZp.js";import{Cr as ee,Sr as te,dr as ne,ii as re,ur as ie,wr as v,xr as ae}from"./index-BGk8EFQb.js";import"./use-monaco-theme-C3_wfz5J.js";import"./use-inline-blame-BA2mrMxT.js";import{DiffViewer as y}from"./diff-viewer-BKJkesHk.js";var b=e(t(),1),x=`ppm:branch-review`,S=`${x}:recent`,C=20;function w(e,t,n){return`${x}:${e}:${t}:${n}`}function T(e,t){return e[t.path]===t.blob}function E(e,t){let n={...e};return T(e,t)?delete n[t.path]:n[t.path]=t.blob,n}function oe(e,t,n){if(!n)return{};let r={...e};for(let e of t)r[e.path]=e.blob;return r}function se(e,t){return t.reduce((t,n)=>t+(T(e,n)?1:0),0)}function D(e,t){let n=new Set(t.map(e=>e.path)),r={};for(let[t,i]of Object.entries(e))n.has(t)&&(r[t]=i);return r}function ce(e){return e.find(e=>!e.binary)??e[0]??null}function le(e,t,n){if(t.length===0)return null;let r=n?t.findIndex(e=>e.path===n)+1:0;for(let n=0;n<t.length;n++){let i=t[(r+n)%t.length];if(i&&!T(e,i))return i}return null}function ue(e){try{let t=localStorage.getItem(e);if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))return{};let r={};for(let[e,t]of Object.entries(n))typeof t==`string`&&(r[e]=t);return r}catch{return{}}}function O(e,t,n=C){let r=[t,...e.filter(e=>e!==t)];return{recent:r.slice(0,n),evicted:r.slice(n)}}function k(){try{let e=JSON.parse(localStorage.getItem(S)??`[]`);return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}catch{return[]}}function A(e,t){try{if(Object.keys(t).length===0){localStorage.removeItem(e);let t=k().filter(t=>t!==e);localStorage.setItem(S,JSON.stringify(t));return}localStorage.setItem(e,JSON.stringify(t));let{recent:n,evicted:r}=O(k(),e);for(let e of r)localStorage.removeItem(e);localStorage.setItem(S,JSON.stringify(n))}catch{}}var j=n(),M={M:`text-warning`,A:`text-success`,D:`text-error`,R:`text-primary`,C:`text-accent-2`,T:`text-text-3`};function N(e){let{node:t,depth:n,byPath:i,reviewed:s,selectedPath:c,collapsed:l,onToggleCollapse:u,onSelect:d,onToggleReviewed:f}=e,p=t.file?i.get(t.fullPath):void 0;if(!p){let r=l.has(t.fullPath);return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`button`,{type:`button`,"data-testid":`branch-review-folder`,className:`w-full flex items-center gap-1 px-2 py-1 text-xs min-h-11 md:min-h-0 hover:bg-surface-hover text-left`,style:{paddingLeft:n*14+8},onClick:()=>u(t.fullPath),children:[r?(0,j.jsx)(a,{className:`size-3 shrink-0`}):(0,j.jsx)(o,{className:`size-3 shrink-0`}),(0,j.jsx)(`span`,{className:`truncate text-text-2`,children:t.name})]}),!r&&t.children.map(t=>(0,j.jsx)(N,{...e,node:t,depth:n+1},t.fullPath))]})}let h=T(s,p),_=c===p.path;return(0,j.jsxs)(`div`,{className:`flex items-center gap-1.5 pr-2 py-1 text-xs cursor-pointer border-l-2 min-h-11 md:min-h-0 hover:bg-surface-hover ${_?`bg-primary/10 border-primary`:`border-transparent`}`,style:{paddingLeft:n*14+6},onClick:()=>d(p.path),"aria-current":_?`true`:void 0,"data-testid":`branch-review-file`,"data-path":p.path,"data-selected":_?`true`:`false`,"data-reviewed":h?`true`:`false`,children:[(0,j.jsx)(`button`,{type:`button`,"aria-label":h?`Mark ${p.path} unreviewed`:`Mark ${p.path} reviewed`,"data-testid":`branch-review-check`,className:`size-11 md:size-4 shrink-0 flex items-center justify-center`,onClick:e=>{e.stopPropagation(),f(p)},children:(0,j.jsx)(`span`,{"data-testid":`branch-review-check-box`,className:`size-4 rounded border flex items-center justify-center ${h?`bg-primary border-primary text-primary-foreground`:`border-border`}`,children:h&&(0,j.jsx)(r,{className:`size-3`})})}),(0,j.jsx)(m,{name:t.name,className:`size-3.5 shrink-0`}),(0,j.jsx)(g,{children:t.name}),(0,j.jsx)(`span`,{className:`shrink-0 font-mono ${M[p.status]}`,children:p.status}),p.binary?(0,j.jsx)(`span`,{className:`shrink-0 text-text-3 italic`,children:`bin`}):(0,j.jsxs)(`span`,{className:`shrink-0 tabular-nums text-[10px]`,children:[(0,j.jsxs)(`span`,{className:`text-success`,children:[`+`,p.additions]}),` `,(0,j.jsxs)(`span`,{className:`text-error`,children:[`-`,p.deletions]})]})]})}function P(e,t){let n=e.filter(e=>!e.remote&&e.name!==t);return n.find(e=>e.name===`main`)?.name??n.find(e=>e.name===`master`)?.name??n[0]?.name??``}function F({metadata:e}){let t=e?.projectName,n=re(t),r=f(),[a,o]=(0,b.useState)([]),[m,x]=(0,b.useState)(``),[S,C]=(0,b.useState)(``),[T,O]=(0,b.useState)(null),[k,M]=(0,b.useState)(null),[F,I]=(0,b.useState)({}),[de,L]=(0,b.useState)(new Set),[R,z]=(0,b.useState)(!1),[B,V]=(0,b.useState)(null),[fe,H]=(0,b.useState)(!1);(0,b.useEffect)(()=>{if(!t||!n.repo)return;let e=!1;return d.get(n.gitUrl(`/branches`)).then(t=>{if(e)return;o(t);let n=t.find(e=>e.current)?.name;C(e=>e||n||``),x(e=>e||P(t,n))}).catch(t=>!e&&V(t instanceof Error?t.message:`Could not list branches`)),()=>{e=!0}},[t,n]);let U=(0,b.useRef)(null),W=(0,b.useCallback)(async()=>{if(!t||!n.repo||!m||!S)return;U.current?.abort();let e=new AbortController;U.current=e,z(!0),V(null);try{let t=new URLSearchParams({base:m,head:S}),r=await d.get(n.gitUrl(`/branch-diff?${t}`),{signal:e.signal});if(e.signal.aborted)return;O(r),M(e=>e&&r.files.some(t=>t.path===e)?e:ce(r.files)?.path??null)}catch(t){if(e.signal.aborted)return;O(null),V(t instanceof Error?t.message:`Could not compare these branches`)}finally{e.signal.aborted||z(!1)}},[t,n,m,S]);(0,b.useEffect)(()=>(W(),()=>U.current?.abort()),[W]);let G=t&&m&&S?w(t,m,S):null;(0,b.useEffect)(()=>{L(new Set)},[G]),(0,b.useEffect)(()=>{I(G?ue(G):{})},[G]);let K=T&&T.base===m&&T.head===S?T:null;(0,b.useEffect)(()=>{!G||!K||I(e=>{let t=D(e,K.files);return Object.keys(t).length!==Object.keys(e).length&&A(G,t),t})},[G,K]);let q=(0,b.useCallback)(e=>{I(e),G&&A(G,e)},[G]),J=K?.files??[],Y=(0,b.useMemo)(()=>new Map(J.map(e=>[e.path,e])),[J]),X=(0,b.useMemo)(()=>se(F,J),[F,J]),pe=(0,b.useMemo)(()=>ne(ie(J.map(e=>({path:e.path,status:e.status===`T`?`M`:e.status})))),[J]),Z=k?Y.get(k)??null:null,Q=(0,b.useCallback)(()=>{let e=le(F,J,k);e&&(M(e.path),H(!1))},[F,J,k]);if(n.noRepo)return(0,j.jsx)(ae,{onReload:n.reload});if(n.needsPick)return(0,j.jsx)(ee,{repos:n.repos,onChoose:n.choose});let $=(0,j.jsx)(_,{className:`h-full`,children:(0,j.jsxs)(`div`,{className:`py-1`,children:[J.length===0&&!R&&(0,j.jsx)(`div`,{className:`px-3 py-6 text-center text-xs text-text-3`,children:B?`—`:`These branches have identical trees.`}),pe.map(e=>(0,j.jsx)(N,{node:e,depth:0,byPath:Y,reviewed:F,selectedPath:k,collapsed:de,onToggleCollapse:e=>L(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),onSelect:e=>{M(e),H(!1)},onToggleReviewed:e=>q(E(F,e))},e.fullPath)),!!K?.omitted&&(0,j.jsxs)(`div`,{className:`px-3 py-3 text-center text-xs text-text-3`,children:[K.omitted.toLocaleString(),` more `,K.omitted===1?`file`:`files`,` not listed.`]})]})});return(0,j.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden bg-bg`,children:[n.isNested&&n.repo&&(0,j.jsx)(te,{repo:n.repo,repos:n.repos,onChoose:n.choose}),(0,j.jsxs)(`div`,{className:`flex items-center gap-2 px-2 py-1.5 border-b border-border shrink-0 flex-wrap`,children:[(0,j.jsx)(v,{value:m,branches:a,onChange:x,label:`Base branch`,testId:`branch-review-base`,className:`max-w-[38%]`}),(0,j.jsx)(l,{className:`size-3.5 text-text-3 shrink-0`}),(0,j.jsx)(v,{value:S,branches:a,onChange:C,label:`Branch to review`,testId:`branch-review-head`,className:`max-w-[38%]`}),(0,j.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,j.jsxs)(`span`,{className:`text-xs text-text-2 tabular-nums`,"data-testid":`branch-review-progress`,children:[X,`/`,J.length,` reviewed`]}),(0,j.jsx)(p,{variant:`ghost`,size:`icon-xs`,title:X===J.length&&J.length>0?`Clear all`:`Mark all reviewed`,disabled:J.length===0,onClick:()=>q(oe(F,J,X!==J.length)),children:(0,j.jsx)(s,{className:`size-3.5`})}),(0,j.jsx)(p,{variant:`ghost`,size:`icon-xs`,title:`Reload`,onClick:()=>void W(),children:(0,j.jsx)(c,{className:R?`animate-spin`:``})})]})]}),B&&(0,j.jsx)(`div`,{className:`px-3 py-1.5 text-xs text-destructive bg-destructive/10 shrink-0`,children:B}),(0,j.jsxs)(`div`,{className:`flex-1 flex min-h-0`,children:[!r&&(0,j.jsx)(`div`,{className:`w-72 shrink-0 border-r border-border flex flex-col min-h-0`,children:$}),(0,j.jsx)(`div`,{className:`flex-1 min-w-0 flex flex-col`,children:Z?(0,j.jsx)(y,{metadata:{filePath:n.projectFile(Z.path),projectName:t,ref1:K?.mergeBase,ref2:K?.headCommit}},`${Z.path}:${K?.mergeBase}:${K?.headCommit}`):(0,j.jsx)(`div`,{className:`flex-1 flex items-center justify-center text-xs text-text-3`,children:R?(0,j.jsx)(u,{className:`size-4 animate-spin`}):`Nothing to review.`})})]}),r&&(0,j.jsxs)(`div`,{className:`flex items-center gap-2 border-t border-border p-2 shrink-0`,children:[(0,j.jsxs)(p,{variant:`secondary`,size:`sm`,className:`flex-1 min-h-11`,onClick:()=>H(!0),children:[(0,j.jsx)(i,{className:`size-4`}),J.length,` files`]}),(0,j.jsx)(p,{variant:`secondary`,size:`sm`,className:`flex-1 min-h-11`,onClick:Q,children:`Next unreviewed`})]}),r&&(0,j.jsx)(h,{open:fe,onClose:()=>H(!1),children:(0,j.jsx)(`div`,{className:`max-h-[70vh] overflow-hidden flex flex-col`,children:$})}),!r&&Z&&(0,j.jsxs)(`div`,{className:`flex items-center gap-2 border-t border-border px-2 py-1 shrink-0`,children:[(0,j.jsx)(g,{children:Z.path}),(0,j.jsx)(p,{variant:`ghost`,size:`xs`,onClick:Q,children:`Next unreviewed`})]})]})}export{F as BranchReviewTab};
@@ -1 +1 @@
1
- import"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import"./icons-BwyIKaTT.js";import{t as e}from"./chat-tab-D-cl4yMo.js";import"./api-client-xQDlhUTu.js";import"./settings-store-B4mLp19V.js";import"./portal-container-context-NBi-KGK0.js";import"./window-store-DqX_qmkQ.js";import"./panel-store-BJhazigC.js";import"./project-store-BLGl9IAO.js";import"./project-framework-store-DwLxaRan.js";import"./session-list-sync-triggers-DtJI5KF0.js";import"./tab-store-D5I52eLN.js";import"./context-menu-BCuZYfWC.js";import"./chat-preparation-cache-190LLyy7.js";import"./file-store-BQ41vIs5.js";import"./use-is-mobile-VRV9eZy1.js";import"./settings-categories-Ajj4ui27.js";import"./open-settings-EXR4zoZG.js";import"./onboarding-quick-orientation-CTHtIRib.js";import"./button-C9ZXWb3b.js";import"./dialog-Dn_2tuYa.js";import"./file-icons-JInFtBVl.js";import"./patch-tab-metadata-C92YkrRX.js";import"./dropdown-menu-BQidk_OJ.js";import"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import"./fs-api-CFtQzsIJ.js";import"./input-C3oVNCMq.js";import"./start-ellipsis-CU8GkxaV.js";import"./ws-auth-CbF6GqxP.js";import"./agent-session-sheet-store-BAfLnsLX.js";import"./libesm-B6LsX5wH.js";import"./tool-cards-BDzK03U4.js";import"./use-blob-url-Clm7wbB_.js";import"./design-canvas-check-BIHc2d_k.js";import"./db-ai-tools-CVbbW_MZ.js";import"./use-websocket-rWdrMWa8.js";import"./api-settings-vmIRFNwZ.js";import"./session-changes-bar-VfS2sHuH.js";import"./onboarding-entry-eehqBvyM.js";import"./send-to-chat-CWV1qd3c.js";import"./slash-command-picker-DpZsPuNf.js";import"./ai-settings-section-CNdbcCaI.js";import"./codex-reset-credit-button-C0a2svAw.js";export{e as ChatTab};
1
+ import"./vendor-markdown-C-P1aR4p.js";import"./vendor-ui-BTSIXzhZ.js";import"./icons-BwyIKaTT.js";import{t as e}from"./chat-tab-DsW93LTL.js";import"./api-client-xQDlhUTu.js";import"./settings-store-B4mLp19V.js";import"./portal-container-context-NBi-KGK0.js";import"./window-store-DqX_qmkQ.js";import"./panel-store-BJhazigC.js";import"./project-store-BLGl9IAO.js";import"./project-framework-store-DwLxaRan.js";import"./session-list-sync-triggers-DtJI5KF0.js";import"./tab-store-D5I52eLN.js";import"./context-menu-BCuZYfWC.js";import"./chat-preparation-cache-190LLyy7.js";import"./file-store-BQ41vIs5.js";import"./use-is-mobile-VRV9eZy1.js";import"./settings-categories-Ajj4ui27.js";import"./open-settings-EXR4zoZG.js";import"./onboarding-quick-orientation-CTHtIRib.js";import"./button-C9ZXWb3b.js";import"./dialog-Dn_2tuYa.js";import"./file-icons-JInFtBVl.js";import"./patch-tab-metadata-C92YkrRX.js";import"./dropdown-menu-BQidk_OJ.js";import"./mobile-bottom-sheet-DArbIyrD.js";import"./use-visual-viewport-MmugpRg-.js";import"./fs-api-CFtQzsIJ.js";import"./input-C3oVNCMq.js";import"./start-ellipsis-CU8GkxaV.js";import"./ws-auth-CbF6GqxP.js";import"./agent-session-sheet-store-BAfLnsLX.js";import"./libesm-B6LsX5wH.js";import"./tool-cards-CsD_VXcG.js";import"./use-blob-url-Clm7wbB_.js";import"./design-canvas-check-BIHc2d_k.js";import"./db-ai-tools-CVbbW_MZ.js";import"./use-websocket-BFnUq0-x.js";import"./api-settings-vmIRFNwZ.js";import"./session-changes-bar-VfS2sHuH.js";import"./onboarding-entry-eehqBvyM.js";import"./send-to-chat-CWV1qd3c.js";import"./slash-command-picker-Cn2Fdz2p.js";import"./ai-settings-section-DVKJPM0n.js";import"./codex-reset-credit-button-BnRmkBZu.js";export{e as ChatTab};
@@ -0,0 +1,3 @@
1
+ � ���r�'��i���le�X�vD.�(����r��\Σ$�b
2
+ E���cX�t:�����J��I(tqY�쓽ӈT�J���Y|>��d�$Pǹ]
3
+ ���Q���e�> ~�3I&�@[ �is��Mu {~Kíi�Զ�`�@Wj|�y�99�['o��$j��{O[��Wg���0dTz���l.�`Y�+�r���7�_���BW�u�ޱ�gйN�� ���B��R�)y2��?ym��LhB=?Z�rD���m2$�g/���Q/��I�X��D�[��'��k]�y�^B'8�^��2J���*�uo� ��gnV�+p3e��4��ǡش�󰑂��V�g�vq�,=IhoP�Fj�c�ǘؾX��n�a���mf��g�;�og4v�7~����Z�C-y�����h1���D�