@blue-soda/dsh-remote 0.4.28

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 (225) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +81 -0
  3. package/bin/ds-harness-remote.js +11 -0
  4. package/cordis.patch.yml +32 -0
  5. package/dist/acp.d.ts +75 -0
  6. package/dist/acp.d.ts.map +1 -0
  7. package/dist/acp.js +61 -0
  8. package/dist/acp.js.map +1 -0
  9. package/dist/api-proxy-switch.d.ts +33 -0
  10. package/dist/api-proxy-switch.d.ts.map +1 -0
  11. package/dist/api-proxy-switch.js +109 -0
  12. package/dist/api-proxy-switch.js.map +1 -0
  13. package/dist/bin/doctor.d.ts +3 -0
  14. package/dist/bin/doctor.d.ts.map +1 -0
  15. package/dist/bin/doctor.js +13 -0
  16. package/dist/bin/doctor.js.map +1 -0
  17. package/dist/cli.d.ts +32 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +289 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/client-runtime.d.ts +239 -0
  22. package/dist/client-runtime.d.ts.map +1 -0
  23. package/dist/client-runtime.js +1391 -0
  24. package/dist/client-runtime.js.map +1 -0
  25. package/dist/client-secure-transport.d.ts +23 -0
  26. package/dist/client-secure-transport.d.ts.map +1 -0
  27. package/dist/client-secure-transport.js +143 -0
  28. package/dist/client-secure-transport.js.map +1 -0
  29. package/dist/client.d.ts +13 -0
  30. package/dist/client.d.ts.map +1 -0
  31. package/dist/client.github.js +4231 -0
  32. package/dist/client.js +4231 -0
  33. package/dist/codex/app-server.d.ts +71 -0
  34. package/dist/codex/app-server.d.ts.map +1 -0
  35. package/dist/codex/app-server.js +268 -0
  36. package/dist/codex/app-server.js.map +1 -0
  37. package/dist/codex/codex-image-codec.d.ts +7 -0
  38. package/dist/codex/codex-image-codec.d.ts.map +1 -0
  39. package/dist/codex/codex-image-codec.js +288 -0
  40. package/dist/codex/codex-image-codec.js.map +1 -0
  41. package/dist/codex/domain.d.ts +93 -0
  42. package/dist/codex/domain.d.ts.map +1 -0
  43. package/dist/codex/domain.js +1282 -0
  44. package/dist/codex/domain.js.map +1 -0
  45. package/dist/codex/method-policy.d.ts +338 -0
  46. package/dist/codex/method-policy.d.ts.map +1 -0
  47. package/dist/codex/method-policy.js +141 -0
  48. package/dist/codex/method-policy.js.map +1 -0
  49. package/dist/codex/peer-bridge.d.ts +57 -0
  50. package/dist/codex/peer-bridge.d.ts.map +1 -0
  51. package/dist/codex/peer-bridge.js +299 -0
  52. package/dist/codex/peer-bridge.js.map +1 -0
  53. package/dist/codex/permissions.d.ts +4 -0
  54. package/dist/codex/permissions.d.ts.map +1 -0
  55. package/dist/codex/permissions.js +21 -0
  56. package/dist/codex/permissions.js.map +1 -0
  57. package/dist/codex/session-id.d.ts +10 -0
  58. package/dist/codex/session-id.d.ts.map +1 -0
  59. package/dist/codex/session-id.js +15 -0
  60. package/dist/codex/session-id.js.map +1 -0
  61. package/dist/codex/virtual-harness.d.ts +209 -0
  62. package/dist/codex/virtual-harness.d.ts.map +1 -0
  63. package/dist/codex/virtual-harness.js +2616 -0
  64. package/dist/codex/virtual-harness.js.map +1 -0
  65. package/dist/codex-workspace-bridge.d.ts +108 -0
  66. package/dist/codex-workspace-bridge.d.ts.map +1 -0
  67. package/dist/codex-workspace-bridge.js +502 -0
  68. package/dist/codex-workspace-bridge.js.map +1 -0
  69. package/dist/config.d.ts +99 -0
  70. package/dist/config.d.ts.map +1 -0
  71. package/dist/config.js +127 -0
  72. package/dist/config.js.map +1 -0
  73. package/dist/connection-controller.d.ts +44 -0
  74. package/dist/connection-controller.d.ts.map +1 -0
  75. package/dist/connection-controller.js +185 -0
  76. package/dist/connection-controller.js.map +1 -0
  77. package/dist/control-route.d.ts +34 -0
  78. package/dist/control-route.d.ts.map +1 -0
  79. package/dist/control-route.js +136 -0
  80. package/dist/control-route.js.map +1 -0
  81. package/dist/control-runtime.d.ts +138 -0
  82. package/dist/control-runtime.d.ts.map +1 -0
  83. package/dist/control-runtime.js +543 -0
  84. package/dist/control-runtime.js.map +1 -0
  85. package/dist/control-stream.d.ts +67 -0
  86. package/dist/control-stream.d.ts.map +1 -0
  87. package/dist/control-stream.js +179 -0
  88. package/dist/control-stream.js.map +1 -0
  89. package/dist/defaults.d.ts +9 -0
  90. package/dist/defaults.d.ts.map +1 -0
  91. package/dist/defaults.js +9 -0
  92. package/dist/defaults.js.map +1 -0
  93. package/dist/file-viewer-bridge.d.ts +30 -0
  94. package/dist/file-viewer-bridge.d.ts.map +1 -0
  95. package/dist/file-viewer-bridge.js +128 -0
  96. package/dist/file-viewer-bridge.js.map +1 -0
  97. package/dist/file-viewer-contract.d.ts +5 -0
  98. package/dist/file-viewer-contract.d.ts.map +1 -0
  99. package/dist/file-viewer-contract.js +4 -0
  100. package/dist/file-viewer-contract.js.map +1 -0
  101. package/dist/harness-api-bridge.d.ts +79 -0
  102. package/dist/harness-api-bridge.d.ts.map +1 -0
  103. package/dist/harness-api-bridge.js +852 -0
  104. package/dist/harness-api-bridge.js.map +1 -0
  105. package/dist/harness-api-history.d.ts +3 -0
  106. package/dist/harness-api-history.d.ts.map +1 -0
  107. package/dist/harness-api-history.js +59 -0
  108. package/dist/harness-api-history.js.map +1 -0
  109. package/dist/harness-remote-bridge.d.ts +52 -0
  110. package/dist/harness-remote-bridge.d.ts.map +1 -0
  111. package/dist/harness-remote-bridge.js +529 -0
  112. package/dist/harness-remote-bridge.js.map +1 -0
  113. package/dist/harness-version.d.ts +23 -0
  114. package/dist/harness-version.d.ts.map +1 -0
  115. package/dist/harness-version.js +95 -0
  116. package/dist/harness-version.js.map +1 -0
  117. package/dist/identity-store.d.ts +45 -0
  118. package/dist/identity-store.d.ts.map +1 -0
  119. package/dist/identity-store.js +183 -0
  120. package/dist/identity-store.js.map +1 -0
  121. package/dist/ids.d.ts +2 -0
  122. package/dist/ids.d.ts.map +1 -0
  123. package/dist/ids.js +17 -0
  124. package/dist/ids.js.map +1 -0
  125. package/dist/index.d.ts +78 -0
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +28870 -0
  128. package/dist/index.js.map +7 -0
  129. package/dist/logging.d.ts +18 -0
  130. package/dist/logging.d.ts.map +1 -0
  131. package/dist/logging.js +30 -0
  132. package/dist/logging.js.map +1 -0
  133. package/dist/loopback-host.d.ts +20 -0
  134. package/dist/loopback-host.d.ts.map +1 -0
  135. package/dist/loopback-host.js +245 -0
  136. package/dist/loopback-host.js.map +1 -0
  137. package/dist/loopback-preview.d.ts +19 -0
  138. package/dist/loopback-preview.d.ts.map +1 -0
  139. package/dist/loopback-preview.js +232 -0
  140. package/dist/loopback-preview.js.map +1 -0
  141. package/dist/native-rtc-helper.d.ts +14 -0
  142. package/dist/native-rtc-helper.d.ts.map +1 -0
  143. package/dist/native-rtc-helper.js +575 -0
  144. package/dist/native-rtc-helper.js.map +1 -0
  145. package/dist/remote-api-proxy.d.ts +17 -0
  146. package/dist/remote-api-proxy.d.ts.map +1 -0
  147. package/dist/remote-api-proxy.js +400 -0
  148. package/dist/remote-api-proxy.js.map +1 -0
  149. package/dist/remote-directory-browser.d.ts +16 -0
  150. package/dist/remote-directory-browser.d.ts.map +1 -0
  151. package/dist/remote-directory-browser.js +48 -0
  152. package/dist/remote-directory-browser.js.map +1 -0
  153. package/dist/remote-file-content-provider.d.ts +48 -0
  154. package/dist/remote-file-content-provider.d.ts.map +1 -0
  155. package/dist/remote-file-content-provider.js +93 -0
  156. package/dist/remote-file-content-provider.js.map +1 -0
  157. package/dist/remote-typert-gateway.d.ts +20 -0
  158. package/dist/remote-typert-gateway.d.ts.map +1 -0
  159. package/dist/remote-typert-gateway.js +332 -0
  160. package/dist/remote-typert-gateway.js.map +1 -0
  161. package/dist/rpc-router.d.ts +31 -0
  162. package/dist/rpc-router.d.ts.map +1 -0
  163. package/dist/rpc-router.js +201 -0
  164. package/dist/rpc-router.js.map +1 -0
  165. package/dist/safe-error.d.ts +8 -0
  166. package/dist/safe-error.d.ts.map +1 -0
  167. package/dist/safe-error.js +20 -0
  168. package/dist/safe-error.js.map +1 -0
  169. package/dist/server-api.d.ts +109 -0
  170. package/dist/server-api.d.ts.map +1 -0
  171. package/dist/server-api.js +520 -0
  172. package/dist/server-api.js.map +1 -0
  173. package/dist/server-connection.d.ts +79 -0
  174. package/dist/server-connection.d.ts.map +1 -0
  175. package/dist/server-connection.js +1023 -0
  176. package/dist/server-connection.js.map +1 -0
  177. package/dist/server-credentials.d.ts +55 -0
  178. package/dist/server-credentials.d.ts.map +1 -0
  179. package/dist/server-credentials.js +105 -0
  180. package/dist/server-credentials.js.map +1 -0
  181. package/dist/service.d.ts +141 -0
  182. package/dist/service.d.ts.map +1 -0
  183. package/dist/service.js +432 -0
  184. package/dist/service.js.map +1 -0
  185. package/dist/session-format-compat.d.ts +3 -0
  186. package/dist/session-format-compat.d.ts.map +1 -0
  187. package/dist/session-format-compat.js +183 -0
  188. package/dist/session-format-compat.js.map +1 -0
  189. package/dist/status-stream.d.ts +48 -0
  190. package/dist/status-stream.d.ts.map +1 -0
  191. package/dist/status-stream.js +133 -0
  192. package/dist/status-stream.js.map +1 -0
  193. package/dist/terminal-policy.d.ts +21 -0
  194. package/dist/terminal-policy.d.ts.map +1 -0
  195. package/dist/terminal-policy.js +68 -0
  196. package/dist/terminal-policy.js.map +1 -0
  197. package/dist/tui-command.d.ts +13 -0
  198. package/dist/tui-command.d.ts.map +1 -0
  199. package/dist/tui-command.js +390 -0
  200. package/dist/tui-command.js.map +1 -0
  201. package/dist/typert-gateway-contract.d.ts +59 -0
  202. package/dist/typert-gateway-contract.d.ts.map +1 -0
  203. package/dist/typert-gateway-contract.js +2 -0
  204. package/dist/typert-gateway-contract.js.map +1 -0
  205. package/dist/typert-gateway-switch.d.ts +85 -0
  206. package/dist/typert-gateway-switch.d.ts.map +1 -0
  207. package/dist/typert-gateway-switch.js +315 -0
  208. package/dist/typert-gateway-switch.js.map +1 -0
  209. package/dist/types.d.ts +20 -0
  210. package/dist/types.d.ts.map +1 -0
  211. package/dist/types.js +2 -0
  212. package/dist/types.js.map +1 -0
  213. package/dist/version.d.ts +12 -0
  214. package/dist/version.d.ts.map +1 -0
  215. package/dist/version.js +12 -0
  216. package/dist/version.js.map +1 -0
  217. package/dist/werift-rtc.d.ts +121 -0
  218. package/dist/werift-rtc.d.ts.map +1 -0
  219. package/dist/werift-rtc.js +490 -0
  220. package/dist/werift-rtc.js.map +1 -0
  221. package/dsh-plugin.json +41 -0
  222. package/locale/en.json +6 -0
  223. package/locale/zh.json +6 -0
  224. package/package.json +165 -0
  225. package/public.d.ts +26 -0
@@ -0,0 +1,4231 @@
1
+ "use strict";
2
+ (() => {
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from == "object" || typeof from == "function")
13
+ for (let key of __getOwnPropNames(from))
14
+ !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
23
+ mod
24
+ ));
25
+
26
+ // ../../node_modules/qrcode/lib/can-promise.js
27
+ var require_can_promise = __commonJS({
28
+ "../../node_modules/qrcode/lib/can-promise.js"(exports, module) {
29
+ module.exports = function() {
30
+ return typeof Promise == "function" && Promise.prototype && Promise.prototype.then;
31
+ };
32
+ }
33
+ });
34
+
35
+ // ../../node_modules/qrcode/lib/core/utils.js
36
+ var require_utils = __commonJS({
37
+ "../../node_modules/qrcode/lib/core/utils.js"(exports) {
38
+ var toSJISFunction, CODEWORDS_COUNT = [
39
+ 0,
40
+ // Not used
41
+ 26,
42
+ 44,
43
+ 70,
44
+ 100,
45
+ 134,
46
+ 172,
47
+ 196,
48
+ 242,
49
+ 292,
50
+ 346,
51
+ 404,
52
+ 466,
53
+ 532,
54
+ 581,
55
+ 655,
56
+ 733,
57
+ 815,
58
+ 901,
59
+ 991,
60
+ 1085,
61
+ 1156,
62
+ 1258,
63
+ 1364,
64
+ 1474,
65
+ 1588,
66
+ 1706,
67
+ 1828,
68
+ 1921,
69
+ 2051,
70
+ 2185,
71
+ 2323,
72
+ 2465,
73
+ 2611,
74
+ 2761,
75
+ 2876,
76
+ 3034,
77
+ 3196,
78
+ 3362,
79
+ 3532,
80
+ 3706
81
+ ];
82
+ exports.getSymbolSize = function(version) {
83
+ if (!version) throw new Error('"version" cannot be null or undefined');
84
+ if (version < 1 || version > 40) throw new Error('"version" should be in range from 1 to 40');
85
+ return version * 4 + 17;
86
+ };
87
+ exports.getSymbolTotalCodewords = function(version) {
88
+ return CODEWORDS_COUNT[version];
89
+ };
90
+ exports.getBCHDigit = function(data) {
91
+ let digit = 0;
92
+ for (; data !== 0; )
93
+ digit++, data >>>= 1;
94
+ return digit;
95
+ };
96
+ exports.setToSJISFunction = function(f) {
97
+ if (typeof f != "function")
98
+ throw new Error('"toSJISFunc" is not a valid function.');
99
+ toSJISFunction = f;
100
+ };
101
+ exports.isKanjiModeEnabled = function() {
102
+ return typeof toSJISFunction < "u";
103
+ };
104
+ exports.toSJIS = function(kanji) {
105
+ return toSJISFunction(kanji);
106
+ };
107
+ }
108
+ });
109
+
110
+ // ../../node_modules/qrcode/lib/core/error-correction-level.js
111
+ var require_error_correction_level = __commonJS({
112
+ "../../node_modules/qrcode/lib/core/error-correction-level.js"(exports) {
113
+ exports.L = { bit: 1 };
114
+ exports.M = { bit: 0 };
115
+ exports.Q = { bit: 3 };
116
+ exports.H = { bit: 2 };
117
+ function fromString(string) {
118
+ if (typeof string != "string")
119
+ throw new Error("Param is not a string");
120
+ switch (string.toLowerCase()) {
121
+ case "l":
122
+ case "low":
123
+ return exports.L;
124
+ case "m":
125
+ case "medium":
126
+ return exports.M;
127
+ case "q":
128
+ case "quartile":
129
+ return exports.Q;
130
+ case "h":
131
+ case "high":
132
+ return exports.H;
133
+ default:
134
+ throw new Error("Unknown EC Level: " + string);
135
+ }
136
+ }
137
+ exports.isValid = function(level) {
138
+ return level && typeof level.bit < "u" && level.bit >= 0 && level.bit < 4;
139
+ };
140
+ exports.from = function(value, defaultValue) {
141
+ if (exports.isValid(value))
142
+ return value;
143
+ try {
144
+ return fromString(value);
145
+ } catch {
146
+ return defaultValue;
147
+ }
148
+ };
149
+ }
150
+ });
151
+
152
+ // ../../node_modules/qrcode/lib/core/bit-buffer.js
153
+ var require_bit_buffer = __commonJS({
154
+ "../../node_modules/qrcode/lib/core/bit-buffer.js"(exports, module) {
155
+ function BitBuffer() {
156
+ this.buffer = [], this.length = 0;
157
+ }
158
+ BitBuffer.prototype = {
159
+ get: function(index) {
160
+ let bufIndex = Math.floor(index / 8);
161
+ return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) === 1;
162
+ },
163
+ put: function(num, length) {
164
+ for (let i = 0; i < length; i++)
165
+ this.putBit((num >>> length - i - 1 & 1) === 1);
166
+ },
167
+ getLengthInBits: function() {
168
+ return this.length;
169
+ },
170
+ putBit: function(bit) {
171
+ let bufIndex = Math.floor(this.length / 8);
172
+ this.buffer.length <= bufIndex && this.buffer.push(0), bit && (this.buffer[bufIndex] |= 128 >>> this.length % 8), this.length++;
173
+ }
174
+ };
175
+ module.exports = BitBuffer;
176
+ }
177
+ });
178
+
179
+ // ../../node_modules/qrcode/lib/core/bit-matrix.js
180
+ var require_bit_matrix = __commonJS({
181
+ "../../node_modules/qrcode/lib/core/bit-matrix.js"(exports, module) {
182
+ function BitMatrix(size) {
183
+ if (!size || size < 1)
184
+ throw new Error("BitMatrix size must be defined and greater than 0");
185
+ this.size = size, this.data = new Uint8Array(size * size), this.reservedBit = new Uint8Array(size * size);
186
+ }
187
+ BitMatrix.prototype.set = function(row, col, value, reserved) {
188
+ let index = row * this.size + col;
189
+ this.data[index] = value, reserved && (this.reservedBit[index] = !0);
190
+ };
191
+ BitMatrix.prototype.get = function(row, col) {
192
+ return this.data[row * this.size + col];
193
+ };
194
+ BitMatrix.prototype.xor = function(row, col, value) {
195
+ this.data[row * this.size + col] ^= value;
196
+ };
197
+ BitMatrix.prototype.isReserved = function(row, col) {
198
+ return this.reservedBit[row * this.size + col];
199
+ };
200
+ module.exports = BitMatrix;
201
+ }
202
+ });
203
+
204
+ // ../../node_modules/qrcode/lib/core/alignment-pattern.js
205
+ var require_alignment_pattern = __commonJS({
206
+ "../../node_modules/qrcode/lib/core/alignment-pattern.js"(exports) {
207
+ var getSymbolSize = require_utils().getSymbolSize;
208
+ exports.getRowColCoords = function(version) {
209
+ if (version === 1) return [];
210
+ let posCount = Math.floor(version / 7) + 2, size = getSymbolSize(version), intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2, positions = [size - 7];
211
+ for (let i = 1; i < posCount - 1; i++)
212
+ positions[i] = positions[i - 1] - intervals;
213
+ return positions.push(6), positions.reverse();
214
+ };
215
+ exports.getPositions = function(version) {
216
+ let coords = [], pos = exports.getRowColCoords(version), posLength = pos.length;
217
+ for (let i = 0; i < posLength; i++)
218
+ for (let j = 0; j < posLength; j++)
219
+ i === 0 && j === 0 || // top-left
220
+ i === 0 && j === posLength - 1 || // bottom-left
221
+ i === posLength - 1 && j === 0 || coords.push([pos[i], pos[j]]);
222
+ return coords;
223
+ };
224
+ }
225
+ });
226
+
227
+ // ../../node_modules/qrcode/lib/core/finder-pattern.js
228
+ var require_finder_pattern = __commonJS({
229
+ "../../node_modules/qrcode/lib/core/finder-pattern.js"(exports) {
230
+ var getSymbolSize = require_utils().getSymbolSize, FINDER_PATTERN_SIZE = 7;
231
+ exports.getPositions = function(version) {
232
+ let size = getSymbolSize(version);
233
+ return [
234
+ // top-left
235
+ [0, 0],
236
+ // top-right
237
+ [size - FINDER_PATTERN_SIZE, 0],
238
+ // bottom-left
239
+ [0, size - FINDER_PATTERN_SIZE]
240
+ ];
241
+ };
242
+ }
243
+ });
244
+
245
+ // ../../node_modules/qrcode/lib/core/mask-pattern.js
246
+ var require_mask_pattern = __commonJS({
247
+ "../../node_modules/qrcode/lib/core/mask-pattern.js"(exports) {
248
+ exports.Patterns = {
249
+ PATTERN000: 0,
250
+ PATTERN001: 1,
251
+ PATTERN010: 2,
252
+ PATTERN011: 3,
253
+ PATTERN100: 4,
254
+ PATTERN101: 5,
255
+ PATTERN110: 6,
256
+ PATTERN111: 7
257
+ };
258
+ var PenaltyScores = {
259
+ N1: 3,
260
+ N2: 3,
261
+ N3: 40,
262
+ N4: 10
263
+ };
264
+ exports.isValid = function(mask) {
265
+ return mask != null && mask !== "" && !isNaN(mask) && mask >= 0 && mask <= 7;
266
+ };
267
+ exports.from = function(value) {
268
+ return exports.isValid(value) ? parseInt(value, 10) : void 0;
269
+ };
270
+ exports.getPenaltyN1 = function(data) {
271
+ let size = data.size, points = 0, sameCountCol = 0, sameCountRow = 0, lastCol = null, lastRow = null;
272
+ for (let row = 0; row < size; row++) {
273
+ sameCountCol = sameCountRow = 0, lastCol = lastRow = null;
274
+ for (let col = 0; col < size; col++) {
275
+ let module2 = data.get(row, col);
276
+ module2 === lastCol ? sameCountCol++ : (sameCountCol >= 5 && (points += PenaltyScores.N1 + (sameCountCol - 5)), lastCol = module2, sameCountCol = 1), module2 = data.get(col, row), module2 === lastRow ? sameCountRow++ : (sameCountRow >= 5 && (points += PenaltyScores.N1 + (sameCountRow - 5)), lastRow = module2, sameCountRow = 1);
277
+ }
278
+ sameCountCol >= 5 && (points += PenaltyScores.N1 + (sameCountCol - 5)), sameCountRow >= 5 && (points += PenaltyScores.N1 + (sameCountRow - 5));
279
+ }
280
+ return points;
281
+ };
282
+ exports.getPenaltyN2 = function(data) {
283
+ let size = data.size, points = 0;
284
+ for (let row = 0; row < size - 1; row++)
285
+ for (let col = 0; col < size - 1; col++) {
286
+ let last = data.get(row, col) + data.get(row, col + 1) + data.get(row + 1, col) + data.get(row + 1, col + 1);
287
+ (last === 4 || last === 0) && points++;
288
+ }
289
+ return points * PenaltyScores.N2;
290
+ };
291
+ exports.getPenaltyN3 = function(data) {
292
+ let size = data.size, points = 0, bitsCol = 0, bitsRow = 0;
293
+ for (let row = 0; row < size; row++) {
294
+ bitsCol = bitsRow = 0;
295
+ for (let col = 0; col < size; col++)
296
+ bitsCol = bitsCol << 1 & 2047 | data.get(row, col), col >= 10 && (bitsCol === 1488 || bitsCol === 93) && points++, bitsRow = bitsRow << 1 & 2047 | data.get(col, row), col >= 10 && (bitsRow === 1488 || bitsRow === 93) && points++;
297
+ }
298
+ return points * PenaltyScores.N3;
299
+ };
300
+ exports.getPenaltyN4 = function(data) {
301
+ let darkCount = 0, modulesCount = data.data.length;
302
+ for (let i = 0; i < modulesCount; i++) darkCount += data.data[i];
303
+ return Math.abs(Math.ceil(darkCount * 100 / modulesCount / 5) - 10) * PenaltyScores.N4;
304
+ };
305
+ function getMaskAt(maskPattern, i, j) {
306
+ switch (maskPattern) {
307
+ case exports.Patterns.PATTERN000:
308
+ return (i + j) % 2 === 0;
309
+ case exports.Patterns.PATTERN001:
310
+ return i % 2 === 0;
311
+ case exports.Patterns.PATTERN010:
312
+ return j % 3 === 0;
313
+ case exports.Patterns.PATTERN011:
314
+ return (i + j) % 3 === 0;
315
+ case exports.Patterns.PATTERN100:
316
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0;
317
+ case exports.Patterns.PATTERN101:
318
+ return i * j % 2 + i * j % 3 === 0;
319
+ case exports.Patterns.PATTERN110:
320
+ return (i * j % 2 + i * j % 3) % 2 === 0;
321
+ case exports.Patterns.PATTERN111:
322
+ return (i * j % 3 + (i + j) % 2) % 2 === 0;
323
+ default:
324
+ throw new Error("bad maskPattern:" + maskPattern);
325
+ }
326
+ }
327
+ exports.applyMask = function(pattern, data) {
328
+ let size = data.size;
329
+ for (let col = 0; col < size; col++)
330
+ for (let row = 0; row < size; row++)
331
+ data.isReserved(row, col) || data.xor(row, col, getMaskAt(pattern, row, col));
332
+ };
333
+ exports.getBestMask = function(data, setupFormatFunc) {
334
+ let numPatterns = Object.keys(exports.Patterns).length, bestPattern = 0, lowerPenalty = 1 / 0;
335
+ for (let p = 0; p < numPatterns; p++) {
336
+ setupFormatFunc(p), exports.applyMask(p, data);
337
+ let penalty = exports.getPenaltyN1(data) + exports.getPenaltyN2(data) + exports.getPenaltyN3(data) + exports.getPenaltyN4(data);
338
+ exports.applyMask(p, data), penalty < lowerPenalty && (lowerPenalty = penalty, bestPattern = p);
339
+ }
340
+ return bestPattern;
341
+ };
342
+ }
343
+ });
344
+
345
+ // ../../node_modules/qrcode/lib/core/error-correction-code.js
346
+ var require_error_correction_code = __commonJS({
347
+ "../../node_modules/qrcode/lib/core/error-correction-code.js"(exports) {
348
+ var ECLevel = require_error_correction_level(), EC_BLOCKS_TABLE = [
349
+ // L M Q H
350
+ 1,
351
+ 1,
352
+ 1,
353
+ 1,
354
+ 1,
355
+ 1,
356
+ 1,
357
+ 1,
358
+ 1,
359
+ 1,
360
+ 2,
361
+ 2,
362
+ 1,
363
+ 2,
364
+ 2,
365
+ 4,
366
+ 1,
367
+ 2,
368
+ 4,
369
+ 4,
370
+ 2,
371
+ 4,
372
+ 4,
373
+ 4,
374
+ 2,
375
+ 4,
376
+ 6,
377
+ 5,
378
+ 2,
379
+ 4,
380
+ 6,
381
+ 6,
382
+ 2,
383
+ 5,
384
+ 8,
385
+ 8,
386
+ 4,
387
+ 5,
388
+ 8,
389
+ 8,
390
+ 4,
391
+ 5,
392
+ 8,
393
+ 11,
394
+ 4,
395
+ 8,
396
+ 10,
397
+ 11,
398
+ 4,
399
+ 9,
400
+ 12,
401
+ 16,
402
+ 4,
403
+ 9,
404
+ 16,
405
+ 16,
406
+ 6,
407
+ 10,
408
+ 12,
409
+ 18,
410
+ 6,
411
+ 10,
412
+ 17,
413
+ 16,
414
+ 6,
415
+ 11,
416
+ 16,
417
+ 19,
418
+ 6,
419
+ 13,
420
+ 18,
421
+ 21,
422
+ 7,
423
+ 14,
424
+ 21,
425
+ 25,
426
+ 8,
427
+ 16,
428
+ 20,
429
+ 25,
430
+ 8,
431
+ 17,
432
+ 23,
433
+ 25,
434
+ 9,
435
+ 17,
436
+ 23,
437
+ 34,
438
+ 9,
439
+ 18,
440
+ 25,
441
+ 30,
442
+ 10,
443
+ 20,
444
+ 27,
445
+ 32,
446
+ 12,
447
+ 21,
448
+ 29,
449
+ 35,
450
+ 12,
451
+ 23,
452
+ 34,
453
+ 37,
454
+ 12,
455
+ 25,
456
+ 34,
457
+ 40,
458
+ 13,
459
+ 26,
460
+ 35,
461
+ 42,
462
+ 14,
463
+ 28,
464
+ 38,
465
+ 45,
466
+ 15,
467
+ 29,
468
+ 40,
469
+ 48,
470
+ 16,
471
+ 31,
472
+ 43,
473
+ 51,
474
+ 17,
475
+ 33,
476
+ 45,
477
+ 54,
478
+ 18,
479
+ 35,
480
+ 48,
481
+ 57,
482
+ 19,
483
+ 37,
484
+ 51,
485
+ 60,
486
+ 19,
487
+ 38,
488
+ 53,
489
+ 63,
490
+ 20,
491
+ 40,
492
+ 56,
493
+ 66,
494
+ 21,
495
+ 43,
496
+ 59,
497
+ 70,
498
+ 22,
499
+ 45,
500
+ 62,
501
+ 74,
502
+ 24,
503
+ 47,
504
+ 65,
505
+ 77,
506
+ 25,
507
+ 49,
508
+ 68,
509
+ 81
510
+ ], EC_CODEWORDS_TABLE = [
511
+ // L M Q H
512
+ 7,
513
+ 10,
514
+ 13,
515
+ 17,
516
+ 10,
517
+ 16,
518
+ 22,
519
+ 28,
520
+ 15,
521
+ 26,
522
+ 36,
523
+ 44,
524
+ 20,
525
+ 36,
526
+ 52,
527
+ 64,
528
+ 26,
529
+ 48,
530
+ 72,
531
+ 88,
532
+ 36,
533
+ 64,
534
+ 96,
535
+ 112,
536
+ 40,
537
+ 72,
538
+ 108,
539
+ 130,
540
+ 48,
541
+ 88,
542
+ 132,
543
+ 156,
544
+ 60,
545
+ 110,
546
+ 160,
547
+ 192,
548
+ 72,
549
+ 130,
550
+ 192,
551
+ 224,
552
+ 80,
553
+ 150,
554
+ 224,
555
+ 264,
556
+ 96,
557
+ 176,
558
+ 260,
559
+ 308,
560
+ 104,
561
+ 198,
562
+ 288,
563
+ 352,
564
+ 120,
565
+ 216,
566
+ 320,
567
+ 384,
568
+ 132,
569
+ 240,
570
+ 360,
571
+ 432,
572
+ 144,
573
+ 280,
574
+ 408,
575
+ 480,
576
+ 168,
577
+ 308,
578
+ 448,
579
+ 532,
580
+ 180,
581
+ 338,
582
+ 504,
583
+ 588,
584
+ 196,
585
+ 364,
586
+ 546,
587
+ 650,
588
+ 224,
589
+ 416,
590
+ 600,
591
+ 700,
592
+ 224,
593
+ 442,
594
+ 644,
595
+ 750,
596
+ 252,
597
+ 476,
598
+ 690,
599
+ 816,
600
+ 270,
601
+ 504,
602
+ 750,
603
+ 900,
604
+ 300,
605
+ 560,
606
+ 810,
607
+ 960,
608
+ 312,
609
+ 588,
610
+ 870,
611
+ 1050,
612
+ 336,
613
+ 644,
614
+ 952,
615
+ 1110,
616
+ 360,
617
+ 700,
618
+ 1020,
619
+ 1200,
620
+ 390,
621
+ 728,
622
+ 1050,
623
+ 1260,
624
+ 420,
625
+ 784,
626
+ 1140,
627
+ 1350,
628
+ 450,
629
+ 812,
630
+ 1200,
631
+ 1440,
632
+ 480,
633
+ 868,
634
+ 1290,
635
+ 1530,
636
+ 510,
637
+ 924,
638
+ 1350,
639
+ 1620,
640
+ 540,
641
+ 980,
642
+ 1440,
643
+ 1710,
644
+ 570,
645
+ 1036,
646
+ 1530,
647
+ 1800,
648
+ 570,
649
+ 1064,
650
+ 1590,
651
+ 1890,
652
+ 600,
653
+ 1120,
654
+ 1680,
655
+ 1980,
656
+ 630,
657
+ 1204,
658
+ 1770,
659
+ 2100,
660
+ 660,
661
+ 1260,
662
+ 1860,
663
+ 2220,
664
+ 720,
665
+ 1316,
666
+ 1950,
667
+ 2310,
668
+ 750,
669
+ 1372,
670
+ 2040,
671
+ 2430
672
+ ];
673
+ exports.getBlocksCount = function(version, errorCorrectionLevel) {
674
+ switch (errorCorrectionLevel) {
675
+ case ECLevel.L:
676
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 0];
677
+ case ECLevel.M:
678
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 1];
679
+ case ECLevel.Q:
680
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 2];
681
+ case ECLevel.H:
682
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 3];
683
+ default:
684
+ return;
685
+ }
686
+ };
687
+ exports.getTotalCodewordsCount = function(version, errorCorrectionLevel) {
688
+ switch (errorCorrectionLevel) {
689
+ case ECLevel.L:
690
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0];
691
+ case ECLevel.M:
692
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1];
693
+ case ECLevel.Q:
694
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2];
695
+ case ECLevel.H:
696
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3];
697
+ default:
698
+ return;
699
+ }
700
+ };
701
+ }
702
+ });
703
+
704
+ // ../../node_modules/qrcode/lib/core/galois-field.js
705
+ var require_galois_field = __commonJS({
706
+ "../../node_modules/qrcode/lib/core/galois-field.js"(exports) {
707
+ var EXP_TABLE = new Uint8Array(512), LOG_TABLE = new Uint8Array(256);
708
+ (function() {
709
+ let x = 1;
710
+ for (let i = 0; i < 255; i++)
711
+ EXP_TABLE[i] = x, LOG_TABLE[x] = i, x <<= 1, x & 256 && (x ^= 285);
712
+ for (let i = 255; i < 512; i++)
713
+ EXP_TABLE[i] = EXP_TABLE[i - 255];
714
+ })();
715
+ exports.log = function(n) {
716
+ if (n < 1) throw new Error("log(" + n + ")");
717
+ return LOG_TABLE[n];
718
+ };
719
+ exports.exp = function(n) {
720
+ return EXP_TABLE[n];
721
+ };
722
+ exports.mul = function(x, y) {
723
+ return x === 0 || y === 0 ? 0 : EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]];
724
+ };
725
+ }
726
+ });
727
+
728
+ // ../../node_modules/qrcode/lib/core/polynomial.js
729
+ var require_polynomial = __commonJS({
730
+ "../../node_modules/qrcode/lib/core/polynomial.js"(exports) {
731
+ var GF = require_galois_field();
732
+ exports.mul = function(p1, p2) {
733
+ let coeff = new Uint8Array(p1.length + p2.length - 1);
734
+ for (let i = 0; i < p1.length; i++)
735
+ for (let j = 0; j < p2.length; j++)
736
+ coeff[i + j] ^= GF.mul(p1[i], p2[j]);
737
+ return coeff;
738
+ };
739
+ exports.mod = function(divident, divisor) {
740
+ let result = new Uint8Array(divident);
741
+ for (; result.length - divisor.length >= 0; ) {
742
+ let coeff = result[0];
743
+ for (let i = 0; i < divisor.length; i++)
744
+ result[i] ^= GF.mul(divisor[i], coeff);
745
+ let offset = 0;
746
+ for (; offset < result.length && result[offset] === 0; ) offset++;
747
+ result = result.slice(offset);
748
+ }
749
+ return result;
750
+ };
751
+ exports.generateECPolynomial = function(degree) {
752
+ let poly = new Uint8Array([1]);
753
+ for (let i = 0; i < degree; i++)
754
+ poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]));
755
+ return poly;
756
+ };
757
+ }
758
+ });
759
+
760
+ // ../../node_modules/qrcode/lib/core/reed-solomon-encoder.js
761
+ var require_reed_solomon_encoder = __commonJS({
762
+ "../../node_modules/qrcode/lib/core/reed-solomon-encoder.js"(exports, module) {
763
+ var Polynomial = require_polynomial();
764
+ function ReedSolomonEncoder(degree) {
765
+ this.genPoly = void 0, this.degree = degree, this.degree && this.initialize(this.degree);
766
+ }
767
+ ReedSolomonEncoder.prototype.initialize = function(degree) {
768
+ this.degree = degree, this.genPoly = Polynomial.generateECPolynomial(this.degree);
769
+ };
770
+ ReedSolomonEncoder.prototype.encode = function(data) {
771
+ if (!this.genPoly)
772
+ throw new Error("Encoder not initialized");
773
+ let paddedData = new Uint8Array(data.length + this.degree);
774
+ paddedData.set(data);
775
+ let remainder = Polynomial.mod(paddedData, this.genPoly), start = this.degree - remainder.length;
776
+ if (start > 0) {
777
+ let buff = new Uint8Array(this.degree);
778
+ return buff.set(remainder, start), buff;
779
+ }
780
+ return remainder;
781
+ };
782
+ module.exports = ReedSolomonEncoder;
783
+ }
784
+ });
785
+
786
+ // ../../node_modules/qrcode/lib/core/version-check.js
787
+ var require_version_check = __commonJS({
788
+ "../../node_modules/qrcode/lib/core/version-check.js"(exports) {
789
+ exports.isValid = function(version) {
790
+ return !isNaN(version) && version >= 1 && version <= 40;
791
+ };
792
+ }
793
+ });
794
+
795
+ // ../../node_modules/qrcode/lib/core/regex.js
796
+ var require_regex = __commonJS({
797
+ "../../node_modules/qrcode/lib/core/regex.js"(exports) {
798
+ var numeric = "[0-9]+", alphanumeric = "[A-Z $%*+\\-./:]+", kanji = "(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";
799
+ kanji = kanji.replace(/u/g, "\\u");
800
+ var byte = "(?:(?![A-Z0-9 $%*+\\-./:]|" + kanji + `)(?:.|[\r
801
+ ]))+`;
802
+ exports.KANJI = new RegExp(kanji, "g");
803
+ exports.BYTE_KANJI = new RegExp("[^A-Z0-9 $%*+\\-./:]+", "g");
804
+ exports.BYTE = new RegExp(byte, "g");
805
+ exports.NUMERIC = new RegExp(numeric, "g");
806
+ exports.ALPHANUMERIC = new RegExp(alphanumeric, "g");
807
+ var TEST_KANJI = new RegExp("^" + kanji + "$"), TEST_NUMERIC = new RegExp("^" + numeric + "$"), TEST_ALPHANUMERIC = new RegExp("^[A-Z0-9 $%*+\\-./:]+$");
808
+ exports.testKanji = function(str) {
809
+ return TEST_KANJI.test(str);
810
+ };
811
+ exports.testNumeric = function(str) {
812
+ return TEST_NUMERIC.test(str);
813
+ };
814
+ exports.testAlphanumeric = function(str) {
815
+ return TEST_ALPHANUMERIC.test(str);
816
+ };
817
+ }
818
+ });
819
+
820
+ // ../../node_modules/qrcode/lib/core/mode.js
821
+ var require_mode = __commonJS({
822
+ "../../node_modules/qrcode/lib/core/mode.js"(exports) {
823
+ var VersionCheck = require_version_check(), Regex = require_regex();
824
+ exports.NUMERIC = {
825
+ id: "Numeric",
826
+ bit: 1,
827
+ ccBits: [10, 12, 14]
828
+ };
829
+ exports.ALPHANUMERIC = {
830
+ id: "Alphanumeric",
831
+ bit: 2,
832
+ ccBits: [9, 11, 13]
833
+ };
834
+ exports.BYTE = {
835
+ id: "Byte",
836
+ bit: 4,
837
+ ccBits: [8, 16, 16]
838
+ };
839
+ exports.KANJI = {
840
+ id: "Kanji",
841
+ bit: 8,
842
+ ccBits: [8, 10, 12]
843
+ };
844
+ exports.MIXED = {
845
+ bit: -1
846
+ };
847
+ exports.getCharCountIndicator = function(mode, version) {
848
+ if (!mode.ccBits) throw new Error("Invalid mode: " + mode);
849
+ if (!VersionCheck.isValid(version))
850
+ throw new Error("Invalid version: " + version);
851
+ return version >= 1 && version < 10 ? mode.ccBits[0] : version < 27 ? mode.ccBits[1] : mode.ccBits[2];
852
+ };
853
+ exports.getBestModeForData = function(dataStr) {
854
+ return Regex.testNumeric(dataStr) ? exports.NUMERIC : Regex.testAlphanumeric(dataStr) ? exports.ALPHANUMERIC : Regex.testKanji(dataStr) ? exports.KANJI : exports.BYTE;
855
+ };
856
+ exports.toString = function(mode) {
857
+ if (mode && mode.id) return mode.id;
858
+ throw new Error("Invalid mode");
859
+ };
860
+ exports.isValid = function(mode) {
861
+ return mode && mode.bit && mode.ccBits;
862
+ };
863
+ function fromString(string) {
864
+ if (typeof string != "string")
865
+ throw new Error("Param is not a string");
866
+ switch (string.toLowerCase()) {
867
+ case "numeric":
868
+ return exports.NUMERIC;
869
+ case "alphanumeric":
870
+ return exports.ALPHANUMERIC;
871
+ case "kanji":
872
+ return exports.KANJI;
873
+ case "byte":
874
+ return exports.BYTE;
875
+ default:
876
+ throw new Error("Unknown mode: " + string);
877
+ }
878
+ }
879
+ exports.from = function(value, defaultValue) {
880
+ if (exports.isValid(value))
881
+ return value;
882
+ try {
883
+ return fromString(value);
884
+ } catch {
885
+ return defaultValue;
886
+ }
887
+ };
888
+ }
889
+ });
890
+
891
+ // ../../node_modules/qrcode/lib/core/version.js
892
+ var require_version = __commonJS({
893
+ "../../node_modules/qrcode/lib/core/version.js"(exports) {
894
+ var Utils = require_utils(), ECCode = require_error_correction_code(), ECLevel = require_error_correction_level(), Mode = require_mode(), VersionCheck = require_version_check(), G18 = 7973, G18_BCH = Utils.getBCHDigit(G18);
895
+ function getBestVersionForDataLength(mode, length, errorCorrectionLevel) {
896
+ for (let currentVersion = 1; currentVersion <= 40; currentVersion++)
897
+ if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode))
898
+ return currentVersion;
899
+ }
900
+ function getReservedBitsCount(mode, version) {
901
+ return Mode.getCharCountIndicator(mode, version) + 4;
902
+ }
903
+ function getTotalBitsFromDataArray(segments, version) {
904
+ let totalBits = 0;
905
+ return segments.forEach(function(data) {
906
+ let reservedBits = getReservedBitsCount(data.mode, version);
907
+ totalBits += reservedBits + data.getBitsLength();
908
+ }), totalBits;
909
+ }
910
+ function getBestVersionForMixedData(segments, errorCorrectionLevel) {
911
+ for (let currentVersion = 1; currentVersion <= 40; currentVersion++)
912
+ if (getTotalBitsFromDataArray(segments, currentVersion) <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED))
913
+ return currentVersion;
914
+ }
915
+ exports.from = function(value, defaultValue) {
916
+ return VersionCheck.isValid(value) ? parseInt(value, 10) : defaultValue;
917
+ };
918
+ exports.getCapacity = function(version, errorCorrectionLevel, mode) {
919
+ if (!VersionCheck.isValid(version))
920
+ throw new Error("Invalid QR Code version");
921
+ typeof mode > "u" && (mode = Mode.BYTE);
922
+ let totalCodewords = Utils.getSymbolTotalCodewords(version), ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel), dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8;
923
+ if (mode === Mode.MIXED) return dataTotalCodewordsBits;
924
+ let usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version);
925
+ switch (mode) {
926
+ case Mode.NUMERIC:
927
+ return Math.floor(usableBits / 10 * 3);
928
+ case Mode.ALPHANUMERIC:
929
+ return Math.floor(usableBits / 11 * 2);
930
+ case Mode.KANJI:
931
+ return Math.floor(usableBits / 13);
932
+ case Mode.BYTE:
933
+ default:
934
+ return Math.floor(usableBits / 8);
935
+ }
936
+ };
937
+ exports.getBestVersionForData = function(data, errorCorrectionLevel) {
938
+ let seg, ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M);
939
+ if (Array.isArray(data)) {
940
+ if (data.length > 1)
941
+ return getBestVersionForMixedData(data, ecl);
942
+ if (data.length === 0)
943
+ return 1;
944
+ seg = data[0];
945
+ } else
946
+ seg = data;
947
+ return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl);
948
+ };
949
+ exports.getEncodedBits = function(version) {
950
+ if (!VersionCheck.isValid(version) || version < 7)
951
+ throw new Error("Invalid QR Code version");
952
+ let d = version << 12;
953
+ for (; Utils.getBCHDigit(d) - G18_BCH >= 0; )
954
+ d ^= G18 << Utils.getBCHDigit(d) - G18_BCH;
955
+ return version << 12 | d;
956
+ };
957
+ }
958
+ });
959
+
960
+ // ../../node_modules/qrcode/lib/core/format-info.js
961
+ var require_format_info = __commonJS({
962
+ "../../node_modules/qrcode/lib/core/format-info.js"(exports) {
963
+ var Utils = require_utils(), G15 = 1335, G15_MASK = 21522, G15_BCH = Utils.getBCHDigit(G15);
964
+ exports.getEncodedBits = function(errorCorrectionLevel, mask) {
965
+ let data = errorCorrectionLevel.bit << 3 | mask, d = data << 10;
966
+ for (; Utils.getBCHDigit(d) - G15_BCH >= 0; )
967
+ d ^= G15 << Utils.getBCHDigit(d) - G15_BCH;
968
+ return (data << 10 | d) ^ G15_MASK;
969
+ };
970
+ }
971
+ });
972
+
973
+ // ../../node_modules/qrcode/lib/core/numeric-data.js
974
+ var require_numeric_data = __commonJS({
975
+ "../../node_modules/qrcode/lib/core/numeric-data.js"(exports, module) {
976
+ var Mode = require_mode();
977
+ function NumericData(data) {
978
+ this.mode = Mode.NUMERIC, this.data = data.toString();
979
+ }
980
+ NumericData.getBitsLength = function(length) {
981
+ return 10 * Math.floor(length / 3) + (length % 3 ? length % 3 * 3 + 1 : 0);
982
+ };
983
+ NumericData.prototype.getLength = function() {
984
+ return this.data.length;
985
+ };
986
+ NumericData.prototype.getBitsLength = function() {
987
+ return NumericData.getBitsLength(this.data.length);
988
+ };
989
+ NumericData.prototype.write = function(bitBuffer) {
990
+ let i, group, value;
991
+ for (i = 0; i + 3 <= this.data.length; i += 3)
992
+ group = this.data.substr(i, 3), value = parseInt(group, 10), bitBuffer.put(value, 10);
993
+ let remainingNum = this.data.length - i;
994
+ remainingNum > 0 && (group = this.data.substr(i), value = parseInt(group, 10), bitBuffer.put(value, remainingNum * 3 + 1));
995
+ };
996
+ module.exports = NumericData;
997
+ }
998
+ });
999
+
1000
+ // ../../node_modules/qrcode/lib/core/alphanumeric-data.js
1001
+ var require_alphanumeric_data = __commonJS({
1002
+ "../../node_modules/qrcode/lib/core/alphanumeric-data.js"(exports, module) {
1003
+ var Mode = require_mode(), ALPHA_NUM_CHARS = [
1004
+ "0",
1005
+ "1",
1006
+ "2",
1007
+ "3",
1008
+ "4",
1009
+ "5",
1010
+ "6",
1011
+ "7",
1012
+ "8",
1013
+ "9",
1014
+ "A",
1015
+ "B",
1016
+ "C",
1017
+ "D",
1018
+ "E",
1019
+ "F",
1020
+ "G",
1021
+ "H",
1022
+ "I",
1023
+ "J",
1024
+ "K",
1025
+ "L",
1026
+ "M",
1027
+ "N",
1028
+ "O",
1029
+ "P",
1030
+ "Q",
1031
+ "R",
1032
+ "S",
1033
+ "T",
1034
+ "U",
1035
+ "V",
1036
+ "W",
1037
+ "X",
1038
+ "Y",
1039
+ "Z",
1040
+ " ",
1041
+ "$",
1042
+ "%",
1043
+ "*",
1044
+ "+",
1045
+ "-",
1046
+ ".",
1047
+ "/",
1048
+ ":"
1049
+ ];
1050
+ function AlphanumericData(data) {
1051
+ this.mode = Mode.ALPHANUMERIC, this.data = data;
1052
+ }
1053
+ AlphanumericData.getBitsLength = function(length) {
1054
+ return 11 * Math.floor(length / 2) + 6 * (length % 2);
1055
+ };
1056
+ AlphanumericData.prototype.getLength = function() {
1057
+ return this.data.length;
1058
+ };
1059
+ AlphanumericData.prototype.getBitsLength = function() {
1060
+ return AlphanumericData.getBitsLength(this.data.length);
1061
+ };
1062
+ AlphanumericData.prototype.write = function(bitBuffer) {
1063
+ let i;
1064
+ for (i = 0; i + 2 <= this.data.length; i += 2) {
1065
+ let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45;
1066
+ value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1]), bitBuffer.put(value, 11);
1067
+ }
1068
+ this.data.length % 2 && bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6);
1069
+ };
1070
+ module.exports = AlphanumericData;
1071
+ }
1072
+ });
1073
+
1074
+ // ../../node_modules/qrcode/lib/core/byte-data.js
1075
+ var require_byte_data = __commonJS({
1076
+ "../../node_modules/qrcode/lib/core/byte-data.js"(exports, module) {
1077
+ var Mode = require_mode();
1078
+ function ByteData(data) {
1079
+ this.mode = Mode.BYTE, typeof data == "string" ? this.data = new TextEncoder().encode(data) : this.data = new Uint8Array(data);
1080
+ }
1081
+ ByteData.getBitsLength = function(length) {
1082
+ return length * 8;
1083
+ };
1084
+ ByteData.prototype.getLength = function() {
1085
+ return this.data.length;
1086
+ };
1087
+ ByteData.prototype.getBitsLength = function() {
1088
+ return ByteData.getBitsLength(this.data.length);
1089
+ };
1090
+ ByteData.prototype.write = function(bitBuffer) {
1091
+ for (let i = 0, l = this.data.length; i < l; i++)
1092
+ bitBuffer.put(this.data[i], 8);
1093
+ };
1094
+ module.exports = ByteData;
1095
+ }
1096
+ });
1097
+
1098
+ // ../../node_modules/qrcode/lib/core/kanji-data.js
1099
+ var require_kanji_data = __commonJS({
1100
+ "../../node_modules/qrcode/lib/core/kanji-data.js"(exports, module) {
1101
+ var Mode = require_mode(), Utils = require_utils();
1102
+ function KanjiData(data) {
1103
+ this.mode = Mode.KANJI, this.data = data;
1104
+ }
1105
+ KanjiData.getBitsLength = function(length) {
1106
+ return length * 13;
1107
+ };
1108
+ KanjiData.prototype.getLength = function() {
1109
+ return this.data.length;
1110
+ };
1111
+ KanjiData.prototype.getBitsLength = function() {
1112
+ return KanjiData.getBitsLength(this.data.length);
1113
+ };
1114
+ KanjiData.prototype.write = function(bitBuffer) {
1115
+ let i;
1116
+ for (i = 0; i < this.data.length; i++) {
1117
+ let value = Utils.toSJIS(this.data[i]);
1118
+ if (value >= 33088 && value <= 40956)
1119
+ value -= 33088;
1120
+ else if (value >= 57408 && value <= 60351)
1121
+ value -= 49472;
1122
+ else
1123
+ throw new Error(
1124
+ "Invalid SJIS character: " + this.data[i] + `
1125
+ Make sure your charset is UTF-8`
1126
+ );
1127
+ value = (value >>> 8 & 255) * 192 + (value & 255), bitBuffer.put(value, 13);
1128
+ }
1129
+ };
1130
+ module.exports = KanjiData;
1131
+ }
1132
+ });
1133
+
1134
+ // ../../node_modules/dijkstrajs/dijkstra.js
1135
+ var require_dijkstra = __commonJS({
1136
+ "../../node_modules/dijkstrajs/dijkstra.js"(exports, module) {
1137
+ "use strict";
1138
+ var dijkstra = {
1139
+ single_source_shortest_paths: function(graph, s, d) {
1140
+ var predecessors = {}, costs = {};
1141
+ costs[s] = 0;
1142
+ var open = dijkstra.PriorityQueue.make();
1143
+ open.push(s, 0);
1144
+ for (var closest, u, v, cost_of_s_to_u, adjacent_nodes, cost_of_e, cost_of_s_to_u_plus_cost_of_e, cost_of_s_to_v, first_visit; !open.empty(); ) {
1145
+ closest = open.pop(), u = closest.value, cost_of_s_to_u = closest.cost, adjacent_nodes = graph[u] || {};
1146
+ for (v in adjacent_nodes)
1147
+ adjacent_nodes.hasOwnProperty(v) && (cost_of_e = adjacent_nodes[v], cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e, cost_of_s_to_v = costs[v], first_visit = typeof costs[v] > "u", (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) && (costs[v] = cost_of_s_to_u_plus_cost_of_e, open.push(v, cost_of_s_to_u_plus_cost_of_e), predecessors[v] = u));
1148
+ }
1149
+ if (typeof d < "u" && typeof costs[d] > "u") {
1150
+ var msg = ["Could not find a path from ", s, " to ", d, "."].join("");
1151
+ throw new Error(msg);
1152
+ }
1153
+ return predecessors;
1154
+ },
1155
+ extract_shortest_path_from_predecessor_list: function(predecessors, d) {
1156
+ for (var nodes = [], u = d, predecessor; u; )
1157
+ nodes.push(u), predecessor = predecessors[u], u = predecessors[u];
1158
+ return nodes.reverse(), nodes;
1159
+ },
1160
+ find_path: function(graph, s, d) {
1161
+ var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);
1162
+ return dijkstra.extract_shortest_path_from_predecessor_list(
1163
+ predecessors,
1164
+ d
1165
+ );
1166
+ },
1167
+ /**
1168
+ * A very naive priority queue implementation.
1169
+ */
1170
+ PriorityQueue: {
1171
+ make: function(opts) {
1172
+ var T = dijkstra.PriorityQueue, t = {}, key;
1173
+ opts = opts || {};
1174
+ for (key in T)
1175
+ T.hasOwnProperty(key) && (t[key] = T[key]);
1176
+ return t.queue = [], t.sorter = opts.sorter || T.default_sorter, t;
1177
+ },
1178
+ default_sorter: function(a, b) {
1179
+ return a.cost - b.cost;
1180
+ },
1181
+ /**
1182
+ * Add a new item to the queue and ensure the highest priority element
1183
+ * is at the front of the queue.
1184
+ */
1185
+ push: function(value, cost) {
1186
+ var item = { value, cost };
1187
+ this.queue.push(item), this.queue.sort(this.sorter);
1188
+ },
1189
+ /**
1190
+ * Return the highest priority element in the queue.
1191
+ */
1192
+ pop: function() {
1193
+ return this.queue.shift();
1194
+ },
1195
+ empty: function() {
1196
+ return this.queue.length === 0;
1197
+ }
1198
+ }
1199
+ };
1200
+ typeof module < "u" && (module.exports = dijkstra);
1201
+ }
1202
+ });
1203
+
1204
+ // ../../node_modules/qrcode/lib/core/segments.js
1205
+ var require_segments = __commonJS({
1206
+ "../../node_modules/qrcode/lib/core/segments.js"(exports) {
1207
+ var Mode = require_mode(), NumericData = require_numeric_data(), AlphanumericData = require_alphanumeric_data(), ByteData = require_byte_data(), KanjiData = require_kanji_data(), Regex = require_regex(), Utils = require_utils(), dijkstra = require_dijkstra();
1208
+ function getStringByteLength(str) {
1209
+ return unescape(encodeURIComponent(str)).length;
1210
+ }
1211
+ function getSegments(regex, mode, str) {
1212
+ let segments = [], result;
1213
+ for (; (result = regex.exec(str)) !== null; )
1214
+ segments.push({
1215
+ data: result[0],
1216
+ index: result.index,
1217
+ mode,
1218
+ length: result[0].length
1219
+ });
1220
+ return segments;
1221
+ }
1222
+ function getSegmentsFromString(dataStr) {
1223
+ let numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr), alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr), byteSegs, kanjiSegs;
1224
+ return Utils.isKanjiModeEnabled() ? (byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr), kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr)) : (byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr), kanjiSegs = []), numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs).sort(function(s1, s2) {
1225
+ return s1.index - s2.index;
1226
+ }).map(function(obj) {
1227
+ return {
1228
+ data: obj.data,
1229
+ mode: obj.mode,
1230
+ length: obj.length
1231
+ };
1232
+ });
1233
+ }
1234
+ function getSegmentBitsLength(length, mode) {
1235
+ switch (mode) {
1236
+ case Mode.NUMERIC:
1237
+ return NumericData.getBitsLength(length);
1238
+ case Mode.ALPHANUMERIC:
1239
+ return AlphanumericData.getBitsLength(length);
1240
+ case Mode.KANJI:
1241
+ return KanjiData.getBitsLength(length);
1242
+ case Mode.BYTE:
1243
+ return ByteData.getBitsLength(length);
1244
+ }
1245
+ }
1246
+ function mergeSegments(segs) {
1247
+ return segs.reduce(function(acc, curr) {
1248
+ let prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null;
1249
+ return prevSeg && prevSeg.mode === curr.mode ? (acc[acc.length - 1].data += curr.data, acc) : (acc.push(curr), acc);
1250
+ }, []);
1251
+ }
1252
+ function buildNodes(segs) {
1253
+ let nodes = [];
1254
+ for (let i = 0; i < segs.length; i++) {
1255
+ let seg = segs[i];
1256
+ switch (seg.mode) {
1257
+ case Mode.NUMERIC:
1258
+ nodes.push([
1259
+ seg,
1260
+ { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },
1261
+ { data: seg.data, mode: Mode.BYTE, length: seg.length }
1262
+ ]);
1263
+ break;
1264
+ case Mode.ALPHANUMERIC:
1265
+ nodes.push([
1266
+ seg,
1267
+ { data: seg.data, mode: Mode.BYTE, length: seg.length }
1268
+ ]);
1269
+ break;
1270
+ case Mode.KANJI:
1271
+ nodes.push([
1272
+ seg,
1273
+ { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
1274
+ ]);
1275
+ break;
1276
+ case Mode.BYTE:
1277
+ nodes.push([
1278
+ { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
1279
+ ]);
1280
+ }
1281
+ }
1282
+ return nodes;
1283
+ }
1284
+ function buildGraph(nodes, version) {
1285
+ let table = {}, graph = { start: {} }, prevNodeIds = ["start"];
1286
+ for (let i = 0; i < nodes.length; i++) {
1287
+ let nodeGroup = nodes[i], currentNodeIds = [];
1288
+ for (let j = 0; j < nodeGroup.length; j++) {
1289
+ let node = nodeGroup[j], key = "" + i + j;
1290
+ currentNodeIds.push(key), table[key] = { node, lastCount: 0 }, graph[key] = {};
1291
+ for (let n = 0; n < prevNodeIds.length; n++) {
1292
+ let prevNodeId = prevNodeIds[n];
1293
+ table[prevNodeId] && table[prevNodeId].node.mode === node.mode ? (graph[prevNodeId][key] = getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) - getSegmentBitsLength(table[prevNodeId].lastCount, node.mode), table[prevNodeId].lastCount += node.length) : (table[prevNodeId] && (table[prevNodeId].lastCount = node.length), graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) + 4 + Mode.getCharCountIndicator(node.mode, version));
1294
+ }
1295
+ }
1296
+ prevNodeIds = currentNodeIds;
1297
+ }
1298
+ for (let n = 0; n < prevNodeIds.length; n++)
1299
+ graph[prevNodeIds[n]].end = 0;
1300
+ return { map: graph, table };
1301
+ }
1302
+ function buildSingleSegment(data, modesHint) {
1303
+ let mode, bestMode = Mode.getBestModeForData(data);
1304
+ if (mode = Mode.from(modesHint, bestMode), mode !== Mode.BYTE && mode.bit < bestMode.bit)
1305
+ throw new Error('"' + data + '" cannot be encoded with mode ' + Mode.toString(mode) + `.
1306
+ Suggested mode is: ` + Mode.toString(bestMode));
1307
+ switch (mode === Mode.KANJI && !Utils.isKanjiModeEnabled() && (mode = Mode.BYTE), mode) {
1308
+ case Mode.NUMERIC:
1309
+ return new NumericData(data);
1310
+ case Mode.ALPHANUMERIC:
1311
+ return new AlphanumericData(data);
1312
+ case Mode.KANJI:
1313
+ return new KanjiData(data);
1314
+ case Mode.BYTE:
1315
+ return new ByteData(data);
1316
+ }
1317
+ }
1318
+ exports.fromArray = function(array) {
1319
+ return array.reduce(function(acc, seg) {
1320
+ return typeof seg == "string" ? acc.push(buildSingleSegment(seg, null)) : seg.data && acc.push(buildSingleSegment(seg.data, seg.mode)), acc;
1321
+ }, []);
1322
+ };
1323
+ exports.fromString = function(data, version) {
1324
+ let segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled()), nodes = buildNodes(segs), graph = buildGraph(nodes, version), path = dijkstra.find_path(graph.map, "start", "end"), optimizedSegs = [];
1325
+ for (let i = 1; i < path.length - 1; i++)
1326
+ optimizedSegs.push(graph.table[path[i]].node);
1327
+ return exports.fromArray(mergeSegments(optimizedSegs));
1328
+ };
1329
+ exports.rawSplit = function(data) {
1330
+ return exports.fromArray(
1331
+ getSegmentsFromString(data, Utils.isKanjiModeEnabled())
1332
+ );
1333
+ };
1334
+ }
1335
+ });
1336
+
1337
+ // ../../node_modules/qrcode/lib/core/qrcode.js
1338
+ var require_qrcode = __commonJS({
1339
+ "../../node_modules/qrcode/lib/core/qrcode.js"(exports) {
1340
+ var Utils = require_utils(), ECLevel = require_error_correction_level(), BitBuffer = require_bit_buffer(), BitMatrix = require_bit_matrix(), AlignmentPattern = require_alignment_pattern(), FinderPattern = require_finder_pattern(), MaskPattern = require_mask_pattern(), ECCode = require_error_correction_code(), ReedSolomonEncoder = require_reed_solomon_encoder(), Version = require_version(), FormatInfo = require_format_info(), Mode = require_mode(), Segments = require_segments();
1341
+ function setupFinderPattern(matrix, version) {
1342
+ let size = matrix.size, pos = FinderPattern.getPositions(version);
1343
+ for (let i = 0; i < pos.length; i++) {
1344
+ let row = pos[i][0], col = pos[i][1];
1345
+ for (let r = -1; r <= 7; r++)
1346
+ if (!(row + r <= -1 || size <= row + r))
1347
+ for (let c = -1; c <= 7; c++)
1348
+ col + c <= -1 || size <= col + c || (r >= 0 && r <= 6 && (c === 0 || c === 6) || c >= 0 && c <= 6 && (r === 0 || r === 6) || r >= 2 && r <= 4 && c >= 2 && c <= 4 ? matrix.set(row + r, col + c, !0, !0) : matrix.set(row + r, col + c, !1, !0));
1349
+ }
1350
+ }
1351
+ function setupTimingPattern(matrix) {
1352
+ let size = matrix.size;
1353
+ for (let r = 8; r < size - 8; r++) {
1354
+ let value = r % 2 === 0;
1355
+ matrix.set(r, 6, value, !0), matrix.set(6, r, value, !0);
1356
+ }
1357
+ }
1358
+ function setupAlignmentPattern(matrix, version) {
1359
+ let pos = AlignmentPattern.getPositions(version);
1360
+ for (let i = 0; i < pos.length; i++) {
1361
+ let row = pos[i][0], col = pos[i][1];
1362
+ for (let r = -2; r <= 2; r++)
1363
+ for (let c = -2; c <= 2; c++)
1364
+ r === -2 || r === 2 || c === -2 || c === 2 || r === 0 && c === 0 ? matrix.set(row + r, col + c, !0, !0) : matrix.set(row + r, col + c, !1, !0);
1365
+ }
1366
+ }
1367
+ function setupVersionInfo(matrix, version) {
1368
+ let size = matrix.size, bits = Version.getEncodedBits(version), row, col, mod;
1369
+ for (let i = 0; i < 18; i++)
1370
+ row = Math.floor(i / 3), col = i % 3 + size - 8 - 3, mod = (bits >> i & 1) === 1, matrix.set(row, col, mod, !0), matrix.set(col, row, mod, !0);
1371
+ }
1372
+ function setupFormatInfo(matrix, errorCorrectionLevel, maskPattern) {
1373
+ let size = matrix.size, bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern), i, mod;
1374
+ for (i = 0; i < 15; i++)
1375
+ mod = (bits >> i & 1) === 1, i < 6 ? matrix.set(i, 8, mod, !0) : i < 8 ? matrix.set(i + 1, 8, mod, !0) : matrix.set(size - 15 + i, 8, mod, !0), i < 8 ? matrix.set(8, size - i - 1, mod, !0) : i < 9 ? matrix.set(8, 15 - i - 1 + 1, mod, !0) : matrix.set(8, 15 - i - 1, mod, !0);
1376
+ matrix.set(size - 8, 8, 1, !0);
1377
+ }
1378
+ function setupData(matrix, data) {
1379
+ let size = matrix.size, inc = -1, row = size - 1, bitIndex = 7, byteIndex = 0;
1380
+ for (let col = size - 1; col > 0; col -= 2)
1381
+ for (col === 6 && col--; ; ) {
1382
+ for (let c = 0; c < 2; c++)
1383
+ if (!matrix.isReserved(row, col - c)) {
1384
+ let dark = !1;
1385
+ byteIndex < data.length && (dark = (data[byteIndex] >>> bitIndex & 1) === 1), matrix.set(row, col - c, dark), bitIndex--, bitIndex === -1 && (byteIndex++, bitIndex = 7);
1386
+ }
1387
+ if (row += inc, row < 0 || size <= row) {
1388
+ row -= inc, inc = -inc;
1389
+ break;
1390
+ }
1391
+ }
1392
+ }
1393
+ function createData(version, errorCorrectionLevel, segments) {
1394
+ let buffer = new BitBuffer();
1395
+ segments.forEach(function(data) {
1396
+ buffer.put(data.mode.bit, 4), buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version)), data.write(buffer);
1397
+ });
1398
+ let totalCodewords = Utils.getSymbolTotalCodewords(version), ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel), dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8;
1399
+ for (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits && buffer.put(0, 4); buffer.getLengthInBits() % 8 !== 0; )
1400
+ buffer.putBit(0);
1401
+ let remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8;
1402
+ for (let i = 0; i < remainingByte; i++)
1403
+ buffer.put(i % 2 ? 17 : 236, 8);
1404
+ return createCodewords(buffer, version, errorCorrectionLevel);
1405
+ }
1406
+ function createCodewords(bitBuffer, version, errorCorrectionLevel) {
1407
+ let totalCodewords = Utils.getSymbolTotalCodewords(version), ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel), dataTotalCodewords = totalCodewords - ecTotalCodewords, ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel), blocksInGroup2 = totalCodewords % ecTotalBlocks, blocksInGroup1 = ecTotalBlocks - blocksInGroup2, totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks), dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks), dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1, ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1, rs = new ReedSolomonEncoder(ecCount), offset = 0, dcData = new Array(ecTotalBlocks), ecData = new Array(ecTotalBlocks), maxDataSize = 0, buffer = new Uint8Array(bitBuffer.buffer);
1408
+ for (let b = 0; b < ecTotalBlocks; b++) {
1409
+ let dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2;
1410
+ dcData[b] = buffer.slice(offset, offset + dataSize), ecData[b] = rs.encode(dcData[b]), offset += dataSize, maxDataSize = Math.max(maxDataSize, dataSize);
1411
+ }
1412
+ let data = new Uint8Array(totalCodewords), index = 0, i, r;
1413
+ for (i = 0; i < maxDataSize; i++)
1414
+ for (r = 0; r < ecTotalBlocks; r++)
1415
+ i < dcData[r].length && (data[index++] = dcData[r][i]);
1416
+ for (i = 0; i < ecCount; i++)
1417
+ for (r = 0; r < ecTotalBlocks; r++)
1418
+ data[index++] = ecData[r][i];
1419
+ return data;
1420
+ }
1421
+ function createSymbol(data, version, errorCorrectionLevel, maskPattern) {
1422
+ let segments;
1423
+ if (Array.isArray(data))
1424
+ segments = Segments.fromArray(data);
1425
+ else if (typeof data == "string") {
1426
+ let estimatedVersion = version;
1427
+ if (!estimatedVersion) {
1428
+ let rawSegments = Segments.rawSplit(data);
1429
+ estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel);
1430
+ }
1431
+ segments = Segments.fromString(data, estimatedVersion || 40);
1432
+ } else
1433
+ throw new Error("Invalid data");
1434
+ let bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel);
1435
+ if (!bestVersion)
1436
+ throw new Error("The amount of data is too big to be stored in a QR Code");
1437
+ if (!version)
1438
+ version = bestVersion;
1439
+ else if (version < bestVersion)
1440
+ throw new Error(
1441
+ `
1442
+ The chosen QR Code version cannot contain this amount of data.
1443
+ Minimum version required to store current data is: ` + bestVersion + `.
1444
+ `
1445
+ );
1446
+ let dataBits = createData(version, errorCorrectionLevel, segments), moduleCount = Utils.getSymbolSize(version), modules = new BitMatrix(moduleCount);
1447
+ return setupFinderPattern(modules, version), setupTimingPattern(modules), setupAlignmentPattern(modules, version), setupFormatInfo(modules, errorCorrectionLevel, 0), version >= 7 && setupVersionInfo(modules, version), setupData(modules, dataBits), isNaN(maskPattern) && (maskPattern = MaskPattern.getBestMask(
1448
+ modules,
1449
+ setupFormatInfo.bind(null, modules, errorCorrectionLevel)
1450
+ )), MaskPattern.applyMask(maskPattern, modules), setupFormatInfo(modules, errorCorrectionLevel, maskPattern), {
1451
+ modules,
1452
+ version,
1453
+ errorCorrectionLevel,
1454
+ maskPattern,
1455
+ segments
1456
+ };
1457
+ }
1458
+ exports.create = function(data, options) {
1459
+ if (typeof data > "u" || data === "")
1460
+ throw new Error("No input text");
1461
+ let errorCorrectionLevel = ECLevel.M, version, mask;
1462
+ return typeof options < "u" && (errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M), version = Version.from(options.version), mask = MaskPattern.from(options.maskPattern), options.toSJISFunc && Utils.setToSJISFunction(options.toSJISFunc)), createSymbol(data, version, errorCorrectionLevel, mask);
1463
+ };
1464
+ }
1465
+ });
1466
+
1467
+ // ../../node_modules/qrcode/lib/renderer/utils.js
1468
+ var require_utils2 = __commonJS({
1469
+ "../../node_modules/qrcode/lib/renderer/utils.js"(exports) {
1470
+ function hex2rgba(hex) {
1471
+ if (typeof hex == "number" && (hex = hex.toString()), typeof hex != "string")
1472
+ throw new Error("Color should be defined as hex string");
1473
+ let hexCode = hex.slice().replace("#", "").split("");
1474
+ if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8)
1475
+ throw new Error("Invalid hex color: " + hex);
1476
+ (hexCode.length === 3 || hexCode.length === 4) && (hexCode = Array.prototype.concat.apply([], hexCode.map(function(c) {
1477
+ return [c, c];
1478
+ }))), hexCode.length === 6 && hexCode.push("F", "F");
1479
+ let hexValue = parseInt(hexCode.join(""), 16);
1480
+ return {
1481
+ r: hexValue >> 24 & 255,
1482
+ g: hexValue >> 16 & 255,
1483
+ b: hexValue >> 8 & 255,
1484
+ a: hexValue & 255,
1485
+ hex: "#" + hexCode.slice(0, 6).join("")
1486
+ };
1487
+ }
1488
+ exports.getOptions = function(options) {
1489
+ options || (options = {}), options.color || (options.color = {});
1490
+ let margin = typeof options.margin > "u" || options.margin === null || options.margin < 0 ? 4 : options.margin, width = options.width && options.width >= 21 ? options.width : void 0, scale = options.scale || 4;
1491
+ return {
1492
+ width,
1493
+ scale: width ? 4 : scale,
1494
+ margin,
1495
+ color: {
1496
+ dark: hex2rgba(options.color.dark || "#000000ff"),
1497
+ light: hex2rgba(options.color.light || "#ffffffff")
1498
+ },
1499
+ type: options.type,
1500
+ rendererOpts: options.rendererOpts || {}
1501
+ };
1502
+ };
1503
+ exports.getScale = function(qrSize, opts) {
1504
+ return opts.width && opts.width >= qrSize + opts.margin * 2 ? opts.width / (qrSize + opts.margin * 2) : opts.scale;
1505
+ };
1506
+ exports.getImageWidth = function(qrSize, opts) {
1507
+ let scale = exports.getScale(qrSize, opts);
1508
+ return Math.floor((qrSize + opts.margin * 2) * scale);
1509
+ };
1510
+ exports.qrToImageData = function(imgData, qr, opts) {
1511
+ let size = qr.modules.size, data = qr.modules.data, scale = exports.getScale(size, opts), symbolSize = Math.floor((size + opts.margin * 2) * scale), scaledMargin = opts.margin * scale, palette = [opts.color.light, opts.color.dark];
1512
+ for (let i = 0; i < symbolSize; i++)
1513
+ for (let j = 0; j < symbolSize; j++) {
1514
+ let posDst = (i * symbolSize + j) * 4, pxColor = opts.color.light;
1515
+ if (i >= scaledMargin && j >= scaledMargin && i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {
1516
+ let iSrc = Math.floor((i - scaledMargin) / scale), jSrc = Math.floor((j - scaledMargin) / scale);
1517
+ pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0];
1518
+ }
1519
+ imgData[posDst++] = pxColor.r, imgData[posDst++] = pxColor.g, imgData[posDst++] = pxColor.b, imgData[posDst] = pxColor.a;
1520
+ }
1521
+ };
1522
+ }
1523
+ });
1524
+
1525
+ // ../../node_modules/qrcode/lib/renderer/canvas.js
1526
+ var require_canvas = __commonJS({
1527
+ "../../node_modules/qrcode/lib/renderer/canvas.js"(exports) {
1528
+ var Utils = require_utils2();
1529
+ function clearCanvas(ctx, canvas, size) {
1530
+ ctx.clearRect(0, 0, canvas.width, canvas.height), canvas.style || (canvas.style = {}), canvas.height = size, canvas.width = size, canvas.style.height = size + "px", canvas.style.width = size + "px";
1531
+ }
1532
+ function getCanvasElement() {
1533
+ try {
1534
+ return document.createElement("canvas");
1535
+ } catch {
1536
+ throw new Error("You need to specify a canvas element");
1537
+ }
1538
+ }
1539
+ exports.render = function(qrData, canvas, options) {
1540
+ let opts = options, canvasEl = canvas;
1541
+ typeof opts > "u" && (!canvas || !canvas.getContext) && (opts = canvas, canvas = void 0), canvas || (canvasEl = getCanvasElement()), opts = Utils.getOptions(opts);
1542
+ let size = Utils.getImageWidth(qrData.modules.size, opts), ctx = canvasEl.getContext("2d"), image = ctx.createImageData(size, size);
1543
+ return Utils.qrToImageData(image.data, qrData, opts), clearCanvas(ctx, canvasEl, size), ctx.putImageData(image, 0, 0), canvasEl;
1544
+ };
1545
+ exports.renderToDataURL = function(qrData, canvas, options) {
1546
+ let opts = options;
1547
+ typeof opts > "u" && (!canvas || !canvas.getContext) && (opts = canvas, canvas = void 0), opts || (opts = {});
1548
+ let canvasEl = exports.render(qrData, canvas, opts), type = opts.type || "image/png", rendererOpts = opts.rendererOpts || {};
1549
+ return canvasEl.toDataURL(type, rendererOpts.quality);
1550
+ };
1551
+ }
1552
+ });
1553
+
1554
+ // ../../node_modules/qrcode/lib/renderer/svg-tag.js
1555
+ var require_svg_tag = __commonJS({
1556
+ "../../node_modules/qrcode/lib/renderer/svg-tag.js"(exports) {
1557
+ var Utils = require_utils2();
1558
+ function getColorAttrib(color, attrib) {
1559
+ let alpha = color.a / 255, str = attrib + '="' + color.hex + '"';
1560
+ return alpha < 1 ? str + " " + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"' : str;
1561
+ }
1562
+ function svgCmd(cmd, x, y) {
1563
+ let str = cmd + x;
1564
+ return typeof y < "u" && (str += " " + y), str;
1565
+ }
1566
+ function qrToPath(data, size, margin) {
1567
+ let path = "", moveBy = 0, newRow = !1, lineLength = 0;
1568
+ for (let i = 0; i < data.length; i++) {
1569
+ let col = Math.floor(i % size), row = Math.floor(i / size);
1570
+ !col && !newRow && (newRow = !0), data[i] ? (lineLength++, i > 0 && col > 0 && data[i - 1] || (path += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0), moveBy = 0, newRow = !1), col + 1 < size && data[i + 1] || (path += svgCmd("h", lineLength), lineLength = 0)) : moveBy++;
1571
+ }
1572
+ return path;
1573
+ }
1574
+ exports.render = function(qrData, options, cb) {
1575
+ let opts = Utils.getOptions(options), size = qrData.modules.size, data = qrData.modules.data, qrcodesize = size + opts.margin * 2, bg = opts.color.light.a ? "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>' : "", path = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>', viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"', svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + (opts.width ? 'width="' + opts.width + '" height="' + opts.width + '" ' : "") + viewBox + ' shape-rendering="crispEdges">' + bg + path + `</svg>
1576
+ `;
1577
+ return typeof cb == "function" && cb(null, svgTag), svgTag;
1578
+ };
1579
+ }
1580
+ });
1581
+
1582
+ // ../../node_modules/qrcode/lib/browser.js
1583
+ var require_browser = __commonJS({
1584
+ "../../node_modules/qrcode/lib/browser.js"(exports) {
1585
+ var canPromise = require_can_promise(), QRCode2 = require_qrcode(), CanvasRenderer = require_canvas(), SvgRenderer = require_svg_tag();
1586
+ function renderCanvas(renderFunc, canvas, text, opts, cb) {
1587
+ let args = [].slice.call(arguments, 1), argsNum = args.length, isLastArgCb = typeof args[argsNum - 1] == "function";
1588
+ if (!isLastArgCb && !canPromise())
1589
+ throw new Error("Callback required as last argument");
1590
+ if (isLastArgCb) {
1591
+ if (argsNum < 2)
1592
+ throw new Error("Too few arguments provided");
1593
+ argsNum === 2 ? (cb = text, text = canvas, canvas = opts = void 0) : argsNum === 3 && (canvas.getContext && typeof cb > "u" ? (cb = opts, opts = void 0) : (cb = opts, opts = text, text = canvas, canvas = void 0));
1594
+ } else {
1595
+ if (argsNum < 1)
1596
+ throw new Error("Too few arguments provided");
1597
+ return argsNum === 1 ? (text = canvas, canvas = opts = void 0) : argsNum === 2 && !canvas.getContext && (opts = text, text = canvas, canvas = void 0), new Promise(function(resolve, reject) {
1598
+ try {
1599
+ let data = QRCode2.create(text, opts);
1600
+ resolve(renderFunc(data, canvas, opts));
1601
+ } catch (e) {
1602
+ reject(e);
1603
+ }
1604
+ });
1605
+ }
1606
+ try {
1607
+ let data = QRCode2.create(text, opts);
1608
+ cb(null, renderFunc(data, canvas, opts));
1609
+ } catch (e) {
1610
+ cb(e);
1611
+ }
1612
+ }
1613
+ exports.create = QRCode2.create;
1614
+ exports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render);
1615
+ exports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL);
1616
+ exports.toString = renderCanvas.bind(null, function(data, _, opts) {
1617
+ return SvgRenderer.render(data, opts);
1618
+ });
1619
+ }
1620
+ });
1621
+
1622
+ // src/client.ts
1623
+ var import_qrcode = __toESM(require_browser(), 1);
1624
+
1625
+ // src/remote-file-content-provider.ts
1626
+ function shouldUseRemoteFileViewer(status) {
1627
+ return status.mode === "remote" && status.remoteFeatures?.fileViewer === !0;
1628
+ }
1629
+ var REMOTE_FILE_SAVE_AS_MAX_BYTES = 100 * 1024 * 1024, REMOTE_FILE_FAST_SAVE_AS_MAX_BYTES = 1024 * 1024 * 1024;
1630
+ function shouldAllowRemoteFileSaveAs(status) {
1631
+ return shouldUseRemoteFileViewer(status) && (status.transport === "LAN" || status.transport === "P2P" || status.transport === "TURN");
1632
+ }
1633
+ function remoteFileSaveAsMaxBytes(status) {
1634
+ return status.transport === "LAN" || status.transport === "P2P" ? REMOTE_FILE_FAST_SAVE_AS_MAX_BYTES : REMOTE_FILE_SAVE_AS_MAX_BYTES;
1635
+ }
1636
+ function createRemoteFileContentProvider(call, options = {}) {
1637
+ return {
1638
+ id: "dsh-remote-files",
1639
+ priority: 1e4,
1640
+ supports: () => !0,
1641
+ saveAsAllowed: () => ({
1642
+ allowed: currentSaveAsAllowed(options.saveAsAllowed),
1643
+ maxBytes: currentSaveAsMaxBytes(options.saveAsMaxBytes)
1644
+ }),
1645
+ async stat(locator, signal) {
1646
+ let value = await call("fileviewer.stat", { path: locator }, signal);
1647
+ if (value.exists)
1648
+ return {
1649
+ name: value.name,
1650
+ size: value.isDirectory ? 0 : value.size,
1651
+ mime: value.mime,
1652
+ mtimeMs: value.mtimeMs,
1653
+ isDirectory: value.isDirectory
1654
+ };
1655
+ },
1656
+ async read(locator, request) {
1657
+ if (!Number.isInteger(request.offset) || request.offset < 0) throw new Error("A non-negative integer offset is required.");
1658
+ if (!Number.isInteger(request.length) || request.length <= 0) throw new Error("A positive integer length is required.");
1659
+ let chunks = [], received = 0;
1660
+ for (; received < request.length; ) {
1661
+ request.signal.throwIfAborted();
1662
+ let length = Math.min(524288, request.length - received), offset = request.offset + received, range = await call("fileviewer.readRange", { path: locator, offset, length }, request.signal);
1663
+ if (range.offset !== offset) throw new Error("The Remote Host returned a mismatched file range.");
1664
+ let bytes = decodeBase64(range.data);
1665
+ if (bytes.byteLength > length) throw new Error("The Remote Host returned more file bytes than requested.");
1666
+ if (chunks.push(bytes), received += bytes.byteLength, range.eof || bytes.byteLength === 0) break;
1667
+ }
1668
+ let merged = new Uint8Array(received), cursor = 0;
1669
+ for (let chunk of chunks)
1670
+ merged.set(chunk, cursor), cursor += chunk.byteLength;
1671
+ return merged;
1672
+ },
1673
+ async list(locator, signal) {
1674
+ return (await call("fileviewer.list", { path: locator }, signal)).entries.map((entry) => ({
1675
+ locator: entry.path,
1676
+ name: entry.name,
1677
+ size: entry.isDirectory ? 0 : entry.size ?? 0,
1678
+ mtimeMs: entry.mtimeMs,
1679
+ isDirectory: entry.isDirectory
1680
+ }));
1681
+ }
1682
+ };
1683
+ }
1684
+ function currentSaveAsAllowed(value) {
1685
+ return typeof value == "function" ? value() : value === !0;
1686
+ }
1687
+ function currentSaveAsMaxBytes(value) {
1688
+ return typeof value == "function" ? value() : value ?? REMOTE_FILE_SAVE_AS_MAX_BYTES;
1689
+ }
1690
+ function decodeBase64(value) {
1691
+ let binary = atob(value), bytes = new Uint8Array(binary.length);
1692
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
1693
+ return bytes;
1694
+ }
1695
+
1696
+ // src/control-route.ts
1697
+ var CONTROL_RPC_PREFIX = "/ds-harness-remote", STATUS_STREAM_ENDPOINT = "status.events", STATUS_STREAM_PATH = `${CONTROL_RPC_PREFIX}/${STATUS_STREAM_ENDPOINT}`;
1698
+
1699
+ // src/status-stream.ts
1700
+ function parseStatus(data) {
1701
+ if (typeof data == "string")
1702
+ try {
1703
+ let parsed = JSON.parse(data);
1704
+ return parsed === null || typeof parsed != "object" ? void 0 : parsed;
1705
+ } catch {
1706
+ return;
1707
+ }
1708
+ }
1709
+ function createStatusFeed(options) {
1710
+ let listeners = /* @__PURE__ */ new Set(), pollIntervalMs = options.pollIntervalMs ?? 1500, openTimeoutMs = options.openTimeoutMs ?? 4e3, createSource = options.createSource ?? ((url) => new EventSource(url)), status, source, openTimer, pollTimer, publish = (next) => {
1711
+ status = next;
1712
+ for (let listener of [...listeners]) listener(next);
1713
+ }, teardown = () => {
1714
+ openTimer !== void 0 && (clearTimeout(openTimer), openTimer = void 0), pollTimer !== void 0 && (clearInterval(pollTimer), pollTimer = void 0), source?.close(), source = void 0;
1715
+ }, poll = () => {
1716
+ options.readStatus().then((next) => {
1717
+ pollTimer !== void 0 && publish(next);
1718
+ }).catch(() => {
1719
+ });
1720
+ }, fallbackToPolling = (reason) => {
1721
+ pollTimer !== void 0 || listeners.size === 0 || (openTimer !== void 0 && (clearTimeout(openTimer), openTimer = void 0), source?.close(), source = void 0, options.onFallback?.(reason), poll(), pollTimer = setInterval(poll, pollIntervalMs));
1722
+ }, openStream = () => {
1723
+ let opened;
1724
+ try {
1725
+ opened = createSource(options.url);
1726
+ } catch {
1727
+ fallbackToPolling("unsupported");
1728
+ return;
1729
+ }
1730
+ source = opened;
1731
+ let received = !1;
1732
+ openTimer = setTimeout(() => {
1733
+ received || fallbackToPolling("silent");
1734
+ }, openTimeoutMs), opened.onmessage = (event) => {
1735
+ received = !0, openTimer !== void 0 && (clearTimeout(openTimer), openTimer = void 0);
1736
+ let next = parseStatus(event.data);
1737
+ next !== void 0 && publish(next);
1738
+ }, opened.onerror = () => {
1739
+ opened.readyState === 2 && fallbackToPolling("unavailable");
1740
+ };
1741
+ };
1742
+ return {
1743
+ getSnapshot: () => status,
1744
+ subscribe: (listener) => (listeners.add(listener), status !== void 0 && listener(status), listeners.size === 1 && openStream(), () => {
1745
+ listeners.delete(listener), listeners.size === 0 && teardown();
1746
+ }),
1747
+ close: () => {
1748
+ listeners.clear(), teardown();
1749
+ }
1750
+ };
1751
+ }
1752
+
1753
+ // src/defaults.ts
1754
+ var DEFAULT_REMOTE_SERVER_URL = "https://sakakibara.ink:8443";
1755
+
1756
+ // src/client.ts
1757
+ var clientModuleId = "@blue-soda/dsh-remote", pendingWorkspaceSelectionKey = "dsh-remote:pending-workspace-selection", deepSeekWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAACVBMVEUAAADy8vXx8fUsA3vyAAAAAXRSTlMAQObYZgAAAOxJREFUWMPtlsEOwyAMQxP+/6OnTZMGxHGcot3wDYgfhkJbs6urprzveGtu9d1NgEdto8w93GuA7zPS2RFg7ynsCOAokbtAmLr2YaeKgJ6fxpT8jCAC0qSqPyNoO5DXdvyouj4ClFAdYaDxK09uiBDCIYBf6CxLesnR0uF2pG+JmhCqrUb0AOvjjoQaYDTCEAAgMg5grhAeAQIB+/M15IcKlnUIp4CkTCd0AKb4zVsRSJVGYEVzT0agK107IMGMEurvromEpaX4wzk/IKw378kq4LafED6Oowxfk7AP2q8W16EdM3p29Eyvrv6vF0WIBfBziKyCAAAAAElFTkSuQmCC", gptWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAclBMVEX////v7+++wMf////s7O3k5OTExcrX2Ny6vMTv8PPW19yXmqRqboJmaHd3eoaqrLPs7fGMjpfb3eKlpq1eYXOxs7pWWWd+gY5HSVdRVGVub3k+QU74+Pg4OkcvMT1ISlUoKjUiIy4fICueoKkaGyUSFB21Bp+qAAAAAXRSTlMAQObYZgAABChJREFUWMPtl916qjoQhlsdEwIECEgMYCBxx/u/xT1DrFUL1LO1DtY8LSLJvPnmB4gfH//sr7TPDfvdebf/xXZbkE/4zZ0MVhGHd9zJDsv+7F3//Z69tT5wljAu3tXw+TIlzXKJlhflYmJ+5uF5WpWhb54X+C/zZCmT2wJA4dJZwus0UYjIGqWyMhVbEp4yKNRRqlv0opW5PJLJ4rFJXvP4JKDRMqturBZjkMVJFYjR6iHQDQDI4+k2k51wZbWrqwp4mR/1CVYATyko9TFGxBUqL5IvMbXSWt0T8bkGgFLqgqZBI/Uxbx5UAxLaNcCNLBpttM7wbCc1pmJOpWAsDtey68UaQMyrFgb9uxLPjqg3+nGluyKN0XUdWw0BJ0NvTFFqgzpr9J+Dh4w0Ga1qkqBNswagxdRgFPAbgHRQG5jumGWyMxrTIaRRa4AzFs0YrNMXgI4MJWnsKYFhGNMnIh/mBOPsV8CZBFjN9w8ArowxnZzDr5IcvxTaKpxJCVsoI3SWysz1UM4AqQdzlCgho1IKrK+x1mKFzisANtgEU8E7GwHDgOqxe4w9tnM166wbaA2xBMBLrTWcAGYGdCiYVUJUrMCF+7l6gklrW1RwPi8ByjuActANqhKzVWoYrFGcCFzbDgNaBrTWpncFQMcI2DfWoAiDqRCiHcYM/ZdCEKkZqfR8spj4F0CiJjv2gHL6URNoCQDaYacL6O1oFDO2eQDUFP7AKdCRdC4CRDZaNifbjA41l/uYb/SZMAFNTBGzY7sG4J2jTsJgToOzIzXF3HZqBpSOAGduXbkGEKV1OqVGqRJpRxtvwbSw5IqAiUJItwBCOT9R32FCGo3nCkAN3t0UTBRC6zDONcBeOee9pr4T+ASbnDOdc5OmtREwEEB5w8Wqgt4bOV5c7Lt9iiK8zdP/IsBbutUGX4gNwEVCqd3FUt/xYnRWt7BvPBYQjwjAGXa3ASguHVAZ/WXKlA3eZDX1wRegFsr7E2wAlB9xFbx/7MV70kFT8aqNgLL3F8nFBmA3hrn/IJHjKJOK2oj1WI4Z4FzwN/81AOhgYD6v2xbIvaZIurLC9AfvB1WLTYAoXejF1xeBL5cpBIyEbmxkZymIXwDQh1BAfOrhI1lfwtgz8tozF5T4ttf3+32AyxC6klwAgw/YVTHpoK82xYt3wLP/Bw4AAI4D7/01TLKXBj9NEz2wEuGiKpoy68S/FwCLMQAZ3gXhihaCa25vQo6RyToOz9PE6wYjJgGi1YnqZX8qMIK+TDlnargGzSv4NvFjlwXf/nfLLMrAB4O/Xl3BH0d+RIASFgDA8IYMIXgr2+cBsbDdPSwAAHjSZFmb3txETCKIxc0uWwI8rxsLJcTiVndNwyMgKljbbNN2/zcEAja2+4RgIDYN2Bu/WtAOaEodnu2dnzz/7I/Y/w/LaEcX/MdfAAAAAElFTkSuQmCC", ENABLED_QR_PROVIDERS = ["github"], QR_LOGIN_ENABLED = !1, QR_PROVIDER_LABELS = {
1758
+ wechat: "wechatLogin",
1759
+ github: "githubLogin",
1760
+ zhihu: "zhihuLogin"
1761
+ };
1762
+ var defaultQrProvider = ENABLED_QR_PROVIDERS[0] ?? "wechat";
1763
+ function isEnabledQrProvider(provider) {
1764
+ return ENABLED_QR_PROVIDERS.includes(provider);
1765
+ }
1766
+ function storedWorkspaceSelection() {
1767
+ let raw = window.sessionStorage.getItem(pendingWorkspaceSelectionKey);
1768
+ if (raw !== null)
1769
+ try {
1770
+ let value = JSON.parse(raw);
1771
+ if (typeof value.targetDeviceId != "string" || typeof value.workspaceId != "string") throw new Error("invalid");
1772
+ if (value.backend !== void 0 && value.backend !== "harness" && value.backend !== "codex") throw new Error("invalid");
1773
+ if (value.sessionId !== void 0 && typeof value.sessionId != "string") throw new Error("invalid");
1774
+ return value;
1775
+ } catch {
1776
+ window.sessionStorage.removeItem(pendingWorkspaceSelectionKey);
1777
+ return;
1778
+ }
1779
+ }
1780
+ function workspacesReady(snapshot) {
1781
+ return snapshot.baselinesReady === !0 || snapshot.phase === "ready";
1782
+ }
1783
+ var localeNamespace = "ds-harness-remote", en = {
1784
+ terminalRemote: "Remote terminal",
1785
+ terminalRemoteHint: "Allow trusted Remote devices to run an interactive shell as this Host user. On by default; independent of Agent approvals. Toggling saves and applies immediately.",
1786
+ terminalRemoteUnavailable: "Remote terminal is unavailable. Enable Remote terminal in the Host Remote settings; the switch applies immediately.",
1787
+ previewPorts: "Remote preview ports",
1788
+ previewPortsHint: "Allow specific Host ports (1024\u201365535), separated by commas. Empty disables preview. HTTP, WebSocket and hot reload are supported.",
1789
+ developmentSave: "Save access settings",
1790
+ developmentSaved: "Remote preview ports saved. Changes apply immediately.",
1791
+ terminalSaved: "Remote terminal setting saved. Applies immediately.",
1792
+ previewOpen: "Preview service",
1793
+ previewPort: "Host port",
1794
+ previewLocalOnly: "Preview requires Desktop or a browser connected to Harness on this computer.",
1795
+ pluginTitle: "DeepSeek Remote",
1796
+ pluginDescription: "Connect once. Available anytime.",
1797
+ expandSettings: "Show settings: {name}",
1798
+ collapseSettings: "Hide settings: {name}",
1799
+ unsaved: "Unsaved",
1800
+ associated: "Authorized",
1801
+ authorizationComplete: "Authorization complete",
1802
+ loadingSettings: "Loading DeepSeek Remote settings\u2026",
1803
+ mode: "Mode",
1804
+ pluginMode: "Plugin mode",
1805
+ host: "Host",
1806
+ client: "Client",
1807
+ authorization: "Authorization",
1808
+ account: "Account",
1809
+ hostRegistrationCode: "One-time device authorization code",
1810
+ ownedDeviceAuthorization: "Owned device",
1811
+ authorizedOn: "{role} is authorized on {serverUrl}.",
1812
+ readOnly: "This DSH profile does not provide writable user settings.",
1813
+ discard: "Discard",
1814
+ save: "Save",
1815
+ saving: "Saving\u2026",
1816
+ signOut: "Sign out",
1817
+ signingOut: "Signing out\u2026",
1818
+ hostName: "Host name",
1819
+ deviceId: "Device ID",
1820
+ serverUrl: "Server URL",
1821
+ serverUrlHint: "HTTPS origin used for account authorization and encrypted relay.",
1822
+ serverSaved: "Server address saved. Restart DSH to apply it.",
1823
+ codexRemote: "Codex Remote",
1824
+ codexRemoteHint: "Expose Codex projects through this Host. Restart DSH after changing this setting.",
1825
+ codexSaved: "Codex Remote setting saved. Restart DSH to apply it.",
1826
+ codexBinaryLabel: "Codex command or path",
1827
+ codexBinaryMissing: 'No Codex found automatically. Install the Codex desktop app, or enter the path to a Codex CLI that supports "codex app-server".',
1828
+ codexBinaryConfirm: "Confirm",
1829
+ codexBinaryAuto: "Use auto-discovery",
1830
+ codexBinaryPlaceholder: 'Path to a Codex CLI that supports "codex app-server"',
1831
+ codexBinaryPinned: "Set by hand. Clear the field and confirm to discover it automatically again.",
1832
+ authorizeFromRemote: "Sign in from the Remote entry in the sidebar, then return here to manage this device.",
1833
+ authorizationMethod: "Authorization method",
1834
+ accountPassword: "Account password",
1835
+ registrationCode: "Device authorization code",
1836
+ registrationCodeHint: "Generate it after signing in on the Server website. Use it once to connect this device.",
1837
+ accountHint: "The account must belong to the selected Server.",
1838
+ password: "Password",
1839
+ passwordHint: "Used only for this HTTPS authorization request and never saved.",
1840
+ modeSavedNeedsAuthorization: "Mode saved. Authorize {role} before connecting. Existing registrations were kept.",
1841
+ modeSavedReused: "Mode saved. Existing registration reused. Restart Harness to apply.",
1842
+ modeSavedOwnedRole: "Mode saved. This owned device was authorized automatically. Restart Harness to apply.",
1843
+ enterRegistrationCode: "Enter the device authorization code.",
1844
+ enterAccountPassword: "Enter the Server account and password.",
1845
+ associationSaved: "Associated. Restart Harness to apply.",
1846
+ signedOut: "Signed out. Restart Harness to disconnect this mode.",
1847
+ signedOutDeepseek: "Signed out, and your DSH DeepSeek account was signed out too.",
1848
+ remoteRequestFailed: "Remote mode request failed.",
1849
+ remoteControlUnavailable: "Remote plugin control is still starting. Restart DSH if it stays unavailable.",
1850
+ switchTarget: "Switch Local / Remote Harness target",
1851
+ harnessTarget: "Harness target",
1852
+ close: "Close",
1853
+ refreshRemote: "Refresh remote hosts",
1854
+ refreshRemoteShort: "Refresh",
1855
+ local: "Local",
1856
+ remoteTarget: "Remote \xB7 {name}",
1857
+ thisMachineLocal: "This machine (Local)",
1858
+ currentDevice: "Current device",
1859
+ noRemoteHosts: "No authorized remote Host for this account.",
1860
+ online: "Online",
1861
+ offline: "Offline",
1862
+ thisMachineHost: "This machine as Remote Host",
1863
+ connected: "Connected",
1864
+ connectedAs: "Connected as {account}",
1865
+ connection: "Connection",
1866
+ checkingConnection: "Checking connection\u2026",
1867
+ connecting: "Connecting",
1868
+ reconnecting: "Reconnecting",
1869
+ lastActive: "Last active: {time}",
1870
+ neverConnected: "No successful connection yet.",
1871
+ reconnect: "Reconnect",
1872
+ reconnectingAction: "Reconnecting\u2026",
1873
+ reconnectStarted: "Reconnect requested.",
1874
+ connectionAuthorizationExpired: "Authorization expired. Sign out and authorize this Host again.",
1875
+ connectionReplaced: "Another instance is using this Host identity. Stop it or use a separate DSH_HOME before reconnecting.",
1876
+ connectionCredentialsBusy: "Credential refresh is locked. Stop other instances. After a crash, stop all instances before removing server-credentials.json.refresh-lock and authorizing again.",
1877
+ connectionDeviceRevoked: "This Host was revoked on the Server. Sign out and authorize it again.",
1878
+ connectionOwnershipRequired: "The Server no longer recognizes this Host as an owned device.",
1879
+ connectionRateLimited: "The Server is receiving too many requests. Automatic retry will continue.",
1880
+ connectionVersionMismatch: "The Plugin and Server protocol versions are incompatible.",
1881
+ connectionInvalidResponse: "The Server returned an invalid control message.",
1882
+ connectionReachability: "Cannot reach the Server. Check the network and Server address.",
1883
+ connectionUnexpected: "The connection stopped unexpectedly. Automatic retry will continue.",
1884
+ hostSignInHint: "Sign in to authorize this Host on the selected Server.",
1885
+ checkingHost: "Checking Host registration\u2026",
1886
+ hostUnavailable: "Host unavailable: {error}",
1887
+ serverAccountEmail: "Server account email",
1888
+ serverAccountPassword: "Server account password",
1889
+ signInRegisterHost: "Sign in and register Host",
1890
+ signingIn: "Signing in\u2026",
1891
+ useRegistrationCode: "Use connection code",
1892
+ registering: "Registering\u2026",
1893
+ remoteEntry: "Remote",
1894
+ remoteTitle: "Open a remote workspace",
1895
+ remoteDescription: "Choose one of your Hosts, then select a working directory. The Harness interface stays on this device.",
1896
+ chooseHost: "Host",
1897
+ chooseDirectory: "Working directory",
1898
+ selectHostHint: "Select an online Host to browse its directories.",
1899
+ emptyDirectory: "This directory has no visible subdirectories.",
1900
+ openWorkspace: "Open workspace",
1901
+ openingWorkspace: "Opening\u2026",
1902
+ loadingDirectory: "Loading directories\u2026",
1903
+ remoteProgressCheckingHost: "Checking Host",
1904
+ remoteProgressCheckingHostDetail: "Finding the selected device and checking whether it is online.",
1905
+ remoteProgressAuthorizingPeer: "Verifying authorization",
1906
+ remoteProgressAuthorizingPeerDetail: "Confirming account membership and pinned Host identity.",
1907
+ remoteProgressOpeningChannel: "Opening encrypted channel",
1908
+ remoteProgressOpeningChannelDetail: "Trying LAN, P2P, TURN, then Relay if needed.",
1909
+ remoteProgressProbeLan: "Probing LAN",
1910
+ remoteProgressProbeLanDetail: "Checking whether the Host is reachable on the local network.",
1911
+ remoteProgressProbeP2p: "Probing P2P",
1912
+ remoteProgressProbeP2pDetail: "Checking direct internet candidates between this device and the Host.",
1913
+ remoteProgressProbeTurn: "Probing TURN",
1914
+ remoteProgressProbeTurnDetail: "Checking the TURN relay path for restricted networks.",
1915
+ remoteProgressProbeRelay: "Preparing Relay",
1916
+ remoteProgressProbeRelayDetail: "Preparing the encrypted Server Relay fallback if direct paths do not open.",
1917
+ remoteProgressTryingPrefix: "Trying ",
1918
+ remoteProgressUsingPrefix: "Using ",
1919
+ remoteProgressLoadingWorkspaces: "Loading workspaces",
1920
+ remoteProgressLoadingWorkspacesDetail: "Reading the remote Harness workspace list through the tunnel.",
1921
+ remoteProgressSwitchingWorkspace: "Switching interface",
1922
+ remoteProgressSwitchingWorkspaceDetail: "Handing the remote workspace to the local Harness UI.",
1923
+ remoteProgressReady: "Ready",
1924
+ remoteProgressReadyDetail: "The remote Host is connected and encrypted.",
1925
+ backToHosts: "Choose another Host",
1926
+ currentDirectory: "Selected directory",
1927
+ directoryTruncated: "Only part of this directory could be shown.",
1928
+ pluginVersion: "Plugin {version}",
1929
+ harnessVersion: "Harness {version}",
1930
+ existingWorkspaces: "Existing workspaces",
1931
+ remotePathPlaceholder: "/home/user/project",
1932
+ remotePathHint: "Enter an absolute directory path on the selected Host.",
1933
+ noRemoteWorkspaces: "No remote workspaces yet. Use + to add one.",
1934
+ activeRemote: "{name}",
1935
+ exitRemote: "Exit",
1936
+ addRemoteWorkspace: "Add remote workspace",
1937
+ addCodexWorkspace: "Add CodeX workspace",
1938
+ noCodexWorkspaces: "No CodeX workspaces yet.",
1939
+ cancelAddWorkspace: "Cancel",
1940
+ confirmAddWorkspace: "Add and open",
1941
+ showAllWorkspaces: "Show all DSH workspaces",
1942
+ showAllCodexWorkspaces: "Show all CodeX workspaces",
1943
+ remoteModePrefix: "Remote mode \xB7 ",
1944
+ remoteNetworkP2p: "P2P",
1945
+ remoteNetworkTurn: "TURN",
1946
+ remoteNetworkRelay: "Relay",
1947
+ remoteNetworkLan: "LAN",
1948
+ remoteNetworkOffline: "Disconnected",
1949
+ remoteLinkEncrypted: "End-to-end encrypted",
1950
+ connectionRouteTitle: "Connection route",
1951
+ connectionRouteFrom: "From",
1952
+ connectionRouteVia: "Via",
1953
+ connectionRouteTo: "To",
1954
+ connectionRouteCurrentDevice: "This device",
1955
+ connectionRouteLan: "Local network",
1956
+ connectionRouteP2p: "Direct internet path",
1957
+ connectionRouteTurn: "TURN relay service",
1958
+ connectionRouteRelay: "Remote Server",
1959
+ connectionRouteHost: "Work computer running Harness",
1960
+ connectionRouteLanDetail: "Direct transfer over the local network",
1961
+ connectionRouteP2pDetail: "Direct transfer over the internet",
1962
+ connectionRouteTurnDetail: "Encrypted transfer through the TURN service",
1963
+ connectionRouteRelayDetail: "Encrypted transfer through the Remote Server",
1964
+ connectionRouteEncrypted: "Application data remains end-to-end encrypted along this route.",
1965
+ connectionDetailsConnection: "Connection",
1966
+ connectionDetailsWebRtc: "Network details \xB7 WebRTC / ICE",
1967
+ connectionId: "Connection ID",
1968
+ connectedAt: "Established",
1969
+ preferredTransports: "Attempt order",
1970
+ controlChannel: "Control channel",
1971
+ controlAddress: "Control address",
1972
+ controlStateConnecting: "Connecting",
1973
+ controlStateOpen: "Connected",
1974
+ controlStateClosing: "Closing",
1975
+ controlStateClosed: "Closed",
1976
+ peerState: "Peer connection",
1977
+ dataChannel: "DataChannel",
1978
+ localCandidate: "Local candidate",
1979
+ remoteCandidate: "Remote candidate",
1980
+ localAddress: "Local address",
1981
+ remoteAddress: "Remote address",
1982
+ networkProtocol: "Network protocol",
1983
+ relayProtocol: "TURN protocol",
1984
+ roundTripTime: "Round-trip time",
1985
+ availableBitrate: "Available outgoing bitrate",
1986
+ bytesSent: "WebRTC bytes sent",
1987
+ bytesReceived: "WebRTC bytes received",
1988
+ notProvided: "Not provided",
1989
+ candidateHost: "Local address \xB7 host",
1990
+ candidateSrflx: "Public address \xB7 srflx",
1991
+ candidatePrflx: "Peer address \xB7 prflx",
1992
+ candidateRelay: "TURN address \xB7 relay",
1993
+ openLocalWorkspaces: "Open local workspaces",
1994
+ clientSignInHint: "Sign in to this Server to list your remote Hosts.",
1995
+ deepseekSignIn: "Sign in with DeepSeek account",
1996
+ deepseekSignInRequesting: "Requesting the DeepSeek sign-in page\u2026",
1997
+ deepseekSignInWaiting: "Finish signing in to DeepSeek in the browser.",
1998
+ deepseekSignInOpen: "Open the sign-in page",
1999
+ deepseekSignInTimeout: "DeepSeek sign-in was not completed. Try again.",
2000
+ deepseekAuthorizeUnavailable: "DeepSeek did not return a sign-in page. Try again.",
2001
+ changeServerUrl: "Change address",
2002
+ startSignIn: "Start sign-in",
2003
+ allowControlCurrentDevice: "Allow control of this device",
2004
+ allowControlDevice: "Allow control of device",
2005
+ connectedClientCount: "{count} connected",
2006
+ checkAcp: "Check ACP",
2007
+ checkingAcp: "Checking ACP\u2026",
2008
+ acpAvailable: "ACP available",
2009
+ acpUnavailable: "ACP unavailable",
2010
+ acpHint: "Connect compatible coding agents through the Agent Client Protocol.",
2011
+ acpCheckPassed: "Check passed",
2012
+ acpCheckFailed: "Check failed",
2013
+ addAcp: "Add ACP",
2014
+ acpName: "Service name",
2015
+ acpCommand: "Command",
2016
+ acpArguments: "Arguments",
2017
+ removeAcp: "Remove",
2018
+ currentConnectedDevices: "Currently connected devices",
2019
+ noConnectedClients: "No devices are currently connected to this Host.",
2020
+ unknownDevice: "Unknown device",
2021
+ exitRemoteAccount: "Sign out",
2022
+ cancel: "Cancel",
2023
+ signOutImpact: "Signing out disconnects this plugin and also signs DSH out of your DeepSeek account.",
2024
+ wechatLogin: "WeChat QR",
2025
+ githubLogin: "GitHub QR",
2026
+ zhihuLogin: "Zhihu QR",
2027
+ scanWithWeChat: "Scan to continue with WeChat",
2028
+ scanWithGitHub: "Scan to continue with GitHub",
2029
+ scanWithZhihu: "Scan to continue with Zhihu",
2030
+ openInBrowser: "Continue in browser",
2031
+ scanLoginHint: "Authorize on your phone. This window will continue automatically.",
2032
+ currentServiceAddress: "Current service address:",
2033
+ accountPasswordLogin: "Password",
2034
+ qrLoginExpired: "This QR code expired. Refresh it to continue.",
2035
+ refreshQrCode: "Refresh QR code",
2036
+ codexVirtualWorkspace: "CodeX virtual workspace",
2037
+ codexVirtualSessions: "Sessions"
2038
+ }, zh = {
2039
+ terminalRemote: "\u8FDC\u7A0B\u7EC8\u7AEF",
2040
+ terminalRemoteHint: "\u5141\u8BB8\u53D7\u4FE1\u4EFB\u7684 Remote \u8BBE\u5907\u4EE5\u6B64 Host \u7528\u6237\u8EAB\u4EFD\u8FD0\u884C\u4EA4\u4E92\u5F0F Shell\u3002\u9ED8\u8BA4\u5F00\u542F\uFF0C\u72EC\u7ACB\u4E8E Agent \u5BA1\u6279\uFF1B\u5207\u6362\u540E\u7ACB\u5373\u4FDD\u5B58\u5E76\u751F\u6548\u3002",
2041
+ terminalRemoteUnavailable: "\u8FDC\u7A0B\u7EC8\u7AEF\u4E0D\u53EF\u7528\u3002\u8BF7\u5728 Host \u7684 Remote \u8BBE\u7F6E\u4E2D\u5F00\u542F\u300C\u8FDC\u7A0B\u7EC8\u7AEF\u300D\uFF0C\u5F00\u5173\u4F1A\u7ACB\u5373\u751F\u6548\u3002",
2042
+ previewPorts: "\u8FDC\u7A0B\u9884\u89C8\u7AEF\u53E3",
2043
+ previewPortsHint: "\u586B\u5199\u5141\u8BB8\u8BBF\u95EE\u7684 Host \u7AEF\u53E3\uFF081024\u201365535\uFF09\uFF0C\u4EE5\u9017\u53F7\u5206\u9694\u3002\u7559\u7A7A\u7981\u7528\u9884\u89C8\uFF1B\u652F\u6301 HTTP\u3001WebSocket \u548C\u70ED\u66F4\u65B0\u3002",
2044
+ developmentSave: "\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E",
2045
+ developmentSaved: "\u8FDC\u7A0B\u9884\u89C8\u7AEF\u53E3\u5DF2\u4FDD\u5B58\uFF0C\u7ACB\u5373\u751F\u6548\u3002",
2046
+ terminalSaved: "\u8FDC\u7A0B\u7EC8\u7AEF\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u7ACB\u5373\u751F\u6548\u3002",
2047
+ previewOpen: "\u9884\u89C8\u670D\u52A1",
2048
+ previewPort: "Host \u7AEF\u53E3",
2049
+ previewLocalOnly: "\u9884\u89C8\u9700\u8981 Desktop\uFF0C\u6216\u8FDE\u63A5\u5230\u672C\u673A Harness \u7684\u6D4F\u89C8\u5668\u3002",
2050
+ pluginTitle: "DeepSeek \u8FDC\u7A0B\u8FDE\u63A5",
2051
+ pluginDescription: "\u4E00\u6B21\u8FDE\u63A5\uFF0C\u968F\u65F6\u53EF\u7528\u3002",
2052
+ expandSettings: "\u5C55\u5F00\u8BBE\u7F6E\uFF1A{name}",
2053
+ collapseSettings: "\u6536\u8D77\u8BBE\u7F6E\uFF1A{name}",
2054
+ unsaved: "\u672A\u4FDD\u5B58",
2055
+ associated: "\u5DF2\u6388\u6743",
2056
+ authorizationComplete: "\u5DF2\u5B8C\u6210\u6388\u6743",
2057
+ loadingSettings: "\u6B63\u5728\u52A0\u8F7D DeepSeek \u8FDC\u7A0B\u8FDE\u63A5\u8BBE\u7F6E\u2026",
2058
+ mode: "\u6A21\u5F0F",
2059
+ pluginMode: "\u63D2\u4EF6\u6A21\u5F0F",
2060
+ host: "\u4E3B\u673A",
2061
+ client: "Client",
2062
+ authorization: "\u6388\u6743",
2063
+ account: "\u8D26\u53F7",
2064
+ hostRegistrationCode: "\u4E00\u6B21\u6027\u8BBE\u5907\u6388\u6743\u7801",
2065
+ ownedDeviceAuthorization: "\u81EA\u6709\u8BBE\u5907",
2066
+ authorizedOn: "{role}\u5DF2\u7ECF\u5728 {serverUrl} \u5B8C\u6210\u6388\u6743\u3002",
2067
+ readOnly: "\u6B64 DSH profile \u4E0D\u63D0\u4F9B\u53EF\u5199\u7684\u7528\u6237\u8BBE\u7F6E\u3002",
2068
+ discard: "\u653E\u5F03\u4FEE\u6539",
2069
+ save: "\u4FDD\u5B58",
2070
+ saving: "\u4FDD\u5B58\u4E2D\u2026",
2071
+ signOut: "\u9000\u51FA\u6388\u6743",
2072
+ signingOut: "\u6B63\u5728\u9000\u51FA\u2026",
2073
+ hostName: "\u4E3B\u673A\u540D\u79F0",
2074
+ deviceId: "\u8BBE\u5907 ID",
2075
+ serverUrl: "Server \u5730\u5740",
2076
+ serverUrlHint: "\u7528\u4E8E\u8D26\u53F7\u6388\u6743\u548C\u52A0\u5BC6\u4E2D\u7EE7\u7684 HTTPS \u5730\u5740\u3002",
2077
+ serverSaved: "Server \u5730\u5740\u5DF2\u4FDD\u5B58\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
2078
+ codexRemote: "Codex Remote",
2079
+ codexRemoteHint: "\u901A\u8FC7\u8FD9\u53F0 Host \u63D0\u4F9B Codex \u9879\u76EE\uFF1B\u4FEE\u6539\u540E\u9700\u91CD\u542F DSH \u751F\u6548\u3002",
2080
+ codexSaved: "Codex Remote \u8BBE\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
2081
+ codexBinaryLabel: "Codex \u547D\u4EE4\u6216\u8DEF\u5F84",
2082
+ codexBinaryMissing: '\u672A\u81EA\u52A8\u53D1\u73B0 Codex\u3002\u8BF7\u5B89\u88C5 Codex \u684C\u9762\u5E94\u7528\uFF0C\u6216\u586B\u5199\u652F\u6301 "codex app-server" \u7684 Codex CLI \u8DEF\u5F84\u3002',
2083
+ codexBinaryConfirm: "\u786E\u8BA4",
2084
+ codexBinaryAuto: "\u6062\u590D\u81EA\u52A8\u53D1\u73B0",
2085
+ codexBinaryPlaceholder: '\u652F\u6301 "codex app-server" \u7684 Codex CLI \u8DEF\u5F84',
2086
+ codexBinaryPinned: "\u5F53\u524D\u4E3A\u624B\u52A8\u6307\u5B9A\uFF1B\u6E05\u7A7A\u540E\u786E\u8BA4\u5373\u53EF\u6062\u590D\u81EA\u52A8\u53D1\u73B0\u3002",
2087
+ authorizeFromRemote: "\u8BF7\u4ECE\u4FA7\u680F Remote \u5165\u53E3\u767B\u5F55\uFF0C\u767B\u5F55\u540E\u53EF\u5728\u8FD9\u91CC\u7BA1\u7406\u5F53\u524D\u8BBE\u5907\u3002",
2088
+ authorizationMethod: "\u6388\u6743\u65B9\u5F0F",
2089
+ accountPassword: "\u8D26\u53F7\u5BC6\u7801",
2090
+ registrationCode: "\u8BBE\u5907\u6388\u6743\u7801",
2091
+ registrationCodeHint: "\u767B\u5F55 Server \u7F51\u9875\u540E\u751F\u6210\uFF0C\u7528\u4E00\u6B21\u5373\u53EF\u8FDE\u63A5\u8FD9\u53F0\u8BBE\u5907\u3002",
2092
+ accountHint: "\u8D26\u53F7\u5FC5\u987B\u5C5E\u4E8E\u6240\u9009 Server\u3002",
2093
+ password: "\u5BC6\u7801",
2094
+ passwordHint: "\u4EC5\u7528\u4E8E\u672C\u6B21 HTTPS \u6388\u6743\u8BF7\u6C42\uFF0C\u4E0D\u4F1A\u4FDD\u5B58\u3002",
2095
+ modeSavedNeedsAuthorization: "\u6A21\u5F0F\u5DF2\u4FDD\u5B58\u3002\u8FDE\u63A5\u524D\u8BF7\u5148\u6388\u6743 {role}\uFF1B\u5DF2\u6709\u6CE8\u518C\u4FE1\u606F\u5DF2\u4FDD\u7559\u3002",
2096
+ modeSavedReused: "\u6A21\u5F0F\u5DF2\u4FDD\u5B58\u5E76\u590D\u7528\u5DF2\u6709\u6CE8\u518C\u4FE1\u606F\u3002\u91CD\u542F Harness \u540E\u751F\u6548\u3002",
2097
+ modeSavedOwnedRole: "\u6A21\u5F0F\u5DF2\u4FDD\u5B58\uFF0C\u5E76\u5DF2\u81EA\u52A8\u6388\u6743\u6B64\u81EA\u6709\u8BBE\u5907\u3002\u91CD\u542F Harness \u540E\u751F\u6548\u3002",
2098
+ enterRegistrationCode: "\u8BF7\u8F93\u5165\u8BBE\u5907\u6388\u6743\u7801\u3002",
2099
+ enterAccountPassword: "\u8BF7\u8F93\u5165 Server \u8D26\u53F7\u548C\u5BC6\u7801\u3002",
2100
+ associationSaved: "\u5173\u8054\u6210\u529F\u3002\u91CD\u542F Harness \u540E\u751F\u6548\u3002",
2101
+ signedOut: "\u5DF2\u9000\u51FA\u6388\u6743\u3002\u91CD\u542F Harness \u540E\u5C06\u65AD\u5F00\u6B64\u6A21\u5F0F\u3002",
2102
+ signedOutDeepseek: "\u5DF2\u9000\u51FA\u6388\u6743\uFF0CDSH \u7684 DeepSeek \u8D26\u53F7\u4E5F\u5DF2\u4E00\u5E76\u9000\u51FA\u767B\u5F55\u3002",
2103
+ remoteRequestFailed: "\u8FDC\u7A0B\u6A21\u5F0F\u8BF7\u6C42\u5931\u8D25\u3002",
2104
+ remoteControlUnavailable: "Remote \u63D2\u4EF6\u63A7\u5236\u901A\u9053\u4ECD\u5728\u542F\u52A8\uFF1B\u5982\u679C\u4E00\u76F4\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u542F DSH\u3002",
2105
+ switchTarget: "\u5207\u6362\u672C\u5730\u6216\u8FDC\u7A0B Harness",
2106
+ harnessTarget: "Harness \u76EE\u6807",
2107
+ close: "\u5173\u95ED",
2108
+ refreshRemote: "\u5237\u65B0\u8FDC\u7A0B\u4E3B\u673A",
2109
+ refreshRemoteShort: "\u5237\u65B0",
2110
+ local: "\u672C\u5730",
2111
+ remoteTarget: "\u8FDC\u7A0B \xB7 {name}",
2112
+ thisMachineLocal: "\u6B64\u8BBE\u5907\uFF08\u672C\u5730\uFF09",
2113
+ currentDevice: "\u5F53\u524D\u8BBE\u5907",
2114
+ noRemoteHosts: "\u6B64\u8D26\u53F7\u6CA1\u6709\u5DF2\u6388\u6743\u7684\u8FDC\u7A0B Host\u3002",
2115
+ online: "\u5728\u7EBF",
2116
+ offline: "\u79BB\u7EBF",
2117
+ thisMachineHost: "\u5C06\u6B64\u8BBE\u5907\u4F5C\u4E3A\u8FDC\u7A0B Host",
2118
+ connected: "\u5DF2\u8FDE\u63A5",
2119
+ connectedAs: "\u5DF2\u4F7F\u7528 {account} \u8FDE\u63A5",
2120
+ connection: "\u8FDE\u63A5\u72B6\u6001",
2121
+ checkingConnection: "\u6B63\u5728\u68C0\u67E5\u8FDE\u63A5\u2026",
2122
+ connecting: "\u6B63\u5728\u8FDE\u63A5",
2123
+ reconnecting: "\u6B63\u5728\u91CD\u8FDE",
2124
+ lastActive: "\u6700\u540E\u6D3B\u8DC3\uFF1A{time}",
2125
+ neverConnected: "\u5C1A\u672A\u6210\u529F\u8FDE\u63A5\u8FC7\u3002",
2126
+ reconnect: "\u624B\u52A8\u91CD\u8FDE",
2127
+ reconnectingAction: "\u6B63\u5728\u91CD\u8FDE\u2026",
2128
+ reconnectStarted: "\u5DF2\u53D1\u8D77\u91CD\u8FDE\u3002",
2129
+ connectionAuthorizationExpired: "\u6388\u6743\u5DF2\u5931\u6548\uFF0C\u8BF7\u9000\u51FA\u6388\u6743\u540E\u91CD\u65B0\u8FDE\u63A5\u6B64 Host\u3002",
2130
+ connectionReplaced: "\u53E6\u4E00\u5B9E\u4F8B\u6B63\u5728\u4F7F\u7528\u6B64 Host \u8EAB\u4EFD\u3002\u8BF7\u505C\u6B62\u8BE5\u5B9E\u4F8B\uFF0C\u6216\u4F7F\u7528\u72EC\u7ACB\u7684 DSH_HOME \u540E\u91CD\u65B0\u8FDE\u63A5\u3002",
2131
+ connectionCredentialsBusy: "\u51ED\u636E\u5237\u65B0\u88AB\u9501\u5B9A\uFF0C\u8BF7\u505C\u6B62\u5176\u4ED6\u5B9E\u4F8B\u3002\u82E5\u6B64\u524D\u5F02\u5E38\u9000\u51FA\uFF0C\u8BF7\u505C\u6B62\u6240\u6709\u5B9E\u4F8B\u540E\u79FB\u9664 server-credentials.json.refresh-lock \u5E76\u91CD\u65B0\u6388\u6743\u3002",
2132
+ connectionDeviceRevoked: "\u6B64 Host \u5DF2\u5728 Server \u4E0A\u88AB\u64A4\u9500\uFF0C\u8BF7\u9000\u51FA\u6388\u6743\u540E\u91CD\u65B0\u8FDE\u63A5\u3002",
2133
+ connectionOwnershipRequired: "Server \u5DF2\u4E0D\u518D\u5C06\u6B64 Host \u8BC6\u522B\u4E3A\u5F53\u524D\u8D26\u53F7\u7684\u8BBE\u5907\u3002",
2134
+ connectionRateLimited: "Server \u8BF7\u6C42\u8FC7\u591A\uFF0C\u63D2\u4EF6\u5C06\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5\u3002",
2135
+ connectionVersionMismatch: "Plugin \u4E0E Server \u7684\u534F\u8BAE\u7248\u672C\u4E0D\u517C\u5BB9\u3002",
2136
+ connectionInvalidResponse: "Server \u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u63A7\u5236\u6D88\u606F\u3002",
2137
+ connectionReachability: "\u65E0\u6CD5\u8FDE\u63A5 Server\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C Server \u5730\u5740\u3002",
2138
+ connectionUnexpected: "\u8FDE\u63A5\u610F\u5916\u4E2D\u65AD\uFF0C\u63D2\u4EF6\u5C06\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5\u3002",
2139
+ hostSignInHint: "\u767B\u5F55\u540E\u5728\u6240\u9009 Server \u4E0A\u6388\u6743\u6B64 Host\u3002",
2140
+ checkingHost: "\u6B63\u5728\u68C0\u67E5 Host \u6CE8\u518C\u72B6\u6001\u2026",
2141
+ hostUnavailable: "Host \u4E0D\u53EF\u7528\uFF1A{error}",
2142
+ serverAccountEmail: "Server \u8D26\u53F7\u90AE\u7BB1",
2143
+ serverAccountPassword: "Server \u8D26\u53F7\u5BC6\u7801",
2144
+ signInRegisterHost: "\u767B\u5F55\u5E76\u6CE8\u518C Host",
2145
+ signingIn: "\u6B63\u5728\u767B\u5F55\u2026",
2146
+ useRegistrationCode: "\u4F7F\u7528\u8FDE\u63A5\u7801",
2147
+ registering: "\u6B63\u5728\u6CE8\u518C\u2026",
2148
+ remoteEntry: "Remote",
2149
+ remoteTitle: "\u6253\u5F00\u8FDC\u7AEF\u5DE5\u4F5C\u533A",
2150
+ remoteDescription: "\u9009\u62E9\u60F3\u8981\u8FDE\u63A5\u4E3B\u673A\u548C\u5DE5\u4F5C\u76EE\u5F55\u3002",
2151
+ chooseHost: "\u4E3B\u673A",
2152
+ chooseDirectory: "\u5DE5\u4F5C\u76EE\u5F55",
2153
+ selectHostHint: "\u9009\u62E9\u4E00\u53F0\u5728\u7EBF\u4E3B\u673A\u4EE5\u6D4F\u89C8\u5176\u76EE\u5F55\u3002",
2154
+ emptyDirectory: "\u8FD9\u4E2A\u76EE\u5F55\u4E0B\u6CA1\u6709\u53EF\u89C1\u7684\u5B50\u76EE\u5F55\u3002",
2155
+ openWorkspace: "\u6253\u5F00\u5DE5\u4F5C\u533A",
2156
+ openingWorkspace: "\u6B63\u5728\u6253\u5F00\u2026",
2157
+ loadingDirectory: "\u6B63\u5728\u52A0\u8F7D\u76EE\u5F55\u2026",
2158
+ remoteProgressCheckingHost: "\u6B63\u5728\u68C0\u67E5 Host",
2159
+ remoteProgressCheckingHostDetail: "\u6B63\u5728\u67E5\u627E\u6240\u9009\u8BBE\u5907\u5E76\u786E\u8BA4\u662F\u5426\u5728\u7EBF\u3002",
2160
+ remoteProgressAuthorizingPeer: "\u6B63\u5728\u9A8C\u8BC1\u6388\u6743",
2161
+ remoteProgressAuthorizingPeerDetail: "\u6B63\u5728\u786E\u8BA4\u8D26\u53F7\u6210\u5458\u5173\u7CFB\u548C\u5DF2\u56FA\u5B9A\u7684 Host \u8EAB\u4EFD\u3002",
2162
+ remoteProgressOpeningChannel: "\u6B63\u5728\u5EFA\u7ACB\u52A0\u5BC6\u901A\u9053",
2163
+ remoteProgressOpeningChannelDetail: "\u4F9D\u6B21\u5C1D\u8BD5\u5C40\u57DF\u7F51\u3001P2P\u3001TURN\uFF0C\u5FC5\u8981\u65F6\u56DE\u843D\u5230 Relay\u3002",
2164
+ remoteProgressProbeLan: "\u6B63\u5728\u63A2\u6D4B\u5C40\u57DF\u7F51",
2165
+ remoteProgressProbeLanDetail: "\u68C0\u67E5\u5F53\u524D\u8BBE\u5907\u662F\u5426\u80FD\u901A\u8FC7\u672C\u5730\u7F51\u7EDC\u76F4\u8FDE Host\u3002",
2166
+ remoteProgressProbeP2p: "\u6B63\u5728\u63A2\u6D4B P2P",
2167
+ remoteProgressProbeP2pDetail: "\u68C0\u67E5\u5F53\u524D\u8BBE\u5907\u548C Host \u4E4B\u95F4\u7684\u4E92\u8054\u7F51\u76F4\u8FDE\u5019\u9009\u8DEF\u5F84\u3002",
2168
+ remoteProgressProbeTurn: "\u6B63\u5728\u63A2\u6D4B TURN",
2169
+ remoteProgressProbeTurnDetail: "\u68C0\u67E5\u53D7\u9650\u7F51\u7EDC\u4E0B\u53EF\u7528\u7684 TURN \u4E2D\u7EE7\u8DEF\u5F84\u3002",
2170
+ remoteProgressProbeRelay: "\u6B63\u5728\u51C6\u5907 Relay",
2171
+ remoteProgressProbeRelayDetail: "\u5982\u679C\u76F4\u8FDE\u8DEF\u5F84\u672A\u6253\u5F00\uFF0C\u5C06\u56DE\u843D\u5230\u52A0\u5BC6\u7684 Server Relay\u3002",
2172
+ remoteProgressTryingPrefix: "\u6B63\u5728\u5C1D\u8BD5 ",
2173
+ remoteProgressUsingPrefix: "\u5DF2\u8FDE\u63A5 ",
2174
+ remoteProgressLoadingWorkspaces: "\u6B63\u5728\u52A0\u8F7D\u5DE5\u4F5C\u533A",
2175
+ remoteProgressLoadingWorkspacesDetail: "\u901A\u8FC7\u96A7\u9053\u8BFB\u53D6\u8FDC\u7AEF Harness \u5DE5\u4F5C\u533A\u5217\u8868\u3002",
2176
+ remoteProgressSwitchingWorkspace: "\u6B63\u5728\u5207\u6362\u754C\u9762",
2177
+ remoteProgressSwitchingWorkspaceDetail: "\u6B63\u5728\u628A\u8FDC\u7AEF\u5DE5\u4F5C\u533A\u4EA4\u7ED9\u672C\u5730 Harness UI\u3002",
2178
+ remoteProgressReady: "\u5DF2\u5C31\u7EEA",
2179
+ remoteProgressReadyDetail: "\u8FDC\u7AEF Host \u5DF2\u8FDE\u63A5\uFF0C\u7AEF\u5230\u7AEF\u52A0\u5BC6\u5DF2\u5EFA\u7ACB\u3002",
2180
+ backToHosts: "\u9009\u62E9\u5176\u4ED6\u4E3B\u673A",
2181
+ currentDirectory: "\u5DF2\u9009\u76EE\u5F55",
2182
+ directoryTruncated: "\u76EE\u5F55\u5185\u5BB9\u8F83\u591A\uFF0C\u76EE\u524D\u53EA\u663E\u793A\u4E86\u4E00\u90E8\u5206\u3002",
2183
+ pluginVersion: "\u63D2\u4EF6 {version}",
2184
+ harnessVersion: "Harness {version}",
2185
+ existingWorkspaces: "\u5DF2\u6709\u5DE5\u4F5C\u533A",
2186
+ remotePathPlaceholder: "/home/user/project",
2187
+ remotePathHint: "\u8F93\u5165\u6240\u9009\u4E3B\u673A\u4E0A\u7684\u7EDD\u5BF9\u76EE\u5F55\u8DEF\u5F84\u3002",
2188
+ noRemoteWorkspaces: "\u8FD9\u53F0\u4E3B\u673A\u8FD8\u6CA1\u6709\u5DE5\u4F5C\u533A\uFF0C\u70B9\u51FB + \u6DFB\u52A0\u3002",
2189
+ activeRemote: "{name}",
2190
+ exitRemote: "\u9000\u51FA",
2191
+ addRemoteWorkspace: "\u6DFB\u52A0\u8FDC\u7A0B\u5DE5\u4F5C\u533A",
2192
+ addCodexWorkspace: "\u6DFB\u52A0 CodeX \u5DE5\u4F5C\u533A",
2193
+ noCodexWorkspaces: "\u8FD8\u6CA1\u6709 CodeX \u5DE5\u4F5C\u533A\u3002",
2194
+ cancelAddWorkspace: "\u53D6\u6D88",
2195
+ confirmAddWorkspace: "\u786E\u8BA4\u5E76\u6253\u5F00",
2196
+ showAllWorkspaces: "\u663E\u793A\u5168\u90E8 DSH \u5DE5\u4F5C\u533A",
2197
+ showAllCodexWorkspaces: "\u663E\u793A\u5168\u90E8 CodeX \u5DE5\u4F5C\u533A",
2198
+ remoteModePrefix: "\u8FDC\u7A0B\u6A21\u5F0F \xB7 ",
2199
+ remoteNetworkP2p: "P2P",
2200
+ remoteNetworkTurn: "TURN",
2201
+ remoteNetworkRelay: "\u4E2D\u7EE7",
2202
+ remoteNetworkLan: "\u5C40\u57DF\u7F51",
2203
+ remoteNetworkOffline: "\u5DF2\u65AD\u5F00",
2204
+ remoteLinkEncrypted: "\u7AEF\u5230\u7AEF\u52A0\u5BC6",
2205
+ connectionRouteTitle: "\u8FDE\u63A5\u7EBF\u8DEF",
2206
+ connectionRouteFrom: "\u8D77\u70B9",
2207
+ connectionRouteVia: "\u7ECF\u8FC7",
2208
+ connectionRouteTo: "\u7EC8\u70B9",
2209
+ connectionRouteCurrentDevice: "\u5F53\u524D\u8BBE\u5907",
2210
+ connectionRouteLan: "\u540C\u4E00\u5C40\u57DF\u7F51",
2211
+ connectionRouteP2p: "\u4E92\u8054\u7F51\u76F4\u8FDE",
2212
+ connectionRouteTurn: "TURN \u4E2D\u7EE7\u670D\u52A1",
2213
+ connectionRouteRelay: "Remote Server",
2214
+ connectionRouteHost: "\u8FD0\u884C Harness \u7684\u5DE5\u4F5C\u7535\u8111",
2215
+ connectionRouteLanDetail: "\u5728\u672C\u5730\u7F51\u7EDC\u4E2D\u76F4\u63A5\u4F20\u8F93",
2216
+ connectionRouteP2pDetail: "\u901A\u8FC7\u4E92\u8054\u7F51\u76F4\u63A5\u4F20\u8F93",
2217
+ connectionRouteTurnDetail: "\u901A\u8FC7 TURN \u670D\u52A1\u8F6C\u53D1\u52A0\u5BC6\u6570\u636E",
2218
+ connectionRouteRelayDetail: "\u901A\u8FC7 Remote Server \u8F6C\u53D1\u52A0\u5BC6\u6570\u636E",
2219
+ connectionRouteEncrypted: "\u7EBF\u8DEF\u4E0A\u7684\u4E1A\u52A1\u6570\u636E\u4FDD\u6301\u7AEF\u5230\u7AEF\u52A0\u5BC6\u3002",
2220
+ connectionDetailsConnection: "\u8FDE\u63A5",
2221
+ connectionDetailsWebRtc: "\u7F51\u7EDC\u8BE6\u60C5 \xB7 WebRTC / ICE",
2222
+ connectionId: "\u8FDE\u63A5\u7F16\u53F7",
2223
+ connectedAt: "\u5EFA\u7ACB\u65F6\u95F4",
2224
+ preferredTransports: "\u5C1D\u8BD5\u987A\u5E8F",
2225
+ controlChannel: "\u63A7\u5236\u901A\u9053",
2226
+ controlAddress: "\u63A7\u5236\u5730\u5740",
2227
+ controlStateConnecting: "\u8FDE\u63A5\u4E2D",
2228
+ controlStateOpen: "\u5DF2\u8FDE\u63A5",
2229
+ controlStateClosing: "\u6B63\u5728\u5173\u95ED",
2230
+ controlStateClosed: "\u5DF2\u5173\u95ED",
2231
+ peerState: "\u8FDE\u63A5\u72B6\u6001",
2232
+ dataChannel: "DataChannel",
2233
+ localCandidate: "\u672C\u5730\u5019\u9009",
2234
+ remoteCandidate: "\u8FDC\u7AEF\u5019\u9009",
2235
+ localAddress: "\u672C\u5730\u5730\u5740",
2236
+ remoteAddress: "\u8FDC\u7AEF\u5730\u5740",
2237
+ networkProtocol: "\u4F20\u8F93\u534F\u8BAE",
2238
+ relayProtocol: "TURN \u534F\u8BAE",
2239
+ roundTripTime: "\u5F80\u8FD4\u65F6\u5EF6",
2240
+ availableBitrate: "\u53EF\u7528\u4E0A\u884C\u5E26\u5BBD",
2241
+ bytesSent: "WebRTC \u5DF2\u53D1\u9001",
2242
+ bytesReceived: "WebRTC \u5DF2\u63A5\u6536",
2243
+ notProvided: "\u672A\u63D0\u4F9B",
2244
+ candidateHost: "\u672C\u5730\u5730\u5740 \xB7 host",
2245
+ candidateSrflx: "\u516C\u7F51\u5730\u5740 \xB7 srflx",
2246
+ candidatePrflx: "\u5BF9\u7AEF\u5730\u5740 \xB7 prflx",
2247
+ candidateRelay: "TURN \u5730\u5740 \xB7 relay",
2248
+ openLocalWorkspaces: "\u6253\u5F00\u672C\u5730\u5DE5\u4F5C\u533A",
2249
+ clientSignInHint: "\u767B\u5F55 Server \u540E\u5373\u53EF\u67E5\u770B\u81EA\u5DF1\u7684\u8FDC\u7AEF\u4E3B\u673A\u3002",
2250
+ deepseekSignIn: "\u4F7F\u7528 DeepSeek \u8D26\u53F7\u767B\u5F55",
2251
+ deepseekSignInRequesting: "\u6B63\u5728\u83B7\u53D6 DeepSeek \u767B\u5F55\u9875\u2026",
2252
+ deepseekSignInWaiting: "\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210 DeepSeek \u767B\u5F55\u3002",
2253
+ deepseekSignInOpen: "\u624B\u52A8\u6253\u5F00\u767B\u5F55\u9875",
2254
+ deepseekSignInTimeout: "DeepSeek \u767B\u5F55\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
2255
+ deepseekAuthorizeUnavailable: "\u672A\u80FD\u83B7\u53D6 DeepSeek \u767B\u5F55\u9875\uFF0C\u8BF7\u91CD\u8BD5\u3002",
2256
+ changeServerUrl: "\u4FEE\u6539\u5730\u5740",
2257
+ startSignIn: "\u5F00\u59CB\u767B\u5F55",
2258
+ allowControlCurrentDevice: "\u5141\u8BB8\u63A7\u5236\u5F53\u524D\u8BBE\u5907",
2259
+ allowControlDevice: "\u5141\u8BB8\u63A7\u5236\u8BBE\u5907",
2260
+ connectedClientCount: "{count} \u53F0\u5DF2\u8FDE\u63A5",
2261
+ checkAcp: "\u68C0\u6D4B ACP",
2262
+ checkingAcp: "\u6B63\u5728\u68C0\u6D4B ACP\u2026",
2263
+ acpAvailable: "ACP \u53EF\u7528",
2264
+ acpUnavailable: "ACP \u4E0D\u53EF\u7528",
2265
+ acpHint: "\u901A\u8FC7 Agent Client Protocol \u8FDE\u63A5\u517C\u5BB9\u7684\u7F16\u7801 Agent\u3002",
2266
+ acpCheckPassed: "\u68C0\u6D4B\u901A\u8FC7",
2267
+ acpCheckFailed: "\u68C0\u6D4B\u5931\u8D25",
2268
+ addAcp: "\u6DFB\u52A0 ACP",
2269
+ acpName: "\u670D\u52A1\u540D\u79F0",
2270
+ acpCommand: "\u542F\u52A8\u547D\u4EE4",
2271
+ acpArguments: "\u547D\u4EE4\u53C2\u6570",
2272
+ removeAcp: "\u79FB\u9664",
2273
+ currentConnectedDevices: "\u5F53\u524D\u8FDE\u63A5\u7684\u8BBE\u5907",
2274
+ noConnectedClients: "\u76EE\u524D\u6CA1\u6709\u8BBE\u5907\u8FDE\u63A5\u5230\u8FD9\u53F0\u4E3B\u673A\u3002",
2275
+ unknownDevice: "\u672A\u77E5\u8BBE\u5907",
2276
+ exitRemoteAccount: "\u9000\u51FA\u8D26\u53F7",
2277
+ cancel: "\u53D6\u6D88",
2278
+ signOutImpact: "\u9000\u51FA\u540E\u4F1A\u65AD\u5F00\u672C\u63D2\u4EF6\u7684\u8FDE\u63A5\uFF0C\u5E76\u4E14\u4F1A\u4E00\u5E76\u9000\u51FA DSH \u7684 DeepSeek \u8D26\u53F7\u767B\u5F55\u3002",
2279
+ wechatLogin: "\u5FAE\u4FE1\u626B\u7801",
2280
+ githubLogin: "GitHub \u626B\u7801",
2281
+ zhihuLogin: "\u77E5\u4E4E\u626B\u7801",
2282
+ scanWithWeChat: "\u4F7F\u7528\u5FAE\u4FE1\u626B\u7801\u767B\u5F55",
2283
+ scanWithGitHub: "\u4F7F\u7528 GitHub \u626B\u7801\u767B\u5F55",
2284
+ scanWithZhihu: "\u4F7F\u7528\u77E5\u4E4E\u626B\u7801\u767B\u5F55",
2285
+ openInBrowser: "\u5728\u6D4F\u89C8\u5668\u4E2D\u7EE7\u7EED",
2286
+ scanLoginHint: "\u8BF7\u5728\u624B\u673A\u4E0A\u5B8C\u6210\u6388\u6743\uFF0C\u6B64\u7A97\u53E3\u4F1A\u81EA\u52A8\u7EE7\u7EED\u3002",
2287
+ currentServiceAddress: "\u5F53\u524D\u670D\u52A1\u5730\u5740\uFF1A",
2288
+ accountPasswordLogin: "\u8D26\u53F7\u5BC6\u7801",
2289
+ qrLoginExpired: "\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002",
2290
+ refreshQrCode: "\u5237\u65B0\u4E8C\u7EF4\u7801",
2291
+ codexVirtualWorkspace: "CodeX \u5DE5\u4F5C\u533A",
2292
+ codexVirtualSessions: "Sessions"
2293
+ }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
2294
+ constructor(message) {
2295
+ super(message), this.name = "ControlRouteUnavailableError";
2296
+ }
2297
+ };
2298
+ function controlRouteUnavailableStatus() {
2299
+ return {
2300
+ mode: "local",
2301
+ available: !1,
2302
+ controlUnavailable: !0,
2303
+ connected: !1,
2304
+ transport: "Disconnected",
2305
+ remoteFeatures: { commandList: !1, fileViewer: !1, terminal: !1, codex: !1 },
2306
+ hostAuthorizationAvailable: !1
2307
+ };
2308
+ }
2309
+ function normalizedPreferredTransports(value) {
2310
+ return value === void 0 || value.length === 0 ? [...defaultPreferredTransports] : [...value];
2311
+ }
2312
+ function formatLocalTime(value) {
2313
+ let date = new Date(value);
2314
+ return Number.isNaN(date.getTime()) ? "\u2014" : date.toLocaleString();
2315
+ }
2316
+ function formatByteSize(value) {
2317
+ if (value < 1024) return `${value.toLocaleString()} B`;
2318
+ let units = ["KiB", "MiB", "GiB"], amount = value, unit = "B";
2319
+ for (let nextUnit of units)
2320
+ if (amount /= 1024, unit = nextUnit, amount < 1024) break;
2321
+ return `${amount.toLocaleString(void 0, { maximumFractionDigits: 1 })} ${unit}`;
2322
+ }
2323
+ function formatBitrate(value) {
2324
+ let units = ["bit/s", "Kbit/s", "Mbit/s", "Gbit/s"], amount = value, unitIndex = 0;
2325
+ for (; amount >= 1e3 && unitIndex < units.length - 1; )
2326
+ amount /= 1e3, unitIndex += 1;
2327
+ return `${amount.toLocaleString(void 0, { maximumFractionDigits: 1 })} ${units[unitIndex]}`;
2328
+ }
2329
+ function shortDeviceId(value) {
2330
+ return value.length <= 14 ? value : `${value.slice(0, 8)}\u2026${value.slice(-4)}`;
2331
+ }
2332
+ function transportLabel(value, t) {
2333
+ return t(value === "lan" ? "remoteNetworkLan" : value === "p2p" ? "remoteNetworkP2p" : value === "turn" ? "remoteNetworkTurn" : "remoteNetworkRelay");
2334
+ }
2335
+ function transportDiagnosticLabel(value) {
2336
+ return value === "lan" ? "LAN" : value === "p2p" ? "P2P" : value === "turn" ? "TURN" : "Relay";
2337
+ }
2338
+ function transportProgressCopy(value) {
2339
+ return value === "lan" ? { label: "remoteProgressProbeLan", detail: "remoteProgressProbeLanDetail" } : value === "p2p" ? { label: "remoteProgressProbeP2p", detail: "remoteProgressProbeP2pDetail" } : value === "turn" ? { label: "remoteProgressProbeTurn", detail: "remoteProgressProbeTurnDetail" } : { label: "remoteProgressProbeRelay", detail: "remoteProgressProbeRelayDetail" };
2340
+ }
2341
+ function statusTransportPreference(status) {
2342
+ if (status?.transport === "LAN") return "lan";
2343
+ if (status?.transport === "P2P") return "p2p";
2344
+ if (status?.transport === "TURN") return "turn";
2345
+ if (status?.transport === "Relay") return "relay";
2346
+ }
2347
+ function connectedProgress(status) {
2348
+ let activeTransport = statusTransportPreference(status);
2349
+ if (activeTransport !== void 0)
2350
+ return {
2351
+ label: "remoteProgressReady",
2352
+ detail: "remoteProgressReadyDetail",
2353
+ percent: 100,
2354
+ transports: normalizedPreferredTransports(status?.preferredTransports),
2355
+ activeTransports: [activeTransport],
2356
+ routeVerb: "using"
2357
+ };
2358
+ }
2359
+ function loadingProgressPercent(elapsedMs) {
2360
+ return elapsedMs >= 6800 ? 96 : elapsedMs >= 3800 ? 93 : elapsedMs >= 1600 ? 89 : 84;
2361
+ }
2362
+ function observedConnectionProgress(status, targetDeviceId, preferredTransports, connectedStep, connectedAt) {
2363
+ let transports = normalizedPreferredTransports(status.preferredTransports ?? preferredTransports), connection = status.connectionProgress;
2364
+ if (connection?.targetDeviceId === targetDeviceId) {
2365
+ if (connection.phase === "checking-host")
2366
+ return { label: "remoteProgressCheckingHost", detail: "remoteProgressCheckingHostDetail", percent: 12 };
2367
+ if (connection.phase === "authorizing-peer")
2368
+ return { label: "remoteProgressAuthorizingPeer", detail: "remoteProgressAuthorizingPeerDetail", percent: 30 };
2369
+ let activeTransports = connection.activeTransports?.filter((transport) => transports.includes(transport)) ?? [];
2370
+ if (connection.phase === "probing") {
2371
+ let activeIndex = Math.max(0, ...activeTransports.map((transport) => transports.indexOf(transport)));
2372
+ return {
2373
+ ...activeTransports.length === 1 ? transportProgressCopy(activeTransports[0]) : { label: "remoteProgressOpeningChannel", detail: "remoteProgressOpeningChannelDetail" },
2374
+ percent: Math.min(76, 42 + activeIndex * 10),
2375
+ transports,
2376
+ activeTransports,
2377
+ routeVerb: "trying"
2378
+ };
2379
+ }
2380
+ return {
2381
+ ...connectedStep,
2382
+ percent: loadingProgressPercent(connectedAt === void 0 ? 0 : Date.now() - connectedAt),
2383
+ transports,
2384
+ activeTransports,
2385
+ routeVerb: "using"
2386
+ };
2387
+ }
2388
+ if (status.connectedTargetDeviceId !== targetDeviceId) return;
2389
+ let activeTransport = statusTransportPreference(status);
2390
+ return {
2391
+ ...connectedStep,
2392
+ percent: loadingProgressPercent(connectedAt === void 0 ? 0 : Date.now() - connectedAt),
2393
+ transports,
2394
+ ...activeTransport === void 0 ? {} : { activeTransports: [activeTransport], routeVerb: "using" }
2395
+ };
2396
+ }
2397
+ function connectionErrorMessage(code, t) {
2398
+ return t(code === "ACCOUNT_AUTH_REQUIRED" || code === "AUTH_INVALID" || code === "TOKEN_EXPIRED" ? "connectionAuthorizationExpired" : code === "CONNECTION_REPLACED" ? "connectionReplaced" : code === "SERVER_CREDENTIALS_BUSY" ? "connectionCredentialsBusy" : code === "DEVICE_REVOKED" ? "connectionDeviceRevoked" : code === "DEVICE_OWNERSHIP_REQUIRED" ? "connectionOwnershipRequired" : code === "RATE_LIMITED" ? "connectionRateLimited" : code === "UNSUPPORTED_VERSION" ? "connectionVersionMismatch" : code === "INVALID_MESSAGE" ? "connectionInvalidResponse" : code === "CONNECTION_FAILED" || code === "SERVER_NOT_CONFIGURED" ? "connectionReachability" : "connectionUnexpected");
2399
+ }
2400
+ async function setDeviceControl(control, enabled, authorized) {
2401
+ return enabled && !authorized ? await control("host.authorization.set", { enabled: !0 }) : await control("host.connection.set", { connected: enabled });
2402
+ }
2403
+ function connectionStatusLabel(status, t) {
2404
+ return status === void 0 ? t("checkingConnection") : status.online ? t("online") : status.reconnecting ? t(status.lastActiveAt === void 0 && status.error === void 0 ? "connecting" : "reconnecting") : t("offline");
2405
+ }
2406
+ function connectionStatusClass(status) {
2407
+ return status?.online ? " isOnline" : status?.reconnecting ? " isReconnecting" : status === void 0 ? "" : " isOffline";
2408
+ }
2409
+ window.__ModuleLoader__.load({
2410
+ id: clientModuleId,
2411
+ factory: (require2) => {
2412
+ let module = { exports: {} }, React = require2("react"), inject = [
2413
+ "connection",
2414
+ "slots",
2415
+ "locale",
2416
+ "workspaces",
2417
+ "sessions",
2418
+ "uiWorkspace"
2419
+ ];
2420
+ function RemoteProgressView(props) {
2421
+ let progress = props.progress;
2422
+ if (progress === void 0) return null;
2423
+ let percent = Math.max(0, Math.min(100, Math.round(progress.percent))), activeTransports = new Set(progress.activeTransports ?? []), detail = progress.transports !== void 0 && activeTransports.size > 0 ? React.createElement(
2424
+ "span",
2425
+ { className: "dshRemoteProgressRoute" },
2426
+ props.t(progress.routeVerb === "using" ? "remoteProgressUsingPrefix" : "remoteProgressTryingPrefix"),
2427
+ progress.transports.map((transport, index) => React.createElement(
2428
+ React.Fragment,
2429
+ { key: `${transport}:${index}` },
2430
+ index === 0 ? null : React.createElement("span", { className: "dshRemoteProgressRouteArrow", "aria-hidden": !0 }, " -> "),
2431
+ React.createElement("span", {
2432
+ className: activeTransports.has(transport) ? "isActive" : void 0
2433
+ }, transportDiagnosticLabel(transport))
2434
+ ))
2435
+ ) : props.t(progress.detail);
2436
+ return React.createElement(
2437
+ "div",
2438
+ {
2439
+ className: "dshRemoteProgress",
2440
+ role: "status",
2441
+ "aria-live": "polite"
2442
+ },
2443
+ React.createElement(
2444
+ "div",
2445
+ { className: "dshRemoteProgressHeader" },
2446
+ React.createElement("strong", null, props.t(progress.label)),
2447
+ React.createElement("span", null, `${percent}%`)
2448
+ ),
2449
+ React.createElement("p", null, detail),
2450
+ React.createElement("div", {
2451
+ className: "dshRemoteProgressBar",
2452
+ role: "progressbar",
2453
+ "aria-valuemin": 0,
2454
+ "aria-valuemax": 100,
2455
+ "aria-valuenow": percent,
2456
+ "aria-label": props.t(progress.label)
2457
+ }, React.createElement("span", { style: { transform: `scaleX(${percent / 100})` } }))
2458
+ );
2459
+ }
2460
+ async function runConnectHostProgress(preferredTransports, targetDeviceId, control, connectedStep, setProgress, progressRun, action, readyProgress) {
2461
+ let runId = progressRun.current + 1;
2462
+ progressRun.current = runId;
2463
+ let polling = !0, pollTimer, connectedAt, apply2 = (next) => {
2464
+ progressRun.current === runId && setProgress(next);
2465
+ }, poll = async () => {
2466
+ try {
2467
+ let status = await control("status");
2468
+ if (!polling || progressRun.current !== runId) return;
2469
+ (status.connectionProgress?.phase === "connected" || status.connectedTargetDeviceId === targetDeviceId) && connectedAt === void 0 && (connectedAt = Date.now());
2470
+ let next = observedConnectionProgress(status, targetDeviceId, preferredTransports, connectedStep, connectedAt);
2471
+ next !== void 0 && apply2(next);
2472
+ } catch {
2473
+ } finally {
2474
+ polling && progressRun.current === runId && (pollTimer = window.setTimeout(() => {
2475
+ poll();
2476
+ }, 300));
2477
+ }
2478
+ };
2479
+ apply2({ label: "remoteProgressCheckingHost", detail: "remoteProgressCheckingHostDetail", percent: 12 });
2480
+ let pending = action();
2481
+ poll();
2482
+ try {
2483
+ let result = await pending;
2484
+ return polling = !1, pollTimer !== void 0 && window.clearTimeout(pollTimer), apply2(readyProgress?.(result) ?? { label: "remoteProgressReady", detail: "remoteProgressReadyDetail", percent: 100 }), await new Promise((resolve) => window.setTimeout(resolve, 520)), result;
2485
+ } finally {
2486
+ polling = !1, pollTimer !== void 0 && window.clearTimeout(pollTimer), progressRun.current === runId && setProgress(void 0);
2487
+ }
2488
+ }
2489
+ function RemotePluginOptions(props) {
2490
+ let { t } = props, [open, setOpen] = React.useState(props.view === "page"), [serverUrl, setServerUrl] = React.useState(""), [codexEnabled, setCodexEnabled] = React.useState(!0), [codexBinary, setCodexBinary] = React.useState("codex"), [portsBusy, setPortsBusy] = React.useState(!1), [previewPorts, setPreviewPorts] = React.useState(""), role = "host", [registrationCode, setRegistrationCode] = React.useState(""), [associations, setAssociations] = React.useState({}), [loaded, setLoaded] = React.useState(!1), [writable, setWritable] = React.useState(!1), [busy, setBusy] = React.useState(!1), [terminalEnabled, setTerminalEnabled] = React.useState(!1), [terminalBusy, setTerminalBusy] = React.useState(!1), [codexBusy, setCodexBusy] = React.useState(!1), [acpBackends, setAcpBackends] = React.useState([]), [acpAvailability, setAcpAvailability] = React.useState({}), [acpChecking, setAcpChecking] = React.useState({}), [acpCheckResults, setAcpCheckResults] = React.useState({}), [addingAcp, setAddingAcp] = React.useState(!1), [acpName, setAcpName] = React.useState(""), [acpCommand, setAcpCommand] = React.useState(""), [acpArguments, setAcpArguments] = React.useState("acp"), [reconnectBusy, setReconnectBusy] = React.useState(!1), [hostStatus, setHostStatus] = React.useState(void 0), [hostName, setHostName] = React.useState(""), [hostDeviceId, setHostDeviceId] = React.useState(""), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0), [settingsView, setSettingsView] = React.useState(void 0), persistedServerUrl = settingsView?.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL, association = associations.client ?? associations.host, serverDirty = settingsView !== void 0 && serverUrl !== persistedServerUrl, draftDirty = serverDirty, applyView = (view) => {
2491
+ setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !0), setCodexBinary(view.config.codex?.binary ?? "codex"), setTerminalEnabled(view.config.terminal?.enabled ?? !0), setPreviewPorts((view.config.loopback?.ports ?? []).join(", ")), setAcpBackends((view.config.acp?.backends ?? []).map((item) => ({ id: item.id, enabled: item.enabled !== !1 }))), setAcpAvailability(view.acpAvailability ?? {}), setAssociations(view.associations ?? (view.association === void 0 ? {} : { host: view.association })), setWritable(view.writable), setLoaded(!0);
2492
+ }, load = async () => {
2493
+ let [view, status] = await Promise.all([
2494
+ props.control("settings.get"),
2495
+ props.control("status").catch(() => {
2496
+ })
2497
+ ]);
2498
+ applyView(view), setHostStatus(status?.host), setHostName(status?.deviceName ?? ""), setHostDeviceId(status?.host?.deviceId ?? "");
2499
+ };
2500
+ React.useEffect(() => {
2501
+ load().catch((reason) => setError(messageOf(reason)));
2502
+ }, []), React.useEffect(() => {
2503
+ if (association !== void 0)
2504
+ return props.statusFeed.subscribe((status) => {
2505
+ setHostStatus(status.host), setHostName(status.deviceName ?? ""), setHostDeviceId(status.host?.deviceId ?? "");
2506
+ });
2507
+ }, [association !== void 0]);
2508
+ let save = async (event) => {
2509
+ if (event?.preventDefault(), !(!writable || !serverDirty)) {
2510
+ setBusy(!0), setNotice(void 0), setError(void 0);
2511
+ try {
2512
+ let view = await props.control("settings.server.set", {
2513
+ serverUrl
2514
+ });
2515
+ applyView(view), setNotice({ key: "serverSaved" });
2516
+ } catch (reason) {
2517
+ setError(messageOf(reason));
2518
+ } finally {
2519
+ setBusy(!1);
2520
+ }
2521
+ }
2522
+ }, logout = async () => {
2523
+ setBusy(!0), setError(void 0), setNotice(void 0);
2524
+ try {
2525
+ let view = await props.control("settings.logout");
2526
+ applyView(view), setRegistrationCode(""), setNotice({ key: view.deepseekSignedOut === !0 ? "signedOutDeepseek" : "signedOut" });
2527
+ } catch (reason) {
2528
+ setError(messageOf(reason));
2529
+ } finally {
2530
+ setBusy(!1);
2531
+ }
2532
+ }, reconnectHost = async () => {
2533
+ setReconnectBusy(!0), setError(void 0), setNotice(void 0);
2534
+ try {
2535
+ let status = await props.control("host.reconnect");
2536
+ setHostStatus(status.host), setNotice({ key: "reconnectStarted" });
2537
+ } catch (reason) {
2538
+ setError(messageOf(reason));
2539
+ } finally {
2540
+ setReconnectBusy(!1);
2541
+ }
2542
+ }, setCurrentDeviceControl = async (enabled) => {
2543
+ setBusy(!0), setError(void 0), setNotice(void 0);
2544
+ try {
2545
+ setHostStatus((await setDeviceControl(props.control, enabled, hostStatus?.authorized === !0)).host);
2546
+ } catch (reason) {
2547
+ setError(messageOf(reason));
2548
+ } finally {
2549
+ setBusy(!1);
2550
+ }
2551
+ }, setCodexRemote = async (enabled) => {
2552
+ let previous = codexEnabled;
2553
+ setCodexEnabled(enabled), setCodexBusy(!0), setError(void 0), setNotice(void 0);
2554
+ try {
2555
+ let view = await props.control("settings.codex.set", { enabled });
2556
+ applyView(view), setNotice({ key: "codexSaved" });
2557
+ } catch (reason) {
2558
+ setCodexEnabled(previous), setError(messageOf(reason));
2559
+ } finally {
2560
+ setCodexBusy(!1);
2561
+ }
2562
+ }, setCodexBinaryPath = async (binary) => {
2563
+ setCodexBusy(!0), setError(void 0), setNotice(void 0);
2564
+ try {
2565
+ let view = await props.control("settings.codex.set", { enabled: codexEnabled, binary });
2566
+ applyView(view), setNotice({ key: "codexSaved" });
2567
+ } catch (reason) {
2568
+ setCodexBinary(settingsView?.config.codex?.binary ?? "codex"), setError(messageOf(reason));
2569
+ } finally {
2570
+ setCodexBusy(!1);
2571
+ }
2572
+ }, setTerminalRemote = async (enabled) => {
2573
+ let previous = terminalEnabled, portsDraft = previewPorts;
2574
+ setTerminalEnabled(enabled), setTerminalBusy(!0), setError(void 0), setNotice(void 0);
2575
+ try {
2576
+ let view = await props.control("settings.development.set", { terminalEnabled: enabled });
2577
+ applyView(view), setPreviewPorts(portsDraft), setNotice({ key: "terminalSaved" });
2578
+ } catch (reason) {
2579
+ setTerminalEnabled(previous), setError(messageOf(reason));
2580
+ } finally {
2581
+ setTerminalBusy(!1);
2582
+ }
2583
+ }, savePreviewPorts = async () => {
2584
+ setPortsBusy(!0), setError(void 0), setNotice(void 0);
2585
+ try {
2586
+ let ports = previewPorts.trim() === "" ? [] : previewPorts.split(/[,,]/).map((value) => Number(value.trim())), view = await props.control("settings.development.set", { ports });
2587
+ applyView(view), setNotice({ key: "developmentSaved" });
2588
+ } catch (reason) {
2589
+ setError(messageOf(reason));
2590
+ } finally {
2591
+ setPortsBusy(!1);
2592
+ }
2593
+ }, checkAcp = async (backend) => {
2594
+ setAcpChecking((current) => ({ ...current, [backend]: !0 })), setAcpCheckResults((current) => ({ ...current, [backend]: void 0 })), setError(void 0);
2595
+ try {
2596
+ let view = await props.control("settings.get");
2597
+ applyView(view);
2598
+ let available = view.acpAvailability?.[backend] === !0;
2599
+ if (!available) {
2600
+ let disabledView = await props.control("settings.acp.set", { backend, enabled: !1 });
2601
+ applyView(disabledView);
2602
+ }
2603
+ setAcpCheckResults((current) => ({ ...current, [backend]: available })), setNotice({ key: available ? "acpAvailable" : "acpUnavailable" }), window.setTimeout(() => setAcpCheckResults((current) => ({ ...current, [backend]: void 0 })), 5e3);
2604
+ } catch (reason) {
2605
+ setError(messageOf(reason));
2606
+ } finally {
2607
+ setAcpChecking((current) => ({ ...current, [backend]: !1 }));
2608
+ }
2609
+ }, addAcp = async () => {
2610
+ setBusy(!0), setError(void 0);
2611
+ try {
2612
+ let view = await props.control("settings.acp.add", {
2613
+ id: acpName.trim(),
2614
+ command: acpCommand.trim(),
2615
+ args: acpArguments.trim() === "" ? [] : acpArguments.trim().split(/\s+/)
2616
+ });
2617
+ applyView(view), setAddingAcp(!1), setAcpName(""), setAcpCommand(""), setAcpArguments("acp");
2618
+ } catch (reason) {
2619
+ setError(messageOf(reason));
2620
+ } finally {
2621
+ setBusy(!1);
2622
+ }
2623
+ }, removeAcp = async (backend) => {
2624
+ setBusy(!0), setError(void 0);
2625
+ try {
2626
+ let view = await props.control("settings.acp.remove", { id: backend });
2627
+ applyView(view);
2628
+ } catch (reason) {
2629
+ setError(messageOf(reason));
2630
+ } finally {
2631
+ setBusy(!1);
2632
+ }
2633
+ }, discard = () => {
2634
+ settingsView !== void 0 && applyView(settingsView), setRegistrationCode(""), setNotice(void 0), setError(void 0);
2635
+ }, developmentSetting = React.createElement(
2636
+ "section",
2637
+ { className: "dshRemoteDevelopmentSettings" },
2638
+ React.createElement(
2639
+ "div",
2640
+ { className: "dshRemoteAuthorizationSetting" },
2641
+ React.createElement(
2642
+ "div",
2643
+ null,
2644
+ React.createElement("strong", null, t("terminalRemote")),
2645
+ React.createElement("p", null, t("terminalRemoteHint"))
2646
+ ),
2647
+ React.createElement("input", {
2648
+ type: "checkbox",
2649
+ role: "switch",
2650
+ checked: terminalEnabled,
2651
+ disabled: busy || terminalBusy || !writable,
2652
+ "aria-label": t("terminalRemote"),
2653
+ onChange: (event) => void setTerminalRemote(event.target.checked)
2654
+ })
2655
+ ),
2656
+ React.createElement(
2657
+ "div",
2658
+ { className: "dshRemotePathField" },
2659
+ React.createElement("span", null, t("previewPorts")),
2660
+ React.createElement(
2661
+ "div",
2662
+ { className: "dshRemotePortsRow" },
2663
+ React.createElement("input", {
2664
+ value: previewPorts,
2665
+ maxLength: 128,
2666
+ disabled: !writable,
2667
+ placeholder: "3000, 5173",
2668
+ "aria-label": t("previewPorts"),
2669
+ onChange: (event) => setPreviewPorts(event.target.value)
2670
+ }),
2671
+ React.createElement("button", {
2672
+ type: "button",
2673
+ disabled: portsBusy || terminalBusy || !writable,
2674
+ onClick: () => void savePreviewPorts()
2675
+ }, t("developmentSave"))
2676
+ ),
2677
+ React.createElement("small", null, t("previewPortsHint"))
2678
+ )
2679
+ ), codexBinaryConfigured = settingsView?.config.codex?.binary ?? "codex", codexBinaryDiscovered = settingsView?.discoveredCodexBinary, codexBinaryPinned = codexBinaryConfigured !== "codex", codexBinaryEditable = codexBinaryPinned || codexBinaryDiscovered === void 0, codexSetting = React.createElement(
2680
+ React.Fragment,
2681
+ null,
2682
+ React.createElement(
2683
+ "div",
2684
+ { className: "dshRemoteAuthorizationSetting" },
2685
+ React.createElement(
2686
+ "div",
2687
+ null,
2688
+ React.createElement("strong", null, t("codexRemote")),
2689
+ React.createElement("p", null, t("codexRemoteHint"))
2690
+ ),
2691
+ React.createElement("input", {
2692
+ type: "checkbox",
2693
+ role: "switch",
2694
+ disabled: busy || codexBusy || !writable,
2695
+ "aria-label": t("codexRemote"),
2696
+ checked: codexEnabled,
2697
+ onChange: (event) => void setCodexRemote(event.target.checked)
2698
+ })
2699
+ ),
2700
+ React.createElement(
2701
+ "div",
2702
+ { className: "dshRemoteCodexBinary" },
2703
+ React.createElement("input", {
2704
+ type: "text",
2705
+ value: codexBinaryEditable ? codexBinary : codexBinaryDiscovered ?? "",
2706
+ readOnly: !codexBinaryEditable,
2707
+ disabled: busy || codexBusy || !writable,
2708
+ className: codexBinaryEditable ? "" : "isDiscovered",
2709
+ placeholder: codexBinaryEditable ? t("codexBinaryPlaceholder") : void 0,
2710
+ "aria-label": t("codexBinaryLabel"),
2711
+ onChange: (event) => setCodexBinary(event.target.value),
2712
+ onKeyDown: (event) => {
2713
+ event.key === "Enter" && codexBinaryEditable && setCodexBinaryPath(codexBinary);
2714
+ }
2715
+ }),
2716
+ codexBinaryEditable ? React.createElement("button", {
2717
+ type: "button",
2718
+ className: "dshRemoteDiscard",
2719
+ disabled: busy || codexBusy || !writable,
2720
+ onClick: () => void setCodexBinaryPath(codexBinary)
2721
+ }, t("codexBinaryConfirm")) : null,
2722
+ codexBinaryPinned ? React.createElement("button", {
2723
+ type: "button",
2724
+ className: "dshRemoteDiscard",
2725
+ disabled: busy || codexBusy || !writable,
2726
+ onClick: () => {
2727
+ setCodexBinary(""), setCodexBinaryPath("");
2728
+ }
2729
+ }, t("codexBinaryAuto")) : null,
2730
+ // The greyed field already shows the discovered path, so the only line
2731
+ // worth printing is the one that asks the user for something.
2732
+ codexBinaryPinned || codexBinaryDiscovered === void 0 ? React.createElement("p", null, t(codexBinaryPinned ? "codexBinaryPinned" : "codexBinaryMissing")) : null
2733
+ )
2734
+ ), acpSetting = React.createElement(
2735
+ "details",
2736
+ { className: "dshRemoteAuthorizationSetting dshRemoteAcpSetting" },
2737
+ React.createElement(
2738
+ "summary",
2739
+ null,
2740
+ React.createElement(
2741
+ "div",
2742
+ { className: "dshRemoteAcpSummaryText" },
2743
+ React.createElement("strong", null, "ACP Agent backends"),
2744
+ React.createElement("p", null, t("acpHint"))
2745
+ )
2746
+ ),
2747
+ React.createElement(
2748
+ "div",
2749
+ { className: "dshRemoteAcpList" },
2750
+ acpBackends.map((item) => React.createElement(
2751
+ "div",
2752
+ { key: item.id, className: "dshRemoteAuthorizationSetting" },
2753
+ React.createElement("span", null, item.id),
2754
+ React.createElement(
2755
+ "span",
2756
+ { className: "dshRemoteAcpCheckCell" },
2757
+ React.createElement(
2758
+ "a",
2759
+ { href: `#check-acp-${item.id}`, className: `dshRemoteAcpCheckLink${acpChecking[item.id] ? " isChecking" : acpCheckResults[item.id] === void 0 ? "" : acpCheckResults[item.id] ? " isPassed" : " isFailed"}`, onClick: (event) => {
2760
+ event.preventDefault(), checkAcp(item.id);
2761
+ } },
2762
+ acpChecking[item.id] ? t("checkingAcp") : acpCheckResults[item.id] === void 0 ? t("checkAcp") : t(acpCheckResults[item.id] ? "acpCheckPassed" : "acpCheckFailed")
2763
+ )
2764
+ ),
2765
+ ["codex", "cursor", "kimi"].includes(item.id) ? null : React.createElement("a", { href: `#remove-acp-${item.id}`, className: "dshRemoteAcpRemoveLink", onClick: (event) => {
2766
+ event.preventDefault(), removeAcp(item.id);
2767
+ } }, t("removeAcp")),
2768
+ React.createElement("input", {
2769
+ type: "checkbox",
2770
+ role: "switch",
2771
+ checked: item.enabled && acpAvailability[item.id] === !0,
2772
+ disabled: busy || !writable || !acpAvailability[item.id],
2773
+ onChange: (event) => void props.control("settings.acp.set", { backend: item.id, enabled: event.target.checked }).then((view) => {
2774
+ applyView(view), setAcpBackends((view.config.acp?.backends ?? []).map((v) => ({ id: v.id, enabled: v.enabled !== !1 })));
2775
+ }).catch((reason) => setError(messageOf(reason)))
2776
+ })
2777
+ )),
2778
+ addingAcp ? React.createElement(
2779
+ "div",
2780
+ { className: "dshRemoteAcpAddForm" },
2781
+ React.createElement("input", { value: acpName, placeholder: t("acpName"), "aria-label": t("acpName"), onChange: (event) => setAcpName(event.target.value) }),
2782
+ React.createElement("input", { value: acpCommand, placeholder: t("acpCommand"), "aria-label": t("acpCommand"), onChange: (event) => setAcpCommand(event.target.value) }),
2783
+ React.createElement("input", { value: acpArguments, placeholder: t("acpArguments"), "aria-label": t("acpArguments"), onChange: (event) => setAcpArguments(event.target.value) }),
2784
+ React.createElement("button", { type: "button", disabled: busy || acpName.trim() === "" || acpCommand.trim() === "", onClick: () => void addAcp() }, t("addAcp"))
2785
+ ) : React.createElement("a", { href: "#add-acp", className: "dshRemoteAcpAddLink", onClick: (event) => {
2786
+ event.preventDefault(), setAddingAcp(!0);
2787
+ } }, t("addAcp"))
2788
+ )
2789
+ );
2790
+ return props.view === "summary" ? React.createElement("span", null, t("pluginDescription")) : React.createElement(
2791
+ props.view === "page" ? "div" : "li",
2792
+ { className: `dshRemotePluginCard${open ? " isOpen" : ""}${props.view === "page" ? " dshRemotePluginModern" : ""}` },
2793
+ React.createElement(
2794
+ "div",
2795
+ { className: "dshRemotePluginCardHeader" },
2796
+ React.createElement(
2797
+ "button",
2798
+ {
2799
+ type: "button",
2800
+ className: "dshRemotePluginCardToggle",
2801
+ "aria-expanded": open,
2802
+ "aria-label": t(open ? "collapseSettings" : "expandSettings", { name: t("pluginTitle") }),
2803
+ onClick: () => setOpen((current) => !current)
2804
+ },
2805
+ React.createElement(
2806
+ "span",
2807
+ { className: "dshRemotePluginCardHeading" },
2808
+ React.createElement("strong", null, t("pluginTitle")),
2809
+ React.createElement("span", null, t("pluginDescription"))
2810
+ ),
2811
+ draftDirty ? React.createElement("span", { className: "dshRemotePluginCardStatus" }, t("unsaved")) : association === void 0 ? null : React.createElement("span", {
2812
+ className: `dshRemotePluginCardStatus${connectionStatusClass(hostStatus)}`
2813
+ }, hostStatus === void 0 ? t("associated") : connectionStatusLabel(hostStatus, t)),
2814
+ React.createElement("span", { className: "dshRemotePluginCardChevron", "aria-hidden": !0 }, "\u2304")
2815
+ )
2816
+ ),
2817
+ open ? React.createElement(
2818
+ "div",
2819
+ { className: "dshRemotePluginCardBody" },
2820
+ loaded ? association !== void 0 ? React.createElement(
2821
+ "div",
2822
+ { className: "dshRemoteSettings" },
2823
+ React.createElement(
2824
+ "div",
2825
+ { className: "dshRemoteSettingsTop" },
2826
+ React.createElement(
2827
+ "div",
2828
+ { className: "dshRemoteAssociation" },
2829
+ React.createElement("span", null, t(association.account === void 0 ? "authorization" : "account")),
2830
+ React.createElement("strong", null, association.account ?? t("authorizationComplete")),
2831
+ React.createElement("p", null, association.account === void 0 ? serverUrl : t("authorizedOn", { role: "Remote", serverUrl }))
2832
+ )
2833
+ ),
2834
+ React.createElement(
2835
+ "div",
2836
+ { className: "dshRemoteHostIdentity" },
2837
+ React.createElement(
2838
+ "div",
2839
+ null,
2840
+ React.createElement("span", null, t("hostName")),
2841
+ React.createElement("strong", null, hostName || "\u2014")
2842
+ ),
2843
+ React.createElement(
2844
+ "div",
2845
+ null,
2846
+ React.createElement("span", null, t("deviceId")),
2847
+ React.createElement("code", null, hostDeviceId || "\u2014")
2848
+ )
2849
+ ),
2850
+ React.createElement(
2851
+ "div",
2852
+ { className: "dshRemoteField" },
2853
+ React.createElement("label", { htmlFor: "dsh-remote-server-url-authorized" }, t("serverUrl")),
2854
+ React.createElement("input", {
2855
+ id: "dsh-remote-server-url-authorized",
2856
+ type: "url",
2857
+ value: serverUrl,
2858
+ disabled: !0,
2859
+ required: !0,
2860
+ placeholder: DEFAULT_REMOTE_SERVER_URL,
2861
+ onChange: (event) => {
2862
+ setServerUrl(event.target.value), setNotice(void 0);
2863
+ }
2864
+ }),
2865
+ React.createElement("p", null, t("serverUrlHint"))
2866
+ ),
2867
+ developmentSetting,
2868
+ codexSetting,
2869
+ acpSetting,
2870
+ React.createElement(
2871
+ "div",
2872
+ { className: "dshRemoteAuthorizationSetting" },
2873
+ React.createElement(
2874
+ "div",
2875
+ null,
2876
+ React.createElement("strong", null, t("allowControlCurrentDevice")),
2877
+ React.createElement("p", null, t("thisMachineHost"))
2878
+ ),
2879
+ React.createElement("input", {
2880
+ type: "checkbox",
2881
+ role: "switch",
2882
+ disabled: busy,
2883
+ "aria-label": t("allowControlCurrentDevice"),
2884
+ checked: hostStatus?.authorized === !0 && hostStatus?.paused !== !0,
2885
+ onChange: (event) => void setCurrentDeviceControl(event.target.checked)
2886
+ })
2887
+ ),
2888
+ React.createElement(
2889
+ "div",
2890
+ { className: "dshRemoteConnection", "aria-live": "polite" },
2891
+ React.createElement(
2892
+ "div",
2893
+ { className: "dshRemoteConnectionSummary" },
2894
+ React.createElement("span", null, t("connection")),
2895
+ React.createElement(
2896
+ "strong",
2897
+ null,
2898
+ React.createElement("span", {
2899
+ className: `dshRemoteConnectionDot${connectionStatusClass(hostStatus)}`,
2900
+ "aria-hidden": !0
2901
+ }),
2902
+ connectionStatusLabel(hostStatus, t)
2903
+ ),
2904
+ React.createElement("p", null, hostStatus === void 0 ? t("checkingConnection") : hostStatus.lastActiveAt === void 0 ? t("neverConnected") : t("lastActive", { time: formatLocalTime(hostStatus.lastActiveAt) }))
2905
+ ),
2906
+ React.createElement("button", {
2907
+ type: "button",
2908
+ className: "dshRemoteReconnect",
2909
+ disabled: reconnectBusy || hostStatus?.configured === !1,
2910
+ onClick: () => void reconnectHost()
2911
+ }, t(reconnectBusy ? "reconnectingAction" : "reconnect"))
2912
+ ),
2913
+ hostStatus?.error === void 0 || hostStatus.online ? null : React.createElement("p", { className: "dshRemoteConnectionIssue", role: "status" }, connectionErrorMessage(hostStatus.error, t)),
2914
+ writable ? null : React.createElement("p", { className: "dshRemoteError" }, t("readOnly")),
2915
+ React.createElement(
2916
+ "div",
2917
+ { className: "dshRemoteSettingsFooter" },
2918
+ React.createElement("p", {
2919
+ className: error !== void 0 ? "dshRemoteError" : "dshRemoteNotice",
2920
+ role: error !== void 0 ? "alert" : "status"
2921
+ }, error ?? (notice === void 0 ? "" : t(notice.key, notice.params))),
2922
+ draftDirty ? React.createElement(
2923
+ React.Fragment,
2924
+ null,
2925
+ React.createElement("button", { type: "button", className: "dshRemoteDiscard", disabled: busy, onClick: discard }, t("discard")),
2926
+ React.createElement("button", { type: "button", className: "dshRemoteSave", disabled: busy || !writable, onClick: () => void save() }, t(busy ? "saving" : "save")),
2927
+ React.createElement("button", { type: "button", className: "dshRemoteDiscard", disabled: busy || !writable, onClick: () => void logout() }, t(busy ? "signingOut" : "signOut"))
2928
+ ) : React.createElement("button", {
2929
+ type: "button",
2930
+ className: "dshRemoteDiscard",
2931
+ disabled: busy || !writable,
2932
+ onClick: () => void logout()
2933
+ }, t(busy ? "signingOut" : "signOut"))
2934
+ )
2935
+ ) : React.createElement(
2936
+ "form",
2937
+ { className: "dshRemoteSettings", noValidate: !0, onSubmit: (event) => void save(event) },
2938
+ React.createElement(
2939
+ "div",
2940
+ { className: "dshRemoteHostIdentity" },
2941
+ React.createElement(
2942
+ "div",
2943
+ null,
2944
+ React.createElement("span", null, t("hostName")),
2945
+ React.createElement("strong", null, hostName || "\u2014")
2946
+ ),
2947
+ React.createElement(
2948
+ "div",
2949
+ null,
2950
+ React.createElement("span", null, t("deviceId")),
2951
+ React.createElement("code", null, hostDeviceId || "\u2014")
2952
+ )
2953
+ ),
2954
+ React.createElement(
2955
+ "div",
2956
+ { className: "dshRemoteField" },
2957
+ React.createElement("label", { htmlFor: "dsh-remote-server-url" }, t("serverUrl")),
2958
+ React.createElement("input", {
2959
+ id: "dsh-remote-server-url",
2960
+ type: "url",
2961
+ value: serverUrl,
2962
+ disabled: busy || !writable,
2963
+ required: !0,
2964
+ placeholder: DEFAULT_REMOTE_SERVER_URL,
2965
+ onChange: (event) => {
2966
+ setServerUrl(event.target.value), setNotice(void 0);
2967
+ }
2968
+ }),
2969
+ React.createElement("p", null, t("serverUrlHint"))
2970
+ ),
2971
+ developmentSetting,
2972
+ codexSetting,
2973
+ acpSetting,
2974
+ React.createElement("p", { className: "dshRemoteSettingsState" }, t("authorizeFromRemote")),
2975
+ writable ? null : React.createElement("p", { className: "dshRemoteError" }, t("readOnly")),
2976
+ React.createElement(
2977
+ "div",
2978
+ { className: "dshRemoteSettingsFooter" },
2979
+ React.createElement("p", {
2980
+ className: error !== void 0 ? "dshRemoteError" : "dshRemoteNotice",
2981
+ role: error !== void 0 ? "alert" : "status"
2982
+ }, error ?? (notice === void 0 ? "" : t(notice.key, notice.params))),
2983
+ React.createElement("button", { type: "button", className: "dshRemoteDiscard", disabled: busy || !draftDirty, onClick: discard }, t("discard")),
2984
+ React.createElement("button", { type: "submit", className: "dshRemoteSave", disabled: busy || !writable || !serverDirty }, t(busy ? "saving" : "save"))
2985
+ )
2986
+ ) : React.createElement("p", { className: "dshRemoteSettingsState" }, error ?? t("loadingSettings"))
2987
+ ) : null
2988
+ );
2989
+ }
2990
+ function RemoteWorkspaceAction(props) {
2991
+ let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [selectedHost, setSelectedHost] = React.useState(void 0), [connectingHost, setConnectingHost] = React.useState(void 0), [workspaces, setWorkspaces] = React.useState([]), [codexWorkspaces, setCodexWorkspaces] = React.useState([]), [workspaceBackend, setWorkspaceBackend] = React.useState("harness"), [codexWorkspaceId, setCodexWorkspaceId] = React.useState(void 0), [directory, setDirectory] = React.useState(void 0), [path, setPath] = React.useState(""), [addingWorkspace, setAddingWorkspace] = React.useState(!1), [showAllWorkspaces, setShowAllWorkspaces] = React.useState(!1), [showAllCodexWorkspaces, setShowAllCodexWorkspaces] = React.useState(!1), [devicesOpen, setDevicesOpen] = React.useState(!1), workspaceListId = "dsh-remote-workspace-list", codexWorkspaceHeadingId = "dsh-remote-codex-workspace-heading", codexWorkspaceListId = "dsh-remote-codex-workspace-list", [busy, setBusy] = React.useState(!1), [needsAuthorization, setNeedsAuthorization] = React.useState(!1), [authorizationResolved, setAuthorizationResolved] = React.useState(!1), [email, setEmail] = React.useState(""), [password, setPassword] = React.useState(""), [loginServerUrl, setLoginServerUrl] = React.useState(DEFAULT_REMOTE_SERVER_URL), [editingServerUrl, setEditingServerUrl] = React.useState(!1), [awaitingDeepSeek, setAwaitingDeepSeek] = React.useState(!1), [pendingAuthorizeUrl, setPendingAuthorizeUrl] = React.useState(void 0), [loginMethod, setLoginMethod] = React.useState(
2992
+ isEnabledQrProvider(props.preferredQrProvider) ? props.preferredQrProvider : defaultQrProvider
2993
+ ), [loginMethodManuallySelected, setLoginMethodManuallySelected] = React.useState(!1), [qrSession, setQrSession] = React.useState(void 0), [qrImage, setQrImage] = React.useState(void 0), [qrExpired, setQrExpired] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), qrFlowRun = React.useRef(0), [notice, setNotice] = React.useState(void 0), [confirmingSignOut, setConfirmingSignOut] = React.useState(!1), [error, setError] = React.useState(void 0);
2994
+ React.useEffect(() => {
2995
+ open || setDevicesOpen(!1);
2996
+ }, [open]), React.useEffect(() => {
2997
+ if (!open) return;
2998
+ let closeOnEscape = (event) => {
2999
+ if (event.key === "Escape") {
3000
+ if (devicesOpen) {
3001
+ event.stopPropagation(), setDevicesOpen(!1);
3002
+ return;
3003
+ }
3004
+ setOpen(!1);
3005
+ }
3006
+ };
3007
+ return window.addEventListener("keydown", closeOnEscape), () => window.removeEventListener("keydown", closeOnEscape);
3008
+ }, [open, devicesOpen]), React.useEffect(() => {
3009
+ if (!devicesOpen) return;
3010
+ let closeOnPointer = (event) => {
3011
+ let target = event.target;
3012
+ target instanceof Element && target.closest(".dshRemoteConnectedMenu") === null && setDevicesOpen(!1);
3013
+ };
3014
+ return window.addEventListener("mousedown", closeOnPointer), () => window.removeEventListener("mousedown", closeOnPointer);
3015
+ }, [devicesOpen]), React.useEffect(() => {
3016
+ (status?.host?.connectedClients?.length ?? 0) === 0 && setDevicesOpen(!1);
3017
+ }, [status?.host?.connectedClients?.length]), React.useEffect(() => {
3018
+ props.control("status").then(setStatus).catch(() => {
3019
+ });
3020
+ }, []), React.useEffect(() => {
3021
+ status?.serverUrl !== void 0 && loginServerUrl === DEFAULT_REMOTE_SERVER_URL && setLoginServerUrl(status.serverUrl);
3022
+ }, [status?.serverUrl]), React.useEffect(() => {
3023
+ let remoteActive = status?.mode === "remote";
3024
+ return document.documentElement.classList.toggle("dshRemoteTargetActive", remoteActive), () => {
3025
+ remoteActive && document.documentElement.classList.remove("dshRemoteTargetActive");
3026
+ };
3027
+ }, [status?.mode]);
3028
+ let startQrLogin = async (provider) => {
3029
+ let run = ++qrFlowRun.current;
3030
+ setBusy(!0), setError(void 0), setQrExpired(!1);
3031
+ try {
3032
+ let session = await props.control("client.account.qr.start", { provider }), image = await import_qrcode.default.toDataURL(session.scanUrl, {
3033
+ width: 184,
3034
+ margin: 1,
3035
+ errorCorrectionLevel: "L"
3036
+ });
3037
+ if (run !== qrFlowRun.current) return;
3038
+ setQrSession(session), setQrImage(image);
3039
+ } catch (reason) {
3040
+ run === qrFlowRun.current && setError(messageOf(reason));
3041
+ } finally {
3042
+ run === qrFlowRun.current && setBusy(!1);
3043
+ }
3044
+ };
3045
+ React.useEffect(() => {
3046
+ !QR_LOGIN_ENABLED || !open || !needsAuthorization || loginMethod === "password" || qrSession !== void 0 || qrExpired || startQrLogin(loginMethod);
3047
+ }, [open, needsAuthorization, loginMethod, qrSession, qrExpired]), React.useEffect(() => {
3048
+ if (!QR_LOGIN_ENABLED || !open || loginMethod === "password" || qrSession === void 0) return;
3049
+ let active = !0, polling = !1, settled = !1, run = qrFlowRun.current, timer, poll = () => {
3050
+ polling || settled || (polling = !0, props.control("client.account.qr.poll", { qrId: qrSession.qrId }).then(async (result) => {
3051
+ if (!(!active || settled || run !== qrFlowRun.current))
3052
+ if (result.status === "complete") {
3053
+ settled = !0, timer !== void 0 && window.clearInterval(timer), setBusy(!0), setError(void 0), setQrExpired(!1), setNeedsAuthorization(!1);
3054
+ try {
3055
+ let [nextDevices, nextStatus] = await Promise.all([
3056
+ props.control("devices"),
3057
+ props.control("status")
3058
+ ]);
3059
+ active && run === qrFlowRun.current && (setDevices(nextDevices), setStatus(nextStatus));
3060
+ } catch (reason) {
3061
+ active && run === qrFlowRun.current && setError(messageOf(reason));
3062
+ } finally {
3063
+ run === qrFlowRun.current && (setQrSession(void 0), setQrImage(void 0), setBusy(!1));
3064
+ }
3065
+ } else result.status === "expired" && (settled = !0, timer !== void 0 && window.clearInterval(timer), setQrExpired(!0), setQrSession(void 0), setQrImage(void 0));
3066
+ }).catch((reason) => {
3067
+ active && !settled && run === qrFlowRun.current && setError(messageOf(reason));
3068
+ }).finally(() => {
3069
+ polling = !1;
3070
+ }));
3071
+ };
3072
+ return poll(), timer = window.setInterval(poll, 1500), () => {
3073
+ active = !1, timer !== void 0 && window.clearInterval(timer);
3074
+ };
3075
+ }, [open, loginMethod, qrSession]), React.useEffect(() => {
3076
+ loginMethodManuallySelected || loginMethod === props.preferredQrProvider || (qrFlowRun.current += 1, setLoginMethod(props.preferredQrProvider), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
3077
+ }, [props.preferredQrProvider, loginMethodManuallySelected]);
3078
+ let selectLoginMethod = (method) => {
3079
+ setLoginMethodManuallySelected(!0), method !== loginMethod && (qrFlowRun.current += 1, setLoginMethod(method), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
3080
+ }, orderedQrProviders = ENABLED_QR_PROVIDERS, qrLoginTab = (provider) => React.createElement("button", {
3081
+ key: provider,
3082
+ type: "button",
3083
+ role: "tab",
3084
+ id: `dsh-remote-${provider}-tab`,
3085
+ "aria-selected": loginMethod === provider,
3086
+ "aria-controls": `dsh-remote-${provider}-panel`,
3087
+ className: loginMethod === provider ? "isActive" : "",
3088
+ disabled: busy,
3089
+ onClick: () => selectLoginMethod(provider)
3090
+ }, t(QR_PROVIDER_LABELS[provider])), selectHost = async (host) => {
3091
+ setBusy(!0), setError(void 0), setConnectingHost(host), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1);
3092
+ try {
3093
+ let result = await runConnectHostProgress(
3094
+ status?.preferredTransports,
3095
+ host.deviceId,
3096
+ props.control,
3097
+ { label: "remoteProgressLoadingWorkspaces", detail: "remoteProgressLoadingWorkspacesDetail" },
3098
+ setProgress,
3099
+ progressRun,
3100
+ async () => {
3101
+ let nextWorkspaces = await props.control("workspaces.list", {
3102
+ targetDeviceId: host.deviceId
3103
+ }), nextCodexWorkspaces = await props.control("codex.workspaces.list", {
3104
+ targetDeviceId: host.deviceId
3105
+ }).catch(() => []), nextStatus = await props.control("status").catch(() => {
3106
+ });
3107
+ return nextStatus !== void 0 && setStatus(nextStatus), { workspaces: nextWorkspaces, codexWorkspaces: nextCodexWorkspaces, status: nextStatus };
3108
+ },
3109
+ (result2) => connectedProgress(result2.status)
3110
+ );
3111
+ setWorkspaces(result.workspaces), setCodexWorkspaces(result.codexWorkspaces), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setSelectedHost(host), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3112
+ } catch (reason) {
3113
+ setError(messageOf(reason));
3114
+ } finally {
3115
+ setConnectingHost(void 0), setBusy(!1);
3116
+ }
3117
+ }, browseDirectory = async (nextPath) => {
3118
+ if (selectedHost !== void 0) {
3119
+ setBusy(!0), setError(void 0);
3120
+ try {
3121
+ let listing = await props.control("directory.list", {
3122
+ targetDeviceId: selectedHost.deviceId,
3123
+ ...nextPath === void 0 ? {} : { path: nextPath }
3124
+ });
3125
+ setDirectory(listing), setCodexWorkspaceId(void 0), setPath(listing.path);
3126
+ } catch (reason) {
3127
+ setError(messageOf(reason));
3128
+ } finally {
3129
+ setBusy(!1);
3130
+ }
3131
+ }
3132
+ }, startAddingWorkspace = (backend) => {
3133
+ setAddingWorkspace(!0), setWorkspaceBackend(backend), setCodexWorkspaceId(void 0), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setDirectory(void 0), setPath(""), browseDirectory();
3134
+ }, cancelAddingWorkspace = () => {
3135
+ setAddingWorkspace(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setDirectory(void 0), setPath("");
3136
+ }, refreshRemote = async () => {
3137
+ setBusy(!0), setNotice(void 0), setError(void 0);
3138
+ try {
3139
+ let nextStatus = await props.control("status");
3140
+ if (setStatus(nextStatus), !nextStatus.available) {
3141
+ setDevices([]), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3142
+ return;
3143
+ }
3144
+ try {
3145
+ let local = await props.control("authorization.local");
3146
+ setNeedsAuthorization(local?.stored !== !0);
3147
+ } catch {
3148
+ setNeedsAuthorization(!1);
3149
+ } finally {
3150
+ setAuthorizationResolved(!0);
3151
+ }
3152
+ try {
3153
+ let nextDevices = await props.control("devices");
3154
+ if (setDevices(nextDevices), setNeedsAuthorization(!1), selectedHost !== void 0) {
3155
+ let nextSelectedHost = nextDevices.find((device) => device.deviceId === selectedHost.deviceId);
3156
+ nextSelectedHost === void 0 ? (setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0)) : setSelectedHost(nextSelectedHost);
3157
+ }
3158
+ } catch {
3159
+ setDevices([]), setNeedsAuthorization(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3160
+ }
3161
+ } catch (reason) {
3162
+ setError(messageOf(reason)), setAuthorizationResolved(!0);
3163
+ } finally {
3164
+ setBusy(!1);
3165
+ }
3166
+ }, show = async () => {
3167
+ setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setOpen(!0), await refreshRemote();
3168
+ };
3169
+ React.useEffect(() => {
3170
+ if (!(!open || selectedHost !== void 0))
3171
+ return props.statusFeed.subscribe(setStatus);
3172
+ }, [open, selectedHost]);
3173
+ let chooseAnotherHost = () => {
3174
+ setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setDirectory(void 0), setPath(""), setAddingWorkspace(!1), setError(void 0);
3175
+ }, requestDeepSeekSignIn = async () => {
3176
+ let transport = globalThis.__DSH_TRANSPORT__, callbackOrigin = transport?.streamBaseUrl !== void 0 ? new URL(transport.streamBaseUrl).origin : window.location.origin, result = await props.control("settings.configure", {
3177
+ role: "client",
3178
+ serverUrl: loginServerUrl.trim(),
3179
+ provider: "deepseek",
3180
+ callbackOrigin,
3181
+ loginSource: "dshDesktop" in globalThis ? "desktop" : "web",
3182
+ locale: navigator.language,
3183
+ timezoneOffsetSeconds: -(/* @__PURE__ */ new Date()).getTimezoneOffset() * 60
3184
+ });
3185
+ return result?.status === "deepseek-sign-in-required" ? { pending: !0, ...typeof result.authorizeUrl == "string" ? { authorizeUrl: result.authorizeUrl } : {} } : { pending: !1 };
3186
+ }, signInClient = async () => {
3187
+ if (loginServerUrl.trim() === "") return;
3188
+ let tab = window.open("", "_blank");
3189
+ if (tab !== null)
3190
+ try {
3191
+ tab.opener = null;
3192
+ } catch {
3193
+ }
3194
+ setBusy(!0), setError(void 0), setAwaitingDeepSeek(!0);
3195
+ try {
3196
+ let state = await requestDeepSeekSignIn();
3197
+ if (state.pending) {
3198
+ for (let wait = 0; wait < 30 && state.pending && state.authorizeUrl === void 0; wait++)
3199
+ await new Promise((resolve) => {
3200
+ setTimeout(resolve, 1e3);
3201
+ }), state = await requestDeepSeekSignIn();
3202
+ if (state.authorizeUrl === void 0)
3203
+ throw tab?.close(), new Error(t("deepseekAuthorizeUnavailable"));
3204
+ setPendingAuthorizeUrl(state.authorizeUrl), tab === null || tab.closed ? window.open(state.authorizeUrl, "_blank", "noopener,noreferrer") : tab.location.replace(state.authorizeUrl);
3205
+ for (let poll = 0; poll < 40 && state.pending; poll++)
3206
+ await new Promise((resolve) => {
3207
+ setTimeout(resolve, 3e3);
3208
+ }), state = await requestDeepSeekSignIn();
3209
+ if (state.pending) throw new Error(t("deepseekSignInTimeout"));
3210
+ } else
3211
+ tab?.close();
3212
+ setDevices(await props.control("devices")), setStatus(await props.control("status")), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setPassword(""), setNotice(void 0);
3213
+ } catch (reason) {
3214
+ setError(messageOf(reason));
3215
+ } finally {
3216
+ setAwaitingDeepSeek(!1), setPendingAuthorizeUrl(void 0), setBusy(!1);
3217
+ }
3218
+ }, openLocalWorkspaces = async () => {
3219
+ setBusy(!0), setError(void 0);
3220
+ try {
3221
+ await props.control("mode.set", { mode: "local" }), window.location.reload();
3222
+ } catch (reason) {
3223
+ setError(messageOf(reason)), setBusy(!1);
3224
+ }
3225
+ }, setCurrentDeviceControl = async (enabled) => {
3226
+ setBusy(!0), setError(void 0);
3227
+ try {
3228
+ setStatus(await setDeviceControl(props.control, enabled, status?.host?.authorized === !0));
3229
+ } catch (reason) {
3230
+ setError(messageOf(reason));
3231
+ } finally {
3232
+ setBusy(!1);
3233
+ }
3234
+ }, logoutRemote = async () => {
3235
+ setBusy(!0), setError(void 0), setNotice(void 0);
3236
+ try {
3237
+ await props.control("settings.logout"), setDevices([]), setNeedsAuthorization(!0), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setStatus(await props.control("status"));
3238
+ } catch (reason) {
3239
+ setError(messageOf(reason));
3240
+ } finally {
3241
+ setConfirmingSignOut(!1), setBusy(!1);
3242
+ }
3243
+ }, openWorkspace = async (selection) => {
3244
+ let targetBackend = selection?.backend ?? workspaceBackend, targetPath = (selection?.path ?? path).trim(), targetCodexWorkspaceId = selection?.backend === "codex" ? selection.workspaceId : selection === void 0 ? codexWorkspaceId : void 0, createWorkspace = selection === void 0 && addingWorkspace;
3245
+ if (!(selectedHost === void 0 || targetPath === "" || !createWorkspace && targetBackend === "codex" && targetCodexWorkspaceId === void 0)) {
3246
+ setBusy(!0), setError(void 0);
3247
+ try {
3248
+ let nextStatus = await (targetBackend === "codex" ? createWorkspace ? props.control("codex.workspace.create", {
3249
+ targetDeviceId: selectedHost.deviceId,
3250
+ path: targetPath
3251
+ }) : props.control("codex.workspace.open", {
3252
+ targetDeviceId: selectedHost.deviceId,
3253
+ workspaceId: targetCodexWorkspaceId
3254
+ }) : props.control("workspace.open", {
3255
+ targetDeviceId: selectedHost.deviceId,
3256
+ path: targetPath
3257
+ }));
3258
+ setStatus(nextStatus), nextStatus.workspaceSelection !== void 0 && window.sessionStorage.setItem(pendingWorkspaceSelectionKey, JSON.stringify(nextStatus.workspaceSelection)), window.location.reload();
3259
+ } catch (reason) {
3260
+ setError(messageOf(reason)), setBusy(!1);
3261
+ }
3262
+ }
3263
+ }, remoteLabel = status?.mode === "remote" ? t("activeRemote", { name: status.target?.name ?? t("host") }) : t("remoteEntry"), visibleWorkspaces = showAllWorkspaces ? workspaces : workspaces.slice(0, 3), visibleCodexWorkspaces = showAllCodexWorkspaces ? codexWorkspaces : codexWorkspaces.slice(0, 3), codexAvailable = status?.remoteFeatures?.codex === !0, selectedHostDetails = selectedHost === void 0 ? void 0 : [
3264
+ formatPlatform(selectedHost.platform),
3265
+ selectedHost.harnessVersion === void 0 ? void 0 : t("harnessVersion", { version: selectedHost.harnessVersion }),
3266
+ selectedHost.clientVersion === void 0 ? void 0 : t("pluginVersion", { version: selectedHost.clientVersion })
3267
+ ].filter(Boolean).join(" \xB7 "), connectedClients = status?.host?.connectedClients ?? [], connectedCount = connectedClients.length, connectedCountLabel = t("connectedClientCount", { count: connectedCount }), connectedMenu = !needsAuthorization && status?.hostAuthorizationAvailable === !0 ? React.createElement(
3268
+ "div",
3269
+ {
3270
+ className: `dshRemoteConnectedMenu${devicesOpen ? " isOpen" : ""}`
3271
+ },
3272
+ React.createElement("a", {
3273
+ href: connectedCount > 0 ? "#connected-devices" : void 0,
3274
+ className: `dshRemoteConnectedCount${connectedCount > 0 ? " isOnline isInteractive" : ""}`,
3275
+ "aria-expanded": connectedCount > 0 ? devicesOpen : void 0,
3276
+ "aria-haspopup": connectedCount > 0 ? "dialog" : void 0,
3277
+ title: connectedCountLabel,
3278
+ "aria-label": connectedCountLabel,
3279
+ onClick: (event) => {
3280
+ event.preventDefault(), connectedCount !== 0 && setDevicesOpen((current) => !current);
3281
+ }
3282
+ }, connectedCountLabel),
3283
+ devicesOpen && connectedCount > 0 ? React.createElement(
3284
+ "div",
3285
+ {
3286
+ className: "dshRemoteConnectedPanel",
3287
+ id: "connected-devices",
3288
+ role: "dialog",
3289
+ "aria-label": t("currentConnectedDevices")
3290
+ },
3291
+ React.createElement("strong", { className: "dshRemoteConnectedPanelTitle" }, t("currentConnectedDevices")),
3292
+ React.createElement(
3293
+ "div",
3294
+ { className: "dshRemoteClientList", "aria-label": t("currentConnectedDevices") },
3295
+ ...connectedClients.map((client) => React.createElement(
3296
+ "div",
3297
+ {
3298
+ key: client.deviceId,
3299
+ className: "dshRemoteClientRow"
3300
+ },
3301
+ React.createElement(
3302
+ "span",
3303
+ null,
3304
+ React.createElement("strong", null, client.name.trim() === "" ? t("unknownDevice") : client.name),
3305
+ React.createElement("small", null, [
3306
+ client.platform === void 0 ? void 0 : formatPlatform(client.platform),
3307
+ connectedClientModeLabel(client.mode, t)
3308
+ ].filter(Boolean).join(" \xB7 "))
3309
+ ),
3310
+ React.createElement("small", { className: "dshRemoteClientOnline" }, t("connected"))
3311
+ ))
3312
+ )
3313
+ ) : null
3314
+ ) : null, listedHosts = connectingHost === void 0 ? devices : [connectingHost];
3315
+ return React.createElement(
3316
+ React.Fragment,
3317
+ null,
3318
+ React.createElement(
3319
+ "div",
3320
+ { className: `dshRemoteSidebarEntry${status?.mode === "remote" ? " isActive" : ""}${props.wide ? " isWide" : " isRail"}` },
3321
+ React.createElement(status?.mode === "remote" ? "div" : "button", {
3322
+ ...status?.mode === "remote" ? {} : { type: "button", onClick: () => void show() },
3323
+ className: "dshRemoteModeButton",
3324
+ title: remoteLabel,
3325
+ "aria-label": remoteLabel
3326
+ }, React.createElement(
3327
+ "svg",
3328
+ {
3329
+ className: "dshRemoteComputerIcon",
3330
+ viewBox: "0 0 24 24",
3331
+ fill: "none",
3332
+ stroke: "currentColor",
3333
+ strokeWidth: 1.7,
3334
+ strokeLinecap: "round",
3335
+ strokeLinejoin: "round",
3336
+ "aria-hidden": !0
3337
+ },
3338
+ React.createElement("rect", { x: 3, y: 4, width: 18, height: 13, rx: 2 }),
3339
+ React.createElement("path", { d: "M8 21h8M12 17v4" })
3340
+ ), props.wide ? React.createElement("span", { className: "dshRemoteSidebarLabel" }, remoteLabel) : null),
3341
+ (status?.mode === "remote" || status?.fellBackToLocal === !0) && props.wide ? React.createElement("button", {
3342
+ type: "button",
3343
+ className: "dshRemoteExitLink",
3344
+ disabled: busy,
3345
+ onClick: () => void openLocalWorkspaces()
3346
+ }, t("exitRemote")) : null
3347
+ ),
3348
+ open ? React.createElement("div", {
3349
+ className: "dshRemoteBackdrop",
3350
+ role: "presentation",
3351
+ onMouseDown: (event) => {
3352
+ event.target === event.currentTarget && setOpen(!1);
3353
+ }
3354
+ }, React.createElement(
3355
+ "section",
3356
+ {
3357
+ className: `dshRemotePage${selectedHost === void 0 ? "" : " hasSelectedHost"}`,
3358
+ role: "dialog",
3359
+ "aria-modal": !0,
3360
+ "aria-label": selectedHost?.name ?? t("remoteTitle")
3361
+ },
3362
+ React.createElement(
3363
+ "header",
3364
+ { className: "dshRemotePageHeader" },
3365
+ React.createElement(
3366
+ "div",
3367
+ { className: "dshRemotePageIntro" },
3368
+ React.createElement(
3369
+ "div",
3370
+ { className: "dshRemotePageTitleRow" },
3371
+ React.createElement("strong", null, selectedHost?.name ?? t("remoteTitle"))
3372
+ ),
3373
+ React.createElement("p", null, selectedHostDetails ?? t("remoteDescription"))
3374
+ ),
3375
+ React.createElement(
3376
+ "div",
3377
+ { className: "dshRemotePageActions" },
3378
+ selectedHost === void 0 ? null : React.createElement("button", {
3379
+ type: "button",
3380
+ className: "dshRemotePageBack",
3381
+ disabled: busy,
3382
+ title: t("backToHosts"),
3383
+ onClick: chooseAnotherHost
3384
+ }, t("backToHosts")),
3385
+ React.createElement("button", {
3386
+ type: "button",
3387
+ className: "dshRemotePageRefresh",
3388
+ disabled: busy,
3389
+ title: t("refreshRemote"),
3390
+ "aria-label": t("refreshRemote"),
3391
+ onClick: () => void refreshRemote()
3392
+ }, t("refreshRemoteShort")),
3393
+ React.createElement("button", { type: "button", className: "dshRemotePageClose", onClick: () => setOpen(!1), "aria-label": t("close") }, "\xD7")
3394
+ )
3395
+ ),
3396
+ React.createElement(
3397
+ "main",
3398
+ { className: "dshRemotePageBody" },
3399
+ status?.mode === "remote" || status?.fellBackToLocal === !0 ? React.createElement("button", {
3400
+ type: "button",
3401
+ className: "dshRemoteLocalLink",
3402
+ disabled: busy,
3403
+ onClick: () => void openLocalWorkspaces()
3404
+ }, t("openLocalWorkspaces")) : null,
3405
+ React.createElement(
3406
+ React.Fragment,
3407
+ null,
3408
+ authorizationResolved && needsAuthorization ? React.createElement(
3409
+ "section",
3410
+ { className: "dshRemoteEnable" },
3411
+ React.createElement(
3412
+ "div",
3413
+ { className: "dshRemoteClientLogin" },
3414
+ editingServerUrl ? React.createElement("input", {
3415
+ type: "url",
3416
+ value: loginServerUrl,
3417
+ disabled: busy,
3418
+ autoComplete: "url",
3419
+ className: "dshRemoteServerInput",
3420
+ placeholder: t("serverUrl"),
3421
+ autoFocus: !0,
3422
+ "aria-label": t("serverUrl"),
3423
+ // Leaving the field restores the read-only line, so the
3424
+ // editor is a transient state rather than a mode.
3425
+ onBlur: () => setEditingServerUrl(!1),
3426
+ onChange: (event) => setLoginServerUrl(event.target.value)
3427
+ }) : React.createElement(
3428
+ "div",
3429
+ { className: "dshRemoteServerRow" },
3430
+ // Plain text that happens to be clickable: the address
3431
+ // stays quiet until someone reaches for it.
3432
+ React.createElement("button", {
3433
+ type: "button",
3434
+ className: "dshRemoteServerValue",
3435
+ disabled: busy,
3436
+ title: t("changeServerUrl"),
3437
+ "aria-label": t("changeServerUrl"),
3438
+ onClick: () => setEditingServerUrl(!0)
3439
+ }, loginServerUrl)
3440
+ ),
3441
+ React.createElement(
3442
+ "button",
3443
+ { type: "button", disabled: busy || loginServerUrl.trim() === "", onClick: () => void signInClient() },
3444
+ t(busy ? "signingIn" : "deepseekSignIn")
3445
+ ),
3446
+ awaitingDeepSeek ? React.createElement(
3447
+ "p",
3448
+ { className: "dshRemoteServiceAddress" },
3449
+ t(pendingAuthorizeUrl === void 0 ? "deepseekSignInRequesting" : "deepseekSignInWaiting"),
3450
+ pendingAuthorizeUrl === void 0 ? null : React.createElement("a", {
3451
+ href: pendingAuthorizeUrl,
3452
+ target: "_blank",
3453
+ rel: "noreferrer",
3454
+ style: { marginLeft: "6px", color: "var(--dsw-alias-brand-primary)" }
3455
+ }, t("deepseekSignInOpen"))
3456
+ ) : null
3457
+ )
3458
+ ) : null,
3459
+ !authorizationResolved || needsAuthorization ? null : React.createElement(
3460
+ React.Fragment,
3461
+ null,
3462
+ selectedHost === void 0 ? React.createElement(
3463
+ "section",
3464
+ { className: "dshRemoteHosts", "aria-label": t("chooseHost") },
3465
+ React.createElement(
3466
+ "div",
3467
+ { className: "dshRemoteSectionHeading" },
3468
+ React.createElement(
3469
+ "div",
3470
+ { className: "dshRemoteSectionTitle" },
3471
+ React.createElement("strong", null, t("chooseHost")),
3472
+ status?.hostAuthorizationAvailable ? React.createElement(
3473
+ "div",
3474
+ { className: "dshRemoteHostControlToggle" },
3475
+ React.createElement("span", null, t("allowControlDevice")),
3476
+ React.createElement("input", {
3477
+ type: "checkbox",
3478
+ role: "switch",
3479
+ disabled: busy,
3480
+ "aria-label": t("allowControlDevice"),
3481
+ checked: status.host?.authorized === !0 && status.host?.paused !== !0,
3482
+ onChange: (event) => void setCurrentDeviceControl(event.target.checked)
3483
+ })
3484
+ ) : null,
3485
+ connectedMenu
3486
+ )
3487
+ ),
3488
+ React.createElement("div", {
3489
+ className: `dshRemoteHostList${connectingHost === void 0 ? "" : " isCollapsed"}`,
3490
+ "aria-busy": connectingHost === void 0 ? void 0 : !0
3491
+ }, listedHosts.length === 0 ? React.createElement("p", null, t(busy ? "checkingConnection" : "noRemoteHosts")) : listedHosts.map((device) => React.createElement(
3492
+ "button",
3493
+ {
3494
+ type: "button",
3495
+ key: device.deviceId,
3496
+ disabled: busy || !device.online,
3497
+ "aria-current": connectingHost?.deviceId === device.deviceId ? "true" : void 0,
3498
+ onClick: () => void selectHost(device)
3499
+ },
3500
+ React.createElement(
3501
+ "span",
3502
+ null,
3503
+ React.createElement("strong", null, device.name),
3504
+ React.createElement("small", null, [
3505
+ formatPlatform(device.platform),
3506
+ device.harnessVersion === void 0 ? void 0 : t("harnessVersion", { version: device.harnessVersion }),
3507
+ device.clientVersion === void 0 ? void 0 : t("pluginVersion", { version: device.clientVersion })
3508
+ ].filter(Boolean).join(" \xB7 "))
3509
+ ),
3510
+ React.createElement("small", null, t(device.online ? "online" : "offline"))
3511
+ )))
3512
+ ) : null,
3513
+ React.createElement(RemoteProgressView, { progress, t }),
3514
+ selectedHost === void 0 ? connectingHost === void 0 ? React.createElement(
3515
+ React.Fragment,
3516
+ null,
3517
+ React.createElement(
3518
+ "p",
3519
+ { className: "dshRemoteHint" },
3520
+ t(confirmingSignOut ? "signOutImpact" : "selectHostHint")
3521
+ ),
3522
+ React.createElement(
3523
+ "footer",
3524
+ { className: "dshRemoteAccountFooter" },
3525
+ confirmingSignOut ? React.createElement(
3526
+ React.Fragment,
3527
+ null,
3528
+ React.createElement("button", {
3529
+ type: "button",
3530
+ className: "dshRemoteDiscard",
3531
+ disabled: busy,
3532
+ onClick: () => setConfirmingSignOut(!1)
3533
+ }, t("cancel")),
3534
+ React.createElement("button", {
3535
+ type: "button",
3536
+ className: "dshRemoteAccountExit",
3537
+ disabled: busy,
3538
+ onClick: () => void logoutRemote()
3539
+ }, t("exitRemoteAccount"))
3540
+ ) : React.createElement(
3541
+ React.Fragment,
3542
+ null,
3543
+ React.createElement("span", null, status?.host?.account ?? t("account")),
3544
+ React.createElement("button", {
3545
+ type: "button",
3546
+ className: "dshRemoteAccountExit",
3547
+ disabled: busy,
3548
+ onClick: () => setConfirmingSignOut(!0)
3549
+ }, t("exitRemoteAccount"))
3550
+ )
3551
+ )
3552
+ ) : null : React.createElement(
3553
+ "section",
3554
+ { className: "dshRemoteBrowser", "aria-label": t("chooseDirectory") },
3555
+ React.createElement(
3556
+ "div",
3557
+ { className: "dshRemoteSectionHeading dshRemoteWorkspaceHeading" },
3558
+ React.createElement("strong", null, t(addingWorkspace ? workspaceBackend === "codex" ? "addCodexWorkspace" : "addRemoteWorkspace" : "existingWorkspaces")),
3559
+ addingWorkspace ? React.createElement("button", {
3560
+ type: "button",
3561
+ className: "dshRemoteCancelWorkspace",
3562
+ disabled: busy,
3563
+ onClick: cancelAddingWorkspace
3564
+ }, t("cancelAddWorkspace")) : React.createElement("button", {
3565
+ type: "button",
3566
+ className: "dshRemoteAddWorkspace",
3567
+ disabled: busy,
3568
+ title: t("addRemoteWorkspace"),
3569
+ "aria-label": t("addRemoteWorkspace"),
3570
+ onClick: () => startAddingWorkspace("harness")
3571
+ }, React.createElement("svg", {
3572
+ className: "dshRemoteAddWorkspaceIcon",
3573
+ viewBox: "0 0 16 16",
3574
+ "aria-hidden": !0,
3575
+ focusable: !1
3576
+ }, React.createElement("path", { d: "M8 3v10M3 8h10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round" })))
3577
+ ),
3578
+ addingWorkspace ? React.createElement(
3579
+ "div",
3580
+ { className: "dshRemoteFolderBrowser" },
3581
+ directory === void 0 ? React.createElement("p", null, t("loadingDirectory")) : React.createElement(
3582
+ React.Fragment,
3583
+ null,
3584
+ React.createElement(
3585
+ "nav",
3586
+ { className: "dshRemoteCrumbs", "aria-label": t("currentDirectory") },
3587
+ directory.crumbs.map((crumb) => React.createElement("button", {
3588
+ type: "button",
3589
+ key: crumb.path,
3590
+ disabled: busy || crumb.path === directory.path,
3591
+ onClick: () => void browseDirectory(crumb.path)
3592
+ }, crumb.path === directory.home ? "\u2302" : crumb.name))
3593
+ ),
3594
+ React.createElement("div", { className: "dshRemoteFolderList" }, directory.entries.filter((entry) => !entry.hidden).length === 0 ? React.createElement("p", null, t("emptyDirectory")) : directory.entries.filter((entry) => !entry.hidden).map((entry) => React.createElement("button", {
3595
+ type: "button",
3596
+ key: entry.path,
3597
+ disabled: busy,
3598
+ onClick: () => void browseDirectory(entry.path)
3599
+ }, React.createElement("span", { "aria-hidden": !0 }, "\u25B1"), React.createElement("span", null, entry.name)))),
3600
+ directory.truncated ? React.createElement("small", null, t("directoryTruncated")) : null
3601
+ )
3602
+ ) : React.createElement(
3603
+ React.Fragment,
3604
+ null,
3605
+ React.createElement(
3606
+ "div",
3607
+ { className: "dshRemoteWorkspaceLists" },
3608
+ React.createElement(
3609
+ "div",
3610
+ { id: workspaceListId, className: "dshRemoteDirectoryList" },
3611
+ workspaces.length === 0 ? React.createElement("p", null, t("noRemoteWorkspaces")) : visibleWorkspaces.map((workspace) => React.createElement(
3612
+ "button",
3613
+ {
3614
+ type: "button",
3615
+ key: workspace.workspaceId,
3616
+ disabled: busy,
3617
+ className: workspaceBackend === "harness" && path === workspace.path ? "isSelected" : "",
3618
+ "aria-pressed": workspaceBackend === "harness" && path === workspace.path,
3619
+ onClick: () => {
3620
+ setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(workspace.path);
3621
+ },
3622
+ onDoubleClick: () => void openWorkspace({ backend: "harness", path: workspace.path })
3623
+ },
3624
+ React.createElement("img", { className: "dshRemoteWorkspaceIcon", src: deepSeekWorkspaceIcon, alt: "", "aria-hidden": !0 }),
3625
+ React.createElement("span", null, workspace.title),
3626
+ React.createElement("small", null, workspace.path)
3627
+ )),
3628
+ workspaces.length <= 3 || showAllWorkspaces ? null : React.createElement("button", {
3629
+ type: "button",
3630
+ className: "dshRemoteWorkspaceMore",
3631
+ disabled: busy,
3632
+ "aria-controls": workspaceListId,
3633
+ "aria-label": t("showAllWorkspaces"),
3634
+ onClick: () => setShowAllWorkspaces(!0)
3635
+ }, React.createElement("span", { "aria-hidden": !0 }, "\u2026"))
3636
+ )
3637
+ ),
3638
+ !codexAvailable && codexWorkspaces.length === 0 ? null : React.createElement(
3639
+ "section",
3640
+ { className: "dshRemoteCodexWorkspaceGroup" },
3641
+ React.createElement(
3642
+ "div",
3643
+ {
3644
+ id: codexWorkspaceHeadingId,
3645
+ className: "dshRemoteWorkspaceSourceHeading"
3646
+ },
3647
+ React.createElement(
3648
+ "span",
3649
+ { className: "dshRemoteWorkspaceSourceText" },
3650
+ React.createElement("strong", null, t("codexVirtualWorkspace"))
3651
+ ),
3652
+ codexAvailable ? React.createElement("button", {
3653
+ type: "button",
3654
+ className: "dshRemoteAddWorkspace",
3655
+ disabled: busy,
3656
+ title: t("addCodexWorkspace"),
3657
+ "aria-label": t("addCodexWorkspace"),
3658
+ onClick: () => startAddingWorkspace("codex")
3659
+ }, React.createElement("svg", {
3660
+ className: "dshRemoteAddWorkspaceIcon",
3661
+ viewBox: "0 0 16 16",
3662
+ "aria-hidden": !0,
3663
+ focusable: !1
3664
+ }, React.createElement("path", { d: "M8 3v10M3 8h10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round" }))) : null
3665
+ ),
3666
+ React.createElement("div", {
3667
+ id: codexWorkspaceListId,
3668
+ className: "dshRemoteDirectoryList dshRemoteCodexWorkspaceList",
3669
+ "aria-labelledby": codexWorkspaceHeadingId
3670
+ }, visibleCodexWorkspaces.length === 0 ? React.createElement("p", null, t("noCodexWorkspaces")) : visibleCodexWorkspaces.map((workspace) => React.createElement(
3671
+ "button",
3672
+ {
3673
+ type: "button",
3674
+ key: workspace.workspaceId,
3675
+ disabled: busy,
3676
+ className: workspaceBackend === "codex" && codexWorkspaceId === workspace.workspaceId ? "isSelected" : "",
3677
+ "aria-pressed": workspaceBackend === "codex" && codexWorkspaceId === workspace.workspaceId,
3678
+ onClick: () => {
3679
+ setWorkspaceBackend("codex"), setCodexWorkspaceId(workspace.workspaceId), setPath(workspace.path);
3680
+ },
3681
+ onDoubleClick: () => void openWorkspace({
3682
+ backend: "codex",
3683
+ path: workspace.path,
3684
+ workspaceId: workspace.workspaceId
3685
+ })
3686
+ },
3687
+ React.createElement("img", { className: "dshRemoteWorkspaceIcon isGpt", src: gptWorkspaceIcon, alt: "", "aria-hidden": !0 }),
3688
+ React.createElement("span", null, workspace.title),
3689
+ React.createElement("small", null, `${workspace.path} \xB7 ${workspace.sessionCount}`)
3690
+ ))),
3691
+ codexWorkspaces.length <= 3 || showAllCodexWorkspaces ? null : React.createElement("button", {
3692
+ type: "button",
3693
+ className: "dshRemoteWorkspaceMore",
3694
+ disabled: busy,
3695
+ "aria-controls": codexWorkspaceListId,
3696
+ "aria-label": t("showAllCodexWorkspaces"),
3697
+ onClick: () => setShowAllCodexWorkspaces(!0)
3698
+ }, React.createElement("span", { "aria-hidden": !0 }, "\u2026"))
3699
+ )
3700
+ ),
3701
+ React.createElement(
3702
+ "footer",
3703
+ { className: "dshRemoteOpenBar" },
3704
+ React.createElement("div", null, React.createElement("span", null, t("currentDirectory")), React.createElement("strong", null, path || "\u2014")),
3705
+ React.createElement("button", {
3706
+ type: "button",
3707
+ disabled: busy || path.trim() === "" || !addingWorkspace && workspaceBackend === "codex" && codexWorkspaceId === void 0,
3708
+ onClick: () => void openWorkspace()
3709
+ }, t(busy ? "openingWorkspace" : addingWorkspace ? "confirmAddWorkspace" : "openWorkspace"))
3710
+ )
3711
+ )
3712
+ )
3713
+ ),
3714
+ notice === void 0 ? null : React.createElement("p", { className: "dshRemoteNotice", role: "status" }, notice),
3715
+ error === void 0 ? null : React.createElement("p", { className: "dshRemoteError", role: "alert" }, error)
3716
+ )
3717
+ )) : null
3718
+ );
3719
+ }
3720
+ function RemoteModeAction(props) {
3721
+ let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [hostRegistrationCode, setHostRegistrationCode] = React.useState(""), [email, setEmail] = React.useState(""), [password, setPassword] = React.useState(""), [busy, setBusy] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), [error, setError] = React.useState(void 0), [supported, setSupported] = React.useState(!0), refresh = async () => {
3722
+ let [nextStatus, nextDevices] = await Promise.all([
3723
+ props.control("status"),
3724
+ props.control("devices").catch(() => [])
3725
+ ]);
3726
+ setStatus(nextStatus), setDevices(nextDevices);
3727
+ }, refreshStatus = async () => {
3728
+ setStatus(await props.control("status"));
3729
+ };
3730
+ React.useEffect(() => {
3731
+ refresh().catch((reason) => {
3732
+ setError(messageOf(reason)), setSupported(!1);
3733
+ });
3734
+ }, []), React.useEffect(() => {
3735
+ if (open)
3736
+ return props.statusFeed.subscribe(setStatus);
3737
+ }, [open]);
3738
+ let switchMode = async (mode, targetDeviceId) => {
3739
+ setBusy(!0), setError(void 0);
3740
+ try {
3741
+ let action = () => props.control("mode.set", { mode, ...targetDeviceId === void 0 ? {} : { targetDeviceId } });
3742
+ setStatus(mode === "remote" && targetDeviceId !== void 0 ? await runConnectHostProgress(
3743
+ status?.preferredTransports,
3744
+ targetDeviceId,
3745
+ props.control,
3746
+ { label: "remoteProgressSwitchingWorkspace", detail: "remoteProgressSwitchingWorkspaceDetail" },
3747
+ setProgress,
3748
+ progressRun,
3749
+ action,
3750
+ connectedProgress
3751
+ ) : await action()), window.location.reload();
3752
+ } catch (reason) {
3753
+ setError(messageOf(reason)), setBusy(!1);
3754
+ }
3755
+ }, loginHost = async () => {
3756
+ if (!(email.trim() === "" || password === "")) {
3757
+ setBusy(!0), setError(void 0);
3758
+ try {
3759
+ await props.control("host.account.login", { email: email.trim(), password }), await refreshStatus();
3760
+ } catch (reason) {
3761
+ setError(messageOf(reason));
3762
+ } finally {
3763
+ setPassword(""), setBusy(!1);
3764
+ }
3765
+ }
3766
+ }, registerHostWithCode = async () => {
3767
+ if (hostRegistrationCode.trim() !== "") {
3768
+ setBusy(!0), setError(void 0);
3769
+ try {
3770
+ await props.control("host.registration-code.submit", { code: hostRegistrationCode.trim() }), setHostRegistrationCode(""), await refreshStatus();
3771
+ } catch (reason) {
3772
+ setError(messageOf(reason));
3773
+ } finally {
3774
+ setBusy(!1);
3775
+ }
3776
+ }
3777
+ }, label = status?.mode === "remote" ? t("remoteTarget", { name: status.target?.name ?? t("host") }) : t("local");
3778
+ return supported ? React.createElement(
3779
+ React.Fragment,
3780
+ null,
3781
+ React.createElement("button", {
3782
+ type: "button",
3783
+ className: "dshRemoteModeButton",
3784
+ title: t("switchTarget"),
3785
+ "aria-label": t("switchTarget"),
3786
+ onClick: () => setOpen(!0)
3787
+ }, React.createElement("span", { "aria-hidden": !0 }, "\u25CE"), props.wide ? React.createElement("span", null, label) : null),
3788
+ open ? React.createElement(
3789
+ "div",
3790
+ { className: "dshRemoteBackdrop", role: "presentation" },
3791
+ React.createElement(
3792
+ "section",
3793
+ {
3794
+ className: "dshRemoteDialog",
3795
+ role: "dialog",
3796
+ "aria-modal": !0,
3797
+ "aria-label": t("harnessTarget")
3798
+ },
3799
+ React.createElement(
3800
+ "div",
3801
+ { className: "dshRemoteHeader" },
3802
+ React.createElement("strong", null, t("harnessTarget")),
3803
+ React.createElement("button", { type: "button", onClick: () => setOpen(!1), "aria-label": t("close") }, "\xD7")
3804
+ ),
3805
+ React.createElement("button", {
3806
+ type: "button",
3807
+ disabled: busy || status?.mode === "local",
3808
+ onClick: () => void switchMode("local")
3809
+ }, t("thisMachineLocal")),
3810
+ React.createElement("div", { className: "dshRemoteDevices" }, devices.length === 0 ? React.createElement("p", null, t("noRemoteHosts")) : devices.map((device) => React.createElement("button", {
3811
+ type: "button",
3812
+ key: device.deviceId,
3813
+ disabled: busy || !device.online || status?.target?.deviceId === device.deviceId,
3814
+ onClick: () => void switchMode("remote", device.deviceId)
3815
+ }, `${device.name} \xB7 ${t(device.online ? "online" : "offline")}`))),
3816
+ React.createElement(RemoteProgressView, { progress, t }),
3817
+ status?.hostAuthorizationAvailable && status.host !== void 0 ? React.createElement(
3818
+ "div",
3819
+ { className: "dshRemoteHostAccount" },
3820
+ React.createElement("strong", null, t("thisMachineHost")),
3821
+ React.createElement("p", null, status.host.online ? status.host.account === void 0 ? t("connected") : t("connectedAs", { account: status.host.account }) : status.host.accountRequired ? t("hostSignInHint") : status.host.error === void 0 ? t("checkingHost") : t("hostUnavailable", { error: connectionErrorMessage(status.host.error, t) })),
3822
+ status.host.accountRequired ? React.createElement(
3823
+ "div",
3824
+ { className: "dshRemoteLogin" },
3825
+ React.createElement("input", {
3826
+ type: "email",
3827
+ value: email,
3828
+ disabled: busy,
3829
+ autoComplete: "username",
3830
+ placeholder: t("serverAccountEmail"),
3831
+ "aria-label": t("serverAccountEmail"),
3832
+ onChange: (event) => setEmail(event.target.value)
3833
+ }),
3834
+ React.createElement("input", {
3835
+ type: "password",
3836
+ value: password,
3837
+ disabled: busy,
3838
+ autoComplete: "current-password",
3839
+ placeholder: t("password"),
3840
+ "aria-label": t("serverAccountPassword"),
3841
+ onChange: (event) => setPassword(event.target.value)
3842
+ }),
3843
+ React.createElement("button", {
3844
+ type: "button",
3845
+ disabled: busy || email.trim() === "" || password === "",
3846
+ onClick: () => void loginHost()
3847
+ }, t(busy ? "signingIn" : "signInRegisterHost")),
3848
+ React.createElement("input", {
3849
+ value: hostRegistrationCode,
3850
+ disabled: busy,
3851
+ autoComplete: "one-time-code",
3852
+ placeholder: t("hostRegistrationCode"),
3853
+ "aria-label": t("hostRegistrationCode"),
3854
+ onChange: (event) => setHostRegistrationCode(event.target.value)
3855
+ }),
3856
+ React.createElement("button", {
3857
+ type: "button",
3858
+ disabled: busy || hostRegistrationCode.trim() === "",
3859
+ onClick: () => void registerHostWithCode()
3860
+ }, t(busy ? "registering" : "useRegistrationCode"))
3861
+ ) : null
3862
+ ) : null,
3863
+ error === void 0 ? null : React.createElement("p", { className: "dshRemoteError", role: "alert" }, error)
3864
+ )
3865
+ ) : null
3866
+ ) : null;
3867
+ }
3868
+ function RemoteSessionHeaderAction(props) {
3869
+ let { t } = props, status = React.useSyncExternalStore(
3870
+ props.statusFeed.subscribe,
3871
+ props.statusFeed.getSnapshot,
3872
+ props.statusFeed.getSnapshot
3873
+ ), [routeOpen, setRouteOpen] = React.useState(!1);
3874
+ if (React.useEffect(() => {
3875
+ if (status?.mode === "remote")
3876
+ return hideLocalSessionActions();
3877
+ }, [status?.mode]), React.useEffect(() => (document.documentElement.classList.toggle(
3878
+ "dshRemoteCodexTargetActive",
3879
+ status?.mode === "remote" && status.backend === "codex"
3880
+ ), () => document.documentElement.classList.remove("dshRemoteCodexTargetActive")), [status?.mode, status?.backend]), React.useEffect(() => {
3881
+ if (!routeOpen) return;
3882
+ let closeOnEscape = (event) => {
3883
+ event.key === "Escape" && setRouteOpen(!1);
3884
+ };
3885
+ return document.addEventListener("keydown", closeOnEscape), () => document.removeEventListener("keydown", closeOnEscape);
3886
+ }, [routeOpen]), status?.mode !== "remote") return null;
3887
+ let transport = status.network?.webRtc?.mode ?? status.transport ?? "Disconnected", networkLabel = t(transport === "P2P" ? "remoteNetworkP2p" : transport === "TURN" ? "remoteNetworkTurn" : transport === "Relay" ? "remoteNetworkRelay" : transport === "LAN" ? "remoteNetworkLan" : "remoteNetworkOffline"), networkOnline = status.connected === !0 && transport !== "Disconnected", routeVia = t(transport === "P2P" ? "connectionRouteP2p" : transport === "TURN" ? "connectionRouteTurn" : transport === "Relay" ? "connectionRouteRelay" : "connectionRouteLan"), routeViaDetail = t(transport === "P2P" ? "connectionRouteP2pDetail" : transport === "TURN" ? "connectionRouteTurnDetail" : transport === "Relay" ? "connectionRouteRelayDetail" : "connectionRouteLanDetail"), network = status.network, webRtc = network?.webRtc, controlStateLabel = network?.controlChannelState === "connecting" ? t("controlStateConnecting") : network?.controlChannelState === "open" ? t("controlStateOpen") : network?.controlChannelState === "closing" ? t("controlStateClosing") : t("controlStateClosed"), detailValue = (value) => value === void 0 || value === "" ? t("notProvided") : String(value), candidateLabel = (value) => value === "host" ? t("candidateHost") : value === "srflx" ? t("candidateSrflx") : value === "prflx" ? t("candidatePrflx") : value === "relay" ? t("candidateRelay") : detailValue(value), fact = (label, value, mono = !1) => React.createElement(
3888
+ "div",
3889
+ null,
3890
+ React.createElement("dt", null, label),
3891
+ React.createElement("dd", { className: mono ? "isMono" : void 0, title: mono ? value : void 0 }, value)
3892
+ );
3893
+ return React.createElement(
3894
+ "div",
3895
+ { className: "dshRemoteSessionHeader", role: "status" },
3896
+ React.createElement("svg", {
3897
+ viewBox: "0 0 24 24",
3898
+ fill: "none",
3899
+ stroke: "currentColor",
3900
+ strokeWidth: 1.7,
3901
+ strokeLinecap: "round",
3902
+ strokeLinejoin: "round",
3903
+ "aria-hidden": !0
3904
+ }, React.createElement("rect", { x: 3, y: 4, width: 18, height: 13, rx: 2 }), React.createElement("path", { d: "M8 21h8M12 17v4" })),
3905
+ React.createElement("span", { className: "dshRemoteModePrefix" }, t("remoteModePrefix")),
3906
+ React.createElement("span", { className: "dshRemoteSessionTarget" }, status.target?.name ?? t("host")),
3907
+ React.createElement("button", {
3908
+ type: "button",
3909
+ className: `dshRemoteNetwork${networkOnline ? " isOnline" : " isOffline"}`,
3910
+ title: networkLabel,
3911
+ disabled: !networkOnline,
3912
+ "aria-haspopup": "dialog",
3913
+ "aria-expanded": routeOpen,
3914
+ onClick: () => setRouteOpen((value) => !value)
3915
+ }, React.createElement("i", { "aria-hidden": !0 }), networkLabel),
3916
+ networkOnline ? React.createElement("span", { className: "dshRemoteEncrypted" }, t("remoteLinkEncrypted")) : null,
3917
+ routeOpen ? React.createElement("div", {
3918
+ className: "dshRemoteRouteBackdrop",
3919
+ role: "presentation",
3920
+ onMouseDown: (event) => {
3921
+ event.target === event.currentTarget && setRouteOpen(!1);
3922
+ }
3923
+ }, React.createElement(
3924
+ "section",
3925
+ {
3926
+ className: "dshRemoteRoutePanel",
3927
+ role: "dialog",
3928
+ "aria-label": t("connectionRouteTitle")
3929
+ },
3930
+ React.createElement(
3931
+ "header",
3932
+ null,
3933
+ React.createElement("strong", null, t("connectionRouteTitle")),
3934
+ React.createElement("button", { type: "button", "aria-label": t("close"), onClick: () => setRouteOpen(!1) }, "\xD7")
3935
+ ),
3936
+ React.createElement(
3937
+ "ol",
3938
+ null,
3939
+ React.createElement(
3940
+ "li",
3941
+ null,
3942
+ React.createElement("small", null, t("connectionRouteFrom")),
3943
+ React.createElement("strong", null, network?.local.name ?? t("connectionRouteCurrentDevice")),
3944
+ network === void 0 ? null : React.createElement("span", null, `${network.local.platform} \xB7 ${shortDeviceId(network.local.deviceId)}`)
3945
+ ),
3946
+ React.createElement(
3947
+ "li",
3948
+ null,
3949
+ React.createElement("small", null, t("connectionRouteVia")),
3950
+ React.createElement("strong", null, routeVia),
3951
+ React.createElement("span", null, routeViaDetail)
3952
+ ),
3953
+ React.createElement(
3954
+ "li",
3955
+ null,
3956
+ React.createElement("small", null, t("connectionRouteTo")),
3957
+ React.createElement("strong", null, network?.remote.name ?? status.target?.name ?? t("host")),
3958
+ React.createElement("span", null, network === void 0 ? t("connectionRouteHost") : `${network.remote.platform} \xB7 ${shortDeviceId(network.remote.deviceId)}`)
3959
+ )
3960
+ ),
3961
+ network === void 0 ? null : React.createElement(
3962
+ "section",
3963
+ { className: "dshRemoteRouteSection" },
3964
+ React.createElement("h3", null, t("connectionDetailsConnection")),
3965
+ React.createElement(
3966
+ "dl",
3967
+ null,
3968
+ fact(t("connectionId"), detailValue(network.connectionId), !0),
3969
+ fact(t("connectedAt"), network.connectedAt === void 0 ? t("notProvided") : formatLocalTime(network.connectedAt)),
3970
+ fact(t("preferredTransports"), network.preferredTransports.map((value) => transportLabel(value, t)).join(" \u2192 ")),
3971
+ fact(t("controlChannel"), `WebSocket \xB7 ${controlStateLabel}`),
3972
+ fact(t("controlAddress"), network.controlChannelUrl, !0)
3973
+ )
3974
+ ),
3975
+ webRtc === void 0 ? null : React.createElement(
3976
+ "section",
3977
+ { className: "dshRemoteRouteSection" },
3978
+ React.createElement("h3", null, t("connectionDetailsWebRtc")),
3979
+ React.createElement(
3980
+ "dl",
3981
+ null,
3982
+ fact(t("peerState"), `${webRtc.connectionState} \xB7 ICE ${webRtc.iceConnectionState}`),
3983
+ fact(t("dataChannel"), detailValue(webRtc.dataChannelState)),
3984
+ fact(t("localCandidate"), candidateLabel(webRtc.localCandidateType)),
3985
+ fact(t("remoteCandidate"), candidateLabel(webRtc.remoteCandidateType)),
3986
+ fact(t("localAddress"), detailValue(webRtc.localAddress), !0),
3987
+ fact(t("remoteAddress"), detailValue(webRtc.remoteAddress), !0),
3988
+ fact(t("networkProtocol"), detailValue(webRtc.protocol?.toUpperCase())),
3989
+ fact(t("relayProtocol"), detailValue(webRtc.relayProtocol?.toUpperCase())),
3990
+ fact(t("roundTripTime"), webRtc.currentRoundTripTimeMs === void 0 ? t("notProvided") : `${webRtc.currentRoundTripTimeMs.toLocaleString()} ms`),
3991
+ fact(t("availableBitrate"), webRtc.availableOutgoingBitrate === void 0 ? t("notProvided") : formatBitrate(webRtc.availableOutgoingBitrate)),
3992
+ fact(t("bytesSent"), webRtc.bytesSent === void 0 ? t("notProvided") : formatByteSize(webRtc.bytesSent)),
3993
+ fact(t("bytesReceived"), webRtc.bytesReceived === void 0 ? t("notProvided") : formatByteSize(webRtc.bytesReceived))
3994
+ )
3995
+ ),
3996
+ React.createElement("p", null, t("connectionRouteEncrypted"))
3997
+ )) : null
3998
+ );
3999
+ }
4000
+ function hideLocalSessionActions() {
4001
+ let selector = 'button,a,[role="button"]', hiddenAttribute = "data-dsh-remote-hidden-action", localAction = /(?:open|打开).{0,12}vs\s*code|vs\s*code.{0,12}(?:open|打开)|session\s*logs?|download.{0,12}session\s*logs?|会话日志|下载.{0,8}日志/i, inspect = (root) => {
4002
+ let candidates = root instanceof Element && root.matches(selector) ? [root, ...Array.from(root.querySelectorAll(selector))] : Array.from(root.querySelectorAll(selector));
4003
+ for (let candidate of candidates) {
4004
+ if (candidate.closest(".dshRemoteSessionHeader") !== null) continue;
4005
+ let label = [
4006
+ candidate.getAttribute("aria-label"),
4007
+ candidate.getAttribute("title"),
4008
+ candidate.getAttribute("data-tooltip"),
4009
+ candidate.textContent
4010
+ ].filter(Boolean).join(" ");
4011
+ localAction.test(label) && candidate.setAttribute(hiddenAttribute, "");
4012
+ }
4013
+ };
4014
+ inspect(document.body);
4015
+ let observer = new MutationObserver((records) => {
4016
+ for (let record of records) {
4017
+ record.type === "attributes" && inspect(record.target);
4018
+ for (let node of Array.from(record.addedNodes))
4019
+ node instanceof Element && inspect(node);
4020
+ }
4021
+ });
4022
+ return observer.observe(document.body, {
4023
+ subtree: !0,
4024
+ childList: !0,
4025
+ attributes: !0,
4026
+ attributeFilter: ["aria-label", "title", "data-tooltip"]
4027
+ }), () => {
4028
+ observer.disconnect(), document.querySelectorAll(`[${hiddenAttribute}]`).forEach((element) => element.removeAttribute(hiddenAttribute));
4029
+ };
4030
+ }
4031
+ function installStyle() {
4032
+ let style = document.createElement("style");
4033
+ return style.dataset.plugin = clientModuleId, style.dataset.pluginCss = "dsh-remote", style.textContent = [
4034
+ 'html.dshRemoteTargetActive button[aria-label="\u6DFB\u52A0\u5DE5\u4F5C\u533A"],html.dshRemoteTargetActive button[aria-label="Add workspace"]{display:none!important}',
4035
+ 'html.dshRemoteCodexTargetActive [data-composer-card] button[aria-haspopup="listbox"][aria-label="\u6307\u4EE4"],html.dshRemoteCodexTargetActive [data-composer-card] button[aria-haspopup="listbox"][aria-label="Commands"]{display:none!important}',
4036
+ "[data-dsh-remote-hidden-action]{display:none!important}",
4037
+ // The 0.1.6 right sidebar occupies the same shell header area as the
4038
+ // remote status strip. Hide the strip while that sidebar is expanded;
4039
+ // the sidebar itself remains the active context for terminal/files.
4040
+ ":has([data-sidebar-right-open]) .dshRemoteSessionHeader{display:none!important}",
4041
+ // TerminalRecovery renders a retry action in the conversation header.
4042
+ // A failed remote terminal is reported when its tab is opened/closed;
4043
+ // keeping this background recovery action out of the top-left header
4044
+ // avoids overlapping the session controls.
4045
+ '[title^="\u6062\u590D\u7EC8\u7AEF\u5931\u8D25"],[title^="Terminal recovery failed"]{display:none!important}',
4046
+ ".dshRemoteTerminalUnavailable{box-sizing:border-box;margin:12px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);font-size:13px;line-height:1.5}",
4047
+ ".dshRemoteModeButton{min-height:36px;border:0;background:transparent;color:var(--dsw-alias-label-primary);display:flex;align-items:center;gap:8px;padding:0 10px;border-radius:8px}.dshRemoteModeButton:is(button){cursor:pointer}",
4048
+ ".dshRemoteModeButton:is(button):hover{background:var(--dsw-alias-interactive-bg-hover)}",
4049
+ ".dshRemoteSidebarEntry{box-sizing:border-box;position:relative;min-width:0;display:block;overflow:hidden}.dshRemoteSidebarEntry .dshRemoteModeButton{box-sizing:border-box;width:100%;min-width:0}.dshRemoteSidebarEntry.isWide{width:calc(100% + 8px);height:34px;margin:4px -4px}.dshRemoteSidebarEntry.isWide .dshRemoteModeButton{height:34px;min-height:34px;padding:6px 48px 6px 10px;border-radius:12px}.dshRemoteSidebarEntry.isRail{width:36px;height:54px}.dshRemoteSidebarEntry.isRail .dshRemoteModeButton{width:36px;height:36px;min-height:36px;justify-content:center;gap:0;margin:8px 0 10px;padding:0;border-radius:50%}.dshRemoteSidebarEntry.isActive .dshRemoteModeButton{color:var(--dsw-alias-label-secondary);background:transparent}.dshRemoteSidebarLabel{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dshRemoteExitLink{position:absolute;top:50%;right:10px;transform:translateY(-50%);white-space:nowrap;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:0;font:inherit;font-size:12px;line-height:20px;cursor:pointer}.dshRemoteExitLink:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteExitLink:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:2px}.dshRemoteExitLink:disabled{opacity:.45;cursor:default;text-decoration:none}",
4050
+ ".dshRemoteComputerIcon{box-sizing:border-box;width:18px;height:18px;flex:0 0 18px;color:var(--dsw-alias-label-secondary)}",
4051
+ '.dshRemoteSessionHeader{position:fixed;z-index:25;top:12px;left:50%;transform:translateX(-50%);max-width:calc(100vw - 360px);height:28px;display:inline-flex;align-items:center;gap:7px;color:var(--dsw-alias-label-secondary);font-size:12px;white-space:nowrap;overflow:hidden}.dshRemoteSessionHeader>svg{width:15px;height:15px;flex:0 0 auto}.dshRemoteModePrefix{flex:0 0 auto}.dshRemoteSessionTarget{flex:0 1 auto;min-width:0;max-width:260px;overflow:hidden;text-overflow:ellipsis}.dshRemoteNetwork{flex:0 0 auto;border:0;background:transparent;color:inherit;font:inherit;padding:3px 2px;display:inline-flex;align-items:center;gap:5px;cursor:pointer}.dshRemoteNetwork:hover:not(:disabled){color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteNetwork:disabled{cursor:default}.dshRemoteNetwork>i{width:6px;height:6px;border-radius:50%;background:var(--dsw-alias-label-tertiary)}.dshRemoteNetwork.isOnline>i{background:var(--dsw-alias-state-success-primary)}.dshRemoteNetwork.isOffline{color:var(--dsw-alias-state-error-primary)}.dshRemoteNetwork.isOffline>i{background:currentColor}.dshRemoteEncrypted{flex:0 0 auto;color:var(--dsw-alias-label-tertiary)}.dshRemoteNetwork:focus-visible,.dshRemoteRoutePanel>header button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.dshRemoteRouteBackdrop{position:fixed;inset:0;z-index:26}.dshRemoteRoutePanel{box-sizing:border-box;position:absolute;top:48px;right:28px;width:min(680px,calc(100vw - 32px));max-height:calc(100vh - 72px);overflow:auto;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;padding:16px;white-space:normal}.dshRemoteRoutePanel>header{position:sticky;top:-16px;z-index:1;display:flex;align-items:center;justify-content:space-between;margin:-16px -16px 0;padding:16px;background:var(--dsw-alias-bg-layer-1)}.dshRemoteRoutePanel>header strong{font-size:14px}.dshRemoteRoutePanel>header button{width:28px;height:28px;border:0;border-radius:7px;background:transparent;color:inherit;font-size:20px;cursor:pointer}.dshRemoteRoutePanel>header button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteRoutePanel ol{display:flex;align-items:stretch;margin:12px 0 0;padding:0 0 16px;border-bottom:1px solid var(--dsw-alias-border-l2);list-style:none}.dshRemoteRoutePanel li{position:relative;min-width:0;flex:1;display:flex;flex-direction:column;gap:4px;padding-right:20px}.dshRemoteRoutePanel li:not(:last-child)::after{content:"\u2192";position:absolute;right:7px;top:21px;color:var(--dsw-alias-label-tertiary)}.dshRemoteRoutePanel li small{color:var(--dsw-alias-label-tertiary)}.dshRemoteRoutePanel li strong,.dshRemoteRoutePanel li span{overflow:hidden;text-overflow:ellipsis}.dshRemoteRoutePanel li strong{font-size:13px}.dshRemoteRoutePanel li span{color:var(--dsw-alias-label-secondary);font-size:11px}.dshRemoteRouteSection{padding-top:16px}.dshRemoteRouteSection h3{margin:0 0 10px;font-size:12px;font-weight:600;color:var(--dsw-alias-label-secondary)}.dshRemoteRouteSection dl{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 24px;margin:0}.dshRemoteRouteSection dl>div{min-width:0;display:grid;grid-template-columns:minmax(104px,auto) minmax(0,1fr);gap:10px;padding:7px 0;border-bottom:1px solid var(--dsw-alias-border-l2);font-size:12px;line-height:1.45}.dshRemoteRouteSection dt{color:var(--dsw-alias-label-tertiary)}.dshRemoteRouteSection dd{min-width:0;margin:0;text-align:right;overflow-wrap:anywhere}.dshRemoteRouteSection dd.isMono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px}.dshRemoteRoutePanel>p{margin:16px 0 0;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}@media(max-width:620px){.dshRemoteSessionHeader{top:8px;max-width:calc(100vw - 112px)}.dshRemoteSessionHeader>svg{display:none}.dshRemoteSessionTarget{max-width:130px}.dshRemoteEncrypted{display:none}.dshRemoteRoutePanel{top:42px;right:12px;max-height:calc(100vh - 56px)}.dshRemoteRoutePanel ol{flex-direction:column;gap:18px}.dshRemoteRoutePanel li:not(:last-child)::after{content:"\u2193";top:auto;right:auto;bottom:-16px;left:3px}.dshRemoteRouteSection dl{grid-template-columns:1fr}.dshRemoteRouteSection dl>div{grid-template-columns:1fr;gap:2px}.dshRemoteRouteSection dd{text-align:left}}',
4052
+ ".dshRemoteSessionHeader{left:auto;right:148px;transform:none;max-width:calc(100vw - 420px)}@media(max-width:760px){.dshRemoteSessionHeader{left:auto;right:88px;transform:none;max-width:calc(100vw - 104px);padding:3px 8px;border:1px solid var(--dsw-alias-border-l1);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}.dshRemoteModePrefix,.dshRemoteEncrypted{display:none}.dshRemoteSessionTarget{max-width:min(30vw,150px)}}",
4053
+ ".dshRemoteModeButton:focus-visible,.dshRemotePage button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}",
4054
+ ".dshRemotePage{width:min(720px,100%);max-height:min(760px,calc(100vh - 40px));display:flex;flex-direction:column;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:14px;overflow:hidden;animation:dshRemotePageIn .18s cubic-bezier(.25,1,.5,1)}",
4055
+ ".dshRemotePageHeader{min-height:72px;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:14px 24px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemotePageIntro{min-width:0;flex:1}.dshRemotePageHeader strong{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:18px;line-height:1.4}.dshRemotePageHeader p{min-width:0;max-width:70ch;margin:3px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5}.dshRemotePageActions{flex:0 0 auto;display:flex;align-items:center;gap:4px}.dshRemotePageActions>button{height:40px;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;border:0;border-radius:8px;background:transparent;color:inherit;line-height:1;cursor:pointer}.dshRemotePageActions>button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.dshRemotePageActions>button:disabled{opacity:.45;cursor:default}.dshRemotePageBack,.dshRemotePageRefresh{min-width:48px;padding:0 10px;font:inherit;font-size:13px}.dshRemotePageBack{color:var(--dsw-alias-label-secondary)!important}.dshRemotePageClose{width:40px;padding:0;font-size:24px}",
4056
+ ".dshRemotePageBody{padding:24px;overflow:auto;display:flex;flex-direction:column;gap:24px}.dshRemotePageBody button{font:inherit;color:inherit}",
4057
+ ".dshRemotePageTitleRow{display:flex;align-items:center;gap:10px;min-width:0}.dshRemotePageTitleRow>strong{min-width:0;flex:0 1 auto}",
4058
+ ".dshRemoteSectionHeading{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:10px}.dshRemoteSectionTitle{min-width:0;display:flex;align-items:center;gap:10px}.dshRemoteSectionTitle>strong{font-size:14px}.dshRemoteSectionActions{display:flex;align-items:center;gap:14px}.dshRemoteSectionActions>button{border:0;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;padding:5px 0;font-size:12px}.dshRemoteSectionActions>button:hover:not(:disabled){color:var(--dsw-alias-label-primary);text-decoration:underline}",
4059
+ ".dshRemoteSectionTitle{flex:1}.dshRemoteSectionTitle>.dshRemoteConnectedMenu{margin-left:auto}",
4060
+ '.dshRemoteAcpSetting{display:block!important;width:100%;padding:0}.dshRemoteAcpSetting>summary{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;cursor:pointer;list-style:none}.dshRemoteAcpSetting>summary::-webkit-details-marker{display:none}.dshRemoteAcpSetting>summary::after{content:"\u2304";color:var(--dsw-alias-label-secondary);transition:transform .18s ease-out}.dshRemoteAcpSetting[open]>summary::after{transform:rotate(180deg)}.dshRemoteAcpSummaryText{min-width:0}.dshRemoteAcpSummaryText strong{display:block}.dshRemoteAcpSummaryText p{margin:4px 0 0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.4}.dshRemoteAcpCheckLink{grid-column:2;grid-row:1;color:var(--dsw-alias-brand-primary);font-size:12px;text-decoration:underline;text-underline-offset:3px}.dshRemoteAcpCheckLink:hover{color:var(--dsw-alias-label-primary)}.dshRemoteAcpCheckResult{grid-column:3;grid-row:1;font-size:11px;line-height:1.4;white-space:nowrap}.dshRemoteAcpCheckResult.isPassed{color:var(--dsw-alias-state-success-primary)}.dshRemoteAcpCheckResult.isFailed{color:var(--dsw-alias-state-danger-primary)}.dshRemoteAcpList{display:flex;flex-direction:column;gap:0;margin-top:12px;padding-top:0;border-top:0}.dshRemoteAcpList>.dshRemoteAuthorizationSetting{display:grid;width:100%;grid-template-columns:minmax(0,1fr) auto auto auto auto;align-items:center;column-gap:18px;line-height:1.4}.dshRemoteAcpList>.dshRemoteAuthorizationSetting>span:first-child{min-width:0;line-height:1.4}.dshRemoteAcpList>.dshRemoteAuthorizationSetting>input{grid-column:4;grid-row:1}',
4061
+ ".dshRemoteAcpAddLink{align-self:flex-start;margin-top:12px;color:var(--dsw-alias-brand-primary);font-size:12px;text-decoration:underline;text-underline-offset:3px}.dshRemoteAcpAddForm{display:grid;grid-template-columns:minmax(100px,.8fr) minmax(140px,1fr) minmax(100px,1fr) auto;gap:8px;margin-top:12px}.dshRemoteAcpAddForm input{min-width:0;height:34px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);color:inherit;padding:0 10px}.dshRemoteAcpAddForm button{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);padding:0 12px;cursor:pointer;font:inherit;font-size:12px}.dshRemoteAcpAddForm button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteAcpRemoveLink{grid-column:3;grid-row:1;color:var(--dsw-alias-label-secondary);font-size:12px;text-decoration:underline;text-underline-offset:3px}.dshRemoteAcpRemoveLink:hover{color:var(--dsw-alias-state-danger-primary)}",
4062
+ ".dshRemoteAcpCheckResult.isPassed,.dshRemoteAcpCheckResult.isFailed{color:var(--dsw-alias-label-secondary)}",
4063
+ ".dshRemoteAcpList>.dshRemoteAuthorizationSetting{grid-template-columns:minmax(0,1fr) 190px 40px 56px;column-gap:18px}.dshRemoteAcpCheckCell{grid-column:2;display:flex;align-items:center;gap:10px;min-width:0}.dshRemoteAcpCheckLink,.dshRemoteAcpRemoveLink{justify-self:start}.dshRemoteAcpCheckResult{position:static}",
4064
+ ".dshRemoteAcpCheckLink.isPassed{color:var(--dsw-alias-state-success-primary)}.dshRemoteAcpCheckLink.isFailed{color:var(--dsw-alias-state-danger-primary)}.dshRemoteAcpCheckLink.isChecking{color:var(--dsw-alias-label-secondary)}",
4065
+ ".dshRemoteCancelWorkspace{min-height:36px;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:6px 0;cursor:pointer}.dshRemoteCancelWorkspace:hover:not(:disabled){color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteCancelWorkspace:disabled{opacity:.5;cursor:default}",
4066
+ '.dshRemoteHostList{display:flex;flex-direction:column;border-top:1px solid var(--dsw-alias-border-l2);max-height:296px;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable}.dshRemoteHostList.isCollapsed{max-height:none;overflow-y:visible}.dshRemoteHostList>button{min-height:58px;flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:16px;text-align:left;border:0;border-bottom:1px solid var(--dsw-alias-border-l2);background:transparent;padding:10px 4px;cursor:pointer}.dshRemoteHostList>button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteHostList>button:disabled{opacity:.5;cursor:default}.dshRemoteHostList>button[aria-current="true"]{background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteHostList>button>span{min-width:0;display:flex;flex-direction:column;gap:3px}.dshRemoteHostList>button strong{font-size:14px;font-weight:500}.dshRemoteHostList small{color:var(--dsw-alias-label-secondary);font-size:12px}',
4067
+ '.dshRemoteConnectedMenu{position:relative;flex:0 0 auto;margin-right:4px}.dshRemoteConnectedCount{appearance:none;display:inline-flex;align-items:center;justify-content:center;height:22px;border:0;border-radius:999px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);box-shadow:0 1px 2px rgba(0,0,0,.18),0 0 0 1px rgba(255,255,255,.04) inset;padding:0 10px;font:inherit;font-size:11px;font-weight:500;line-height:17px;white-space:nowrap;cursor:default}.dshRemoteConnectedCount.isOnline{color:var(--dsw-alias-state-success-primary)}.dshRemoteConnectedCount.isInteractive{cursor:pointer}.dshRemoteConnectedCount.isInteractive:hover{filter:brightness(1.08)}.dshRemoteConnectedCount:disabled{opacity:1;cursor:default}.dshRemoteConnectedCount:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.dshRemoteConnectedPanel{position:absolute;top:calc(100% + 8px);right:0;z-index:4;width:min(320px,calc(100vw - 48px));max-height:min(280px,40vh);overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);box-shadow:0 10px 28px rgba(0,0,0,.28);padding:10px 12px}.dshRemoteConnectedPanelTitle{display:block;margin:0 0 6px;color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600}.dshRemoteClientList{display:flex;flex-direction:column}.dshRemoteClientRow{min-height:44px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0;border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemoteClientRow:last-child{border-bottom:0}.dshRemoteClientRow>span{min-width:0;display:flex;flex-direction:column;gap:2px}.dshRemoteClientRow strong{font-size:13px;font-weight:500}.dshRemoteClientRow small{color:var(--dsw-alias-label-secondary);font-size:11px}.dshRemoteClientOnline{display:inline-flex;align-items:center;gap:6px;color:var(--dsw-alias-state-success-primary)!important}.dshRemoteClientOnline::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}',
4068
+ ".dshRemoteConnectedCount{height:auto;border-radius:0;background:transparent;box-shadow:none;padding:0 4px;text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 45%,transparent);text-underline-offset:3px}.dshRemoteConnectedCount.isInteractive:hover{filter:none;text-decoration-color:currentColor}.dshRemoteConnectedCount:focus-visible{outline-offset:3px;border-radius:3px}",
4069
+ '.dshRemoteProgress{display:flex;flex-direction:column;gap:8px;margin:12px 0;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2)}.dshRemoteProgressHeader{display:flex;align-items:center;justify-content:space-between;gap:12px}.dshRemoteProgressHeader strong{font-size:13px;font-weight:600}.dshRemoteProgressHeader span{color:var(--dsw-alias-label-secondary);font-size:12px}.dshRemoteProgressBar{height:6px;overflow:hidden;border-radius:999px;background:var(--dsw-alias-bg-layer-3)}.dshRemoteProgressBar>span{display:block;width:100%;height:100%;border-radius:inherit;background:var(--dsw-alias-brand-primary);transform-origin:left center;transition:transform .22s ease-out}[dir="rtl"] .dshRemoteProgressBar>span{transform-origin:right center}.dshRemoteProgress p{margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.45}.dshRemoteProgressRoute{font-weight:500}.dshRemoteProgressRoute .isActive{color:var(--dsw-alias-state-success-primary);font-weight:700}.dshRemoteProgressRouteArrow{color:var(--dsw-alias-label-tertiary)}@media(prefers-reduced-motion:reduce){.dshRemoteProgressBar>span{transition:none}}',
4070
+ '.dshRemoteBrowser{display:flex;flex-direction:column}.dshRemoteCrumbs{display:flex;align-items:center;gap:4px;overflow:auto;padding:2px 0 10px}.dshRemoteCrumbs>button{flex:0 0 auto;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:5px 7px;border-radius:6px;cursor:pointer}.dshRemoteCrumbs>button:not(:last-child)::after{content:" /";color:var(--dsw-alias-label-tertiary)}.dshRemoteCrumbs>button:disabled{color:var(--dsw-alias-label-primary);font-weight:600}',
4071
+ ".dshRemoteWorkspaceLists{overflow:visible}",
4072
+ ".dshRemoteDirectoryList{min-height:72px;display:flex;flex-direction:column;border-top:1px solid var(--dsw-alias-border-l2)}.dshRemoteDirectoryList>button{min-height:52px;display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:10px;text-align:left;border:0;border-bottom:1px solid var(--dsw-alias-border-l2);background:transparent;padding:8px 4px;cursor:pointer}.dshRemoteDirectoryList>button:hover,.dshRemoteDirectoryList>button.isSelected{background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteDirectoryList>button.isSelected{color:var(--dsw-alias-label-primary)}.dshRemoteDirectoryList>button>span:first-child,.dshRemoteDirectoryList>button>.dshRemoteWorkspaceIcon{grid-row:1/3}.dshRemoteWorkspaceIcon{box-sizing:border-box;width:22px;height:22px;align-self:center;object-fit:contain}.dshRemoteWorkspaceIcon.isGpt{border-radius:6px}.dshRemoteDirectoryList>button>span:not(:first-child),.dshRemoteDirectoryList>button>small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dshRemoteDirectoryList>button>small{grid-column:2;color:var(--dsw-alias-label-secondary)}.dshRemoteDirectoryList>p,.dshRemoteHint{margin:12px 0;color:var(--dsw-alias-label-secondary);font-size:13px}",
4073
+ ".dshRemoteAddWorkspace{box-sizing:border-box;width:40px;height:40px;display:inline-grid;place-items:center;flex:0 0 auto;border:0;border-radius:8px;background:transparent;color:var(--dsw-alias-label-secondary);padding:0;cursor:pointer}.dshRemoteAddWorkspace:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteAddWorkspace:disabled{opacity:.5;cursor:default}.dshRemoteAddWorkspaceIcon{width:20px;height:20px}.dshRemoteCodexWorkspaceGroup{margin-top:16px}.dshRemoteWorkspaceSourceHeading{min-height:44px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 4px 7px}.dshRemoteWorkspaceSourceText{min-width:0;display:flex;flex-direction:column;gap:2px}.dshRemoteWorkspaceSourceText>strong{font-size:13px}.dshRemoteWorkspaceSourceText>small{color:var(--dsw-alias-label-secondary);font-size:11px}.dshRemoteCodexWorkspaceList{min-height:0}.dshRemoteDirectoryList>.dshRemoteWorkspaceMore,.dshRemoteCodexWorkspaceGroup>.dshRemoteWorkspaceMore{box-sizing:border-box;width:100%;min-height:48px;display:flex;align-items:center;justify-content:center;border:0;border-bottom:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);padding:8px 4px;text-align:center;font-size:16px;cursor:pointer}.dshRemoteWorkspaceMore>span{display:block;line-height:1;transform:translateY(-2px)}.dshRemoteWorkspaceMore:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:transparent}.dshRemoteWorkspaceMore:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.dshRemoteWorkspaceMore:disabled{opacity:.5;cursor:default}",
4074
+ ".dshRemotePreviewAction,.dshRemotePreviewForm{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.dshRemotePreviewForm input{width:90px;color:inherit;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);padding:6px}.dshRemotePreviewForm [role=alert]{max-width:360px;white-space:normal}.dshRemoteDevelopmentSettings{margin:16px 0}.dshRemoteDevelopmentSettings .dshRemotePathField{margin:8px 0}.dshRemoteDevelopmentSettings .dshRemotePortsRow{display:flex;gap:8px;align-items:stretch}.dshRemoteDevelopmentSettings .dshRemotePortsRow>input{flex:1;min-width:0;min-height:40px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:inherit;padding:0 12px;font:inherit}.dshRemoteDevelopmentSettings button{min-height:36px;color:inherit;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:6px 12px;white-space:nowrap}",
4075
+ ".dshRemoteFolderBrowser{margin-top:14px}.dshRemoteFolderBrowser>p,.dshRemoteFolderList>p{margin:12px 0;color:var(--dsw-alias-label-secondary);font-size:13px}.dshRemoteFolderList{max-height:260px;overflow:auto;border-block:1px solid var(--dsw-alias-border-l2)}.dshRemoteFolderList>button{width:100%;min-height:42px;display:flex;align-items:center;gap:9px;border:0;border-bottom:1px solid var(--dsw-alias-border-l2);background:transparent;padding:7px 6px;text-align:left;cursor:pointer}.dshRemoteFolderList>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteFolderBrowser>small{display:block;margin-top:8px;color:var(--dsw-alias-state-warn-label)}",
4076
+ ".dshRemotePathField{display:flex;flex-direction:column;gap:6px;margin-top:20px}.dshRemotePathField>span{font-size:13px;font-weight:600}.dshRemotePathField>input{min-height:40px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:inherit;padding:0 12px;font:inherit}.dshRemotePathField>small{color:var(--dsw-alias-label-secondary)}",
4077
+ ".dshRemoteOpenBar{position:sticky;bottom:-96px;display:flex;align-items:center;justify-content:space-between;gap:20px;margin-top:20px;padding:14px 0;background:var(--dsw-alias-bg-layer-1);border-top:1px solid var(--dsw-alias-border-l2)}.dshRemoteOpenBar>div{min-width:0;display:flex;flex-direction:column;gap:3px}.dshRemoteOpenBar span{color:var(--dsw-alias-label-secondary);font-size:12px}.dshRemoteOpenBar strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.dshRemoteOpenBar>button,.dshRemoteEnable>button{min-height:40px;flex:0 0 auto;border:0;border-radius:8px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-1);padding:8px 16px;cursor:pointer}.dshRemoteOpenBar>button:disabled,.dshRemoteEnable>button:disabled{opacity:.5;cursor:default}",
4078
+ ".dshRemoteEnable{box-sizing:border-box;width:min(440px,100%);max-width:100%;min-height:388px;margin:0 auto;display:flex;flex-direction:column;align-items:stretch;gap:10px}.dshRemoteEnable p{margin:0;color:var(--dsw-alias-label-secondary);line-height:1.5}",
4079
+ '.dshRemoteLoginTabs{width:min(440px,100%);display:flex;border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemoteLoginTabs>button{position:relative;min-height:38px;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:6px 14px;font:inherit;font-size:13px;cursor:pointer}.dshRemoteLoginTabs>button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.dshRemoteLoginTabs>button.isActive{color:var(--dsw-alias-label-primary);font-weight:600}.dshRemoteLoginTabs>button.isActive::after{content:"";position:absolute;right:12px;bottom:-1px;left:12px;height:2px;border-radius:2px 2px 0 0;background:var(--dsw-alias-brand-primary)}.dshRemoteLoginTabs>button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px;border-radius:6px}',
4080
+ ".dshRemoteClientLogin{width:min(440px,100%);display:flex;flex-direction:column;gap:8px}.dshRemoteClientLogin input{min-height:40px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-3);color:inherit;padding:0 12px;font:inherit}.dshRemoteClientLogin button{align-self:flex-start;min-height:40px;border:0;border-radius:8px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-1);padding:8px 16px;cursor:pointer}",
4081
+ ".dshRemoteQrLogin{width:min(440px,100%);display:flex;flex-direction:column;align-items:center;gap:8px;padding:6px 0 2px;text-align:center}.dshRemoteQrLogin img,.dshRemoteQrPlaceholder{box-sizing:border-box;width:200px;height:200px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:#fff;padding:8px}.dshRemoteQrOpen{display:flex;flex-direction:column;align-items:center;gap:5px;color:var(--dsw-alias-label-secondary);font-size:12px;text-decoration:none}.dshRemoteQrOpen:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteQrOpen:hover img{border-color:var(--dsw-alias-label-dimmed)}.dshRemoteQrOpen:focus-visible{border-radius:12px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.dshRemoteQrPlaceholder{display:flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-secondary)}.dshRemoteQrLogin>strong{font-size:14px}.dshRemoteQrLogin>p{max-width:48ch;margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.dshRemoteQrLogin>.dshRemoteServiceAddress{margin-top:2px;color:var(--dsw-alias-label-tertiary)}.dshRemoteServerRow{display:flex;align-items:center;justify-content:center;min-width:0}.dshRemoteClientLogin .dshRemoteServerValue{align-self:center;min-height:0;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:0;border-radius:8px;background:transparent;color:inherit;padding:6px 10px;font:inherit;font-size:13px;cursor:pointer}.dshRemoteClientLogin .dshRemoteServerValue:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteClientLogin .dshRemoteServerValue:disabled{cursor:default;opacity:.45}.dshRemoteClientLogin .dshRemoteServerValue:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.dshRemoteServerInput{text-align:center}.dshRemoteServiceAddress>a{color:var(--dsw-alias-label-secondary);text-decoration:none}.dshRemoteServiceAddress>a:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteQrLogin>button,.dshRemoteClientLogin>.dshRemoteLoginSwitch{min-height:32px;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:4px 8px;font:inherit;font-size:12px;cursor:pointer}.dshRemoteQrLogin>button:hover,.dshRemoteClientLogin>.dshRemoteLoginSwitch:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteClientLogin>.dshRemoteLoginSwitch{align-self:flex-start;background:transparent;color:var(--dsw-alias-label-secondary);padding-left:0}",
4082
+ ".dshRemoteLoginTabs{box-sizing:border-box;width:100%}.dshRemoteLoginTabs>button{min-width:0;flex:1;display:flex;align-items:center;justify-content:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.dshRemoteLoginTabs>button.isActive::after{right:0;left:0;border-radius:0}.dshRemoteClientLogin,.dshRemoteQrLogin{box-sizing:border-box;width:100%;height:300px;min-height:300px}.dshRemoteClientLogin{align-items:stretch;padding-top:16px}.dshRemoteClientLogin>button{align-self:stretch;width:100%}.dshRemoteQrLogin{padding-top:12px}",
4083
+ '.dshRemoteHostControlToggle{display:flex;align-items:center;gap:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;white-space:nowrap;cursor:default}.dshRemoteHostControlToggle>input{appearance:none;box-sizing:border-box;position:relative;width:32px;height:18px;flex:0 0 auto;margin:0;border:1px solid var(--dsw-alias-label-secondary);border-radius:999px;background:var(--dsw-alias-bg-layer-3);cursor:pointer;box-shadow:inset 0 0 0 1px var(--dsw-alias-border-l2);transition:background .16s ease-out,border-color .16s ease-out,box-shadow .16s ease-out}.dshRemoteHostControlToggle>input::after{content:"";position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--dsw-alias-label-secondary);transition:transform .16s ease-out,background .16s ease-out}.dshRemoteHostControlToggle>input:checked{border-color:var(--dsw-alias-state-success-primary);background:var(--dsw-alias-state-success-primary);box-shadow:none}.dshRemoteHostControlToggle>input:checked::after{transform:translateX(14px);background:var(--dsw-alias-bg-layer-1)}.dshRemoteHostControlToggle>input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.dshRemoteHostControlToggle>input:disabled{opacity:.5;cursor:default}@media(prefers-reduced-motion:reduce){.dshRemoteHostControlToggle>input,.dshRemoteHostControlToggle>input::after{transition:none}}',
4084
+ ".dshRemoteAccountFooter{display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:14px;color:var(--dsw-alias-label-secondary);font-size:12px}.dshRemoteAccountExit{flex:0 0 auto;border:0;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;padding:5px 0;font-size:12px;line-height:1.5;white-space:nowrap}.dshRemoteAccountExit:hover:not(:disabled){color:var(--dsw-alias-label-primary);text-decoration:underline}.dshRemoteAccountExit:disabled{opacity:.5;cursor:default;text-decoration:none}",
4085
+ ".dshRemoteLocalLink{align-self:flex-start;border:0;background:transparent;color:var(--dsw-alias-label-secondary);padding:4px 0;cursor:pointer}.dshRemoteLocalLink:hover{color:var(--dsw-alias-label-primary)}",
4086
+ "@keyframes dshRemotePageIn{from{opacity:0;transform:translateY(6px) scale(.99)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.dshRemotePage{animation:none}}@media(max-width:620px){.dshRemoteBackdrop{padding:12px}.dshRemotePage{max-height:calc(100vh - 24px)}.dshRemotePageHeader{gap:8px;padding:12px 16px}.dshRemotePage.hasSelectedHost .dshRemotePageBack{max-width:112px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dshRemoteSectionHeading{align-items:flex-start;flex-direction:column;gap:8px}.dshRemoteWorkspaceHeading{align-items:center;flex-direction:row}.dshRemoteSectionActions{width:100%;justify-content:space-between}.dshRemotePageBody{padding:20px 16px}.dshRemoteOpenBar{align-items:flex-end}.dshRemoteOpenBar>button{min-height:48px}}",
4087
+ ".dshRemoteBackdrop{position:fixed;inset:0;z-index:1000;background:var(--dsw-alias-bg-mask-3);display:grid;place-items:center;padding:20px}",
4088
+ ".dshRemoteDialog{width:min(460px,100%);max-height:80vh;overflow:auto;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l2);border-radius:14px;padding:18px;display:grid;gap:12px;box-shadow:var(--dsw-shadow-lv2)}",
4089
+ ".dshRemoteDialog button,.dshRemoteDialog input{font:inherit;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:9px 10px;background:transparent;color:inherit}",
4090
+ ".dshRemoteDialog button:not(:disabled){cursor:pointer}.dshRemoteDialog button:disabled{opacity:.5}",
4091
+ ".dshRemoteHeader{display:flex;align-items:center;justify-content:space-between}.dshRemoteHeader button{border:0;font-size:22px;padding:0 6px}",
4092
+ ".dshRemoteDevices{display:grid;gap:8px}.dshRemoteDevices p{margin:4px 0;color:var(--dsw-alias-label-secondary)}",
4093
+ ".dshRemoteError{margin:0;color:var(--dsw-alias-state-error-primary)}",
4094
+ ".dshRemoteHostAccount{display:grid;gap:8px;border-top:1px solid var(--dsw-alias-border-l3);padding-top:12px}.dshRemoteHostAccount p{margin:0;color:var(--dsw-alias-label-secondary);font-size:13px}",
4095
+ ".dshRemoteLogin{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dshRemoteLogin button{grid-column:1/-1}",
4096
+ ".dshRemotePluginCard{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}",
4097
+ ".dshRemotePluginModern{box-sizing:border-box;width:100%;max-width:768px;box-shadow:none}.dshRemotePluginModern>.dshRemotePluginCardHeader{display:none}.dshRemotePluginModern>.dshRemotePluginCardBody{border-top:0;margin:0;padding:8px 20px}",
4098
+ ".dshRemotePluginCard:hover{border-color:var(--dsw-alias-label-dimmed)}.dshRemotePluginCard.isOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}",
4099
+ ".dshRemotePluginCardHeader{display:flex;align-items:center}.dshRemotePluginCardToggle{appearance:none;width:100%;min-width:0;font:inherit;color:inherit;text-align:left;cursor:pointer;background:transparent;border:0;border-radius:12px;display:flex;align-items:center;gap:12px;padding:14px 16px}.dshRemotePluginCardToggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}",
4100
+ ".dshRemotePluginCardHeading{display:flex;flex-direction:column;gap:4px;min-width:0;flex:1}.dshRemotePluginCardHeading>strong{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dshRemotePluginCardHeading>span{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.dshRemotePluginCardStatus{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.dshRemotePluginCardStatus.isOnline{color:var(--dsw-alias-state-success-primary)}.dshRemotePluginCardStatus.isReconnecting{color:var(--dsw-alias-state-warn-label)}.dshRemotePluginCardStatus.isOffline{color:var(--dsw-alias-state-error-primary)}.dshRemotePluginCardChevron{color:var(--dsw-alias-label-tertiary);font-size:18px;line-height:14px;transition:transform .16s}.dshRemotePluginCard.isOpen .dshRemotePluginCardChevron{transform:rotate(180deg)}",
4101
+ ".dshRemotePluginCardBody{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.dshRemoteSettings{display:flex;flex-direction:column;max-width:720px}.dshRemoteSettingsTop{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:12px 0}.dshRemoteSettingsState{margin:0;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}",
4102
+ ".dshRemoteHostIdentity{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;padding:12px 0;border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2)}.dshRemoteHostIdentity>div{min-width:0;display:flex;flex-direction:column;gap:3px}.dshRemoteHostIdentity span{color:var(--dsw-alias-label-tertiary);font-size:12px}.dshRemoteHostIdentity strong,.dshRemoteHostIdentity code{min-width:0;overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500}.dshRemoteHostIdentity code{font-family:var(--dsw-font-mono,ui-monospace,SFMono-Regular,Menlo,monospace);font-weight:400}",
4103
+ ".dshRemoteField{display:flex;flex-direction:column;gap:6px;padding:12px 0}.dshRemoteField+.dshRemoteField{border-top:1px solid var(--dsw-alias-border-l2)}.dshRemoteField label{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}.dshRemoteField input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.dshRemoteField input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.dshRemoteField input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.dshRemoteField p{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}",
4104
+ '.dshRemoteAuthorizationSetting{border-top:1px solid var(--dsw-alias-border-l2);display:flex;align-items:center;justify-content:space-between;gap:20px;padding:12px 0}.dshRemoteAuthorizationSetting>div{min-width:0}.dshRemoteAuthorizationSetting strong{font-size:13px;font-weight:500}.dshRemoteAuthorizationSetting p{margin:3px 0 0;color:var(--dsw-alias-label-tertiary);font-size:12px}.dshRemoteAuthorizationSetting>input{appearance:none;position:relative;width:38px;height:22px;flex:0 0 auto;margin:0;border:1px solid var(--dsw-alias-label-secondary);border-radius:999px;background:var(--dsw-alias-bg-layer-3);cursor:pointer;box-shadow:inset 0 0 0 1px var(--dsw-alias-border-l2);transition:background .16s ease-out,border-color .16s ease-out,box-shadow .16s ease-out}.dshRemoteAuthorizationSetting>input::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--dsw-alias-label-secondary);transition:transform .16s ease-out,background .16s ease-out}.dshRemoteAuthorizationSetting>input:checked{border-color:var(--dsw-alias-state-success-primary);background:var(--dsw-alias-state-success-primary);box-shadow:none}.dshRemoteAuthorizationSetting>input:checked::after{transform:translateX(16px);background:var(--dsw-alias-bg-layer-1)}.dshRemoteAuthorizationSetting>input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.dshRemoteAuthorizationSetting>input:disabled{opacity:.5;cursor:default}@media(prefers-reduced-motion:reduce){.dshRemoteAuthorizationSetting>input,.dshRemoteAuthorizationSetting>input::after{transition:none}}.dshRemoteCodexBinary{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:0 0 12px}.dshRemoteCodexBinary input{flex:1 1 320px;min-width:0;font:inherit;font-size:12px;padding:5px 8px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary)}.dshRemoteCodexBinary input.isDiscovered{color:var(--dsw-alias-label-tertiary);cursor:default}.dshRemoteCodexBinary input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.dshRemoteCodexBinary p{flex:1 1 100%;margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}',
4105
+ ".dshRemoteAssociation{min-width:0;flex:1;display:flex;flex-direction:column;gap:4px}.dshRemoteAssociation>span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}.dshRemoteAssociation strong{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:1.5}.dshRemoteAssociation p{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}",
4106
+ ".dshRemoteConnection{border-top:1px solid var(--dsw-alias-border-l2);display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 0}.dshRemoteConnectionSummary{min-width:0;display:flex;flex-direction:column;gap:4px}.dshRemoteConnectionSummary>span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}.dshRemoteConnectionSummary strong{display:flex;align-items:center;gap:7px;color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:1.5}.dshRemoteConnectionSummary p,.dshRemoteConnectionIssue{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}.dshRemoteConnectionDot{width:8px;height:8px;flex:0 0 auto;border-radius:999px;background:var(--dsw-alias-label-tertiary)}.dshRemoteConnectionDot.isOnline{background:var(--dsw-alias-state-success-primary)}.dshRemoteConnectionDot.isReconnecting{background:var(--dsw-alias-state-warn-primary)}.dshRemoteConnectionDot.isOffline{background:var(--dsw-alias-state-error-primary)}.dshRemoteConnectionIssue{color:var(--dsw-alias-state-error-primary);padding:0 0 12px}.dshRemoteReconnect{appearance:none;flex:0 0 auto;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:var(--dsw-alias-label-secondary);min-height:34px;padding:5px 14px;font-size:13px;line-height:1.5}.dshRemoteReconnect:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover)}.dshRemoteReconnect:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.dshRemoteReconnect:disabled{opacity:.4;cursor:default}",
4107
+ ".dshRemoteSettingsFooter{border-top:1px solid var(--dsw-alias-border-l2);display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px}.dshRemoteSettingsFooter .dshRemoteError,.dshRemoteNotice{min-width:0;flex:1;margin:0;font-size:12px;line-height:1.5}.dshRemoteNotice{color:var(--dsw-alias-label-tertiary)}.dshRemoteDiscard,.dshRemoteSave{appearance:none;font:inherit;cursor:pointer;border:1px solid transparent;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.dshRemoteDiscard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:transparent}.dshRemoteDiscard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.dshRemoteSave{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.dshRemoteDiscard:disabled,.dshRemoteSave:disabled{opacity:.4;cursor:default}.dshRemoteDiscard:focus-visible,.dshRemoteSave:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}",
4108
+ "@media(max-width:620px){.dshRemotePluginCardStatus{display:none}.dshRemoteSettingsTop{gap:10px}.dshRemoteConnection{align-items:flex-start}.dshRemoteReconnect{min-height:40px}}"
4109
+ ].join(""), document.head.append(style), () => style.remove();
4110
+ }
4111
+ function apply(ctx) {
4112
+ if (window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__) return;
4113
+ window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__ = !0, ctx.effect(() => () => {
4114
+ window.__DS_HARNESS_REMOTE_CLIENT_ACTIVE__ = !1;
4115
+ }, "ds-harness-remote: client singleton");
4116
+ let t = ctx.locale.bind(localeNamespace), controlRouteRetryAfter = 0, controlRouteBackoffIndex = 0, control = async (endpoint, payload = {}) => {
4117
+ if (endpoint === "status" && Date.now() < controlRouteRetryAfter)
4118
+ return controlRouteUnavailableStatus();
4119
+ let result;
4120
+ try {
4121
+ result = await ctx.connection.rpc.call(CONTROL_RPC_PREFIX, endpoint, payload), controlRouteRetryAfter = 0, controlRouteBackoffIndex = 0;
4122
+ } catch (reason) {
4123
+ if (!isMissingControlRoute(reason)) throw reason;
4124
+ let delayMs = controlRouteBackoffStepsMs[Math.min(controlRouteBackoffIndex, controlRouteBackoffStepsMs.length - 1)];
4125
+ if (controlRouteBackoffIndex += 1, controlRouteRetryAfter = Date.now() + delayMs, endpoint === "status") return controlRouteUnavailableStatus();
4126
+ throw new ControlRouteUnavailableError(t("remoteControlUnavailable"));
4127
+ }
4128
+ if (!result.ok) throw new Error(result.error?.message ?? t("remoteRequestFailed"));
4129
+ return result.value;
4130
+ }, statusFeed = createStatusFeed({
4131
+ url: STATUS_STREAM_PATH,
4132
+ readStatus: () => control("status"),
4133
+ onFallback: (reason) => {
4134
+ console.warn("ds-harness-remote: status event stream unavailable, polling status instead:", reason);
4135
+ }
4136
+ });
4137
+ ctx.effect(() => () => statusFeed.close(), "ds-harness-remote: status stream"), ctx.effect(() => {
4138
+ let disposed = !1, unsubscribeWorkspaces, unsubscribeSessions, selection, opening = !1, reconcile = () => {
4139
+ if (disposed || opening || selection === void 0) return;
4140
+ let pending = selection, workspaceSnapshot = ctx.workspaces.list.getSnapshot();
4141
+ if (!workspacesReady(workspaceSnapshot) || !workspaceSnapshot.items.some((workspace) => workspace.workspaceId === pending.workspaceId)) return;
4142
+ let sessionSnapshot = ctx.sessions.list.getSnapshot();
4143
+ if (pending.backend === "codex" && pending.sessionId !== void 0 && sessionSnapshot.phase !== "ready") return;
4144
+ opening = !0, unsubscribeWorkspaces?.(), unsubscribeSessions?.(), unsubscribeWorkspaces = void 0, unsubscribeSessions = void 0, (pending.backend === "codex" && pending.sessionId !== void 0 && sessionSnapshot.ids.includes(pending.sessionId) ? Promise.resolve(pending.sessionId) : ctx.uiWorkspace.connectWorkspace(pending.workspaceId)).then(async (sessionId) => {
4145
+ disposed || (ctx.sessions.open(sessionId), window.sessionStorage.removeItem(pendingWorkspaceSelectionKey), await control("workspace.selection.consume", pending).catch(() => {
4146
+ }));
4147
+ }).catch((reason) => {
4148
+ disposed || console.warn("remote workspace selection failed:", reason);
4149
+ });
4150
+ };
4151
+ return control("status").then((status) => {
4152
+ let pending = status.workspaceSelection ?? storedWorkspaceSelection();
4153
+ disposed || status.mode !== "remote" || pending === void 0 || status.target?.deviceId !== pending.targetDeviceId || (selection = pending, unsubscribeWorkspaces = ctx.workspaces.list.subscribe(reconcile), unsubscribeSessions = ctx.sessions.list.subscribe(reconcile), reconcile());
4154
+ }).catch(() => {
4155
+ }), () => {
4156
+ disposed = !0, unsubscribeWorkspaces?.(), unsubscribeSessions?.();
4157
+ };
4158
+ }, "ds-harness-remote: resume selected workspace"), ctx.inject(["fileViewer"], (fileViewerContext) => {
4159
+ let viewer = fileViewerContext.get("fileViewer");
4160
+ viewer !== void 0 && fileViewerContext.effect(() => {
4161
+ let unregister, latestSaveAsAllowed = !1, latestSaveAsMaxBytes = REMOTE_FILE_SAVE_AS_MAX_BYTES, unsubscribe = statusFeed.subscribe((status) => {
4162
+ let supported = shouldUseRemoteFileViewer(status);
4163
+ latestSaveAsAllowed = shouldAllowRemoteFileSaveAs(status), latestSaveAsMaxBytes = remoteFileSaveAsMaxBytes(status), supported && unregister === void 0 ? unregister = viewer.registerContentProvider(createRemoteFileContentProvider(
4164
+ (endpoint, payload) => control(endpoint, payload),
4165
+ { saveAsAllowed: () => latestSaveAsAllowed, saveAsMaxBytes: () => latestSaveAsMaxBytes }
4166
+ )) : !supported && unregister !== void 0 && (unregister(), unregister = void 0, latestSaveAsAllowed = !1, latestSaveAsMaxBytes = REMOTE_FILE_SAVE_AS_MAX_BYTES);
4167
+ });
4168
+ return () => {
4169
+ unsubscribe(), unregister?.();
4170
+ };
4171
+ }, "ds-harness-remote: remote file viewer provider");
4172
+ }), ctx.effect(() => ctx.locale.register(localeNamespace, { zh, en }), "ds-harness-remote: dictionaries"), ctx.effect(installStyle, "ds-harness-remote: client styles"), ctx.effect(() => installTerminalAvailabilityNotice(statusFeed, t), "ds-harness-remote: terminal availability notice"), ctx.slots.inject("shell.overlay", () => ctx.slots.register({
4173
+ name: "shell.overlay",
4174
+ id: "ds-harness-remote-global-context",
4175
+ order: 20,
4176
+ locale: localeNamespace,
4177
+ inject: () => ({ control, statusFeed })
4178
+ }, RemoteSessionHeaderAction)), ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
4179
+ name: "sidebar.footer.action",
4180
+ id: "ds-harness-remote-workspace",
4181
+ order: -20,
4182
+ locale: localeNamespace,
4183
+ inject: () => ({
4184
+ control,
4185
+ statusFeed,
4186
+ preferredQrProvider: defaultQrProvider
4187
+ })
4188
+ }, RemoteWorkspaceAction)), ctx.slots.inject("plugins.row.config", () => ctx.slots.register({
4189
+ name: "plugins.row.config",
4190
+ key: "ds-harness-remote#ds-harness-remote",
4191
+ locale: localeNamespace,
4192
+ inject: () => ({ control, statusFeed })
4193
+ }, RemotePluginOptions)), ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
4194
+ name: "plugins.bundle.config",
4195
+ key: "ds-harness-remote",
4196
+ locale: localeNamespace,
4197
+ inject: () => ({ control, statusFeed })
4198
+ }, RemotePluginOptions));
4199
+ }
4200
+ function isMissingControlRoute(reason) {
4201
+ return reason instanceof Error && reason.message.startsWith(`transport failure for ${CONTROL_RPC_PREFIX}/`) && (reason.message.endsWith(": HTTP 404") || reason.message.endsWith(": HTTP 405"));
4202
+ }
4203
+ function installTerminalAvailabilityNotice(feed, t) {
4204
+ let latest, notice, update = () => {
4205
+ let terminal = document.querySelector("[data-sidebar-terminal]"), unavailable = latest?.mode === "remote" && latest.remoteFeatures?.terminal !== !0;
4206
+ if (!terminal || !unavailable) {
4207
+ notice?.remove(), notice = void 0;
4208
+ return;
4209
+ }
4210
+ notice !== void 0 && notice.isConnected || (notice = document.createElement("div"), notice.className = "dshRemoteTerminalUnavailable", notice.setAttribute("role", "alert"), notice.textContent = t("terminalRemoteUnavailable"), terminal.prepend(notice));
4211
+ }, unsubscribe = feed.subscribe((status) => {
4212
+ latest = status, update();
4213
+ }), observer = new MutationObserver(update);
4214
+ return observer.observe(document.body, { childList: !0, subtree: !0 }), update(), () => {
4215
+ unsubscribe(), observer.disconnect(), notice?.remove();
4216
+ };
4217
+ }
4218
+ function messageOf(reason) {
4219
+ return reason instanceof Error ? reason.message : String(reason);
4220
+ }
4221
+ function formatPlatform(value) {
4222
+ let normalized = value.toLowerCase();
4223
+ return normalized === "darwin" || normalized === "macos" ? "macOS" : normalized === "win32" || normalized === "windows" ? "Windows" : normalized === "linux" ? "Linux" : normalized === "android" ? "Android" : value;
4224
+ }
4225
+ function connectedClientModeLabel(mode, t) {
4226
+ return t(mode === "LAN" ? "remoteNetworkLan" : mode === "P2P" ? "remoteNetworkP2p" : mode === "TURN" ? "remoteNetworkTurn" : mode === "Relay" ? "remoteNetworkRelay" : "connected");
4227
+ }
4228
+ return module.exports.apply = apply, module.exports.inject = inject, module.exports;
4229
+ }
4230
+ });
4231
+ })();