termdock 1.4.334 → 1.4.336

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 (345) hide show
  1. package/dist/client/assets/{App-CA8oXFgS.js → App-B1lqBSPB.js} +16 -16
  2. package/dist/client/assets/App-B1lqBSPB.js.br +0 -0
  3. package/dist/client/assets/App-B1lqBSPB.js.gz +0 -0
  4. package/dist/client/assets/{ArchitecturePanel-BkB57agj.js → ArchitecturePanel-BOq2FG6t.js} +2 -2
  5. package/dist/client/assets/ArchitecturePanel-BOq2FG6t.js.br +0 -0
  6. package/dist/client/assets/ArchitecturePanel-BOq2FG6t.js.gz +0 -0
  7. package/dist/client/assets/{ChangeWalkthroughPanel-vh6Z641M.js → ChangeWalkthroughPanel-CxqwQxYc.js} +1 -1
  8. package/dist/client/assets/ChangeWalkthroughPanel-CxqwQxYc.js.br +0 -0
  9. package/dist/client/assets/ChangeWalkthroughPanel-CxqwQxYc.js.gz +0 -0
  10. package/dist/client/assets/{CollaborationMainWorkspace-dTXq04jE.js → CollaborationMainWorkspace-vvAVjIlQ.js} +1 -1
  11. package/dist/client/assets/CollaborationMainWorkspace-vvAVjIlQ.js.br +0 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-vvAVjIlQ.js.gz +0 -0
  13. package/dist/client/assets/CollaborationTaskContent-Bx6Z5gEL.js +2 -0
  14. package/dist/client/assets/{ComputerControlView-Cmar8PMd.js → ComputerControlView-mR6vlp9k.js} +3 -3
  15. package/dist/client/assets/ComputerControlView-mR6vlp9k.js.br +0 -0
  16. package/dist/client/assets/ComputerControlView-mR6vlp9k.js.gz +0 -0
  17. package/dist/client/assets/{DagPlayground-C-JZfG9-.js → DagPlayground-nUK9xIql.js} +1 -1
  18. package/dist/client/assets/DagPlayground-nUK9xIql.js.br +0 -0
  19. package/dist/client/assets/DagPlayground-nUK9xIql.js.gz +0 -0
  20. package/dist/client/assets/{DiffLab-rOEPk8iI.js → DiffLab-D6XhZtPW.js} +1 -1
  21. package/dist/client/assets/DiffLab-D6XhZtPW.js.br +0 -0
  22. package/dist/client/assets/DiffLab-D6XhZtPW.js.gz +0 -0
  23. package/dist/client/assets/{DiffReview-aIj4WHDS.js → DiffReview-BhyYqkD4.js} +1 -1
  24. package/dist/client/assets/DiffReview-BhyYqkD4.js.br +0 -0
  25. package/dist/client/assets/DiffReview-BhyYqkD4.js.gz +0 -0
  26. package/dist/client/assets/{DiffReviewLab-CU4vENL5.js → DiffReviewLab-CvNWVrbl.js} +1 -1
  27. package/dist/client/assets/DiffReviewLab-CvNWVrbl.js.br +0 -0
  28. package/dist/client/assets/DiffReviewLab-CvNWVrbl.js.gz +0 -0
  29. package/dist/client/assets/{DiffViewer-SKlbS7b4.js → DiffViewer-BSbMa2mq.js} +1 -1
  30. package/dist/client/assets/DiffViewer-BSbMa2mq.js.br +0 -0
  31. package/dist/client/assets/DiffViewer-BSbMa2mq.js.gz +0 -0
  32. package/dist/client/assets/{ModelPreview-mGhBeBla.js → ModelPreview-B_VPlNYr.js} +1 -1
  33. package/dist/client/assets/ModelPreview-B_VPlNYr.js.br +0 -0
  34. package/dist/client/assets/ModelPreview-B_VPlNYr.js.gz +0 -0
  35. package/dist/client/assets/{RightSidebar-BtHbt-XD.js → RightSidebar-Cakd9qUZ.js} +3 -3
  36. package/dist/client/assets/RightSidebar-Cakd9qUZ.js.br +0 -0
  37. package/dist/client/assets/RightSidebar-Cakd9qUZ.js.gz +0 -0
  38. package/dist/client/assets/{abnfDiagram-VCTEODGH-BazK9AUo.js → abnfDiagram-VCTEODGH-vWK7F-r_.js} +1 -1
  39. package/dist/client/assets/abnfDiagram-VCTEODGH-vWK7F-r_.js.br +0 -0
  40. package/dist/client/assets/abnfDiagram-VCTEODGH-vWK7F-r_.js.gz +0 -0
  41. package/dist/client/assets/{app-1SAb4dhI.js → app-BZBIr89q.js} +3 -3
  42. package/dist/client/assets/app-BZBIr89q.js.br +0 -0
  43. package/dist/client/assets/app-BZBIr89q.js.gz +0 -0
  44. package/dist/client/assets/{arc-DW2qA73J.js → arc-Bdjvby9b.js} +1 -1
  45. package/dist/client/assets/arc-Bdjvby9b.js.br +0 -0
  46. package/dist/client/assets/arc-Bdjvby9b.js.gz +0 -0
  47. package/dist/client/assets/{architectureDiagram-5GKGNRK7-CVkFu36h.js → architectureDiagram-5GKGNRK7-DTR5hJkG.js} +1 -1
  48. package/dist/client/assets/architectureDiagram-5GKGNRK7-DTR5hJkG.js.br +0 -0
  49. package/dist/client/assets/architectureDiagram-5GKGNRK7-DTR5hJkG.js.gz +0 -0
  50. package/dist/client/assets/{blockDiagram-I7D4REHJ-Cw0LbdUV.js → blockDiagram-I7D4REHJ-DPz3axsu.js} +1 -1
  51. package/dist/client/assets/blockDiagram-I7D4REHJ-DPz3axsu.js.br +0 -0
  52. package/dist/client/assets/blockDiagram-I7D4REHJ-DPz3axsu.js.gz +0 -0
  53. package/dist/client/assets/{c4Diagram-7LVT6UL2-D-7cVLVY.js → c4Diagram-7LVT6UL2-d5ZwPpcN.js} +1 -1
  54. package/dist/client/assets/c4Diagram-7LVT6UL2-d5ZwPpcN.js.br +0 -0
  55. package/dist/client/assets/c4Diagram-7LVT6UL2-d5ZwPpcN.js.gz +0 -0
  56. package/dist/client/assets/channel-M_h_h55d.js +1 -0
  57. package/dist/client/assets/{chunk-2Q5K7J3B-DHms9xFG.js → chunk-2Q5K7J3B-BpEmNpto.js} +1 -1
  58. package/dist/client/assets/{chunk-5VM5RSS4-DT9NVgVz.js → chunk-5VM5RSS4-CXDCiEbN.js} +1 -1
  59. package/dist/client/assets/{chunk-F27PBJKO-BPQlePZ0.js → chunk-F27PBJKO-C1L__gXc.js} +1 -1
  60. package/dist/client/assets/chunk-F27PBJKO-C1L__gXc.js.br +0 -0
  61. package/dist/client/assets/chunk-F27PBJKO-C1L__gXc.js.gz +0 -0
  62. package/dist/client/assets/{chunk-IMKFNOWR-CYpkOg4N.js → chunk-IMKFNOWR-CX0r7pV5.js} +1 -1
  63. package/dist/client/assets/chunk-IMKFNOWR-CX0r7pV5.js.br +0 -0
  64. package/dist/client/assets/chunk-IMKFNOWR-CX0r7pV5.js.gz +0 -0
  65. package/dist/client/assets/{chunk-JWPE2WC7-BetVwCtg.js → chunk-JWPE2WC7-DkbhnrKh.js} +1 -1
  66. package/dist/client/assets/{chunk-POPQ4Y6H-CHVqavTY.js → chunk-POPQ4Y6H-CH-o5PVe.js} +1 -1
  67. package/dist/client/assets/{chunk-SVP7TREG-TridS3zl.js → chunk-SVP7TREG-C1x5c5cy.js} +1 -1
  68. package/dist/client/assets/chunk-SVP7TREG-C1x5c5cy.js.br +0 -0
  69. package/dist/client/assets/chunk-SVP7TREG-C1x5c5cy.js.gz +0 -0
  70. package/dist/client/assets/{chunk-TICWLB2K-CrSU9J1Y.js → chunk-TICWLB2K-DAktkamN.js} +1 -1
  71. package/dist/client/assets/chunk-TICWLB2K-DAktkamN.js.br +0 -0
  72. package/dist/client/assets/chunk-TICWLB2K-DAktkamN.js.gz +0 -0
  73. package/dist/client/assets/{chunk-XXDRQBXY-DvrlcFpp.js → chunk-XXDRQBXY-emNetBN1.js} +1 -1
  74. package/dist/client/assets/classDiagram-ZZMXUADV-BVuw_2Ox.js +1 -0
  75. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BVuw_2Ox.js +1 -0
  76. package/dist/client/assets/{cose-bilkent-JH36ORCC-BPspdiZq.js → cose-bilkent-JH36ORCC-kBGroiho.js} +1 -1
  77. package/dist/client/assets/cose-bilkent-JH36ORCC-kBGroiho.js.br +0 -0
  78. package/dist/client/assets/cose-bilkent-JH36ORCC-kBGroiho.js.gz +0 -0
  79. package/dist/client/assets/{cynefin-OW5HDTMX-CdZ2Ij-1.js → cynefin-OW5HDTMX-C0TjwB46.js} +1 -1
  80. package/dist/client/assets/cynefin-OW5HDTMX-C0TjwB46.js.br +0 -0
  81. package/dist/client/assets/cynefin-OW5HDTMX-C0TjwB46.js.gz +0 -0
  82. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CS4dSANt.js → cynefinDiagram-5FMLGOSQ-CbLSUTuV.js} +1 -1
  83. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CbLSUTuV.js.br +0 -0
  84. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CbLSUTuV.js.gz +0 -0
  85. package/dist/client/assets/{dagre-GXQ25YYZ-jz406NVd.js → dagre-GXQ25YYZ-BoznXKfa.js} +1 -1
  86. package/dist/client/assets/dagre-GXQ25YYZ-BoznXKfa.js.br +0 -0
  87. package/dist/client/assets/dagre-GXQ25YYZ-BoznXKfa.js.gz +0 -0
  88. package/dist/client/assets/{diagram-S7CK7UJ4-BXz7D6hW.js → diagram-S7CK7UJ4-iY9ia7F5.js} +1 -1
  89. package/dist/client/assets/diagram-S7CK7UJ4-iY9ia7F5.js.br +0 -0
  90. package/dist/client/assets/diagram-S7CK7UJ4-iY9ia7F5.js.gz +0 -0
  91. package/dist/client/assets/{diagram-UQ7AKVKN-BtSwQGmR.js → diagram-UQ7AKVKN-DhnC8gBw.js} +1 -1
  92. package/dist/client/assets/diagram-UQ7AKVKN-DhnC8gBw.js.br +0 -0
  93. package/dist/client/assets/diagram-UQ7AKVKN-DhnC8gBw.js.gz +0 -0
  94. package/dist/client/assets/{diagram-VSXAHHWV-B2lDfe93.js → diagram-VSXAHHWV-JFg8cbqX.js} +1 -1
  95. package/dist/client/assets/diagram-VSXAHHWV-JFg8cbqX.js.br +0 -0
  96. package/dist/client/assets/diagram-VSXAHHWV-JFg8cbqX.js.gz +0 -0
  97. package/dist/client/assets/{diagram-VX7I27RA-QDrY0hNk.js → diagram-VX7I27RA-dvyXUTpo.js} +1 -1
  98. package/dist/client/assets/diagram-VX7I27RA-dvyXUTpo.js.br +0 -0
  99. package/dist/client/assets/diagram-VX7I27RA-dvyXUTpo.js.gz +0 -0
  100. package/dist/client/assets/{diagram-Z3DM3KII-D1AFu390.js → diagram-Z3DM3KII-DmjwsCUU.js} +1 -1
  101. package/dist/client/assets/diagram-Z3DM3KII-DmjwsCUU.js.br +0 -0
  102. package/dist/client/assets/diagram-Z3DM3KII-DmjwsCUU.js.gz +0 -0
  103. package/dist/client/assets/{ebnfDiagram-PWID7BFC-L5aoZUCG.js → ebnfDiagram-PWID7BFC-BxCdDL0c.js} +1 -1
  104. package/dist/client/assets/ebnfDiagram-PWID7BFC-BxCdDL0c.js.br +0 -0
  105. package/dist/client/assets/ebnfDiagram-PWID7BFC-BxCdDL0c.js.gz +0 -0
  106. package/dist/client/assets/{erDiagram-RLTQ6QDP-CFUfoWVL.js → erDiagram-RLTQ6QDP-BWvvnoz1.js} +1 -1
  107. package/dist/client/assets/erDiagram-RLTQ6QDP-BWvvnoz1.js.br +0 -0
  108. package/dist/client/assets/erDiagram-RLTQ6QDP-BWvvnoz1.js.gz +0 -0
  109. package/dist/client/assets/{flowDiagram-HODETNUW-A-hvg2q9.js → flowDiagram-HODETNUW-CVU0l_6c.js} +1 -1
  110. package/dist/client/assets/flowDiagram-HODETNUW-CVU0l_6c.js.br +0 -0
  111. package/dist/client/assets/flowDiagram-HODETNUW-CVU0l_6c.js.gz +0 -0
  112. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DSMsjMS7.js → ganttDiagram-EL5Y4UJY-CjO521RP.js} +1 -1
  113. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CjO521RP.js.br +0 -0
  114. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CjO521RP.js.gz +0 -0
  115. package/dist/client/assets/{gestureArbiter-BvkspAa2.js → gestureArbiter-D_fs_PXp.js} +1 -1
  116. package/dist/client/assets/gestureArbiter-D_fs_PXp.js.br +0 -0
  117. package/dist/client/assets/gestureArbiter-D_fs_PXp.js.gz +0 -0
  118. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-BhpWzivx.js → gitGraphDiagram-WWUBYQGX-DbxNhHiO.js} +1 -1
  119. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DbxNhHiO.js.br +0 -0
  120. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DbxNhHiO.js.gz +0 -0
  121. package/dist/client/assets/{infoDiagram-27XIBGKW-a_A60wu0.js → infoDiagram-27XIBGKW-DRcGAFqT.js} +1 -1
  122. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-zp9iSkhD.js → ishikawaDiagram-5VMMS53U-BPbgDJUg.js} +1 -1
  123. package/dist/client/assets/ishikawaDiagram-5VMMS53U-BPbgDJUg.js.br +0 -0
  124. package/dist/client/assets/ishikawaDiagram-5VMMS53U-BPbgDJUg.js.gz +0 -0
  125. package/dist/client/assets/{journeyDiagram-3NMN7TZE-CWIWv2zw.js → journeyDiagram-3NMN7TZE-D1nSzyjD.js} +1 -1
  126. package/dist/client/assets/journeyDiagram-3NMN7TZE-D1nSzyjD.js.br +0 -0
  127. package/dist/client/assets/journeyDiagram-3NMN7TZE-D1nSzyjD.js.gz +0 -0
  128. package/dist/client/assets/{kanban-definition-UXKFOSKX-JzGKFo57.js → kanban-definition-UXKFOSKX-CSCXZnir.js} +1 -1
  129. package/dist/client/assets/kanban-definition-UXKFOSKX-CSCXZnir.js.br +0 -0
  130. package/dist/client/assets/kanban-definition-UXKFOSKX-CSCXZnir.js.gz +0 -0
  131. package/dist/client/assets/{layout-7Cq6z6dO.js → layout-DTNe7C08.js} +1 -1
  132. package/dist/client/assets/layout-DTNe7C08.js.br +0 -0
  133. package/dist/client/assets/layout-DTNe7C08.js.gz +0 -0
  134. package/dist/client/assets/{linear-CuFZW946.js → linear-DELStaU_.js} +1 -1
  135. package/dist/client/assets/linear-DELStaU_.js.br +0 -0
  136. package/dist/client/assets/linear-DELStaU_.js.gz +0 -0
  137. package/dist/client/assets/{mermaid.core-DbR5q1bj.js → mermaid.core-D7uvx0E2.js} +5 -5
  138. package/dist/client/assets/mermaid.core-D7uvx0E2.js.br +0 -0
  139. package/dist/client/assets/mermaid.core-D7uvx0E2.js.gz +0 -0
  140. package/dist/client/assets/{mindmap-definition-YA3MSWOX-DdzejTGB.js → mindmap-definition-YA3MSWOX-C_fF6Gnh.js} +1 -1
  141. package/dist/client/assets/mindmap-definition-YA3MSWOX-C_fF6Gnh.js.br +0 -0
  142. package/dist/client/assets/mindmap-definition-YA3MSWOX-C_fF6Gnh.js.gz +0 -0
  143. package/dist/client/assets/{passwordBootstrap-lisz9s1P.js → passwordBootstrap-Co17Xh3M.js} +1 -1
  144. package/dist/client/assets/passwordBootstrap-Co17Xh3M.js.br +0 -0
  145. package/dist/client/assets/passwordBootstrap-Co17Xh3M.js.gz +0 -0
  146. package/dist/client/assets/{pegDiagram-XKGWAZYB-D720_LqX.js → pegDiagram-XKGWAZYB-BFOfbHg1.js} +1 -1
  147. package/dist/client/assets/pegDiagram-XKGWAZYB-BFOfbHg1.js.br +0 -0
  148. package/dist/client/assets/pegDiagram-XKGWAZYB-BFOfbHg1.js.gz +0 -0
  149. package/dist/client/assets/{pieDiagram-E7YTZNPT-zEDQIxrq.js → pieDiagram-E7YTZNPT-BkLXgY2Y.js} +1 -1
  150. package/dist/client/assets/pieDiagram-E7YTZNPT-BkLXgY2Y.js.br +0 -0
  151. package/dist/client/assets/pieDiagram-E7YTZNPT-BkLXgY2Y.js.gz +0 -0
  152. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Cp0CVTM2.js → quadrantDiagram-AXDQQJYC-DIF7ynjD.js} +1 -1
  153. package/dist/client/assets/quadrantDiagram-AXDQQJYC-DIF7ynjD.js.br +0 -0
  154. package/dist/client/assets/quadrantDiagram-AXDQQJYC-DIF7ynjD.js.gz +0 -0
  155. package/dist/client/assets/{railroadDiagram-O6MQD6OU-DmEhvOdy.js → railroadDiagram-O6MQD6OU-DGeuv8o1.js} +1 -1
  156. package/dist/client/assets/railroadDiagram-O6MQD6OU-DGeuv8o1.js.br +0 -0
  157. package/dist/client/assets/railroadDiagram-O6MQD6OU-DGeuv8o1.js.gz +0 -0
  158. package/dist/client/assets/{rdpSession-DQon3e98.js → rdpSession-DZCrSxpu.js} +1 -1
  159. package/dist/client/assets/rdpSession-DZCrSxpu.js.br +0 -0
  160. package/dist/client/assets/rdpSession-DZCrSxpu.js.gz +0 -0
  161. package/dist/client/assets/{referenceLongPress-DTjCnJH8.js → referenceLongPress-DrY73BHe.js} +1 -1
  162. package/dist/client/assets/referenceLongPress-DrY73BHe.js.br +0 -0
  163. package/dist/client/assets/referenceLongPress-DrY73BHe.js.gz +0 -0
  164. package/dist/client/assets/{requirementDiagram-BXWQKSXE-BnMPYUjE.js → requirementDiagram-BXWQKSXE-CoVdyMn3.js} +1 -1
  165. package/dist/client/assets/requirementDiagram-BXWQKSXE-CoVdyMn3.js.br +0 -0
  166. package/dist/client/assets/requirementDiagram-BXWQKSXE-CoVdyMn3.js.gz +0 -0
  167. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-AvSI5iFI.js → sankeyDiagram-P5KCCOFB-BF-YvoEZ.js} +1 -1
  168. package/dist/client/assets/sankeyDiagram-P5KCCOFB-BF-YvoEZ.js.br +0 -0
  169. package/dist/client/assets/sankeyDiagram-P5KCCOFB-BF-YvoEZ.js.gz +0 -0
  170. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-DPXyiIKd.js → sequenceDiagram-WJ2MYXX4-CMkePZOj.js} +1 -1
  171. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CMkePZOj.js.br +0 -0
  172. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CMkePZOj.js.gz +0 -0
  173. package/dist/client/assets/{sizeCapture-INFHLROL-CER_XOvb.js → sizeCapture-INFHLROL-C9N9vqvo.js} +1 -1
  174. package/dist/client/assets/sizeCapture-INFHLROL-C9N9vqvo.js.br +0 -0
  175. package/dist/client/assets/sizeCapture-INFHLROL-C9N9vqvo.js.gz +0 -0
  176. package/dist/client/assets/{sparkles-CgwSF-UK.js → sparkles-DQ-Y24Kv.js} +1 -1
  177. package/dist/client/assets/{stateDiagram-D77RDMKH-BdWVez-f.js → stateDiagram-D77RDMKH-DFk62G9u.js} +1 -1
  178. package/dist/client/assets/stateDiagram-D77RDMKH-DFk62G9u.js.br +0 -0
  179. package/dist/client/assets/stateDiagram-D77RDMKH-DFk62G9u.js.gz +0 -0
  180. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-Bnyl10vy.js +1 -0
  181. package/dist/client/assets/{swimlanes-42K2YHIH-BJyO3_8y.js → swimlanes-42K2YHIH-CNpYAR3d.js} +1 -1
  182. package/dist/client/assets/swimlanes-42K2YHIH-CNpYAR3d.js.br +0 -0
  183. package/dist/client/assets/{swimlanes-42K2YHIH-BJyO3_8y.js.gz → swimlanes-42K2YHIH-CNpYAR3d.js.gz} +0 -0
  184. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-BwjcVbFS.js +8 -0
  185. package/dist/client/assets/{timeline-definition-24CTP7MA-ocqFrNBu.js → timeline-definition-24CTP7MA-BVEhKc3h.js} +1 -1
  186. package/dist/client/assets/timeline-definition-24CTP7MA-BVEhKc3h.js.br +0 -0
  187. package/dist/client/assets/timeline-definition-24CTP7MA-BVEhKc3h.js.gz +0 -0
  188. package/dist/client/assets/{triangle-alert-CNoodlX6.js → triangle-alert-BIwj1bIH.js} +1 -1
  189. package/dist/client/assets/{vennDiagram-4TSXK5OY-DOaftoeV.js → vennDiagram-4TSXK5OY-DqKMbCx0.js} +1 -1
  190. package/dist/client/assets/vennDiagram-4TSXK5OY-DqKMbCx0.js.br +0 -0
  191. package/dist/client/assets/vennDiagram-4TSXK5OY-DqKMbCx0.js.gz +0 -0
  192. package/dist/client/assets/{videoCompression-Cu21usMU.js → videoCompression-DhppheEu.js} +1 -1
  193. package/dist/client/assets/videoCompression-DhppheEu.js.br +0 -0
  194. package/dist/client/assets/videoCompression-DhppheEu.js.gz +0 -0
  195. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-D__Jujiv.js → wardleyDiagram-VM6X3IG4-Bnhg0vB7.js} +1 -1
  196. package/dist/client/assets/wardleyDiagram-VM6X3IG4-Bnhg0vB7.js.br +0 -0
  197. package/dist/client/assets/wardleyDiagram-VM6X3IG4-Bnhg0vB7.js.gz +0 -0
  198. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DU86_bqa.js → xychartDiagram-S5SC5T6Z-BBRqvRXj.js} +1 -1
  199. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BBRqvRXj.js.br +0 -0
  200. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BBRqvRXj.js.gz +0 -0
  201. package/dist/client/index.html +1 -1
  202. package/dist/client/index.html.br +0 -0
  203. package/dist/client/index.html.gz +0 -0
  204. package/dist/client/sw.js +1 -1
  205. package/dist/client/sw.js.br +0 -0
  206. package/dist/client/sw.js.gz +0 -0
  207. package/dist/server/android/adb.js +6 -0
  208. package/dist/server/android/liveBitrate.js +40 -4
  209. package/dist/server/android/scrcpy.js +71 -19
  210. package/dist/server/android/scrcpyForward.js +83 -0
  211. package/dist/server/routes/android.js +5 -2
  212. package/package.json +1 -1
  213. package/runtime-manifest.json +3 -3
  214. package/scripts/android-bitrate/CaptureReset.java +29 -15
  215. package/scripts/android-bitrate/README.md +26 -5
  216. package/scripts/android-bitrate/bitrate.jar +0 -0
  217. package/dist/client/assets/App-CA8oXFgS.js.br +0 -0
  218. package/dist/client/assets/App-CA8oXFgS.js.gz +0 -0
  219. package/dist/client/assets/ArchitecturePanel-BkB57agj.js.br +0 -0
  220. package/dist/client/assets/ArchitecturePanel-BkB57agj.js.gz +0 -0
  221. package/dist/client/assets/ChangeWalkthroughPanel-vh6Z641M.js.br +0 -0
  222. package/dist/client/assets/ChangeWalkthroughPanel-vh6Z641M.js.gz +0 -0
  223. package/dist/client/assets/CollaborationMainWorkspace-dTXq04jE.js.br +0 -0
  224. package/dist/client/assets/CollaborationMainWorkspace-dTXq04jE.js.gz +0 -0
  225. package/dist/client/assets/CollaborationTaskContent-vtFFtPjY.js +0 -2
  226. package/dist/client/assets/ComputerControlView-Cmar8PMd.js.br +0 -0
  227. package/dist/client/assets/ComputerControlView-Cmar8PMd.js.gz +0 -0
  228. package/dist/client/assets/DagPlayground-C-JZfG9-.js.br +0 -0
  229. package/dist/client/assets/DagPlayground-C-JZfG9-.js.gz +0 -0
  230. package/dist/client/assets/DiffLab-rOEPk8iI.js.br +0 -0
  231. package/dist/client/assets/DiffLab-rOEPk8iI.js.gz +0 -0
  232. package/dist/client/assets/DiffReview-aIj4WHDS.js.br +0 -0
  233. package/dist/client/assets/DiffReview-aIj4WHDS.js.gz +0 -0
  234. package/dist/client/assets/DiffReviewLab-CU4vENL5.js.br +0 -0
  235. package/dist/client/assets/DiffReviewLab-CU4vENL5.js.gz +0 -0
  236. package/dist/client/assets/DiffViewer-SKlbS7b4.js.br +0 -0
  237. package/dist/client/assets/DiffViewer-SKlbS7b4.js.gz +0 -0
  238. package/dist/client/assets/ModelPreview-mGhBeBla.js.br +0 -0
  239. package/dist/client/assets/ModelPreview-mGhBeBla.js.gz +0 -0
  240. package/dist/client/assets/RightSidebar-BtHbt-XD.js.br +0 -0
  241. package/dist/client/assets/RightSidebar-BtHbt-XD.js.gz +0 -0
  242. package/dist/client/assets/abnfDiagram-VCTEODGH-BazK9AUo.js.br +0 -0
  243. package/dist/client/assets/abnfDiagram-VCTEODGH-BazK9AUo.js.gz +0 -0
  244. package/dist/client/assets/app-1SAb4dhI.js.br +0 -0
  245. package/dist/client/assets/app-1SAb4dhI.js.gz +0 -0
  246. package/dist/client/assets/arc-DW2qA73J.js.br +0 -0
  247. package/dist/client/assets/arc-DW2qA73J.js.gz +0 -0
  248. package/dist/client/assets/architectureDiagram-5GKGNRK7-CVkFu36h.js.br +0 -0
  249. package/dist/client/assets/architectureDiagram-5GKGNRK7-CVkFu36h.js.gz +0 -0
  250. package/dist/client/assets/blockDiagram-I7D4REHJ-Cw0LbdUV.js.br +0 -0
  251. package/dist/client/assets/blockDiagram-I7D4REHJ-Cw0LbdUV.js.gz +0 -0
  252. package/dist/client/assets/c4Diagram-7LVT6UL2-D-7cVLVY.js.br +0 -0
  253. package/dist/client/assets/c4Diagram-7LVT6UL2-D-7cVLVY.js.gz +0 -0
  254. package/dist/client/assets/channel-B0ZO96Vf.js +0 -1
  255. package/dist/client/assets/chunk-F27PBJKO-BPQlePZ0.js.br +0 -0
  256. package/dist/client/assets/chunk-F27PBJKO-BPQlePZ0.js.gz +0 -0
  257. package/dist/client/assets/chunk-IMKFNOWR-CYpkOg4N.js.br +0 -0
  258. package/dist/client/assets/chunk-IMKFNOWR-CYpkOg4N.js.gz +0 -0
  259. package/dist/client/assets/chunk-SVP7TREG-TridS3zl.js.br +0 -0
  260. package/dist/client/assets/chunk-SVP7TREG-TridS3zl.js.gz +0 -0
  261. package/dist/client/assets/chunk-TICWLB2K-CrSU9J1Y.js.br +0 -0
  262. package/dist/client/assets/chunk-TICWLB2K-CrSU9J1Y.js.gz +0 -0
  263. package/dist/client/assets/classDiagram-ZZMXUADV-DNgoON1D.js +0 -1
  264. package/dist/client/assets/classDiagram-v2-VYDZK3BY-DNgoON1D.js +0 -1
  265. package/dist/client/assets/cose-bilkent-JH36ORCC-BPspdiZq.js.br +0 -0
  266. package/dist/client/assets/cose-bilkent-JH36ORCC-BPspdiZq.js.gz +0 -0
  267. package/dist/client/assets/cynefin-OW5HDTMX-CdZ2Ij-1.js.br +0 -0
  268. package/dist/client/assets/cynefin-OW5HDTMX-CdZ2Ij-1.js.gz +0 -0
  269. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CS4dSANt.js.br +0 -0
  270. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CS4dSANt.js.gz +0 -0
  271. package/dist/client/assets/dagre-GXQ25YYZ-jz406NVd.js.br +0 -0
  272. package/dist/client/assets/dagre-GXQ25YYZ-jz406NVd.js.gz +0 -0
  273. package/dist/client/assets/diagram-S7CK7UJ4-BXz7D6hW.js.br +0 -0
  274. package/dist/client/assets/diagram-S7CK7UJ4-BXz7D6hW.js.gz +0 -0
  275. package/dist/client/assets/diagram-UQ7AKVKN-BtSwQGmR.js.br +0 -0
  276. package/dist/client/assets/diagram-UQ7AKVKN-BtSwQGmR.js.gz +0 -0
  277. package/dist/client/assets/diagram-VSXAHHWV-B2lDfe93.js.br +0 -0
  278. package/dist/client/assets/diagram-VSXAHHWV-B2lDfe93.js.gz +0 -0
  279. package/dist/client/assets/diagram-VX7I27RA-QDrY0hNk.js.br +0 -0
  280. package/dist/client/assets/diagram-VX7I27RA-QDrY0hNk.js.gz +0 -0
  281. package/dist/client/assets/diagram-Z3DM3KII-D1AFu390.js.br +0 -0
  282. package/dist/client/assets/diagram-Z3DM3KII-D1AFu390.js.gz +0 -0
  283. package/dist/client/assets/ebnfDiagram-PWID7BFC-L5aoZUCG.js.br +0 -0
  284. package/dist/client/assets/ebnfDiagram-PWID7BFC-L5aoZUCG.js.gz +0 -0
  285. package/dist/client/assets/erDiagram-RLTQ6QDP-CFUfoWVL.js.br +0 -0
  286. package/dist/client/assets/erDiagram-RLTQ6QDP-CFUfoWVL.js.gz +0 -0
  287. package/dist/client/assets/flowDiagram-HODETNUW-A-hvg2q9.js.br +0 -0
  288. package/dist/client/assets/flowDiagram-HODETNUW-A-hvg2q9.js.gz +0 -0
  289. package/dist/client/assets/ganttDiagram-EL5Y4UJY-DSMsjMS7.js.br +0 -0
  290. package/dist/client/assets/ganttDiagram-EL5Y4UJY-DSMsjMS7.js.gz +0 -0
  291. package/dist/client/assets/gestureArbiter-BvkspAa2.js.br +0 -0
  292. package/dist/client/assets/gestureArbiter-BvkspAa2.js.gz +0 -0
  293. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BhpWzivx.js.br +0 -0
  294. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BhpWzivx.js.gz +0 -0
  295. package/dist/client/assets/ishikawaDiagram-5VMMS53U-zp9iSkhD.js.br +0 -0
  296. package/dist/client/assets/ishikawaDiagram-5VMMS53U-zp9iSkhD.js.gz +0 -0
  297. package/dist/client/assets/journeyDiagram-3NMN7TZE-CWIWv2zw.js.br +0 -0
  298. package/dist/client/assets/journeyDiagram-3NMN7TZE-CWIWv2zw.js.gz +0 -0
  299. package/dist/client/assets/kanban-definition-UXKFOSKX-JzGKFo57.js.br +0 -0
  300. package/dist/client/assets/kanban-definition-UXKFOSKX-JzGKFo57.js.gz +0 -0
  301. package/dist/client/assets/layout-7Cq6z6dO.js.br +0 -0
  302. package/dist/client/assets/layout-7Cq6z6dO.js.gz +0 -0
  303. package/dist/client/assets/linear-CuFZW946.js.br +0 -0
  304. package/dist/client/assets/linear-CuFZW946.js.gz +0 -0
  305. package/dist/client/assets/mermaid.core-DbR5q1bj.js.br +0 -0
  306. package/dist/client/assets/mermaid.core-DbR5q1bj.js.gz +0 -0
  307. package/dist/client/assets/mindmap-definition-YA3MSWOX-DdzejTGB.js.br +0 -0
  308. package/dist/client/assets/mindmap-definition-YA3MSWOX-DdzejTGB.js.gz +0 -0
  309. package/dist/client/assets/passwordBootstrap-lisz9s1P.js.br +0 -0
  310. package/dist/client/assets/passwordBootstrap-lisz9s1P.js.gz +0 -0
  311. package/dist/client/assets/pegDiagram-XKGWAZYB-D720_LqX.js.br +0 -0
  312. package/dist/client/assets/pegDiagram-XKGWAZYB-D720_LqX.js.gz +0 -0
  313. package/dist/client/assets/pieDiagram-E7YTZNPT-zEDQIxrq.js.br +0 -0
  314. package/dist/client/assets/pieDiagram-E7YTZNPT-zEDQIxrq.js.gz +0 -0
  315. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Cp0CVTM2.js.br +0 -0
  316. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Cp0CVTM2.js.gz +0 -0
  317. package/dist/client/assets/railroadDiagram-O6MQD6OU-DmEhvOdy.js.br +0 -0
  318. package/dist/client/assets/railroadDiagram-O6MQD6OU-DmEhvOdy.js.gz +0 -0
  319. package/dist/client/assets/rdpSession-DQon3e98.js.br +0 -0
  320. package/dist/client/assets/rdpSession-DQon3e98.js.gz +0 -0
  321. package/dist/client/assets/referenceLongPress-DTjCnJH8.js.br +0 -0
  322. package/dist/client/assets/referenceLongPress-DTjCnJH8.js.gz +0 -0
  323. package/dist/client/assets/requirementDiagram-BXWQKSXE-BnMPYUjE.js.br +0 -0
  324. package/dist/client/assets/requirementDiagram-BXWQKSXE-BnMPYUjE.js.gz +0 -0
  325. package/dist/client/assets/sankeyDiagram-P5KCCOFB-AvSI5iFI.js.br +0 -0
  326. package/dist/client/assets/sankeyDiagram-P5KCCOFB-AvSI5iFI.js.gz +0 -0
  327. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-DPXyiIKd.js.br +0 -0
  328. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-DPXyiIKd.js.gz +0 -0
  329. package/dist/client/assets/sizeCapture-INFHLROL-CER_XOvb.js.br +0 -0
  330. package/dist/client/assets/sizeCapture-INFHLROL-CER_XOvb.js.gz +0 -0
  331. package/dist/client/assets/stateDiagram-D77RDMKH-BdWVez-f.js.br +0 -0
  332. package/dist/client/assets/stateDiagram-D77RDMKH-BdWVez-f.js.gz +0 -0
  333. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-Bm_Va34_.js +0 -1
  334. package/dist/client/assets/swimlanes-42K2YHIH-BJyO3_8y.js.br +0 -0
  335. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-C2fV7GHc.js +0 -8
  336. package/dist/client/assets/timeline-definition-24CTP7MA-ocqFrNBu.js.br +0 -0
  337. package/dist/client/assets/timeline-definition-24CTP7MA-ocqFrNBu.js.gz +0 -0
  338. package/dist/client/assets/vennDiagram-4TSXK5OY-DOaftoeV.js.br +0 -0
  339. package/dist/client/assets/vennDiagram-4TSXK5OY-DOaftoeV.js.gz +0 -0
  340. package/dist/client/assets/videoCompression-Cu21usMU.js.br +0 -0
  341. package/dist/client/assets/videoCompression-Cu21usMU.js.gz +0 -0
  342. package/dist/client/assets/wardleyDiagram-VM6X3IG4-D__Jujiv.js.br +0 -0
  343. package/dist/client/assets/wardleyDiagram-VM6X3IG4-D__Jujiv.js.gz +0 -0
  344. package/dist/client/assets/xychartDiagram-S5SC5T6Z-DU86_bqa.js.br +0 -0
  345. package/dist/client/assets/xychartDiagram-S5SC5T6Z-DU86_bqa.js.gz +0 -0
@@ -4,6 +4,7 @@ import net from 'node:net';
4
4
  import { delimiter, dirname, join } from 'node:path';
5
5
  import { randomInt } from 'node:crypto';
6
6
  import { adbSearchPath, resolveAdbBinary } from './adb.js';
7
+ import { connectScrcpyForward } from './scrcpyForward.js';
7
8
  import { LiveBitrateChannel, inspectLiveBitrate, resolveBundledPreviewServer, bitrateOverlayPath, bitrateOverlayRemote } from './liveBitrate.js';
8
9
  const DEVICE_NAME_LENGTH = 64;
9
10
  const VIDEO_HEADER_LENGTH = 12;
@@ -126,11 +127,16 @@ function runAdbCapture(args, timeout = 30_000) {
126
127
  function scidHex(scid) {
127
128
  return scid.toString(16).padStart(8, '0');
128
129
  }
129
- /** 单设备的一条 scrcpy 会话:推送 server → adb reverse → 启动 server → 解析 H.264/H.265 流。 */
130
+ /** 单设备的一条 scrcpy 会话:推送 server → ADB 隧道 → 启动 server → 解析视频流。 */
130
131
  export class ScrcpySession {
131
132
  serial;
132
133
  events;
133
134
  options;
135
+ // Network ADB can acknowledge reverse rules without carrying their data.
136
+ tunnelForward;
137
+ forwardPort = 0;
138
+ bitrateForwardPort = 0;
139
+ connectionAbort = new AbortController();
134
140
  scid = randomInt(1, 0x7fffffff);
135
141
  bitrateChannel = null;
136
142
  child = null;
@@ -148,11 +154,13 @@ export class ScrcpySession {
148
154
  started = false;
149
155
  deviceName = '';
150
156
  resolveHeader = null;
157
+ rejectHeader = null;
151
158
  logLines = [];
152
159
  constructor(serial, events, options = {}) {
153
160
  this.serial = serial;
154
161
  this.events = events;
155
162
  this.options = options;
163
+ this.tunnelForward = /[:.]/.test(serial);
156
164
  }
157
165
  get running() { return this.started && !this.stopped; }
158
166
  log(line) {
@@ -166,6 +174,7 @@ export class ScrcpySession {
166
174
  fail(error) {
167
175
  if (this.stopped)
168
176
  return;
177
+ this.rejectHeader?.(error);
169
178
  this.events.onError(error);
170
179
  void this.stop();
171
180
  }
@@ -178,14 +187,23 @@ export class ScrcpySession {
178
187
  this.protocol = Number.parseInt(version.split('.')[0] ?? '0', 10) >= 4 ? 'session' : 'legacy';
179
188
  const remoteJar = remoteJarPath(version);
180
189
  await runAdbCapture(['-s', this.serial, 'push', serverJar, remoteJar], 60_000);
181
- const server = net.createServer();
182
- this.server = server;
183
- server.on('connection', socket => this.acceptSocket(socket));
184
- await new Promise((resolve, reject) => {
185
- server.once('error', reject);
186
- server.listen(0, '127.0.0.1', () => { this.port = server.address().port; resolve(); });
187
- });
188
- await runAdbCapture(['-s', this.serial, 'reverse', `localabstract:scrcpy_${scidHex(this.scid)}`, `tcp:${this.port}`], 15_000);
190
+ if (this.tunnelForward) {
191
+ const assigned = await runAdbCapture(['-s', this.serial, 'forward', 'tcp:0', `localabstract:scrcpy_${scidHex(this.scid)}`], 15_000);
192
+ const port = Number(assigned);
193
+ if (!Number.isInteger(port) || port < 1 || port > 65535)
194
+ throw new Error('SCRCPY_FORWARD_INVALID_PORT');
195
+ this.forwardPort = port;
196
+ }
197
+ else {
198
+ const server = net.createServer();
199
+ this.server = server;
200
+ server.on('connection', socket => this.acceptSocket(socket));
201
+ await new Promise((resolve, reject) => {
202
+ server.once('error', reject);
203
+ server.listen(0, '127.0.0.1', () => { this.port = server.address().port; resolve(); });
204
+ });
205
+ await runAdbCapture(['-s', this.serial, 'reverse', `localabstract:scrcpy_${scidHex(this.scid)}`, `tcp:${this.port}`], 15_000);
206
+ }
189
207
  let liveBitrate = false;
190
208
  let bitrateFailure = await inspectLiveBitrate(serverJar, version);
191
209
  let bitrateStage = 'BITRATE_LISTEN_FAILED';
@@ -200,11 +218,19 @@ export class ScrcpySession {
200
218
  if (!bitrateFailure) {
201
219
  try {
202
220
  this.bitrateChannel = new LiveBitrateChannel(reportBitrate);
203
- const port = await this.bitrateChannel.listen();
221
+ const port = this.tunnelForward ? 0 : await this.bitrateChannel.listen();
204
222
  bitrateStage = 'BITRATE_PUSH_FAILED';
205
223
  await runAdbCapture(['-s', this.serial, 'push', bitrateOverlayPath, bitrateOverlayRemote]);
206
224
  bitrateStage = 'BITRATE_TUNNEL_FAILED';
207
- await runAdbCapture(['-s', this.serial, 'reverse', `localabstract:termdock_bitrate_${scidHex(this.scid)}`, `tcp:${port}`]);
225
+ if (this.tunnelForward) {
226
+ const assigned = Number(await runAdbCapture(['-s', this.serial, 'forward', 'tcp:0', `localabstract:termdock_bitrate_${scidHex(this.scid)}`]));
227
+ if (!Number.isInteger(assigned) || assigned < 1 || assigned > 65535)
228
+ throw new Error('BITRATE_FORWARD_INVALID_PORT');
229
+ this.bitrateForwardPort = assigned;
230
+ }
231
+ else {
232
+ await runAdbCapture(['-s', this.serial, 'reverse', `localabstract:termdock_bitrate_${scidHex(this.scid)}`, `tcp:${port}`]);
233
+ }
208
234
  liveBitrate = true;
209
235
  }
210
236
  catch (error) {
@@ -218,19 +244,20 @@ export class ScrcpySession {
218
244
  if (this.stopped) {
219
245
  this.bitrateChannel?.close();
220
246
  this.server?.close();
247
+ await this.removeForward();
221
248
  await Promise.allSettled(['scrcpy_', 'termdock_bitrate_'].map(prefix => runAdbCapture(['-s', this.serial, 'reverse', '--remove', `localabstract:${prefix}${scidHex(this.scid)}`], 8000)));
222
249
  return;
223
250
  }
224
251
  const args = [
225
252
  '-s', this.serial, 'shell',
226
253
  `CLASSPATH=${liveBitrate ? bitrateOverlayRemote + ":" : ""}${remoteJar}`,
227
- 'app_process', ...(liveBitrate ? [`-Dtermdock.bitrate=termdock_bitrate_${scidHex(this.scid)}`] : []), '/',
254
+ 'app_process', ...(liveBitrate ? [`-Dtermdock.bitrate=termdock_bitrate_${scidHex(this.scid)}`, ...(this.tunnelForward ? ['-Dtermdock.bitrateForward=true'] : [])] : []), '/',
228
255
  'com.genymobile.scrcpy.Server', version,
229
256
  `scid=${this.scid.toString(16)}`,
230
257
  'log_level=info',
231
258
  'audio=false',
232
259
  'control=true',
233
- 'tunnel_forward=false',
260
+ `tunnel_forward=${this.tunnelForward}`,
234
261
  'power_on=true',
235
262
  'stay_awake=true',
236
263
  'clipboard_autosync=false',
@@ -239,14 +266,23 @@ export class ScrcpySession {
239
266
  ];
240
267
  if (this.options.maxFps && this.options.maxFps > 0)
241
268
  args.push(`max_fps=${this.options.maxFps}`);
269
+ const headerReady = this.waitForHeader();
270
+ // Handle early process exit even while forward is establishing its sockets.
271
+ void headerReady.catch(() => { });
242
272
  const child = spawn(adbBinary(), args, { stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, PATH: adbSearchPath() } });
243
273
  this.child = child;
274
+ if (liveBitrate && this.tunnelForward)
275
+ this.bitrateChannel?.connectForward(this.bitrateForwardPort);
244
276
  child.stdout?.on('data', chunk => this.log(String(chunk).replace(/^\[server\]\s*/, '')));
245
277
  child.stderr?.on('data', chunk => this.log(String(chunk)));
246
278
  child.on('error', error => this.fail(error instanceof Error ? error : new Error('SCRCPY_SPAWN_FAILED')));
247
- child.on('close', () => { if (!this.stopped)
248
- this.fail(new Error(this.logLines.at(-1) || 'SCRCPY_SERVER_EXITED')); });
249
- await this.waitForHeader();
279
+ child.on('close', (code, signal) => {
280
+ if (!this.stopped)
281
+ this.fail(new Error(`SCRCPY_SERVER_EXITED: code=${code ?? 'null'} signal=${signal ?? 'none'}; tunnel=${this.tunnelForward ? 'forward' : 'reverse'}; video=${this.videoSocket ? 'connected' : 'not_connected'}\n${this.logLines.slice(-8).join('\n')}`));
282
+ });
283
+ await Promise.all([headerReady, this.tunnelForward
284
+ ? connectScrcpyForward(this.forwardPort, this.connectionAbort.signal, socket => this.acceptSocket(socket))
285
+ : Promise.resolve()]);
250
286
  }
251
287
  catch (error) {
252
288
  const normalized = error instanceof Error ? error : new Error('SCRCPY_START_FAILED');
@@ -257,8 +293,10 @@ export class ScrcpySession {
257
293
  }
258
294
  waitForHeader() {
259
295
  return new Promise((resolve, reject) => {
260
- const timer = setTimeout(() => { this.resolveHeader = null; reject(new Error('SCRCPY_CONNECT_TIMEOUT')); }, CONNECT_TIMEOUT_MS);
261
- this.resolveHeader = () => { clearTimeout(timer); this.resolveHeader = null; resolve(); };
296
+ const clear = () => { clearTimeout(timer); this.resolveHeader = null; this.rejectHeader = null; };
297
+ const timer = setTimeout(() => { clear(); reject(new Error('SCRCPY_CONNECT_TIMEOUT')); }, CONNECT_TIMEOUT_MS);
298
+ this.resolveHeader = () => { clear(); resolve(); };
299
+ this.rejectHeader = error => { clear(); reject(error); };
262
300
  });
263
301
  }
264
302
  acceptSocket(socket) {
@@ -268,7 +306,7 @@ export class ScrcpySession {
268
306
  socket.on('data', chunk => this.readVideo(chunk));
269
307
  socket.on('error', error => this.fail(error instanceof Error ? error : new Error('VIDEO_SOCKET_ERROR')));
270
308
  socket.on('close', () => { if (!this.stopped)
271
- this.fail(new Error(this.logLines.at(-1) || 'VIDEO_SOCKET_CLOSED')); });
309
+ this.fail(new Error(`VIDEO_SOCKET_CLOSED: tunnel=${this.tunnelForward ? 'forward' : 'reverse'}\n${this.logLines.slice(-8).join('\n')}`)); });
272
310
  return;
273
311
  }
274
312
  if (!this.controlSocket) {
@@ -416,10 +454,23 @@ export class ScrcpySession {
416
454
  setBitrate(value) {
417
455
  return this.bitrateChannel?.setBitrate(value) ?? Promise.resolve(false);
418
456
  }
457
+ async removeForward() {
458
+ const ports = [this.forwardPort, this.bitrateForwardPort].filter(port => port > 0);
459
+ this.forwardPort = 0;
460
+ this.bitrateForwardPort = 0;
461
+ for (const port of ports) {
462
+ try {
463
+ await runAdbCapture(['-s', this.serial, 'forward', '--remove', `tcp:${port}`], 8000);
464
+ }
465
+ catch { /* The device or ADB may already have removed this exact rule. */ }
466
+ }
467
+ }
419
468
  async stop() {
420
469
  if (this.stopped)
421
470
  return;
422
471
  this.stopped = true;
472
+ this.connectionAbort.abort();
473
+ this.rejectHeader?.(new Error('SCRCPY_SESSION_STOPPED'));
423
474
  activeSessions.delete(this);
424
475
  this.bitrateChannel?.close();
425
476
  const child = this.child;
@@ -445,6 +496,7 @@ export class ScrcpySession {
445
496
  }
446
497
  catch { /* ignore */ }
447
498
  }
499
+ await this.removeForward();
448
500
  try {
449
501
  await runAdbCapture(['-s', this.serial, 'reverse', '--remove', `localabstract:scrcpy_${scidHex(this.scid)}`], 8000);
450
502
  }
@@ -0,0 +1,83 @@
1
+ import net from 'node:net';
2
+ /** Wait for scrcpy's dummy byte: an ADB forward TCP accept alone does not
3
+ * prove the device-side localabstract listener has started yet. */
4
+ export async function connectScrcpyForward(port, signal, accept, timeoutMs = 12_000) {
5
+ const deadline = Date.now() + timeoutMs;
6
+ const open = (dummy) => new Promise((resolve, reject) => {
7
+ if (signal.aborted) {
8
+ reject(new Error('SCRCPY_SESSION_STOPPED'));
9
+ return;
10
+ }
11
+ const socket = net.connect({ host: '127.0.0.1', port });
12
+ const timer = setTimeout(() => fail(new Error('SCRCPY_FORWARD_CONNECT_TIMEOUT')), Math.min(500, Math.max(1, deadline - Date.now())));
13
+ const cleanup = () => {
14
+ clearTimeout(timer);
15
+ signal.removeEventListener('abort', abort);
16
+ socket.removeListener('error', fail);
17
+ socket.removeListener('close', closed);
18
+ socket.removeListener('data', data);
19
+ socket.removeListener('connect', connected);
20
+ };
21
+ const fail = (error) => { cleanup(); socket.destroy(); reject(error); };
22
+ const closed = () => fail(new Error('SCRCPY_FORWARD_CONNECTION_CLOSED'));
23
+ const abort = () => fail(new Error('SCRCPY_SESSION_STOPPED'));
24
+ const ready = () => { socket.pause(); cleanup(); resolve(socket); };
25
+ const connected = () => { if (!dummy)
26
+ ready(); };
27
+ const data = (chunk) => {
28
+ if (!chunk.length)
29
+ return;
30
+ if (chunk[0] !== 0) {
31
+ fail(new Error('SCRCPY_FORWARD_HANDSHAKE_INVALID'));
32
+ return;
33
+ }
34
+ socket.pause();
35
+ if (chunk.length > 1)
36
+ socket.unshift(chunk.subarray(1));
37
+ ready();
38
+ };
39
+ signal.addEventListener('abort', abort, { once: true });
40
+ socket.on('error', fail);
41
+ socket.on('close', closed);
42
+ socket.on('connect', connected);
43
+ if (dummy)
44
+ socket.on('data', data);
45
+ });
46
+ let video;
47
+ let control;
48
+ try {
49
+ while (!signal.aborted && Date.now() < deadline) {
50
+ try {
51
+ video = await open(true);
52
+ break;
53
+ }
54
+ catch (error) {
55
+ if (signal.aborted || Date.now() >= deadline)
56
+ throw error;
57
+ await new Promise(resolve => {
58
+ const done = () => { clearTimeout(timer); signal.removeEventListener('abort', done); resolve(); };
59
+ const timer = setTimeout(done, 100);
60
+ signal.addEventListener('abort', done, { once: true });
61
+ if (signal.aborted)
62
+ done();
63
+ });
64
+ }
65
+ }
66
+ if (!video || signal.aborted)
67
+ throw new Error(signal.aborted ? 'SCRCPY_SESSION_STOPPED' : 'SCRCPY_FORWARD_CONNECT_TIMEOUT');
68
+ // Install video error/close listeners before waiting for control.
69
+ accept(video);
70
+ control = await open(false);
71
+ if (signal.aborted)
72
+ throw new Error('SCRCPY_SESSION_STOPPED');
73
+ // Keep video paused until both sockets have listeners and definite roles.
74
+ accept(control);
75
+ video.resume();
76
+ control.resume();
77
+ }
78
+ catch (error) {
79
+ video?.destroy();
80
+ control?.destroy();
81
+ throw error;
82
+ }
83
+ }
@@ -162,14 +162,17 @@ export function handleAndroidWebSocket(socket, serial, _clientId, requested = {}
162
162
  const shutdown = (reason) => {
163
163
  if (closed)
164
164
  return;
165
+ // send() rejects closed sessions: deliver the cause before marking it closed.
166
+ if (reason) {
167
+ console.warn(`[android] session failed serial=${serial}: ${reason}`);
168
+ send({ type: 'error', message: reason });
169
+ }
165
170
  closed = true;
166
171
  clearInterval(flowTimer);
167
172
  if (statsTimer)
168
173
  clearInterval(statsTimer);
169
174
  if (DEBUG_ANDROID)
170
175
  console.log(`[android] session end serial=${serial} sent=${sent} acked=${acked} reason=${reason ?? 'ok'}`);
171
- if (reason)
172
- send({ type: 'error', message: reason });
173
176
  try {
174
177
  session?.stop();
175
178
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termdock",
3
- "version": "1.4.334",
3
+ "version": "1.4.336",
4
4
  "description": "A complete web-based terminal application with modern UI",
5
5
  "type": "module",
6
6
  "main": ".desktop-dist/main.js",
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "packageName": "termdock",
4
- "version": "1.4.334",
4
+ "version": "1.4.336",
5
5
  "runtimeProtocolVersion": 1,
6
6
  "minimumDesktopVersion": "1.4.46",
7
7
  "nodeMajor": 22,
8
8
  "dependencyHash": "sha256-oaGYi/P5ob8sd6VnNBOwshKozjhdV+hYiCmLAsn5x00=",
9
- "serverBundleHash": "sha256-3no4R3NbStrmDJJLVupnUBWo7XLepTMTQ6C+w+LDL6g=",
10
- "clientBundleHash": "sha256-dL4ujXOdndvbe5YUkFAdO8Bl2of7dR2Ky2XxTxsQb0U=",
9
+ "serverBundleHash": "sha256-KvJEGINN1M45Zs/oNpJTb+vlpFCr0C8rKqS2Flp7+tI=",
10
+ "clientBundleHash": "sha256-5AO8soGCDDxFlZjr8zTeNxVLFL4bw+MXYLTu2kdyLs0=",
11
11
  "entrypoint": "dist/server/cli.js",
12
12
  "clientEntrypoint": "dist/client/index.html"
13
13
  }
@@ -5,6 +5,7 @@ package com.genymobile.scrcpy.video;
5
5
 
6
6
  import android.media.MediaCodec;
7
7
  import android.net.LocalSocket;
8
+ import android.net.LocalServerSocket;
8
9
  import android.net.LocalSocketAddress;
9
10
  import android.os.Bundle;
10
11
  import java.io.DataInputStream;
@@ -59,28 +60,41 @@ public class CaptureReset implements SurfaceCapture.CaptureListener {
59
60
  }
60
61
 
61
62
  private void serve(String name) {
62
- try (LocalSocket socket = new LocalSocket()) {
63
- socket.connect(new LocalSocketAddress(name));
64
- DataInputStream input = new DataInputStream(socket.getInputStream());
65
- DataOutputStream output = new DataOutputStream(socket.getOutputStream());
66
- output.writeInt(0x54444232); // TDB2: rejection includes length-prefixed UTF-8 diagnostic
67
- output.flush();
68
- while (true) {
69
- int requested = input.readInt();
70
- String failure = applyBitrate(requested);
71
- output.writeInt(failure == null ? requested : 0);
72
- if (failure != null) {
73
- byte[] detail = failure.substring(0, Math.min(512, failure.length())).getBytes(StandardCharsets.UTF_8);
74
- output.writeInt(detail.length);
75
- output.write(detail);
63
+ try {
64
+ if (Boolean.getBoolean("termdock.bitrateForward")) {
65
+ try (LocalServerSocket server = new LocalServerSocket(name);
66
+ LocalSocket socket = server.accept()) {
67
+ exchange(socket);
68
+ }
69
+ } else {
70
+ try (LocalSocket socket = new LocalSocket()) {
71
+ socket.connect(new LocalSocketAddress(name));
72
+ exchange(socket);
76
73
  }
77
- output.flush();
78
74
  }
79
75
  } catch (IOException ignored) {
80
76
  // A bitrate-channel failure must never tear down video/control.
81
77
  }
82
78
  }
83
79
 
80
+ private void exchange(LocalSocket socket) throws IOException {
81
+ DataInputStream input = new DataInputStream(socket.getInputStream());
82
+ DataOutputStream output = new DataOutputStream(socket.getOutputStream());
83
+ output.writeInt(0x54444232); // TDB2: rejection includes length-prefixed UTF-8 diagnostic
84
+ output.flush();
85
+ while (true) {
86
+ int requested = input.readInt();
87
+ String failure = applyBitrate(requested);
88
+ output.writeInt(failure == null ? requested : 0);
89
+ if (failure != null) {
90
+ byte[] detail = failure.substring(0, Math.min(512, failure.length())).getBytes(StandardCharsets.UTF_8);
91
+ output.writeInt(detail.length);
92
+ output.write(detail);
93
+ }
94
+ output.flush();
95
+ }
96
+ }
97
+
84
98
  @Override
85
99
  public void onInvalidated() { reset(); }
86
100
  }
@@ -1,10 +1,10 @@
1
1
  # scrcpy live bitrate extension
2
2
 
3
- Termdock loads this 3 KB Android DEX overlay before the bundled, verified scrcpy 3.3.4 server
3
+ Termdock loads this small Android DEX overlay before the bundled, verified scrcpy 3.3.4 server
4
4
  for preview sessions only. The host scrcpy version no longer gates automatic quality. Recording uses the unmodified scrcpy executable/server.
5
5
 
6
6
  CaptureReset.java preserves scrcpy 3.3.4's existing ABI and reset behavior,
7
- adding a session-scoped ADB reverse socket. The running hardware encoder receives
7
+ adding a session-scoped ADB socket. The running hardware encoder receives
8
8
  MediaCodec.PARAMETER_KEY_VIDEO_BITRATE via setParameters, under the same lock
9
9
  used to clear the codec before stop/reset. There is no transcoding, frame polling,
10
10
  forced keyframe, video reset, resolution change or new video connection.
@@ -26,6 +26,16 @@ checksum before writing). Its source is https://github.com/Genymobile/scrcpy/tre
26
26
  An explicit TERMDOCK_SCRCPY_SERVER override is honored. Missing/invalid bundled
27
27
  assets fall back to the host server; unverified host builds then retain current
28
28
  quality with a diagnostic. Rejections and channel failures also preserve video.
29
+
30
+ Network ADB preview sessions use `adb forward` for video and control; USB
31
+ sessions retain `adb reverse`. The forward connector waits for the scrcpy dummy
32
+ byte before opening control and removes only its own allocated TCP rule on stop.
33
+ The optional bitrate channel uses its own forward rule for network devices; its
34
+ device-side listener accepts the host connection after the encoder starts. USB
35
+ retains its separate reverse rule. Early forward TCP accepts are retried until
36
+ the TDB handshake arrives, within the existing 15-second limit. Bitrate failures
37
+ remain isolated from video/control, and stop removes both session-owned rules.
38
+
29
39
  Extend the allowlist only after verifying the CaptureReset ABI and real-device
30
40
  behavior. No global scrcpy installation is modified.
31
41
 
@@ -40,10 +50,21 @@ desktop runtime packager. Apache-2.0 license is included.
40
50
 
41
51
  Validation: Mi MIX 2S / Android 13 accepted 1.8 → 6 → 0.9 → 4 Mbps within
42
52
  one session, continuously producing frames, with one video header and one codec
43
- configuration packet. Other vendor encoders and macOS/iOS clients require real
44
- device verification.
53
+ configuration packet.
54
+
55
+ Mac server and iPhone preview rendering were also verified with network
56
+ PTP-AN00 / Android 16 and Pixel 9 / Android 15 using forward video. On those cloud
57
+ routes, reverse registration succeeded without carrying data; this motivated
58
+ using forward for both video and the separate bitrate channel. Physical identity properties matched across
59
+ the PTP IPv4/IPv6 routes; option grouping and selected-route preservation are
60
+ covered by tests. Full native input/recording acceptance remains outside these observations.
61
+ The Pixel 9 forward bitrate channel was verified on the Mac server: all four
62
+ 1.8 → 6 → 0.9 → 4 Mbps requests received matching ACKs in 35–37 ms, with one
63
+ video header and the same scrcpy process throughout a 20-second session. Both
64
+ forward rules were removed on stop. API acceptance does not establish exact
65
+ vendor output bandwidth.
45
66
 
46
- Diagnostics distinguish version/build, missing/corrupt extension, ADB push/reverse,
67
+ Diagnostics distinguish version/build, missing/corrupt extension, ADB push/tunnel,
47
68
  15s handshake timeout, 2.5s device ACK timeout, 4s client confirmation timeout,
48
69
  channel/protocol failure and device codec rejection. Detailed reasons travel over
49
70
  the existing encrypted stream and appear in an expandable warning. Intentional
Binary file
@@ -1,2 +0,0 @@
1
- import{bA as r}from"./app-1SAb4dhI.js";import{b as m}from"./dnd-BCFAPC0L.js";import{b as n}from"./RightSidebar-BtHbt-XD.js";import"./react-XDCjal2T.js";import"./terminal-C7X98Amf.js";import"./App-CA8oXFgS.js";import"./gestureArbiter-BvkspAa2.js";import"./triangle-alert-CNoodlX6.js";import"./referenceLongPress-DTjCnJH8.js";import"./DiffReview-aIj4WHDS.js";import"./sparkles-CgwSF-UK.js";import"./DiffViewer-SKlbS7b4.js";import"./ChangeWalkthroughPanel-vh6Z641M.js";function g({content:o}){const e=m.useMemo(()=>n(o.split(`
2
- `),null,null),[o]);return r.jsx("div",{className:"min-w-0 space-y-3 break-words text-sm leading-6 text-foreground [&_h1]:text-lg [&_h2]:text-base [&_h3]:text-sm [&_pre]:max-w-full [&_table]:text-xs",children:e.map((t,i)=>r.jsx("div",{className:"min-w-0",children:typeof t.content=="function"?t.content(null):t.content},i))})}export{g as default};
@@ -1 +0,0 @@
1
- import{c as a,C as n}from"./mermaid.core-DbR5q1bj.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,a as s,c as t,C as e}from"./chunk-TICWLB2K-CrSU9J1Y.js";import{d as i}from"./mermaid.core-DbR5q1bj.js";import"./chunk-5VM5RSS4-DT9NVgVz.js";import"./chunk-XXDRQBXY-DvrlcFpp.js";import"./chunk-POPQ4Y6H-CHVqavTY.js";import"./chunk-F27PBJKO-BPQlePZ0.js";import"./purify.es-4eNOHKSq.js";import"./app-1SAb4dhI.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
@@ -1 +0,0 @@
1
- import{s as a,a as s,c as t,C as e}from"./chunk-TICWLB2K-CrSU9J1Y.js";import{d as i}from"./mermaid.core-DbR5q1bj.js";import"./chunk-5VM5RSS4-DT9NVgVz.js";import"./chunk-XXDRQBXY-DvrlcFpp.js";import"./chunk-POPQ4Y6H-CHVqavTY.js";import"./chunk-F27PBJKO-BPQlePZ0.js";import"./purify.es-4eNOHKSq.js";import"./app-1SAb4dhI.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};