@v5x/cli 0.0.1 → 0.0.3

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 (2) hide show
  1. package/dist/index.js +4241 -3
  2. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -31,6 +31,19 @@ var __toESM = (mod, isNodeMode, target) => {
31
31
  return to;
32
32
  };
33
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
38
+ var __export = (target, all) => {
39
+ for (var name in all)
40
+ __defProp(target, name, {
41
+ get: all[name],
42
+ enumerable: true,
43
+ configurable: true,
44
+ set: __exportSetter.bind(all, name)
45
+ });
46
+ };
34
47
 
35
48
  // ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
36
49
  var require_picocolors = __commonJS((exports, module) => {
@@ -104,7 +117,7 @@ var require_picocolors = __commonJS((exports, module) => {
104
117
  // package.json
105
118
  var package_default = {
106
119
  name: "@v5x/cli",
107
- version: "0.0.1",
120
+ version: "0.0.3",
108
121
  description: "Command line interface for v5x.",
109
122
  license: "MIT",
110
123
  type: "module",
@@ -141,11 +154,4236 @@ var package_default = {
141
154
  "@types/bun": "^1.3.1"
142
155
  },
143
156
  dependencies: {
157
+ "@v5x/serial": "workspace:*",
158
+ "bun-serialport": "^0.1.1",
144
159
  picocolors: "^1.1.1"
145
160
  }
146
161
  };
147
162
 
148
163
  // src/index.ts
149
164
  var import_picocolors = __toESM(require_picocolors(), 1);
150
- console.log(import_picocolors.default.redBright(`v5x ${package_default.version}`));
151
- console.log("modern cli for v5 development");
165
+
166
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/serialport.js
167
+ import { EventEmitter } from "events";
168
+
169
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/posix.js
170
+ import { dlopen, FFIType, ptr, toArrayBuffer, CString } from "bun:ffi";
171
+
172
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/constants.js
173
+ import { platform } from "os";
174
+ var IS_LINUX = platform() === "linux";
175
+ var IS_DARWIN = platform() === "darwin";
176
+ if (!IS_LINUX && !IS_DARWIN) {
177
+ throw new Error(`bun-serialport: unsupported platform "${platform()}"`);
178
+ }
179
+ var O_RDWR = 2;
180
+ var O_NOCTTY = IS_LINUX ? 256 : 131072;
181
+ var O_NONBLOCK = IS_LINUX ? 2048 : 4;
182
+ var TCSADRAIN = 1;
183
+ var TCSAFLUSH = 2;
184
+ var TCIOFLUSH = IS_LINUX ? 2 : 3;
185
+ var CSIZE = IS_LINUX ? 48 : 768;
186
+ var CS5 = IS_LINUX ? 0 : 0;
187
+ var CS6 = IS_LINUX ? 16 : 256;
188
+ var CS7 = IS_LINUX ? 32 : 512;
189
+ var CS8 = IS_LINUX ? 48 : 768;
190
+ var CSTOPB = IS_LINUX ? 64 : 1024;
191
+ var CREAD = IS_LINUX ? 128 : 2048;
192
+ var PARENB = IS_LINUX ? 256 : 4096;
193
+ var PARODD = IS_LINUX ? 512 : 8192;
194
+ var CLOCAL = IS_LINUX ? 2048 : 32768;
195
+ var CRTSCTS = IS_LINUX ? 2147483648 : 196608;
196
+ var INPCK = IS_LINUX ? 16 : 16;
197
+ var IXON = IS_LINUX ? 1024 : 512;
198
+ var IXOFF = IS_LINUX ? 4096 : 1024;
199
+ var VMIN = IS_LINUX ? 6 : 16;
200
+ var VTIME = IS_LINUX ? 5 : 17;
201
+ var NCCS = IS_LINUX ? 32 : 20;
202
+ var TIOCMGET = IS_LINUX ? 21525 : 1074033770;
203
+ var TIOCMBIS = IS_LINUX ? 21526 : 2147775596;
204
+ var TIOCMBIC = IS_LINUX ? 21527 : 2147775595;
205
+ var TIOCM_DTR = 2;
206
+ var TIOCM_RTS = 4;
207
+ var TIOCM_CTS = 32;
208
+ var TIOCM_DSR = 256;
209
+ var TIOCM_CD = 64;
210
+ var TIOCM_RI = 128;
211
+ var TERMIOS_SIZE = IS_LINUX ? 60 : 72;
212
+ var TCFLAG_SIZE = IS_LINUX ? 4 : 8;
213
+ var TERMIOS_OFFSETS = IS_LINUX ? { c_iflag: 0, c_oflag: 4, c_cflag: 8, c_lflag: 12, c_line: 16, c_cc: 17, c_ispeed: 52, c_ospeed: 56 } : { c_iflag: 0, c_oflag: 8, c_cflag: 16, c_lflag: 24, c_cc: 32, c_ispeed: 56, c_ospeed: 64 };
214
+ var LINUX_BAUD_MAP = {
215
+ 0: 0,
216
+ 110: 3,
217
+ 300: 7,
218
+ 600: 8,
219
+ 1200: 9,
220
+ 2400: 11,
221
+ 4800: 12,
222
+ 9600: 13,
223
+ 19200: 14,
224
+ 38400: 15,
225
+ 57600: 4097,
226
+ 115200: 4098,
227
+ 230400: 4099,
228
+ 460800: 4100,
229
+ 500000: 4101,
230
+ 576000: 4102,
231
+ 921600: 4103,
232
+ 1e6: 4104,
233
+ 1152000: 4105,
234
+ 1500000: 4106,
235
+ 2000000: 4107,
236
+ 2500000: 4108,
237
+ 3000000: 4109,
238
+ 3500000: 4110,
239
+ 4000000: 4111
240
+ };
241
+ function encodeBaudRate(rate) {
242
+ if (IS_DARWIN)
243
+ return rate;
244
+ const encoded = LINUX_BAUD_MAP[rate];
245
+ if (encoded === undefined)
246
+ throw new Error(`Unsupported baud rate: ${rate}`);
247
+ return encoded;
248
+ }
249
+ function dataBitsFlag(bits) {
250
+ switch (bits) {
251
+ case 5:
252
+ return CS5;
253
+ case 6:
254
+ return CS6;
255
+ case 7:
256
+ return CS7;
257
+ case 8:
258
+ return CS8;
259
+ default:
260
+ throw new Error(`Invalid data bits: ${bits}`);
261
+ }
262
+ }
263
+
264
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/bindings/posix.js
265
+ import { platform as platform2 } from "os";
266
+ var IS_LINUX2 = platform2() === "linux";
267
+ var IS_DARWIN2 = platform2() === "darwin";
268
+ var LIBC_PATH = IS_LINUX2 ? "libc.so.6" : "libSystem.B.dylib";
269
+ var libc = dlopen(LIBC_PATH, {
270
+ open: { args: [FFIType.cstring, FFIType.i32], returns: FFIType.i32 },
271
+ close: { args: [FFIType.i32], returns: FFIType.i32 },
272
+ read: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
273
+ write: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 },
274
+ tcgetattr: { args: [FFIType.i32, FFIType.ptr], returns: FFIType.i32 },
275
+ tcsetattr: { args: [FFIType.i32, FFIType.i32, FFIType.ptr], returns: FFIType.i32 },
276
+ tcflush: { args: [FFIType.i32, FFIType.i32], returns: FFIType.i32 },
277
+ tcdrain: { args: [FFIType.i32], returns: FFIType.i32 },
278
+ cfsetispeed: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
279
+ cfsetospeed: { args: [FFIType.ptr, FFIType.u64], returns: FFIType.i32 },
280
+ fcntl: { args: [FFIType.i32, FFIType.i32, FFIType.i32], returns: FFIType.i32 },
281
+ ioctl: { args: [FFIType.i32, FFIType.u64, FFIType.ptr], returns: FFIType.i32 },
282
+ strerror: { args: [FFIType.i32], returns: FFIType.ptr }
283
+ });
284
+ var errnoLib = dlopen(LIBC_PATH, IS_LINUX2 ? { __errno_location: { args: [], returns: FFIType.ptr } } : { __error: { args: [], returns: FFIType.ptr } });
285
+ function getErrno() {
286
+ const errPtr = IS_LINUX2 ? errnoLib.symbols.__errno_location() : errnoLib.symbols.__error();
287
+ const view = new DataView(toArrayBuffer(errPtr, 0, 4));
288
+ return view.getInt32(0, true);
289
+ }
290
+ function errnoError(syscall) {
291
+ const code = getErrno();
292
+ const msgPtr = libc.symbols.strerror(code);
293
+ const msg = msgPtr ? new CString(msgPtr) : `errno ${code}`;
294
+ const err = new Error(`${syscall}: ${msg}`);
295
+ err.code = code;
296
+ err.syscall = syscall;
297
+ return err;
298
+ }
299
+ function readFlag(buf, offset) {
300
+ if (TCFLAG_SIZE === 4) {
301
+ return buf.getUint32(offset, true);
302
+ }
303
+ return Number(buf.getBigUint64(offset, true));
304
+ }
305
+ function writeFlag(buf, offset, value) {
306
+ if (TCFLAG_SIZE === 4) {
307
+ buf.setUint32(offset, value >>> 0, true);
308
+ } else {
309
+ buf.setBigUint64(offset, BigInt(value >>> 0), true);
310
+ }
311
+ }
312
+ function writeSpeed(buf, offset, value) {
313
+ if (TCFLAG_SIZE === 4) {
314
+ buf.setUint32(offset, value >>> 0, true);
315
+ } else {
316
+ buf.setBigUint64(offset, BigInt(value), true);
317
+ }
318
+ }
319
+ function openPort(path, options) {
320
+ const {
321
+ baudRate = 9600,
322
+ dataBits = 8,
323
+ stopBits = 1,
324
+ parity = "none",
325
+ rtscts = false,
326
+ xon = false,
327
+ xoff = false
328
+ } = options;
329
+ const pathBuf = Buffer.from(path + "\x00", "utf-8");
330
+ const fd = libc.symbols.open(ptr(pathBuf), O_RDWR | O_NOCTTY | O_NONBLOCK);
331
+ if (fd < 0)
332
+ throw errnoError("open");
333
+ const termiosBuf = new ArrayBuffer(TERMIOS_SIZE);
334
+ const termiosBytes = new Uint8Array(termiosBuf);
335
+ const termiosView = new DataView(termiosBuf);
336
+ const termiosPtr = ptr(termiosBytes);
337
+ if (libc.symbols.tcgetattr(fd, termiosPtr) < 0) {
338
+ libc.symbols.close(fd);
339
+ throw errnoError("tcgetattr");
340
+ }
341
+ const off = TERMIOS_OFFSETS;
342
+ let cflag = readFlag(termiosView, off.c_cflag);
343
+ cflag &= ~CSIZE;
344
+ cflag |= dataBitsFlag(dataBits);
345
+ cflag |= CREAD | CLOCAL;
346
+ if (stopBits === 2)
347
+ cflag |= CSTOPB;
348
+ else
349
+ cflag &= ~CSTOPB;
350
+ if (parity === "none") {
351
+ cflag &= ~(PARENB | PARODD);
352
+ } else if (parity === "even") {
353
+ cflag |= PARENB;
354
+ cflag &= ~PARODD;
355
+ } else if (parity === "odd") {
356
+ cflag |= PARENB | PARODD;
357
+ }
358
+ if (rtscts)
359
+ cflag |= CRTSCTS;
360
+ else
361
+ cflag &= ~CRTSCTS;
362
+ writeFlag(termiosView, off.c_cflag, cflag);
363
+ let iflag = 0;
364
+ if (parity !== "none")
365
+ iflag |= INPCK;
366
+ if (xon)
367
+ iflag |= IXON;
368
+ if (xoff)
369
+ iflag |= IXOFF;
370
+ writeFlag(termiosView, off.c_iflag, iflag);
371
+ writeFlag(termiosView, off.c_oflag, 0);
372
+ writeFlag(termiosView, off.c_lflag, 0);
373
+ const ccOffset = off.c_cc;
374
+ for (let i = 0;i < NCCS; i++)
375
+ termiosBytes[ccOffset + i] = 0;
376
+ termiosBytes[ccOffset + VMIN] = 1;
377
+ termiosBytes[ccOffset + VTIME] = 0;
378
+ const baudCode = encodeBaudRate(baudRate);
379
+ if (IS_LINUX2) {
380
+ writeSpeed(termiosView, off.c_ispeed, baudCode);
381
+ writeSpeed(termiosView, off.c_ospeed, baudCode);
382
+ }
383
+ if (libc.symbols.cfsetispeed(termiosPtr, baudCode) < 0) {
384
+ libc.symbols.close(fd);
385
+ throw errnoError("cfsetispeed");
386
+ }
387
+ if (libc.symbols.cfsetospeed(termiosPtr, baudCode) < 0) {
388
+ libc.symbols.close(fd);
389
+ throw errnoError("cfsetospeed");
390
+ }
391
+ if (libc.symbols.tcsetattr(fd, TCSAFLUSH, termiosPtr) < 0) {
392
+ libc.symbols.close(fd);
393
+ throw errnoError("tcsetattr");
394
+ }
395
+ libc.symbols.tcflush(fd, TCIOFLUSH);
396
+ return fd;
397
+ }
398
+ function closePort(fd) {
399
+ if (libc.symbols.close(fd) < 0)
400
+ throw errnoError("close");
401
+ }
402
+ var MAX_EAGAIN_RETRIES = 1000;
403
+ function writePort(fd, data) {
404
+ const buf = data instanceof Uint8Array ? data : Buffer.from(data, "utf-8");
405
+ let offset = 0;
406
+ let eagainCount = 0;
407
+ while (offset < buf.length) {
408
+ const slice = buf.subarray(offset);
409
+ const written = Number(libc.symbols.write(fd, ptr(slice), BigInt(slice.length)));
410
+ if (written < 0) {
411
+ const code = getErrno();
412
+ if (code === 11 || code === 35) {
413
+ if (++eagainCount > MAX_EAGAIN_RETRIES) {
414
+ throw new Error("write: device not accepting data (EAGAIN limit exceeded)");
415
+ }
416
+ continue;
417
+ }
418
+ throw errnoError("write");
419
+ }
420
+ eagainCount = 0;
421
+ offset += written;
422
+ }
423
+ return offset;
424
+ }
425
+ function readPort(fd, buffer) {
426
+ const n = Number(libc.symbols.read(fd, ptr(buffer), BigInt(buffer.length)));
427
+ if (n < 0) {
428
+ const code = getErrno();
429
+ if (code === 11 || code === 35)
430
+ return 0;
431
+ throw errnoError("read");
432
+ }
433
+ return n;
434
+ }
435
+ function updateBaudRate(fd, baudRate) {
436
+ const termiosBuf = new ArrayBuffer(TERMIOS_SIZE);
437
+ const termiosPtr = ptr(new Uint8Array(termiosBuf));
438
+ if (libc.symbols.tcgetattr(fd, termiosPtr) < 0)
439
+ throw errnoError("tcgetattr");
440
+ const baudCode = encodeBaudRate(baudRate);
441
+ if (libc.symbols.cfsetispeed(termiosPtr, baudCode) < 0)
442
+ throw errnoError("cfsetispeed");
443
+ if (libc.symbols.cfsetospeed(termiosPtr, baudCode) < 0)
444
+ throw errnoError("cfsetospeed");
445
+ if (IS_LINUX2) {
446
+ const view = new DataView(termiosBuf);
447
+ writeSpeed(view, TERMIOS_OFFSETS.c_ispeed, baudCode);
448
+ writeSpeed(view, TERMIOS_OFFSETS.c_ospeed, baudCode);
449
+ }
450
+ if (libc.symbols.tcsetattr(fd, TCSADRAIN, termiosPtr) < 0)
451
+ throw errnoError("tcsetattr");
452
+ }
453
+ function setModemLines(fd, flags) {
454
+ const { dtr, rts, brk } = flags;
455
+ const intBuf = new ArrayBuffer(4);
456
+ const intView = new DataView(intBuf);
457
+ const intPtr = ptr(new Uint8Array(intBuf));
458
+ let bitsToSet = 0;
459
+ let bitsToClear = 0;
460
+ if (dtr === true)
461
+ bitsToSet |= TIOCM_DTR;
462
+ if (dtr === false)
463
+ bitsToClear |= TIOCM_DTR;
464
+ if (rts === true)
465
+ bitsToSet |= TIOCM_RTS;
466
+ if (rts === false)
467
+ bitsToClear |= TIOCM_RTS;
468
+ if (bitsToSet) {
469
+ intView.setInt32(0, bitsToSet, true);
470
+ if (libc.symbols.ioctl(fd, TIOCMBIS, intPtr) < 0)
471
+ throw errnoError("ioctl TIOCMBIS");
472
+ }
473
+ if (bitsToClear) {
474
+ intView.setInt32(0, bitsToClear, true);
475
+ if (libc.symbols.ioctl(fd, TIOCMBIC, intPtr) < 0)
476
+ throw errnoError("ioctl TIOCMBIC");
477
+ }
478
+ }
479
+ function getModemLines(fd) {
480
+ const intBuf = new ArrayBuffer(4);
481
+ const intView = new DataView(intBuf);
482
+ const intPtr = ptr(new Uint8Array(intBuf));
483
+ if (libc.symbols.ioctl(fd, TIOCMGET, intPtr) < 0)
484
+ throw errnoError("ioctl TIOCMGET");
485
+ const bits = intView.getInt32(0, true);
486
+ return {
487
+ cts: !!(bits & TIOCM_CTS),
488
+ dsr: !!(bits & TIOCM_DSR),
489
+ dcd: !!(bits & TIOCM_CD),
490
+ ri: !!(bits & TIOCM_RI)
491
+ };
492
+ }
493
+ function flushPort(fd) {
494
+ if (libc.symbols.tcflush(fd, TCIOFLUSH) < 0)
495
+ throw errnoError("tcflush");
496
+ }
497
+ function drainPort(fd) {
498
+ if (libc.symbols.tcdrain(fd) < 0)
499
+ throw errnoError("tcdrain");
500
+ }
501
+
502
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/serialport.js
503
+ var DEFAULT_READ_BUFFER_SIZE = 65536;
504
+ var DEFAULT_READ_INTERVAL_MS = 1;
505
+
506
+ class SerialPort extends EventEmitter {
507
+ #fd = -1;
508
+ #path;
509
+ #baudRate;
510
+ #options;
511
+ #isOpen = false;
512
+ #isClosing = false;
513
+ #readBuf;
514
+ #readInterval;
515
+ #readTimer = null;
516
+ constructor(options) {
517
+ super();
518
+ if (!options || !options.path)
519
+ throw new Error("options.path is required");
520
+ if (!options.baudRate)
521
+ throw new Error("options.baudRate is required");
522
+ this.#path = options.path;
523
+ this.#baudRate = options.baudRate;
524
+ this.#options = { ...options };
525
+ this.#readBuf = new Uint8Array(options.readBufferSize || DEFAULT_READ_BUFFER_SIZE);
526
+ this.#readInterval = options.readInterval || DEFAULT_READ_INTERVAL_MS;
527
+ if (options.autoOpen !== false) {
528
+ queueMicrotask(() => this.open().catch((err) => this.emit("error", err)));
529
+ }
530
+ }
531
+ get path() {
532
+ return this.#path;
533
+ }
534
+ get baudRate() {
535
+ return this.#baudRate;
536
+ }
537
+ get isOpen() {
538
+ return this.#isOpen && !this.#isClosing;
539
+ }
540
+ async open() {
541
+ if (this.#isOpen)
542
+ throw new Error("Port is already open");
543
+ try {
544
+ this.#fd = openPort(this.#path, this.#options);
545
+ this.#isOpen = true;
546
+ this.#isClosing = false;
547
+ this.#startReading();
548
+ this.emit("open");
549
+ } catch (err) {
550
+ this.#isOpen = false;
551
+ throw err;
552
+ }
553
+ }
554
+ async close() {
555
+ if (!this.#isOpen)
556
+ throw new Error("Port is not open");
557
+ if (this.#isClosing)
558
+ return;
559
+ this.#isClosing = true;
560
+ this.#stopReading();
561
+ try {
562
+ closePort(this.#fd);
563
+ } catch (err) {
564
+ this.#isClosing = false;
565
+ throw err;
566
+ }
567
+ this.#fd = -1;
568
+ this.#isOpen = false;
569
+ this.#isClosing = false;
570
+ this.emit("close");
571
+ }
572
+ async write(data) {
573
+ if (!this.#isOpen || this.#isClosing) {
574
+ throw new Error("Port is not open");
575
+ }
576
+ const buf = typeof data === "string" ? Buffer.from(data, "utf-8") : data;
577
+ return writePort(this.#fd, buf);
578
+ }
579
+ async update(options) {
580
+ if (!this.#isOpen)
581
+ throw new Error("Port is not open");
582
+ if (options.baudRate !== undefined) {
583
+ updateBaudRate(this.#fd, options.baudRate);
584
+ this.#baudRate = options.baudRate;
585
+ }
586
+ }
587
+ async set(flags) {
588
+ if (!this.#isOpen)
589
+ throw new Error("Port is not open");
590
+ setModemLines(this.#fd, flags);
591
+ }
592
+ async get() {
593
+ if (!this.#isOpen)
594
+ throw new Error("Port is not open");
595
+ return getModemLines(this.#fd);
596
+ }
597
+ async flush() {
598
+ if (!this.#isOpen)
599
+ throw new Error("Port is not open");
600
+ flushPort(this.#fd);
601
+ }
602
+ async drain() {
603
+ if (!this.#isOpen)
604
+ throw new Error("Port is not open");
605
+ drainPort(this.#fd);
606
+ }
607
+ pipe(parser) {
608
+ const handler = (chunk) => parser.push(chunk);
609
+ this.on("data", handler);
610
+ parser._unpipe = () => this.off("data", handler);
611
+ return parser;
612
+ }
613
+ unpipe(parser) {
614
+ if (parser && typeof parser._unpipe === "function") {
615
+ parser._unpipe();
616
+ parser._unpipe = undefined;
617
+ }
618
+ }
619
+ #startReading() {
620
+ this.#readTimer = setInterval(() => {
621
+ if (!this.#isOpen || this.#isClosing)
622
+ return;
623
+ try {
624
+ const n = readPort(this.#fd, this.#readBuf);
625
+ if (n > 0) {
626
+ const data = this.#readBuf.slice(0, n);
627
+ this.emit("data", data);
628
+ }
629
+ } catch (err) {
630
+ err.disconnected = true;
631
+ this.emit("error", err);
632
+ this.close().catch(() => {});
633
+ }
634
+ }, this.#readInterval);
635
+ }
636
+ #stopReading() {
637
+ if (this.#readTimer !== null) {
638
+ clearInterval(this.#readTimer);
639
+ this.#readTimer = null;
640
+ }
641
+ }
642
+ }
643
+ // ../../node_modules/.bun/bun-serialport@0.1.1/node_modules/bun-serialport/src/list.js
644
+ import { platform as platform3 } from "os";
645
+ import { readdir, readlink, access } from "fs/promises";
646
+ import { join } from "path";
647
+ var IS_LINUX3 = platform3() === "linux";
648
+ async function exists(path) {
649
+ try {
650
+ await access(path);
651
+ return true;
652
+ } catch {
653
+ return false;
654
+ }
655
+ }
656
+ async function readFileQuiet(path) {
657
+ try {
658
+ return (await Bun.file(path).text()).trim();
659
+ } catch {
660
+ return "";
661
+ }
662
+ }
663
+ async function listLinux() {
664
+ const ttys = await readdir("/sys/class/tty").catch(() => []);
665
+ const checks = ttys.map(async (name) => {
666
+ const sysPath = `/sys/class/tty/${name}`;
667
+ const devicePath = join(sysPath, "device");
668
+ if (!await exists(devicePath))
669
+ return null;
670
+ const devPath = `/dev/${name}`;
671
+ if (!await exists(devPath))
672
+ return null;
673
+ return { name, devPath, devicePath };
674
+ });
675
+ const valid = (await Promise.all(checks)).filter(Boolean);
676
+ const ports = await Promise.all(valid.map(async ({ devPath, devicePath }) => {
677
+ const info = { path: devPath };
678
+ const subsystem = await readlink(join(devicePath, "subsystem")).catch(() => "");
679
+ if (subsystem.includes("usb-serial") || subsystem.includes("usb")) {
680
+ const usbDevice = await findUsbParent(devicePath);
681
+ if (usbDevice) {
682
+ const [manufacturer, serialNumber, vendorId, productId, product] = await Promise.all([
683
+ readFileQuiet(join(usbDevice, "manufacturer")),
684
+ readFileQuiet(join(usbDevice, "serial")),
685
+ readFileQuiet(join(usbDevice, "idVendor")),
686
+ readFileQuiet(join(usbDevice, "idProduct")),
687
+ readFileQuiet(join(usbDevice, "product"))
688
+ ]);
689
+ info.manufacturer = manufacturer;
690
+ info.serialNumber = serialNumber;
691
+ info.vendorId = vendorId;
692
+ info.productId = productId;
693
+ info.product = product;
694
+ }
695
+ }
696
+ return info;
697
+ }));
698
+ return ports;
699
+ }
700
+ async function findUsbParent(devicePath) {
701
+ let current = devicePath;
702
+ for (let i = 0;i < 10; i++) {
703
+ current = join(current, "..");
704
+ if (await exists(join(current, "idVendor")))
705
+ return current;
706
+ }
707
+ return null;
708
+ }
709
+ async function listDarwin() {
710
+ const devFiles = await readdir("/dev").catch(() => []);
711
+ const seen = new Map;
712
+ for (const name of devFiles) {
713
+ if (!name.startsWith("cu.") && !name.startsWith("tty."))
714
+ continue;
715
+ if (name === "tty")
716
+ continue;
717
+ const isCu = name.startsWith("cu.");
718
+ const suffix = name.slice(isCu ? 3 : 4);
719
+ if (seen.has(suffix) && !isCu)
720
+ continue;
721
+ seen.set(suffix, { path: `/dev/${name}` });
722
+ }
723
+ return [...seen.values()];
724
+ }
725
+ async function list() {
726
+ return IS_LINUX3 ? listLinux() : listDarwin();
727
+ }
728
+ // src/adapter.ts
729
+ import { readdir as readdir2, realpath, readlink as readlink2 } from "fs/promises";
730
+ import { join as join2 } from "path";
731
+ import { platform as platform4 } from "os";
732
+
733
+ class WebSerialPortAdapter extends EventTarget {
734
+ _port = null;
735
+ _path;
736
+ _info;
737
+ _readable = null;
738
+ _writable = null;
739
+ _readerController = null;
740
+ constructor(path, info) {
741
+ super();
742
+ this._path = path;
743
+ this._info = info;
744
+ }
745
+ get readable() {
746
+ return this._readable;
747
+ }
748
+ get writable() {
749
+ return this._writable;
750
+ }
751
+ getInfo() {
752
+ return this._info;
753
+ }
754
+ async open(options) {
755
+ if (this._port)
756
+ throw new Error("Port already open");
757
+ this._port = new SerialPort({
758
+ path: this._path,
759
+ baudRate: options.baudRate,
760
+ autoOpen: false
761
+ });
762
+ await this._port.open();
763
+ this._readable = new ReadableStream({
764
+ start: (controller) => {
765
+ this._readerController = controller;
766
+ this._port?.on("data", (data) => {
767
+ controller.enqueue(data);
768
+ });
769
+ this._port?.on("error", (err) => {
770
+ controller.error(err);
771
+ this.close().catch(() => {});
772
+ });
773
+ },
774
+ cancel: () => {
775
+ this.close();
776
+ }
777
+ });
778
+ this._writable = new WritableStream({
779
+ write: async (chunk) => {
780
+ if (!this._port)
781
+ throw new Error("Port closed");
782
+ await this._port.write(chunk);
783
+ },
784
+ close: async () => {
785
+ await this.close();
786
+ }
787
+ });
788
+ }
789
+ async close() {
790
+ if (!this._port)
791
+ return;
792
+ const port = this._port;
793
+ this._port = null;
794
+ if (this._readerController) {
795
+ try {
796
+ this._readerController.close();
797
+ } catch (e) {}
798
+ this._readerController = null;
799
+ }
800
+ await port.close();
801
+ try {
802
+ port.removeAllListeners?.();
803
+ } catch (e) {}
804
+ this._readable = null;
805
+ this._writable = null;
806
+ this.dispatchEvent(new Event("disconnect"));
807
+ }
808
+ }
809
+
810
+ class WebSerialAdapter {
811
+ async _listPortsLinux() {
812
+ const ttys = await readdir2("/sys/class/tty").catch(() => []);
813
+ const ports = [];
814
+ for (const name of ttys) {
815
+ const sysPath = `/sys/class/tty/${name}`;
816
+ const devicePath = join2(sysPath, "device");
817
+ try {
818
+ const realDevicePath = await realpath(devicePath);
819
+ const subsystem = await readlink2(join2(realDevicePath, "subsystem")).catch(() => "");
820
+ const info = { path: `/dev/${name}` };
821
+ if (subsystem.includes("usb")) {
822
+ let current = realDevicePath;
823
+ for (let i = 0;i < 5; i++) {
824
+ try {
825
+ const vendorId = await Bun.file(join2(current, "idVendor")).text().then((t) => t.trim());
826
+ const productId = await Bun.file(join2(current, "idProduct")).text().then((t) => t.trim());
827
+ info.vendorId = vendorId;
828
+ info.productId = productId;
829
+ break;
830
+ } catch (e) {
831
+ current = join2(current, "..");
832
+ }
833
+ }
834
+ }
835
+ ports.push(info);
836
+ } catch (e) {}
837
+ }
838
+ return ports;
839
+ }
840
+ async getPorts() {
841
+ const ports = platform4() === "linux" ? await this._listPortsLinux() : await list();
842
+ return ports.map((p) => new WebSerialPortAdapter(p.path, {
843
+ usbVendorId: p.vendorId ? parseInt(p.vendorId, 16) : undefined,
844
+ usbProductId: p.productId ? parseInt(p.productId, 16) : undefined
845
+ }));
846
+ }
847
+ async requestPort(options) {
848
+ const ports = await this.getPorts();
849
+ if (options?.filters && options.filters.length > 0) {
850
+ const filtered = ports.filter((p) => {
851
+ const info = p.getInfo();
852
+ return options.filters?.some((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
853
+ });
854
+ if (filtered.length > 0)
855
+ return filtered[0];
856
+ throw new Error("No port found matching filters");
857
+ }
858
+ if (ports.length > 0)
859
+ return ports[0];
860
+ throw new Error("No port found");
861
+ }
862
+ }
863
+ var serial = new WebSerialAdapter;
864
+
865
+ // ../serial/src/vex.ts
866
+ var USER_PROG_CHUNK_SIZE = 4096;
867
+ var USER_FLASH_USR_CODE_START = 58720256;
868
+ // ../serial/src/vex-event.ts
869
+ class VexEventEmitter {
870
+ handlers;
871
+ constructor() {
872
+ this.handlers = {};
873
+ }
874
+ on(eventName, listener) {
875
+ this.handlers[eventName] = this.handlers[eventName] || [];
876
+ this.handlers[eventName].push(listener);
877
+ }
878
+ remove(eventName, listener) {
879
+ this.handlers[eventName] = this.handlers[eventName] || [];
880
+ let index = this.handlers[eventName].indexOf(listener);
881
+ if (index > -1) {
882
+ this.handlers[eventName].splice(index, 1);
883
+ }
884
+ }
885
+ emit(eventName, data) {
886
+ (this.handlers[eventName] || []).forEach((callback) => {
887
+ callback(data);
888
+ });
889
+ }
890
+ clearListeners() {
891
+ Object.keys(this.handlers).forEach((e) => {
892
+ delete this.handlers[e];
893
+ });
894
+ }
895
+ }
896
+
897
+ class VexEventTarget {
898
+ emitter;
899
+ constructor() {
900
+ this.emitter = new VexEventEmitter;
901
+ }
902
+ emit(eventName, data) {
903
+ this.emitter.emit(String(eventName), data);
904
+ }
905
+ on(eventName, listener) {
906
+ this.emitter.on(String(eventName), listener);
907
+ }
908
+ remove(eventName, listener) {
909
+ this.emitter.remove(String(eventName), listener);
910
+ }
911
+ clearListeners() {
912
+ this.emitter.clearListeners();
913
+ }
914
+ }
915
+
916
+ // ../serial/src/vex-packet.ts
917
+ var exports_vex_packet = {};
918
+ __export(exports_vex_packet, {
919
+ WriteKeyValueReplyD2HPacket: () => WriteKeyValueReplyD2HPacket,
920
+ WriteKeyValueH2DPacket: () => WriteKeyValueH2DPacket,
921
+ WriteFileReplyD2HPacket: () => WriteFileReplyD2HPacket,
922
+ WriteFileH2DPacket: () => WriteFileH2DPacket,
923
+ UpdateMatchModeH2DPacket: () => UpdateMatchModeH2DPacket,
924
+ SystemVersionReplyD2HPacket: () => SystemVersionReplyD2HPacket,
925
+ SystemVersionH2DPacket: () => SystemVersionH2DPacket,
926
+ SetFileMetadataReplyD2HPacket: () => SetFileMetadataReplyD2HPacket,
927
+ SetFileMetadataH2DPacket: () => SetFileMetadataH2DPacket,
928
+ SendDashTouchReplyD2HPacket: () => SendDashTouchReplyD2HPacket,
929
+ SendDashTouchH2DPacket: () => SendDashTouchH2DPacket,
930
+ SelectDashReplyD2HPacket: () => SelectDashReplyD2HPacket,
931
+ SelectDashH2DPacket: () => SelectDashH2DPacket,
932
+ ScreenCaptureReplyD2HPacket: () => ScreenCaptureReplyD2HPacket,
933
+ ScreenCaptureH2DPacket: () => ScreenCaptureH2DPacket,
934
+ ReadLogPageReplyD2HPacket: () => ReadLogPageReplyD2HPacket,
935
+ ReadLogPageH2DPacket: () => ReadLogPageH2DPacket,
936
+ ReadKeyValueReplyD2HPacket: () => ReadKeyValueReplyD2HPacket,
937
+ ReadKeyValueH2DPacket: () => ReadKeyValueH2DPacket,
938
+ ReadFileReplyD2HPacket: () => ReadFileReplyD2HPacket,
939
+ ReadFileH2DPacket: () => ReadFileH2DPacket,
940
+ Query1ReplyD2HPacket: () => Query1ReplyD2HPacket,
941
+ Query1H2DPacket: () => Query1H2DPacket,
942
+ PacketEncoder: () => PacketEncoder,
943
+ Packet: () => Packet,
944
+ MatchStatusReplyD2HPacket: () => MatchStatusReplyD2HPacket,
945
+ MatchModeReplyD2HPacket: () => MatchModeReplyD2HPacket,
946
+ LoadFileActionReplyD2HPacket: () => LoadFileActionReplyD2HPacket,
947
+ LoadFileActionH2DPacket: () => LoadFileActionH2DPacket,
948
+ LinkFileReplyD2HPacket: () => LinkFileReplyD2HPacket,
949
+ LinkFileH2DPacket: () => LinkFileH2DPacket,
950
+ InitFileTransferReplyD2HPacket: () => InitFileTransferReplyD2HPacket,
951
+ InitFileTransferH2DPacket: () => InitFileTransferH2DPacket,
952
+ HostBoundPacket: () => HostBoundPacket,
953
+ GetUserDataReplyD2HPacket: () => GetUserDataReplyD2HPacket,
954
+ GetUserDataH2DPacket: () => GetUserDataH2DPacket,
955
+ GetSystemStatusReplyD2HPacket: () => GetSystemStatusReplyD2HPacket,
956
+ GetSystemStatusH2DPacket: () => GetSystemStatusH2DPacket,
957
+ GetSystemFlagsReplyD2HPacket: () => GetSystemFlagsReplyD2HPacket,
958
+ GetSystemFlagsH2DPacket: () => GetSystemFlagsH2DPacket,
959
+ GetSlot5to8InfoReplyD2HPacket: () => GetSlot5to8InfoReplyD2HPacket,
960
+ GetSlot5to8InfoH2DPacket: () => GetSlot5to8InfoH2DPacket,
961
+ GetSlot1to4InfoReplyD2HPacket: () => GetSlot1to4InfoReplyD2HPacket,
962
+ GetSlot1to4InfoH2DPacket: () => GetSlot1to4InfoH2DPacket,
963
+ GetRadioStatusReplyD2HPacket: () => GetRadioStatusReplyD2HPacket,
964
+ GetRadioStatusH2DPacket: () => GetRadioStatusH2DPacket,
965
+ GetRadioModeH2DPacket: () => GetRadioModeH2DPacket,
966
+ GetProgramSlotInfoReplyD2HPacket: () => GetProgramSlotInfoReplyD2HPacket,
967
+ GetProgramSlotInfoH2DPacket: () => GetProgramSlotInfoH2DPacket,
968
+ GetMatchStatusH2DPacket: () => GetMatchStatusH2DPacket,
969
+ GetLogCountReplyD2HPacket: () => GetLogCountReplyD2HPacket,
970
+ GetLogCountH2DPacket: () => GetLogCountH2DPacket,
971
+ GetFileMetadataReplyD2HPacket: () => GetFileMetadataReplyD2HPacket,
972
+ GetFileMetadataH2DPacket: () => GetFileMetadataH2DPacket,
973
+ GetFdtStatusReplyD2HPacket: () => GetFdtStatusReplyD2HPacket,
974
+ GetFdtStatusH2DPacket: () => GetFdtStatusH2DPacket,
975
+ GetDirectoryFileCountReplyD2HPacket: () => GetDirectoryFileCountReplyD2HPacket,
976
+ GetDirectoryFileCountH2DPacket: () => GetDirectoryFileCountH2DPacket,
977
+ GetDirectoryEntryReplyD2HPacket: () => GetDirectoryEntryReplyD2HPacket,
978
+ GetDirectoryEntryH2DPacket: () => GetDirectoryEntryH2DPacket,
979
+ GetDeviceStatusReplyD2HPacket: () => GetDeviceStatusReplyD2HPacket,
980
+ GetDeviceStatusH2DPacket: () => GetDeviceStatusH2DPacket,
981
+ FileFormatReplyD2HPacket: () => FileFormatReplyD2HPacket,
982
+ FileFormatH2DPacket: () => FileFormatH2DPacket,
983
+ FileControlReplyD2HPacket: () => FileControlReplyD2HPacket,
984
+ FileControlH2DPacket: () => FileControlH2DPacket,
985
+ FileClearUpReplyD2HPacket: () => FileClearUpReplyD2HPacket,
986
+ FileClearUpH2DPacket: () => FileClearUpH2DPacket,
987
+ FactoryStatusReplyD2HPacket: () => FactoryStatusReplyD2HPacket,
988
+ FactoryStatusH2DPacket: () => FactoryStatusH2DPacket,
989
+ FactoryEnableReplyD2HPacket: () => FactoryEnableReplyD2HPacket,
990
+ FactoryEnableH2DPacket: () => FactoryEnableH2DPacket,
991
+ ExitFileTransferReplyD2HPacket: () => ExitFileTransferReplyD2HPacket,
992
+ ExitFileTransferH2DPacket: () => ExitFileTransferH2DPacket,
993
+ EraseFileReplyD2HPacket: () => EraseFileReplyD2HPacket,
994
+ EraseFileH2DPacket: () => EraseFileH2DPacket,
995
+ EnableDeshReplyD2HPacket: () => EnableDeshReplyD2HPacket,
996
+ EnableDashH2DPacket: () => EnableDashH2DPacket,
997
+ DisableDeshReplyD2HPacket: () => DisableDeshReplyD2HPacket,
998
+ DisableDashH2DPacket: () => DisableDashH2DPacket,
999
+ DeviceBoundPacket: () => DeviceBoundPacket
1000
+ });
1001
+
1002
+ // ../serial/src/vex-firmware-version.ts
1003
+ class VexFirmwareVersion {
1004
+ major;
1005
+ minor;
1006
+ build;
1007
+ beta;
1008
+ constructor(major, minor, build, beta) {
1009
+ this.major = major;
1010
+ this.minor = minor;
1011
+ this.build = build;
1012
+ this.beta = beta;
1013
+ }
1014
+ static fromString(version) {
1015
+ const parts = version.toLowerCase().replace(/b/g, "").split(".").map((x) => parseInt(x, 10));
1016
+ while (parts.length < 4) {
1017
+ parts.push(0);
1018
+ }
1019
+ return new VexFirmwareVersion(parts[0], parts[1], parts[2], parts[3]);
1020
+ }
1021
+ static fromUint8Array(data, offset = 0, reverse = false) {
1022
+ return new VexFirmwareVersion(data[offset + (reverse ? 3 : 0)], data[offset + (reverse ? 2 : 1)], data[offset + (reverse ? 1 : 2)], data[offset + (reverse ? 0 : 3)]);
1023
+ }
1024
+ static allZero() {
1025
+ return new VexFirmwareVersion(0, 0, 0, 0);
1026
+ }
1027
+ static fromCatalogString(version) {
1028
+ return VexFirmwareVersion.fromString(version.replace(/_/g, "."));
1029
+ }
1030
+ isBeta() {
1031
+ return this.beta !== 0;
1032
+ }
1033
+ toUint8Array(reverse = false) {
1034
+ const data = new Uint8Array(4);
1035
+ data[reverse ? 3 : 0] = this.major;
1036
+ data[reverse ? 2 : 1] = this.minor;
1037
+ data[reverse ? 1 : 2] = this.build;
1038
+ data[reverse ? 0 : 3] = this.beta;
1039
+ return data;
1040
+ }
1041
+ toUserString() {
1042
+ return `${this.major}.${this.minor}.${this.build}`;
1043
+ }
1044
+ toInternalString() {
1045
+ return `${this.toUserString()}.b${this.beta}`;
1046
+ }
1047
+ compare(that) {
1048
+ const majorComp = this.major - that.major;
1049
+ const minorComp = this.minor - that.minor;
1050
+ const buildComp = this.build - that.build;
1051
+ const betaComp = this.beta - that.beta;
1052
+ if (majorComp !== 0) {
1053
+ return majorComp;
1054
+ } else if (minorComp !== 0) {
1055
+ return minorComp;
1056
+ } else if (buildComp !== 0) {
1057
+ return buildComp;
1058
+ } else if (betaComp !== 0) {
1059
+ return betaComp;
1060
+ }
1061
+ return 0;
1062
+ }
1063
+ }
1064
+
1065
+ // ../serial/src/vex-packet-view.ts
1066
+ class PacketView {
1067
+ view;
1068
+ position = 0;
1069
+ littleEndianDefault = true;
1070
+ constructor(buffer, offset = 0, length = buffer.byteLength - offset) {
1071
+ this.view = new DataView(buffer, offset, length);
1072
+ }
1073
+ static fromPacket(packet) {
1074
+ let view = new PacketView(packet.data.buffer, packet.data.byteOffset);
1075
+ view.position = packet.ackIndex + 1;
1076
+ return view;
1077
+ }
1078
+ get byteLength() {
1079
+ return this.view.byteLength;
1080
+ }
1081
+ get buffer() {
1082
+ return this.view.buffer;
1083
+ }
1084
+ getInt8(byteOffset) {
1085
+ return this.view.getInt8(byteOffset);
1086
+ }
1087
+ getUint8(byteOffset) {
1088
+ return this.view.getUint8(byteOffset);
1089
+ }
1090
+ getInt16(byteOffset, littleEndian) {
1091
+ return this.view.getInt16(byteOffset, littleEndian);
1092
+ }
1093
+ getUint16(byteOffset, littleEndian) {
1094
+ return this.view.getUint16(byteOffset, littleEndian);
1095
+ }
1096
+ getInt32(byteOffset, littleEndian) {
1097
+ return this.view.getInt32(byteOffset, littleEndian);
1098
+ }
1099
+ getUint32(byteOffset, littleEndian) {
1100
+ return this.view.getUint32(byteOffset, littleEndian);
1101
+ }
1102
+ nextInt8() {
1103
+ let result = this.getInt8(this.position);
1104
+ this.position += 1;
1105
+ return result;
1106
+ }
1107
+ nextUint8() {
1108
+ let result = this.getUint8(this.position);
1109
+ this.position += 1;
1110
+ return result;
1111
+ }
1112
+ nextInt16(littleEndian = this.littleEndianDefault) {
1113
+ let result = this.getInt16(this.position, littleEndian);
1114
+ this.position += 2;
1115
+ return result;
1116
+ }
1117
+ nextUint16(littleEndian = this.littleEndianDefault) {
1118
+ let result = this.getUint16(this.position, littleEndian);
1119
+ this.position += 2;
1120
+ return result;
1121
+ }
1122
+ nextInt32(littleEndian = this.littleEndianDefault) {
1123
+ let result = this.getInt32(this.position, littleEndian);
1124
+ this.position += 4;
1125
+ return result;
1126
+ }
1127
+ nextUint32(littleEndian = this.littleEndianDefault) {
1128
+ let result = this.getUint32(this.position, littleEndian);
1129
+ this.position += 4;
1130
+ return result;
1131
+ }
1132
+ nextString(length) {
1133
+ let result = "";
1134
+ for (let i = 0;i < length; i++) {
1135
+ result += String.fromCharCode(this.nextUint8());
1136
+ }
1137
+ return result;
1138
+ }
1139
+ nextNTBS(length) {
1140
+ let result = "";
1141
+ let lastPosition = this.position;
1142
+ for (let i = 0;i < length; i++) {
1143
+ if (this.byteLength <= this.position)
1144
+ break;
1145
+ let g = this.nextUint8();
1146
+ if (g === 0)
1147
+ break;
1148
+ result += String.fromCharCode(g);
1149
+ }
1150
+ this.position = lastPosition + length;
1151
+ return result;
1152
+ }
1153
+ nextVarNTBS(length) {
1154
+ let result = "";
1155
+ for (let i = 0;i < length; i++) {
1156
+ if (this.byteLength <= this.position)
1157
+ break;
1158
+ let g = this.nextUint8();
1159
+ if (g === 0)
1160
+ break;
1161
+ result += String.fromCharCode(g);
1162
+ }
1163
+ return result;
1164
+ }
1165
+ nextVersion(reverse = false) {
1166
+ let result = VexFirmwareVersion.fromUint8Array(new Uint8Array(this.buffer), this.position, reverse);
1167
+ this.position += 4;
1168
+ return result;
1169
+ }
1170
+ }
1171
+
1172
+ // ../serial/src/vex-crc.ts
1173
+ var CRC16TABLE = [
1174
+ 0,
1175
+ 4129,
1176
+ 8258,
1177
+ 12387,
1178
+ 16516,
1179
+ 20645,
1180
+ 24774,
1181
+ 28903,
1182
+ 33032,
1183
+ 37161,
1184
+ 41290,
1185
+ 45419,
1186
+ 49548,
1187
+ 53677,
1188
+ 57806,
1189
+ 61935,
1190
+ 4657,
1191
+ 528,
1192
+ 12915,
1193
+ 8786,
1194
+ 21173,
1195
+ 17044,
1196
+ 29431,
1197
+ 25302,
1198
+ 37689,
1199
+ 33560,
1200
+ 45947,
1201
+ 41818,
1202
+ 54205,
1203
+ 50076,
1204
+ 62463,
1205
+ 58334,
1206
+ 9314,
1207
+ 13379,
1208
+ 1056,
1209
+ 5121,
1210
+ 25830,
1211
+ 29895,
1212
+ 17572,
1213
+ 21637,
1214
+ 42346,
1215
+ 46411,
1216
+ 34088,
1217
+ 38153,
1218
+ 58862,
1219
+ 62927,
1220
+ 50604,
1221
+ 54669,
1222
+ 13907,
1223
+ 9842,
1224
+ 5649,
1225
+ 1584,
1226
+ 30423,
1227
+ 26358,
1228
+ 22165,
1229
+ 18100,
1230
+ 46939,
1231
+ 42874,
1232
+ 38681,
1233
+ 34616,
1234
+ 63455,
1235
+ 59390,
1236
+ 55197,
1237
+ 51132,
1238
+ 18628,
1239
+ 22757,
1240
+ 26758,
1241
+ 30887,
1242
+ 2112,
1243
+ 6241,
1244
+ 10242,
1245
+ 14371,
1246
+ 51660,
1247
+ 55789,
1248
+ 59790,
1249
+ 63919,
1250
+ 35144,
1251
+ 39273,
1252
+ 43274,
1253
+ 47403,
1254
+ 23285,
1255
+ 19156,
1256
+ 31415,
1257
+ 27286,
1258
+ 6769,
1259
+ 2640,
1260
+ 14899,
1261
+ 10770,
1262
+ 56317,
1263
+ 52188,
1264
+ 64447,
1265
+ 60318,
1266
+ 39801,
1267
+ 35672,
1268
+ 47931,
1269
+ 43802,
1270
+ 27814,
1271
+ 31879,
1272
+ 19684,
1273
+ 23749,
1274
+ 11298,
1275
+ 15363,
1276
+ 3168,
1277
+ 7233,
1278
+ 60846,
1279
+ 64911,
1280
+ 52716,
1281
+ 56781,
1282
+ 44330,
1283
+ 48395,
1284
+ 36200,
1285
+ 40265,
1286
+ 32407,
1287
+ 28342,
1288
+ 24277,
1289
+ 20212,
1290
+ 15891,
1291
+ 11826,
1292
+ 7761,
1293
+ 3696,
1294
+ 65439,
1295
+ 61374,
1296
+ 57309,
1297
+ 53244,
1298
+ 48923,
1299
+ 44858,
1300
+ 40793,
1301
+ 36728,
1302
+ 37256,
1303
+ 33193,
1304
+ 45514,
1305
+ 41451,
1306
+ 53516,
1307
+ 49453,
1308
+ 61774,
1309
+ 57711,
1310
+ 4224,
1311
+ 161,
1312
+ 12482,
1313
+ 8419,
1314
+ 20484,
1315
+ 16421,
1316
+ 28742,
1317
+ 24679,
1318
+ 33721,
1319
+ 37784,
1320
+ 41979,
1321
+ 46042,
1322
+ 49981,
1323
+ 54044,
1324
+ 58239,
1325
+ 62302,
1326
+ 689,
1327
+ 4752,
1328
+ 8947,
1329
+ 13010,
1330
+ 16949,
1331
+ 21012,
1332
+ 25207,
1333
+ 29270,
1334
+ 46570,
1335
+ 42443,
1336
+ 38312,
1337
+ 34185,
1338
+ 62830,
1339
+ 58703,
1340
+ 54572,
1341
+ 50445,
1342
+ 13538,
1343
+ 9411,
1344
+ 5280,
1345
+ 1153,
1346
+ 29798,
1347
+ 25671,
1348
+ 21540,
1349
+ 17413,
1350
+ 42971,
1351
+ 47098,
1352
+ 34713,
1353
+ 38840,
1354
+ 59231,
1355
+ 63358,
1356
+ 50973,
1357
+ 55100,
1358
+ 9939,
1359
+ 14066,
1360
+ 1681,
1361
+ 5808,
1362
+ 26199,
1363
+ 30326,
1364
+ 17941,
1365
+ 22068,
1366
+ 55628,
1367
+ 51565,
1368
+ 63758,
1369
+ 59695,
1370
+ 39368,
1371
+ 35305,
1372
+ 47498,
1373
+ 43435,
1374
+ 22596,
1375
+ 18533,
1376
+ 30726,
1377
+ 26663,
1378
+ 6336,
1379
+ 2273,
1380
+ 14466,
1381
+ 10403,
1382
+ 52093,
1383
+ 56156,
1384
+ 60223,
1385
+ 64286,
1386
+ 35833,
1387
+ 39896,
1388
+ 43963,
1389
+ 48026,
1390
+ 19061,
1391
+ 23124,
1392
+ 27191,
1393
+ 31254,
1394
+ 2801,
1395
+ 6864,
1396
+ 10931,
1397
+ 14994,
1398
+ 64814,
1399
+ 60687,
1400
+ 56684,
1401
+ 52557,
1402
+ 48554,
1403
+ 44427,
1404
+ 40424,
1405
+ 36297,
1406
+ 31782,
1407
+ 27655,
1408
+ 23652,
1409
+ 19525,
1410
+ 15522,
1411
+ 11395,
1412
+ 7392,
1413
+ 3265,
1414
+ 61215,
1415
+ 65342,
1416
+ 53085,
1417
+ 57212,
1418
+ 44955,
1419
+ 49082,
1420
+ 36825,
1421
+ 40952,
1422
+ 28183,
1423
+ 32310,
1424
+ 20053,
1425
+ 24180,
1426
+ 11923,
1427
+ 16050,
1428
+ 3793,
1429
+ 7920
1430
+ ];
1431
+
1432
+ class CrcGenerator {
1433
+ crc32Table;
1434
+ static POLYNOMIAL_CRC32 = 79764919;
1435
+ static POLYNOMIAL_CRC16 = 4129;
1436
+ constructor() {
1437
+ this.crc32Table = new Uint32Array(256);
1438
+ this.crc32GenTable();
1439
+ }
1440
+ crc16(buf, initValue) {
1441
+ const numberOfBytes = buf.byteLength;
1442
+ let accumulator = initValue;
1443
+ let i;
1444
+ let j;
1445
+ for (j = 0;j < numberOfBytes; j++) {
1446
+ i = (accumulator >>> 8 ^ buf[j]) & 255;
1447
+ accumulator = (accumulator << 8 ^ CRC16TABLE[i]) >>> 0;
1448
+ }
1449
+ return (accumulator & 65535) >>> 0;
1450
+ }
1451
+ crc32GenTable() {
1452
+ var i;
1453
+ var j;
1454
+ var crc_accumulator;
1455
+ for (i = 0;i < 256; i++) {
1456
+ crc_accumulator = i << 24;
1457
+ for (j = 0;j < 8; j++) {
1458
+ if (crc_accumulator & 2147483648)
1459
+ crc_accumulator = crc_accumulator << 1 ^ CrcGenerator.POLYNOMIAL_CRC32;
1460
+ else
1461
+ crc_accumulator = crc_accumulator << 1;
1462
+ }
1463
+ this.crc32Table[i] = crc_accumulator;
1464
+ }
1465
+ }
1466
+ crc32(buf, initValue) {
1467
+ const numberOfBytes = buf.byteLength;
1468
+ let crc_accumulator = initValue;
1469
+ let i;
1470
+ let j;
1471
+ for (j = 0;j < numberOfBytes; j++) {
1472
+ i = (crc_accumulator >>> 24 ^ buf[j]) & 255;
1473
+ crc_accumulator = (crc_accumulator << 8 ^ this.crc32Table[i]) >>> 0;
1474
+ }
1475
+ return (crc_accumulator & 4294967295) >>> 0;
1476
+ }
1477
+ }
1478
+
1479
+ // ../serial/src/vex-packet.ts
1480
+ class PacketEncoder {
1481
+ static HEADERS_LENGTH = 4;
1482
+ static HEADER_TO_DEVICE = [201, 54, 184, 71];
1483
+ static HEADER_TO_HOST = [170, 85];
1484
+ static J2000_EPOCH = 946684800;
1485
+ vexVersion;
1486
+ crcgen;
1487
+ allPacketsTable = {};
1488
+ static getInstance() {
1489
+ if (Packet.ENCODER === undefined) {
1490
+ Packet.ENCODER = new PacketEncoder;
1491
+ }
1492
+ return Packet.ENCODER;
1493
+ }
1494
+ constructor() {
1495
+ this.vexVersion = 0;
1496
+ this.crcgen = new CrcGenerator;
1497
+ Object.values(exports_vex_packet).forEach((packet) => {
1498
+ if (packet.prototype instanceof HostBoundPacket) {
1499
+ this.allPacketsTable[packet.COMMAND_ID + " " + packet.COMMAND_EXTENDED_ID] = packet;
1500
+ }
1501
+ });
1502
+ }
1503
+ createHeader(buf) {
1504
+ if (buf === undefined || buf.byteLength < PacketEncoder.HEADERS_LENGTH) {
1505
+ buf = new ArrayBuffer(PacketEncoder.HEADERS_LENGTH);
1506
+ }
1507
+ const h = new Uint8Array(buf);
1508
+ h.set(PacketEncoder.HEADER_TO_DEVICE);
1509
+ return h;
1510
+ }
1511
+ cdcCommand(cmd) {
1512
+ const buf = new ArrayBuffer(PacketEncoder.HEADERS_LENGTH + 1);
1513
+ const h = this.createHeader(buf);
1514
+ h.set([cmd], PacketEncoder.HEADERS_LENGTH);
1515
+ return h;
1516
+ }
1517
+ cdcCommandWithData(cmd, data) {
1518
+ const buf = new ArrayBuffer(PacketEncoder.HEADERS_LENGTH + 2 + data.length);
1519
+ const h = this.createHeader(buf);
1520
+ h.set([cmd, data.length], PacketEncoder.HEADERS_LENGTH);
1521
+ h.set(data, PacketEncoder.HEADERS_LENGTH + 2);
1522
+ return h;
1523
+ }
1524
+ cdc2Command(cmd, ext) {
1525
+ const buf = new ArrayBuffer(PacketEncoder.HEADERS_LENGTH + 5);
1526
+ const h = this.createHeader(buf);
1527
+ h.set([cmd, ext, 0], PacketEncoder.HEADERS_LENGTH);
1528
+ const crc = this.crcgen.crc16(h.subarray(0, buf.byteLength - 2), 0) >>> 0;
1529
+ h.set([crc >>> 8, crc & 255], buf.byteLength - 2);
1530
+ return h;
1531
+ }
1532
+ cdc2CommandBufferLength(data) {
1533
+ let length = PacketEncoder.HEADERS_LENGTH + data.length + 3 + 2;
1534
+ if (data.length > 127)
1535
+ length += 1;
1536
+ return length;
1537
+ }
1538
+ cdc2CommandWithData(cmd, ext, data) {
1539
+ const buf = new ArrayBuffer(this.cdc2CommandBufferLength(data));
1540
+ const h = this.createHeader(buf);
1541
+ if (data.length < 128) {
1542
+ h.set([cmd, ext, data.length], PacketEncoder.HEADERS_LENGTH);
1543
+ h.set(data, PacketEncoder.HEADERS_LENGTH + 3);
1544
+ } else {
1545
+ const length_msb = (data.length >>> 8 | 128) >>> 0;
1546
+ const length_lsb = (data.length & 255) >>> 0;
1547
+ h.set([cmd, ext, length_msb, length_lsb], PacketEncoder.HEADERS_LENGTH);
1548
+ h.set(data, PacketEncoder.HEADERS_LENGTH + 4);
1549
+ }
1550
+ const crc = this.crcgen.crc16(h.subarray(0, buf.byteLength - 2), 0);
1551
+ h.set([crc >>> 8, crc & 255], buf.byteLength - 2);
1552
+ return h;
1553
+ }
1554
+ validateHeader(data) {
1555
+ return !(data[0] !== PacketEncoder.HEADER_TO_HOST[0] || data[1] !== PacketEncoder.HEADER_TO_HOST[1]);
1556
+ }
1557
+ validateMessageCdc(data) {
1558
+ let message = data.subarray(0, data.byteLength - 2);
1559
+ let lastTwoBytes = (data[data.byteLength - 2] << 8) + data[data.byteLength - 1];
1560
+ return this.crcgen.crc16(message, 0) === lastTwoBytes;
1561
+ }
1562
+ getPayloadSize(data) {
1563
+ let t = 0, a = data[3];
1564
+ if (128 & a) {
1565
+ t = 127 & a;
1566
+ a = data[4];
1567
+ }
1568
+ return (t << 8) + a;
1569
+ }
1570
+ }
1571
+
1572
+ class Packet {
1573
+ data;
1574
+ static ENCODER;
1575
+ constructor(rawData) {
1576
+ this.data = rawData instanceof ArrayBuffer ? new Uint8Array(rawData) : rawData;
1577
+ }
1578
+ }
1579
+
1580
+ class DeviceBoundPacket extends Packet {
1581
+ constructor(payload) {
1582
+ super(new Uint8Array);
1583
+ let me = this.__proto__.constructor;
1584
+ if (me.COMMAND_EXTENDED_ID === undefined) {
1585
+ if (payload === undefined) {
1586
+ this.data = Packet.ENCODER.cdcCommand(me.COMMAND_ID);
1587
+ } else {
1588
+ this.data = Packet.ENCODER.cdcCommandWithData(me.COMMAND_ID, payload);
1589
+ }
1590
+ } else {
1591
+ if (payload === undefined) {
1592
+ this.data = Packet.ENCODER.cdc2Command(me.COMMAND_ID, me.COMMAND_EXTENDED_ID);
1593
+ } else {
1594
+ this.data = Packet.ENCODER.cdc2CommandWithData(me.COMMAND_ID, me.COMMAND_EXTENDED_ID, payload);
1595
+ }
1596
+ }
1597
+ }
1598
+ }
1599
+
1600
+ class Query1H2DPacket extends DeviceBoundPacket {
1601
+ static COMMAND_ID = 33;
1602
+ static COMMAND_EXTENDED_ID = undefined;
1603
+ constructor() {
1604
+ super(undefined);
1605
+ }
1606
+ }
1607
+
1608
+ class SystemVersionH2DPacket extends DeviceBoundPacket {
1609
+ static COMMAND_ID = 164;
1610
+ static COMMAND_EXTENDED_ID = undefined;
1611
+ constructor() {
1612
+ super(undefined);
1613
+ }
1614
+ }
1615
+
1616
+ class UpdateMatchModeH2DPacket extends DeviceBoundPacket {
1617
+ static COMMAND_ID = 88;
1618
+ static COMMAND_EXTENDED_ID = 193;
1619
+ constructor(mode, matchClock) {
1620
+ let bit1;
1621
+ switch (mode) {
1622
+ case "autonomous":
1623
+ bit1 = 10;
1624
+ break;
1625
+ case "driver":
1626
+ bit1 = 8;
1627
+ break;
1628
+ case "disabled":
1629
+ bit1 = 11;
1630
+ }
1631
+ const payload = new Uint8Array(5), view = new DataView(payload.buffer);
1632
+ payload[0] = (15 & bit1) >>> 0;
1633
+ view.setUint32(1, matchClock, true);
1634
+ super(payload);
1635
+ }
1636
+ }
1637
+
1638
+ class GetMatchStatusH2DPacket extends DeviceBoundPacket {
1639
+ static COMMAND_ID = 88;
1640
+ static COMMAND_EXTENDED_ID = 194;
1641
+ constructor() {
1642
+ super(undefined);
1643
+ }
1644
+ }
1645
+
1646
+ class GetRadioModeH2DPacket extends DeviceBoundPacket {
1647
+ static COMMAND_ID = 88;
1648
+ static COMMAND_EXTENDED_ID = 65;
1649
+ constructor(mode) {
1650
+ const payload = new Uint8Array(1);
1651
+ payload[0] = mode;
1652
+ super(payload);
1653
+ }
1654
+ }
1655
+
1656
+ class FileControlH2DPacket extends DeviceBoundPacket {
1657
+ static COMMAND_ID = 86;
1658
+ static COMMAND_EXTENDED_ID = 16;
1659
+ constructor(a, b) {
1660
+ const payload = new Uint8Array(2);
1661
+ payload.set([a, b], 0);
1662
+ super(payload);
1663
+ }
1664
+ }
1665
+
1666
+ class InitFileTransferH2DPacket extends DeviceBoundPacket {
1667
+ static COMMAND_ID = 86;
1668
+ static COMMAND_EXTENDED_ID = 17;
1669
+ constructor(operation, target, vendor, options, binary, addr, name, type, version = new VexFirmwareVersion(1, 0, 0, 0)) {
1670
+ const payload = new Uint8Array(52);
1671
+ const view = new DataView(payload.buffer);
1672
+ view.setUint8(0, operation);
1673
+ view.setUint8(1, target);
1674
+ view.setUint8(2, vendor);
1675
+ view.setUint8(3, options);
1676
+ view.setUint32(4, binary.length, true);
1677
+ view.setUint32(8, addr, true);
1678
+ view.setUint32(12, operation === 1 /* WRITE */ ? Packet.ENCODER.crcgen.crc32(binary, 0) : 0, true);
1679
+ const re = /(?:\.([^.]+))?$/;
1680
+ const reResult = re.exec(name);
1681
+ let ext = reResult ? reResult[1] : undefined;
1682
+ ext = ext === undefined ? "" : ext;
1683
+ ext = ext === "gz" ? "bin" : ext;
1684
+ payload.set(new TextEncoder().encode(type ?? ext), 16);
1685
+ const timestamp = (Date.now() / 1000 >>> 0) - PacketEncoder.J2000_EPOCH;
1686
+ view.setUint32(20, timestamp, true);
1687
+ payload.set(version.toUint8Array(), 24);
1688
+ const nameEncoded = new TextEncoder().encode(name);
1689
+ let offset = nameEncoded.length - 23;
1690
+ if (offset < 0)
1691
+ offset = 0;
1692
+ payload.set(nameEncoded.subarray(offset, offset + 23), 28);
1693
+ view.setUint8(51, 0);
1694
+ super(payload);
1695
+ }
1696
+ }
1697
+
1698
+ class ExitFileTransferH2DPacket extends DeviceBoundPacket {
1699
+ static COMMAND_ID = 86;
1700
+ static COMMAND_EXTENDED_ID = 18;
1701
+ constructor(action) {
1702
+ let payload = new Uint8Array(1);
1703
+ payload[0] = action;
1704
+ super(payload);
1705
+ }
1706
+ }
1707
+
1708
+ class WriteFileH2DPacket extends DeviceBoundPacket {
1709
+ static COMMAND_ID = 86;
1710
+ static COMMAND_EXTENDED_ID = 19;
1711
+ constructor(addr, buf) {
1712
+ const payload = new Uint8Array(4 + buf.length);
1713
+ const view = new DataView(payload.buffer);
1714
+ view.setUint32(0, addr, true);
1715
+ payload.set(buf, 4);
1716
+ super(payload);
1717
+ }
1718
+ }
1719
+
1720
+ class ReadFileH2DPacket extends DeviceBoundPacket {
1721
+ static COMMAND_ID = 86;
1722
+ static COMMAND_EXTENDED_ID = 20;
1723
+ constructor(addr, size) {
1724
+ const payload = new Uint8Array(6);
1725
+ const view = new DataView(payload.buffer);
1726
+ view.setUint32(0, addr, true);
1727
+ view.setUint16(4, size, true);
1728
+ super(payload);
1729
+ }
1730
+ }
1731
+
1732
+ class LinkFileH2DPacket extends DeviceBoundPacket {
1733
+ static COMMAND_ID = 86;
1734
+ static COMMAND_EXTENDED_ID = 21;
1735
+ constructor(vendor, fileName, options) {
1736
+ const str = new TextEncoder().encode(fileName);
1737
+ let payload = new Uint8Array(26);
1738
+ payload.set([vendor, options], 0);
1739
+ payload.set(str.subarray(0, 23), 2);
1740
+ super(payload);
1741
+ }
1742
+ }
1743
+
1744
+ class GetDirectoryFileCountH2DPacket extends DeviceBoundPacket {
1745
+ static COMMAND_ID = 86;
1746
+ static COMMAND_EXTENDED_ID = 22;
1747
+ constructor(vendor) {
1748
+ let payload = new Uint8Array(2);
1749
+ payload.set([vendor, 0], 0);
1750
+ super(payload);
1751
+ }
1752
+ }
1753
+
1754
+ class GetDirectoryEntryH2DPacket extends DeviceBoundPacket {
1755
+ static COMMAND_ID = 86;
1756
+ static COMMAND_EXTENDED_ID = 23;
1757
+ constructor(index) {
1758
+ let payload = new Uint8Array(2);
1759
+ payload.set([index, 0], 0);
1760
+ super(payload);
1761
+ }
1762
+ }
1763
+
1764
+ class LoadFileActionH2DPacket extends DeviceBoundPacket {
1765
+ static COMMAND_ID = 86;
1766
+ static COMMAND_EXTENDED_ID = 24;
1767
+ constructor(vendor, actionId, fileNameOrSlotNumber) {
1768
+ let fileName;
1769
+ if (typeof fileNameOrSlotNumber === "string") {
1770
+ fileName = fileNameOrSlotNumber;
1771
+ } else {
1772
+ fileName = "___s_" + (fileNameOrSlotNumber - 1) + ".bin";
1773
+ }
1774
+ let encodedName = new TextEncoder().encode(fileName), payload = new Uint8Array(26);
1775
+ payload.set([vendor, actionId], 0);
1776
+ payload.set(encodedName.subarray(0, 23), 2);
1777
+ super(payload);
1778
+ }
1779
+ }
1780
+
1781
+ class GetFileMetadataH2DPacket extends DeviceBoundPacket {
1782
+ static COMMAND_ID = 86;
1783
+ static COMMAND_EXTENDED_ID = 25;
1784
+ constructor(vendor, fileName, options) {
1785
+ let encodedName = new TextEncoder().encode(fileName);
1786
+ let payload = new Uint8Array(26);
1787
+ payload.set([vendor, options], 0);
1788
+ payload.set(encodedName.subarray(0, 23), 2);
1789
+ super(payload);
1790
+ }
1791
+ }
1792
+
1793
+ class SetFileMetadataH2DPacket extends DeviceBoundPacket {
1794
+ static COMMAND_ID = 86;
1795
+ static COMMAND_EXTENDED_ID = 26;
1796
+ constructor(vendor, fileName, fileInfo, options) {
1797
+ let encodedName = new TextEncoder().encode(fileName);
1798
+ let encodedType = new TextEncoder().encode(fileInfo.type);
1799
+ let payload = new Uint8Array(42);
1800
+ let view = new DataView(payload.buffer);
1801
+ view.setUint8(0, vendor);
1802
+ view.setUint8(1, options);
1803
+ view.setUint32(2, fileInfo.loadAddress, true);
1804
+ payload.set(encodedType.subarray(0, 4), 6);
1805
+ let timestamp = fileInfo.timestamp - PacketEncoder.J2000_EPOCH + 100;
1806
+ view.setUint32(10, timestamp, true);
1807
+ payload.set(fileInfo.version.toUint8Array(), 14);
1808
+ payload.set(encodedName.subarray(0, 23), 18);
1809
+ super(payload);
1810
+ }
1811
+ }
1812
+
1813
+ class EraseFileH2DPacket extends DeviceBoundPacket {
1814
+ static COMMAND_ID = 86;
1815
+ static COMMAND_EXTENDED_ID = 27;
1816
+ constructor(vendor, fileName) {
1817
+ let encodedName = new TextEncoder().encode(fileName);
1818
+ let payload = new Uint8Array(26);
1819
+ payload.set([vendor, 128], 0);
1820
+ payload.set(encodedName.subarray(0, 23), 2);
1821
+ super(payload);
1822
+ }
1823
+ }
1824
+
1825
+ class GetProgramSlotInfoH2DPacket extends DeviceBoundPacket {
1826
+ static COMMAND_ID = 86;
1827
+ static COMMAND_EXTENDED_ID = 28;
1828
+ constructor(vendor, fileName) {
1829
+ let encodedName = new TextEncoder().encode(fileName);
1830
+ let payload = new Uint8Array(26);
1831
+ payload.set([vendor, 0], 0);
1832
+ payload.set(encodedName.subarray(0, 23), 2);
1833
+ super(payload);
1834
+ }
1835
+ }
1836
+
1837
+ class FileClearUpH2DPacket extends DeviceBoundPacket {
1838
+ static COMMAND_ID = 86;
1839
+ static COMMAND_EXTENDED_ID = 30;
1840
+ constructor(vendor) {
1841
+ let payload = new Uint8Array(2);
1842
+ payload.set([vendor, 0], 0);
1843
+ super(payload);
1844
+ }
1845
+ }
1846
+
1847
+ class FileFormatH2DPacket extends DeviceBoundPacket {
1848
+ static COMMAND_ID = 86;
1849
+ static COMMAND_EXTENDED_ID = 31;
1850
+ constructor() {
1851
+ let payload = new Uint8Array(4);
1852
+ payload.set([68, 67, 66, 65], 0);
1853
+ super(payload);
1854
+ }
1855
+ }
1856
+
1857
+ class GetSystemFlagsH2DPacket extends DeviceBoundPacket {
1858
+ static COMMAND_ID = 86;
1859
+ static COMMAND_EXTENDED_ID = 32;
1860
+ }
1861
+
1862
+ class GetDeviceStatusH2DPacket extends DeviceBoundPacket {
1863
+ static COMMAND_ID = 86;
1864
+ static COMMAND_EXTENDED_ID = 33;
1865
+ constructor() {
1866
+ super(undefined);
1867
+ }
1868
+ }
1869
+
1870
+ class GetSystemStatusH2DPacket extends DeviceBoundPacket {
1871
+ static COMMAND_ID = 86;
1872
+ static COMMAND_EXTENDED_ID = 34;
1873
+ constructor() {
1874
+ super(undefined);
1875
+ }
1876
+ }
1877
+
1878
+ class GetFdtStatusH2DPacket extends DeviceBoundPacket {
1879
+ static COMMAND_ID = 86;
1880
+ static COMMAND_EXTENDED_ID = 35;
1881
+ constructor() {
1882
+ super(undefined);
1883
+ }
1884
+ }
1885
+
1886
+ class GetLogCountH2DPacket extends DeviceBoundPacket {
1887
+ static COMMAND_ID = 86;
1888
+ static COMMAND_EXTENDED_ID = 36;
1889
+ constructor() {
1890
+ super(undefined);
1891
+ }
1892
+ }
1893
+
1894
+ class ReadLogPageH2DPacket extends DeviceBoundPacket {
1895
+ static COMMAND_ID = 86;
1896
+ static COMMAND_EXTENDED_ID = 37;
1897
+ constructor(offset, count) {
1898
+ let payload = new Uint8Array(8);
1899
+ let view = new DataView(payload.buffer);
1900
+ view.setUint32(0, offset, true);
1901
+ view.setUint32(4, count, true);
1902
+ super(payload);
1903
+ }
1904
+ }
1905
+
1906
+ class GetRadioStatusH2DPacket extends DeviceBoundPacket {
1907
+ static COMMAND_ID = 86;
1908
+ static COMMAND_EXTENDED_ID = 38;
1909
+ constructor() {
1910
+ super(undefined);
1911
+ }
1912
+ }
1913
+
1914
+ class GetUserDataH2DPacket extends DeviceBoundPacket {
1915
+ static COMMAND_ID = 86;
1916
+ static COMMAND_EXTENDED_ID = 39;
1917
+ constructor(e) {
1918
+ let len = e?.length || 0;
1919
+ if (len > 244)
1920
+ len = 244;
1921
+ let payload = new Uint8Array(2 + len);
1922
+ payload[0] = 1;
1923
+ payload[1] = len;
1924
+ payload.set(e || new Uint8Array(0), 2);
1925
+ super(payload);
1926
+ }
1927
+ }
1928
+
1929
+ class ScreenCaptureH2DPacket extends DeviceBoundPacket {
1930
+ static COMMAND_ID = 86;
1931
+ static COMMAND_EXTENDED_ID = 40;
1932
+ constructor(e) {
1933
+ let payload = new Uint8Array(1);
1934
+ payload[0] = e;
1935
+ super(payload);
1936
+ }
1937
+ }
1938
+
1939
+ class SendDashTouchH2DPacket extends DeviceBoundPacket {
1940
+ static COMMAND_ID = 86;
1941
+ static COMMAND_EXTENDED_ID = 42;
1942
+ constructor(x, y, press) {
1943
+ let payload = new Uint8Array(6);
1944
+ let view = new DataView(payload.buffer);
1945
+ view.setUint16(0, x, true);
1946
+ view.setUint16(2, y, true);
1947
+ view.setUint16(4, press ? 1 : 0, true);
1948
+ super(payload);
1949
+ }
1950
+ }
1951
+
1952
+ class SelectDashH2DPacket extends DeviceBoundPacket {
1953
+ static COMMAND_ID = 86;
1954
+ static COMMAND_EXTENDED_ID = 43;
1955
+ constructor(screen, port) {
1956
+ let payload = new Uint8Array(2);
1957
+ payload[0] = screen;
1958
+ payload[1] = port;
1959
+ super(payload);
1960
+ }
1961
+ }
1962
+
1963
+ class EnableDashH2DPacket extends DeviceBoundPacket {
1964
+ static COMMAND_ID = 86;
1965
+ static COMMAND_EXTENDED_ID = 44;
1966
+ constructor(unknown1) {
1967
+ if (unknown1 === undefined) {
1968
+ super(undefined);
1969
+ } else {
1970
+ let payload = new Uint8Array(1);
1971
+ payload[0] = unknown1;
1972
+ super(payload);
1973
+ }
1974
+ }
1975
+ }
1976
+
1977
+ class DisableDashH2DPacket extends DeviceBoundPacket {
1978
+ static COMMAND_ID = 86;
1979
+ static COMMAND_EXTENDED_ID = 45;
1980
+ constructor() {
1981
+ super(undefined);
1982
+ }
1983
+ }
1984
+
1985
+ class ReadKeyValueH2DPacket extends DeviceBoundPacket {
1986
+ static COMMAND_ID = 86;
1987
+ static COMMAND_EXTENDED_ID = 46;
1988
+ constructor(key) {
1989
+ let payload = new Uint8Array(32);
1990
+ payload.set(new TextEncoder().encode(key), 0);
1991
+ super(payload);
1992
+ }
1993
+ }
1994
+
1995
+ class WriteKeyValueH2DPacket extends DeviceBoundPacket {
1996
+ static COMMAND_ID = 86;
1997
+ static COMMAND_EXTENDED_ID = 47;
1998
+ constructor(key, value) {
1999
+ let strk = new TextEncoder().encode(key);
2000
+ const strv = new TextEncoder().encode(value);
2001
+ if (strk.byteLength > 31)
2002
+ strk = strk.subarray(0, 31);
2003
+ let payload = new Uint8Array(strk.length + strv.length + 20);
2004
+ payload.set(strk, 0);
2005
+ payload.set(strv, strk.length + 1);
2006
+ super(payload);
2007
+ }
2008
+ }
2009
+
2010
+ class GetSlot1to4InfoH2DPacket extends DeviceBoundPacket {
2011
+ static COMMAND_ID = 86;
2012
+ static COMMAND_EXTENDED_ID = 49;
2013
+ constructor() {
2014
+ super(undefined);
2015
+ }
2016
+ }
2017
+
2018
+ class GetSlot5to8InfoH2DPacket extends DeviceBoundPacket {
2019
+ static COMMAND_ID = 86;
2020
+ static COMMAND_EXTENDED_ID = 50;
2021
+ constructor() {
2022
+ super(undefined);
2023
+ }
2024
+ }
2025
+
2026
+ class FactoryStatusH2DPacket extends DeviceBoundPacket {
2027
+ static COMMAND_ID = 86;
2028
+ static COMMAND_EXTENDED_ID = 241;
2029
+ }
2030
+
2031
+ class FactoryEnableH2DPacket extends DeviceBoundPacket {
2032
+ static COMMAND_ID = 86;
2033
+ static COMMAND_EXTENDED_ID = 255;
2034
+ constructor() {
2035
+ let payload = new Uint8Array(4);
2036
+ payload.set([77, 76, 75, 74], 0);
2037
+ super(payload);
2038
+ }
2039
+ }
2040
+
2041
+ class HostBoundPacket extends Packet {
2042
+ ack = 255 /* CDC2_NACK */;
2043
+ payloadSize;
2044
+ ackIndex;
2045
+ constructor(data) {
2046
+ super(data);
2047
+ this.payloadSize = Packet.ENCODER.getPayloadSize(this.data);
2048
+ const n = this.payloadSize > 128 ? 5 : 4;
2049
+ this.ack = this.data[this.ackIndex = n + 1];
2050
+ }
2051
+ static isValidPacket(data, n) {
2052
+ const ack = data[n + 1];
2053
+ return ack === 118 /* CDC2_ACK */ || ack === 167;
2054
+ }
2055
+ }
2056
+
2057
+ class Query1ReplyD2HPacket extends HostBoundPacket {
2058
+ static COMMAND_ID = 33;
2059
+ static COMMAND_EXTENDED_ID = undefined;
2060
+ joystickFlag1;
2061
+ joystickFlag2;
2062
+ brainFlag1;
2063
+ brainFlag2;
2064
+ bootloadFlag1;
2065
+ bootloadFlag2;
2066
+ constructor(data) {
2067
+ super(data);
2068
+ this.joystickFlag1 = this.data[4];
2069
+ this.joystickFlag2 = this.data[5];
2070
+ this.brainFlag1 = this.data[6];
2071
+ this.brainFlag2 = this.data[7];
2072
+ this.bootloadFlag1 = this.data[10];
2073
+ this.bootloadFlag2 = this.data[11];
2074
+ }
2075
+ }
2076
+
2077
+ class SystemVersionReplyD2HPacket extends HostBoundPacket {
2078
+ static COMMAND_ID = 164;
2079
+ static COMMAND_EXTENDED_ID = undefined;
2080
+ version;
2081
+ hardware;
2082
+ constructor(data) {
2083
+ super(data);
2084
+ this.version = new VexFirmwareVersion(this.data[4], this.data[5], this.data[6], this.data[8]);
2085
+ this.hardware = this.data[7];
2086
+ }
2087
+ }
2088
+
2089
+ class MatchModeReplyD2HPacket extends HostBoundPacket {
2090
+ static COMMAND_ID = 88;
2091
+ static COMMAND_EXTENDED_ID = 193;
2092
+ modebit;
2093
+ constructor(data) {
2094
+ super(data);
2095
+ const dataView = PacketView.fromPacket(this);
2096
+ this.modebit = dataView.nextUint8();
2097
+ }
2098
+ }
2099
+
2100
+ class MatchStatusReplyD2HPacket extends HostBoundPacket {
2101
+ static COMMAND_ID = 88;
2102
+ static COMMAND_EXTENDED_ID = 194;
2103
+ rssi;
2104
+ systemStatusBits;
2105
+ radioStatusBits;
2106
+ fieldStatusBits;
2107
+ matchClock;
2108
+ brainBatteryPercent;
2109
+ controllerBatteryPercent;
2110
+ partnerControllerBatteryPercent;
2111
+ pad;
2112
+ buttons;
2113
+ activeProgram;
2114
+ radioType;
2115
+ radioChannel;
2116
+ radioSlot;
2117
+ robotName;
2118
+ controllerFlags;
2119
+ rxSignalQuality;
2120
+ constructor(data) {
2121
+ super(data);
2122
+ const dataView = PacketView.fromPacket(this);
2123
+ let n = this.ackIndex;
2124
+ this.rssi = dataView.nextInt8();
2125
+ this.systemStatusBits = dataView.nextUint16();
2126
+ this.radioStatusBits = dataView.nextUint16();
2127
+ this.fieldStatusBits = dataView.nextUint8();
2128
+ this.matchClock = dataView.nextUint8();
2129
+ this.brainBatteryPercent = dataView.nextUint8();
2130
+ this.controllerBatteryPercent = dataView.nextUint8();
2131
+ this.partnerControllerBatteryPercent = dataView.nextUint8();
2132
+ this.pad = dataView.nextUint8();
2133
+ this.buttons = dataView.nextUint16();
2134
+ this.activeProgram = dataView.nextUint8();
2135
+ this.radioType = dataView.nextUint8();
2136
+ this.radioChannel = dataView.nextUint8();
2137
+ this.radioSlot = dataView.nextUint8();
2138
+ this.robotName = dataView.nextNTBS(10);
2139
+ this.controllerFlags = dataView.getUint8(n + 28);
2140
+ this.rxSignalQuality = dataView.getUint8(n + 29);
2141
+ let rawStr = new TextDecoder("UTF-8").decode(data.slice(n + 18, n + this.payloadSize + 28));
2142
+ const endIdx = rawStr.indexOf("\x00");
2143
+ if (endIdx > -1) {
2144
+ rawStr = rawStr.substr(0, endIdx);
2145
+ }
2146
+ this.robotName = rawStr;
2147
+ }
2148
+ }
2149
+
2150
+ class FileControlReplyD2HPacket extends HostBoundPacket {
2151
+ static COMMAND_ID = 86;
2152
+ static COMMAND_EXTENDED_ID = 16;
2153
+ }
2154
+
2155
+ class InitFileTransferReplyD2HPacket extends HostBoundPacket {
2156
+ static COMMAND_ID = 86;
2157
+ static COMMAND_EXTENDED_ID = 17;
2158
+ windowSize;
2159
+ fileSize;
2160
+ crc32;
2161
+ constructor(data) {
2162
+ super(data);
2163
+ const dataView = PacketView.fromPacket(this);
2164
+ this.windowSize = dataView.nextUint16();
2165
+ this.fileSize = dataView.nextUint32();
2166
+ this.crc32 = dataView.nextUint32();
2167
+ }
2168
+ }
2169
+
2170
+ class ExitFileTransferReplyD2HPacket extends HostBoundPacket {
2171
+ static COMMAND_ID = 86;
2172
+ static COMMAND_EXTENDED_ID = 18;
2173
+ }
2174
+
2175
+ class WriteFileReplyD2HPacket extends HostBoundPacket {
2176
+ static COMMAND_ID = 86;
2177
+ static COMMAND_EXTENDED_ID = 19;
2178
+ }
2179
+
2180
+ class ReadFileReplyD2HPacket extends HostBoundPacket {
2181
+ static COMMAND_ID = 86;
2182
+ static COMMAND_EXTENDED_ID = 20;
2183
+ addr;
2184
+ length;
2185
+ buf;
2186
+ constructor(data) {
2187
+ super(data);
2188
+ const dataView = PacketView.fromPacket(this);
2189
+ let n = this.ackIndex;
2190
+ this.addr = dataView.getUint32(n, true);
2191
+ this.length = this.payloadSize - 7;
2192
+ this.buf = this.data.slice(n + 4, n + 4 + this.length);
2193
+ }
2194
+ static isValidPacket(data, n) {
2195
+ return data[4] === 4 ? data[n + 1] === 118 /* CDC2_ACK */ : true;
2196
+ }
2197
+ }
2198
+
2199
+ class LinkFileReplyD2HPacket extends HostBoundPacket {
2200
+ static COMMAND_ID = 86;
2201
+ static COMMAND_EXTENDED_ID = 21;
2202
+ }
2203
+
2204
+ class GetDirectoryFileCountReplyD2HPacket extends HostBoundPacket {
2205
+ static COMMAND_ID = 86;
2206
+ static COMMAND_EXTENDED_ID = 22;
2207
+ count;
2208
+ constructor(data) {
2209
+ super(data);
2210
+ const dataView = PacketView.fromPacket(this);
2211
+ this.count = dataView.nextUint16();
2212
+ }
2213
+ }
2214
+
2215
+ class GetDirectoryEntryReplyD2HPacket extends HostBoundPacket {
2216
+ static COMMAND_ID = 86;
2217
+ static COMMAND_EXTENDED_ID = 23;
2218
+ file;
2219
+ constructor(data) {
2220
+ super(data);
2221
+ const dataView = PacketView.fromPacket(this);
2222
+ if (this.payloadSize > 4) {
2223
+ this.file = {
2224
+ index: dataView.nextUint8(),
2225
+ size: dataView.nextUint32(),
2226
+ loadAddress: dataView.nextUint32(),
2227
+ crc32: dataView.nextUint32(),
2228
+ type: dataView.nextString(4),
2229
+ timestamp: dataView.nextUint32() + PacketEncoder.J2000_EPOCH,
2230
+ version: dataView.nextVersion(),
2231
+ filename: dataView.nextNTBS(32)
2232
+ };
2233
+ }
2234
+ }
2235
+ }
2236
+
2237
+ class LoadFileActionReplyD2HPacket extends HostBoundPacket {
2238
+ static COMMAND_ID = 86;
2239
+ static COMMAND_EXTENDED_ID = 24;
2240
+ }
2241
+
2242
+ class GetFileMetadataReplyD2HPacket extends HostBoundPacket {
2243
+ static COMMAND_ID = 86;
2244
+ static COMMAND_EXTENDED_ID = 25;
2245
+ file;
2246
+ constructor(data) {
2247
+ super(data);
2248
+ const dataView = PacketView.fromPacket(this);
2249
+ dataView.nextUint8();
2250
+ if (this.payloadSize > 4) {
2251
+ this.file = {
2252
+ size: dataView.nextUint32(),
2253
+ loadAddress: dataView.nextUint32(),
2254
+ crc32: dataView.nextUint32(),
2255
+ type: dataView.nextString(4),
2256
+ timestamp: dataView.nextUint32() + PacketEncoder.J2000_EPOCH,
2257
+ version: dataView.nextVersion()
2258
+ };
2259
+ }
2260
+ }
2261
+ }
2262
+
2263
+ class SetFileMetadataReplyD2HPacket extends HostBoundPacket {
2264
+ static COMMAND_ID = 86;
2265
+ static COMMAND_EXTENDED_ID = 26;
2266
+ }
2267
+
2268
+ class EraseFileReplyD2HPacket extends HostBoundPacket {
2269
+ static COMMAND_ID = 86;
2270
+ static COMMAND_EXTENDED_ID = 27;
2271
+ }
2272
+
2273
+ class GetProgramSlotInfoReplyD2HPacket extends HostBoundPacket {
2274
+ static COMMAND_ID = 86;
2275
+ static COMMAND_EXTENDED_ID = 28;
2276
+ requestedSlot;
2277
+ slot;
2278
+ constructor(data) {
2279
+ super(data);
2280
+ const dataView = PacketView.fromPacket(this);
2281
+ this.slot = dataView.nextUint8();
2282
+ this.requestedSlot = dataView.nextUint8();
2283
+ }
2284
+ }
2285
+
2286
+ class FileClearUpReplyD2HPacket extends HostBoundPacket {
2287
+ static COMMAND_ID = 86;
2288
+ static COMMAND_EXTENDED_ID = 30;
2289
+ }
2290
+
2291
+ class FileFormatReplyD2HPacket extends HostBoundPacket {
2292
+ static COMMAND_ID = 86;
2293
+ static COMMAND_EXTENDED_ID = 31;
2294
+ }
2295
+
2296
+ class GetSystemFlagsReplyD2HPacket extends HostBoundPacket {
2297
+ static COMMAND_ID = 86;
2298
+ static COMMAND_EXTENDED_ID = 32;
2299
+ flags;
2300
+ radioSearching;
2301
+ radioQuality;
2302
+ controllerBatteryPercent;
2303
+ partnerControllerBatteryPercent;
2304
+ battery;
2305
+ currentProgram;
2306
+ constructor(data) {
2307
+ super(data);
2308
+ const dataView = PacketView.fromPacket(this);
2309
+ this.radioSearching = false;
2310
+ this.currentProgram = 0;
2311
+ this.flags = dataView.nextUint32();
2312
+ let hasPartner = (8192 & this.flags) !== 0;
2313
+ let hasRadio = (1536 & this.flags) === 1536;
2314
+ let byte1 = dataView.nextUint8(), byte2 = dataView.nextUint8();
2315
+ if (this.payloadSize === 11) {
2316
+ this.battery = 8 * (byte1 & 15);
2317
+ if ((this.flags & 256) !== 0 || hasRadio)
2318
+ this.controllerBatteryPercent = 8 * (byte1 >> 4 & 15);
2319
+ if (hasRadio)
2320
+ this.radioQuality = 8 * (byte2 & 15);
2321
+ this.radioSearching = (this.flags & 1536) === 512;
2322
+ if (hasPartner)
2323
+ this.partnerControllerBatteryPercent = 8 * (byte2 >> 4 & 15);
2324
+ this.currentProgram = dataView.nextUint8();
2325
+ if (this.battery && this.battery > 100)
2326
+ this.battery = 100;
2327
+ if (this.controllerBatteryPercent && this.controllerBatteryPercent > 100)
2328
+ this.controllerBatteryPercent = 100;
2329
+ if (this.radioQuality && this.radioQuality > 100)
2330
+ this.radioQuality = 100;
2331
+ if (this.partnerControllerBatteryPercent && this.partnerControllerBatteryPercent > 100)
2332
+ this.partnerControllerBatteryPercent = 100;
2333
+ }
2334
+ }
2335
+ }
2336
+
2337
+ class GetDeviceStatusReplyD2HPacket extends HostBoundPacket {
2338
+ static COMMAND_ID = 86;
2339
+ static COMMAND_EXTENDED_ID = 33;
2340
+ count;
2341
+ devices;
2342
+ constructor(data) {
2343
+ super(data);
2344
+ const dataView = PacketView.fromPacket(this);
2345
+ this.count = dataView.nextUint8();
2346
+ this.devices = [];
2347
+ for (let i = 0;i < this.count; i++) {
2348
+ this.devices.push({
2349
+ port: dataView.nextUint8(),
2350
+ type: dataView.nextUint8(),
2351
+ status: dataView.nextUint8(),
2352
+ betaversion: dataView.nextUint8(),
2353
+ version: dataView.nextUint16(),
2354
+ bootversion: dataView.nextUint16()
2355
+ });
2356
+ }
2357
+ }
2358
+ }
2359
+
2360
+ class GetSystemStatusReplyD2HPacket extends HostBoundPacket {
2361
+ static COMMAND_ID = 86;
2362
+ static COMMAND_EXTENDED_ID = 34;
2363
+ systemVersion;
2364
+ cpu0Version;
2365
+ cpu1Version;
2366
+ nxpVersion;
2367
+ touchVersion;
2368
+ uniqueId;
2369
+ sysflags;
2370
+ eventBrain;
2371
+ romBootloaderActive;
2372
+ ramBootloaderActive;
2373
+ goldenVersion;
2374
+ constructor(data) {
2375
+ super(data);
2376
+ const dataView = PacketView.fromPacket(this);
2377
+ dataView.nextUint8();
2378
+ this.systemVersion = dataView.nextVersion();
2379
+ this.cpu0Version = dataView.nextVersion();
2380
+ this.cpu1Version = dataView.nextVersion();
2381
+ this.touchVersion = dataView.nextVersion(true);
2382
+ this.uniqueId = 1234;
2383
+ this.sysflags = [0, 0, 0, 0, 0, 0, 0];
2384
+ this.goldenVersion = VexFirmwareVersion.allZero();
2385
+ this.nxpVersion = VexFirmwareVersion.allZero();
2386
+ this.eventBrain = false;
2387
+ this.romBootloaderActive = false;
2388
+ this.ramBootloaderActive = false;
2389
+ if (this.payloadSize > 25) {
2390
+ this.uniqueId = dataView.nextUint32();
2391
+ this.sysflags = [
2392
+ dataView.nextUint8(),
2393
+ dataView.nextUint8(),
2394
+ dataView.nextUint8(),
2395
+ dataView.nextUint8(),
2396
+ dataView.nextUint8(),
2397
+ 0,
2398
+ dataView.nextUint8()
2399
+ ];
2400
+ this.eventBrain = (1 & this.sysflags[6]) !== 0;
2401
+ this.romBootloaderActive = (2 & this.sysflags[6]) !== 0;
2402
+ this.ramBootloaderActive = (4 & this.sysflags[6]) !== 0;
2403
+ dataView.nextUint16();
2404
+ this.goldenVersion = dataView.nextVersion();
2405
+ }
2406
+ if (this.payloadSize > 37) {
2407
+ this.nxpVersion = dataView.nextVersion();
2408
+ }
2409
+ }
2410
+ }
2411
+
2412
+ class GetFdtStatusReplyD2HPacket extends HostBoundPacket {
2413
+ static COMMAND_ID = 86;
2414
+ static COMMAND_EXTENDED_ID = 35;
2415
+ count;
2416
+ status;
2417
+ constructor(data) {
2418
+ super(data);
2419
+ const dataView = PacketView.fromPacket(this);
2420
+ this.count = dataView.nextUint8();
2421
+ this.status = [];
2422
+ for (let i = 0;i < this.count; i++) {
2423
+ this.status.push({
2424
+ index: dataView.nextUint8(),
2425
+ type: dataView.nextUint8(),
2426
+ status: dataView.nextUint8(),
2427
+ betaversion: dataView.nextUint8(),
2428
+ version: dataView.nextUint16(),
2429
+ bootversion: dataView.nextUint16()
2430
+ });
2431
+ }
2432
+ }
2433
+ }
2434
+
2435
+ class GetLogCountReplyD2HPacket extends HostBoundPacket {
2436
+ static COMMAND_ID = 86;
2437
+ static COMMAND_EXTENDED_ID = 36;
2438
+ count;
2439
+ constructor(data) {
2440
+ super(data);
2441
+ const dataView = PacketView.fromPacket(this);
2442
+ dataView.nextUint8();
2443
+ this.count = dataView.nextUint32();
2444
+ }
2445
+ }
2446
+
2447
+ class ReadLogPageReplyD2HPacket extends HostBoundPacket {
2448
+ static COMMAND_ID = 86;
2449
+ static COMMAND_EXTENDED_ID = 37;
2450
+ offset;
2451
+ count;
2452
+ entries;
2453
+ constructor(data) {
2454
+ super(data);
2455
+ const dataView = PacketView.fromPacket(this);
2456
+ let n = this.ackIndex;
2457
+ let size = dataView.nextUint8();
2458
+ this.offset = dataView.nextUint32();
2459
+ this.count = dataView.nextUint16();
2460
+ this.entries = [];
2461
+ let j = n + 8;
2462
+ for (let i = 0;i < this.count; i++) {
2463
+ this.entries.push({
2464
+ code: dataView.getUint8(j),
2465
+ type: dataView.getUint8(j + 1),
2466
+ desc: dataView.getUint8(j + 2),
2467
+ spare: dataView.getUint8(j + 3),
2468
+ time: dataView.getUint32(j + 4, true)
2469
+ });
2470
+ j += size;
2471
+ }
2472
+ }
2473
+ }
2474
+
2475
+ class GetRadioStatusReplyD2HPacket extends HostBoundPacket {
2476
+ static COMMAND_ID = 86;
2477
+ static COMMAND_EXTENDED_ID = 38;
2478
+ device;
2479
+ quality;
2480
+ strength;
2481
+ channel;
2482
+ timeslot;
2483
+ constructor(data) {
2484
+ super(data);
2485
+ const dataView = PacketView.fromPacket(this);
2486
+ let n = this.ackIndex;
2487
+ this.device = dataView.nextUint8();
2488
+ this.quality = dataView.nextUint16();
2489
+ this.strength = dataView.nextInt16();
2490
+ this.channel = this.data[n + 6];
2491
+ this.timeslot = this.data[n + 7];
2492
+ }
2493
+ }
2494
+
2495
+ class GetUserDataReplyD2HPacket extends HostBoundPacket {
2496
+ static COMMAND_ID = 86;
2497
+ static COMMAND_EXTENDED_ID = 39;
2498
+ }
2499
+
2500
+ class ScreenCaptureReplyD2HPacket extends HostBoundPacket {
2501
+ static COMMAND_ID = 86;
2502
+ static COMMAND_EXTENDED_ID = 40;
2503
+ }
2504
+
2505
+ class SendDashTouchReplyD2HPacket extends HostBoundPacket {
2506
+ static COMMAND_ID = 86;
2507
+ static COMMAND_EXTENDED_ID = 42;
2508
+ }
2509
+
2510
+ class SelectDashReplyD2HPacket extends HostBoundPacket {
2511
+ static COMMAND_ID = 86;
2512
+ static COMMAND_EXTENDED_ID = 43;
2513
+ }
2514
+
2515
+ class EnableDeshReplyD2HPacket extends HostBoundPacket {
2516
+ static COMMAND_ID = 86;
2517
+ static COMMAND_EXTENDED_ID = 44;
2518
+ }
2519
+
2520
+ class DisableDeshReplyD2HPacket extends HostBoundPacket {
2521
+ static COMMAND_ID = 86;
2522
+ static COMMAND_EXTENDED_ID = 45;
2523
+ }
2524
+
2525
+ class ReadKeyValueReplyD2HPacket extends HostBoundPacket {
2526
+ static COMMAND_ID = 86;
2527
+ static COMMAND_EXTENDED_ID = 46;
2528
+ value;
2529
+ constructor(data) {
2530
+ super(data);
2531
+ const dataView = PacketView.fromPacket(this);
2532
+ this.value = dataView.nextVarNTBS(255);
2533
+ }
2534
+ }
2535
+
2536
+ class WriteKeyValueReplyD2HPacket extends HostBoundPacket {
2537
+ static COMMAND_ID = 86;
2538
+ static COMMAND_EXTENDED_ID = 47;
2539
+ }
2540
+
2541
+ class GetSlot1to4InfoReplyD2HPacket extends HostBoundPacket {
2542
+ static COMMAND_ID = 86;
2543
+ static COMMAND_EXTENDED_ID = 49;
2544
+ slotFlags;
2545
+ slots;
2546
+ constructor(data, start = 1) {
2547
+ super(data);
2548
+ const dataView = PacketView.fromPacket(this);
2549
+ this.slotFlags = dataView.nextUint8();
2550
+ this.slots = [];
2551
+ for (let i = 0;i < 4; i++) {
2552
+ let hasData = (this.slotFlags & Math.pow(2, start - 1 + i)) !== 0;
2553
+ if (!hasData)
2554
+ continue;
2555
+ let iconNum = dataView.nextUint16();
2556
+ let nameLen = dataView.nextUint8();
2557
+ let name = dataView.nextString(nameLen);
2558
+ this.slots.push({
2559
+ slot: start + i,
2560
+ icon: iconNum,
2561
+ name
2562
+ });
2563
+ }
2564
+ }
2565
+ }
2566
+
2567
+ class GetSlot5to8InfoReplyD2HPacket extends GetSlot1to4InfoReplyD2HPacket {
2568
+ static COMMAND_ID = 86;
2569
+ static COMMAND_EXTENDED_ID = 50;
2570
+ slotStartIndex = 5;
2571
+ constructor(data) {
2572
+ super(data, 5);
2573
+ }
2574
+ }
2575
+
2576
+ class FactoryStatusReplyD2HPacket extends HostBoundPacket {
2577
+ static COMMAND_ID = 86;
2578
+ static COMMAND_EXTENDED_ID = 241;
2579
+ status;
2580
+ percent;
2581
+ constructor(data) {
2582
+ super(data);
2583
+ const dataView = PacketView.fromPacket(this);
2584
+ this.status = dataView.nextUint8();
2585
+ this.percent = dataView.nextUint8();
2586
+ }
2587
+ }
2588
+
2589
+ class FactoryEnableReplyD2HPacket extends HostBoundPacket {
2590
+ static COMMAND_ID = 86;
2591
+ static COMMAND_EXTENDED_ID = 255;
2592
+ }
2593
+
2594
+ // ../serial/src/vex-connection.ts
2595
+ var thePacketEncoder = PacketEncoder.getInstance();
2596
+
2597
+ class VexSerialConnection extends VexEventTarget {
2598
+ filters = [{ usbVendorId: 10376 }];
2599
+ writer;
2600
+ reader;
2601
+ port;
2602
+ serial;
2603
+ isClosing = false;
2604
+ callbacksQueue = [];
2605
+ get isConnected() {
2606
+ return this.port && this.reader && this.writer ? true : false;
2607
+ }
2608
+ constructor(serial2) {
2609
+ super();
2610
+ this.serial = serial2;
2611
+ }
2612
+ async close() {
2613
+ if (this.isClosing)
2614
+ return;
2615
+ if (!this.isConnected)
2616
+ return;
2617
+ this.isClosing = true;
2618
+ for (const callbackInfo of this.callbacksQueue) {
2619
+ clearTimeout(callbackInfo.timeout);
2620
+ }
2621
+ this.callbacksQueue = [];
2622
+ try {
2623
+ await this.writer?.close();
2624
+ this.writer = undefined;
2625
+ } catch (e) {}
2626
+ try {
2627
+ await this.reader?.cancel();
2628
+ try {
2629
+ while (this.reader) {
2630
+ const { value, done } = await this.reader.read();
2631
+ if (done)
2632
+ break;
2633
+ }
2634
+ } catch (e) {}
2635
+ this.reader = undefined;
2636
+ } catch (e) {}
2637
+ try {
2638
+ await new Promise((resolve) => setTimeout(resolve, 1));
2639
+ await this.port?.close();
2640
+ this.port = undefined;
2641
+ } catch (e) {
2642
+ console.warn("Close port error.", e);
2643
+ } finally {
2644
+ this.isClosing = false;
2645
+ this.emit("disconnected", undefined);
2646
+ }
2647
+ }
2648
+ async open(use = 0, askUser = true) {
2649
+ if (this.port)
2650
+ throw new Error("Already connected.");
2651
+ let port;
2652
+ if (use !== undefined) {
2653
+ let ports = (await this.serial.getPorts()).filter((p) => {
2654
+ let info = p.getInfo();
2655
+ return this.filters.find((f) => (f.usbVendorId === undefined || f.usbVendorId === info.usbVendorId) && (f.usbProductId === undefined || f.usbProductId === info.usbProductId));
2656
+ }).filter((e) => !e.readable);
2657
+ port = ports[use];
2658
+ }
2659
+ if (!port && askUser) {
2660
+ try {
2661
+ port = await this.serial.requestPort({ filters: this.filters });
2662
+ } catch (e) {
2663
+ throw new Error("No valid port selected.");
2664
+ }
2665
+ }
2666
+ if (!port)
2667
+ return;
2668
+ if (port.readable)
2669
+ return false;
2670
+ try {
2671
+ await port.open({ baudRate: 115200 });
2672
+ this.port = port;
2673
+ this.port.addEventListener("disconnect", async () => {
2674
+ await this.close();
2675
+ });
2676
+ this.emit("connected", undefined);
2677
+ this.writer = this.port.writable.getWriter();
2678
+ this.reader = this.port.readable.getReader();
2679
+ this.startReader();
2680
+ return true;
2681
+ } catch (e) {
2682
+ return false;
2683
+ }
2684
+ }
2685
+ writeData(rawData, resolve, timeout = 1000) {
2686
+ this.writeDataAsync(rawData, timeout).then(resolve);
2687
+ }
2688
+ writeDataAsync(rawData, timeout = 1000) {
2689
+ return new Promise(async (done) => {
2690
+ if (this.writer === undefined) {
2691
+ done(255 /* CDC2_NACK */);
2692
+ return;
2693
+ }
2694
+ let data = rawData instanceof DeviceBoundPacket ? rawData.data : rawData;
2695
+ let cb = {
2696
+ callback: done,
2697
+ timeout: setTimeout(() => {
2698
+ this.callbacksQueue.shift()?.callback(256 /* TIMEOUT */);
2699
+ }, timeout),
2700
+ wantedCommandId: rawData instanceof DeviceBoundPacket ? rawData.constructor.COMMAND_ID : undefined,
2701
+ wantedCommandExId: rawData instanceof DeviceBoundPacket ? rawData.constructor.COMMAND_EXTENDED_ID : undefined
2702
+ };
2703
+ this.callbacksQueue.push(cb);
2704
+ try {
2705
+ this.writer.write(data).then(() => {
2706
+ logData(data, 100);
2707
+ });
2708
+ } catch (error) {
2709
+ this.callbacksQueue.splice(this.callbacksQueue.indexOf(cb), 1);
2710
+ done(257 /* WRITE_ERROR */);
2711
+ return;
2712
+ }
2713
+ });
2714
+ }
2715
+ async readData(cache, expectedSize) {
2716
+ if (!this.reader)
2717
+ throw new Error("No reader");
2718
+ while (cache.byteLength < expectedSize) {
2719
+ const { value: readData, done: isDone } = await this.reader.read();
2720
+ if (isDone)
2721
+ throw new Error("No data");
2722
+ cache = binaryArrayJoin(cache, readData);
2723
+ }
2724
+ return cache;
2725
+ }
2726
+ async startReader() {
2727
+ let cache = new Uint8Array([]), sliceIdx = 0;
2728
+ for (;; )
2729
+ try {
2730
+ cache = await this.readData(cache, 5);
2731
+ sliceIdx = 0;
2732
+ if (!thePacketEncoder.validateHeader(cache))
2733
+ throw new Error("Invalid header");
2734
+ const payloadExpectedSize = thePacketEncoder.getPayloadSize(cache);
2735
+ const n = payloadExpectedSize > 128 ? 5 : 4;
2736
+ const totalSize = n + payloadExpectedSize;
2737
+ cache = await this.readData(cache, totalSize);
2738
+ sliceIdx = totalSize + 1;
2739
+ const cmdId = cache[2];
2740
+ const hasExtId = cmdId == 88 || cmdId == 86;
2741
+ const cmdExId = hasExtId ? cache[n] : undefined;
2742
+ const ack = cache[n + 1];
2743
+ if (hasExtId) {
2744
+ if (!thePacketEncoder.validateMessageCdc(cache))
2745
+ throw new Error("Invalid message CDC");
2746
+ }
2747
+ let callbackInfo;
2748
+ let wantedCmdId;
2749
+ let wantedCmdExId;
2750
+ let tryIdx = 0;
2751
+ while (callbackInfo = this.callbacksQueue[tryIdx++]) {
2752
+ wantedCmdId = callbackInfo?.wantedCommandId;
2753
+ wantedCmdExId = callbackInfo?.wantedCommandExId;
2754
+ if (wantedCmdId !== undefined && wantedCmdId !== cmdId || wantedCmdExId !== undefined && wantedCmdExId !== cmdExId) {
2755
+ continue;
2756
+ }
2757
+ break;
2758
+ }
2759
+ if (callbackInfo === undefined) {
2760
+ console.warn("Unexpected command", cmdId, cmdExId, ack);
2761
+ continue;
2762
+ }
2763
+ let data = cache.slice(0, sliceIdx);
2764
+ let packageType = thePacketEncoder.allPacketsTable[wantedCmdId + " " + wantedCmdExId];
2765
+ if (wantedCmdId === undefined && wantedCmdExId === undefined || packageType === undefined) {
2766
+ callbackInfo.callback(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength));
2767
+ } else {
2768
+ if (!hasExtId || packageType.isValidPacket(data, n)) {
2769
+ callbackInfo.callback(new packageType(data));
2770
+ } else {
2771
+ console.warn("ack", ack);
2772
+ callbackInfo.callback(ack);
2773
+ }
2774
+ }
2775
+ clearTimeout(callbackInfo.timeout);
2776
+ this.callbacksQueue.splice(tryIdx - 1, 1);
2777
+ } catch (e) {
2778
+ if (this.isClosing)
2779
+ break;
2780
+ console.warn("Read error.", e, cache);
2781
+ await this.close();
2782
+ break;
2783
+ } finally {
2784
+ cache = cache.slice(sliceIdx);
2785
+ }
2786
+ }
2787
+ async query1() {
2788
+ let result = await this.writeDataAsync(new Query1H2DPacket, 100);
2789
+ return result instanceof Query1ReplyD2HPacket ? result : null;
2790
+ }
2791
+ async getSystemVersion() {
2792
+ let result = await this.writeDataAsync(new SystemVersionH2DPacket);
2793
+ return result instanceof SystemVersionReplyD2HPacket ? result.version : null;
2794
+ }
2795
+ }
2796
+
2797
+ class V5SerialConnection extends VexSerialConnection {
2798
+ filters = [
2799
+ { usbVendorId: 10376, usbProductId: 1281 /* V5_BRAIN */ },
2800
+ { usbVendorId: 10376, usbProductId: 1282 /* V5_BRAIN_DFU */ },
2801
+ { usbVendorId: 10376, usbProductId: 1283 /* V5_CONTROLLER */ }
2802
+ ];
2803
+ async getDeviceStatus() {
2804
+ let result = await this.writeDataAsync(new GetDeviceStatusH2DPacket);
2805
+ return result instanceof GetDeviceStatusReplyD2HPacket ? result : null;
2806
+ }
2807
+ async getRadioStatus() {
2808
+ let result = await this.writeDataAsync(new GetRadioStatusH2DPacket);
2809
+ return result instanceof GetRadioStatusReplyD2HPacket ? result : null;
2810
+ }
2811
+ async getSystemFlags() {
2812
+ let result = await this.writeDataAsync(new GetSystemFlagsH2DPacket);
2813
+ return result instanceof GetSystemFlagsReplyD2HPacket ? result : null;
2814
+ }
2815
+ async getSystemStatus(timeout = 1000) {
2816
+ let result = await this.writeDataAsync(new GetSystemStatusH2DPacket, timeout);
2817
+ return result instanceof GetSystemStatusReplyD2HPacket ? result : null;
2818
+ }
2819
+ async getMatchStatus() {
2820
+ let result = await this.writeDataAsync(new GetMatchStatusH2DPacket);
2821
+ return result instanceof MatchStatusReplyD2HPacket ? result : null;
2822
+ }
2823
+ async uploadProgramToDevice(iniConfig, binFileBuf, coldFileBuf, progressCallback) {
2824
+ let iniFileBuffer = new TextEncoder().encode(iniConfig.createIni());
2825
+ let basename = iniConfig.baseName;
2826
+ let iniRequest = {
2827
+ filename: basename + ".ini",
2828
+ buf: iniFileBuffer,
2829
+ downloadTarget: 1 /* FILE_TARGET_QSPI */,
2830
+ vid: 1 /* USER */,
2831
+ autoRun: false
2832
+ };
2833
+ let r1 = await this.uploadFileToDevice(iniRequest, (current, total) => progressCallback("INI", current, total));
2834
+ if (!r1)
2835
+ return false;
2836
+ let coldRequest = coldFileBuf !== undefined ? {
2837
+ filename: basename + "_lib.bin",
2838
+ buf: coldFileBuf,
2839
+ downloadTarget: 1 /* FILE_TARGET_QSPI */,
2840
+ vid: 24,
2841
+ autoRun: false
2842
+ } : undefined;
2843
+ if (coldRequest) {
2844
+ let r2 = await this.uploadFileToDevice(coldRequest, (current, total) => progressCallback("COLD", current, total));
2845
+ if (!r2)
2846
+ return;
2847
+ }
2848
+ let binRequest = {
2849
+ filename: basename + ".bin",
2850
+ buf: binFileBuf,
2851
+ downloadTarget: 1 /* FILE_TARGET_QSPI */,
2852
+ vid: 1 /* USER */,
2853
+ loadAddress: coldFileBuf ? 125829120 : undefined,
2854
+ autoRun: iniConfig.autorun,
2855
+ linkedFile: coldRequest
2856
+ };
2857
+ let r3 = await this.uploadFileToDevice(binRequest, (current, total) => progressCallback("BIN", current, total));
2858
+ return r3;
2859
+ }
2860
+ async downloadFileToHost(request, downloadTarget = 1 /* FILE_TARGET_QSPI */, progressCallback) {
2861
+ let { filename, vendor, loadAddress, size } = request;
2862
+ let nextAddress = loadAddress ?? USER_FLASH_USR_CODE_START;
2863
+ let p1 = await this.writeDataAsync(new InitFileTransferH2DPacket(2 /* READ */, downloadTarget, vendor, 0 /* NONE */, new Uint8Array, nextAddress, filename, ""));
2864
+ if (!(p1 instanceof InitFileTransferReplyD2HPacket))
2865
+ throw new Error("InitFileTransferH2DPacket failed");
2866
+ let fileSize = size ?? p1.fileSize;
2867
+ let bufferChunkSize = p1.windowSize > 0 && p1.windowSize <= USER_PROG_CHUNK_SIZE ? p1.windowSize : USER_PROG_CHUNK_SIZE;
2868
+ let bufferOffset = 0;
2869
+ let fileBuf = new Uint8Array(fileSize + bufferChunkSize);
2870
+ let lastBlock = false;
2871
+ while (!lastBlock) {
2872
+ if (fileSize <= bufferOffset + bufferChunkSize) {
2873
+ lastBlock = true;
2874
+ }
2875
+ let p2 = await this.writeDataAsync(new ReadFileH2DPacket(nextAddress, bufferChunkSize), 3000);
2876
+ if (!(p2 instanceof ReadFileReplyD2HPacket))
2877
+ throw new Error("ReadFileReplyD2HPacket failed");
2878
+ fileBuf.set(new Uint8Array(p2.buf), bufferOffset);
2879
+ if (progressCallback)
2880
+ progressCallback(bufferOffset, fileSize);
2881
+ bufferOffset += bufferChunkSize;
2882
+ nextAddress += bufferChunkSize;
2883
+ }
2884
+ let p3 = await this.writeDataAsync(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */), 30000);
2885
+ fileBuf = fileBuf.slice(0, fileSize);
2886
+ return fileBuf;
2887
+ }
2888
+ async uploadFileToDevice(request, progressCallback) {
2889
+ let {
2890
+ filename,
2891
+ buf,
2892
+ downloadTarget,
2893
+ vendor,
2894
+ loadAddress,
2895
+ exttype,
2896
+ autoRun,
2897
+ linkedFile
2898
+ } = request;
2899
+ if (buf === undefined) {
2900
+ return false;
2901
+ }
2902
+ downloadTarget = downloadTarget ?? 1 /* FILE_TARGET_QSPI */;
2903
+ vendor = vendor ?? 1 /* USER */;
2904
+ let nextAddress = loadAddress ?? USER_FLASH_USR_CODE_START;
2905
+ console.log("init file transfer", filename);
2906
+ let p1 = await this.writeDataAsync(new InitFileTransferH2DPacket(1 /* WRITE */, downloadTarget, vendor, 1 /* OVERWRITE */, buf, nextAddress, filename, exttype));
2907
+ if (!(p1 instanceof InitFileTransferReplyD2HPacket))
2908
+ throw new Error("InitFileTransferH2DPacket failed");
2909
+ console.log(p1);
2910
+ if (linkedFile !== undefined) {
2911
+ let p3 = await this.writeDataAsync(new LinkFileH2DPacket(linkedFile.vendor ?? 1 /* USER */, linkedFile.filename, 0), 1e4);
2912
+ if (!(p3 instanceof LinkFileReplyD2HPacket))
2913
+ throw new Error("LinkFileH2DPacket failed");
2914
+ }
2915
+ let bufferChunkSize = p1.windowSize > 0 && p1.windowSize <= USER_PROG_CHUNK_SIZE ? p1.windowSize : USER_PROG_CHUNK_SIZE;
2916
+ let bufferOffset = 0;
2917
+ let lastBlock = false;
2918
+ while (!lastBlock) {
2919
+ var tmpbuf;
2920
+ if (buf.byteLength - bufferOffset > bufferChunkSize) {
2921
+ tmpbuf = buf.subarray(bufferOffset, bufferOffset + bufferChunkSize);
2922
+ } else {
2923
+ let length = (buf.byteLength - bufferOffset + 3) / 4 >>> 0;
2924
+ tmpbuf = new Uint8Array(length * 4);
2925
+ tmpbuf.set(buf.subarray(bufferOffset, buf.byteLength));
2926
+ lastBlock = true;
2927
+ }
2928
+ let p2 = await this.writeDataAsync(new WriteFileH2DPacket(nextAddress, tmpbuf), 3000);
2929
+ if (!(p2 instanceof WriteFileReplyD2HPacket))
2930
+ throw new Error("WriteFileReplyD2HPacket failed");
2931
+ if (progressCallback)
2932
+ progressCallback(bufferOffset, buf.byteLength);
2933
+ bufferOffset += bufferChunkSize;
2934
+ nextAddress += bufferChunkSize;
2935
+ }
2936
+ let p4 = await this.writeDataAsync(new ExitFileTransferH2DPacket(autoRun ? 1 /* EXIT_RUN */ : 3 /* EXIT_HALT */), 30000);
2937
+ return p4 instanceof ExitFileTransferReplyD2HPacket;
2938
+ }
2939
+ async setMatchMode(mode) {
2940
+ let result = await this.writeDataAsync(new UpdateMatchModeH2DPacket(mode, 0));
2941
+ return result instanceof MatchModeReplyD2HPacket ? result : null;
2942
+ }
2943
+ async loadProgram(value) {
2944
+ let result = await this.writeDataAsync(new LoadFileActionH2DPacket(1 /* USER */, 0 /* RUN */, value));
2945
+ return result instanceof LoadFileActionReplyD2HPacket ? result : null;
2946
+ }
2947
+ async stopProgram() {
2948
+ let result = await this.writeDataAsync(new LoadFileActionH2DPacket(1 /* USER */, 128 /* STOP */, ""));
2949
+ return result instanceof LoadFileActionReplyD2HPacket ? result : null;
2950
+ }
2951
+ async mockTouch(x, y, press) {
2952
+ let result = await this.writeDataAsync(new SendDashTouchH2DPacket(x, y, press));
2953
+ return result instanceof SendDashTouchReplyD2HPacket ? result : null;
2954
+ }
2955
+ }
2956
+ function logData(data, limitedSize) {
2957
+ if (data === undefined)
2958
+ return;
2959
+ limitedSize || (limitedSize = data.length);
2960
+ let a = "";
2961
+ for (let n = 0;n < data.length && n < limitedSize; n++)
2962
+ a += ("00" + data[n].toString(16)).substr(-2, 2) + " ";
2963
+ limitedSize < data.length && (a += " ... ");
2964
+ }
2965
+ function binaryArrayJoin(left, right) {
2966
+ const leftSize = left ? left.byteLength : 0;
2967
+ const rightSize = right ? right.byteLength : 0;
2968
+ const all = new Uint8Array(leftSize + rightSize);
2969
+ return all.length === 0 ? new Uint8Array : (left && all.set(left instanceof Uint8Array ? left : new Uint8Array(left), 0), right && all.set(right instanceof Uint8Array ? right : new Uint8Array(right), leftSize), all);
2970
+ }
2971
+ // ../../node_modules/.bun/unzipit@2.0.1/node_modules/unzipit/dist/unzipit.module.js
2972
+ var _a;
2973
+ var _b;
2974
+ function readBlobAsArrayBuffer(blob) {
2975
+ if (blob.arrayBuffer) {
2976
+ return blob.arrayBuffer();
2977
+ }
2978
+ return new Promise((resolve, reject) => {
2979
+ const reader = new FileReader;
2980
+ reader.addEventListener("loadend", () => {
2981
+ resolve(reader.result);
2982
+ });
2983
+ reader.addEventListener("error", reject);
2984
+ reader.readAsArrayBuffer(blob);
2985
+ });
2986
+ }
2987
+ async function readBlobAsUint8Array(blob) {
2988
+ const arrayBuffer = await readBlobAsArrayBuffer(blob);
2989
+ return new Uint8Array(arrayBuffer);
2990
+ }
2991
+ function isBlob(v) {
2992
+ return typeof Blob !== "undefined" && v instanceof Blob;
2993
+ }
2994
+ function isSharedArrayBuffer(b) {
2995
+ return typeof SharedArrayBuffer !== "undefined" && b instanceof SharedArrayBuffer;
2996
+ }
2997
+ var isNode = typeof process !== "undefined" && !!(process === null || process === undefined ? undefined : process.versions) && typeof ((_a = process === null || process === undefined ? undefined : process.versions) === null || _a === undefined ? undefined : _a.node) !== "undefined" && typeof ((_b = process === null || process === undefined ? undefined : process.versions) === null || _b === undefined ? undefined : _b.electron) === "undefined";
2998
+ function isTypedArraySameAsArrayBuffer(typedArray) {
2999
+ return typedArray.byteOffset === 0 && typedArray.byteLength === typedArray.buffer.byteLength;
3000
+ }
3001
+
3002
+ class ArrayBufferReader {
3003
+ constructor(arrayBufferOrView) {
3004
+ this.typedArray = arrayBufferOrView instanceof ArrayBuffer || isSharedArrayBuffer(arrayBufferOrView) ? new Uint8Array(arrayBufferOrView) : new Uint8Array(arrayBufferOrView.buffer, arrayBufferOrView.byteOffset, arrayBufferOrView.byteLength);
3005
+ }
3006
+ async getLength() {
3007
+ return this.typedArray.byteLength;
3008
+ }
3009
+ async read(offset, length) {
3010
+ return new Uint8Array(this.typedArray.buffer, this.typedArray.byteOffset + offset, length);
3011
+ }
3012
+ }
3013
+
3014
+ class BlobReader {
3015
+ constructor(blob) {
3016
+ this.blob = blob;
3017
+ }
3018
+ async getLength() {
3019
+ return this.blob.size;
3020
+ }
3021
+ async read(offset, length) {
3022
+ const blob = this.blob.slice(offset, offset + length);
3023
+ const arrayBuffer = await readBlobAsArrayBuffer(blob);
3024
+ return new Uint8Array(arrayBuffer);
3025
+ }
3026
+ async sliceAsBlob(offset, length, type = "") {
3027
+ return this.blob.slice(offset, offset + length, type);
3028
+ }
3029
+ }
3030
+ var config = {
3031
+ numWorkers: 1,
3032
+ workerURL: "",
3033
+ useWorkers: false
3034
+ };
3035
+ var nextId = 0;
3036
+ var numWorkers = 0;
3037
+ var canUseWorkers = true;
3038
+ var workers = [];
3039
+ var availableWorkers = [];
3040
+ var waitingForWorkerQueue = [];
3041
+ var currentlyProcessingIdToRequestMap = new Map;
3042
+ function handleResult(e) {
3043
+ makeWorkerAvailable(e.target);
3044
+ const { id, error, data } = e.data;
3045
+ const request = currentlyProcessingIdToRequestMap.get(id);
3046
+ currentlyProcessingIdToRequestMap.delete(id);
3047
+ if (error) {
3048
+ request.reject(error);
3049
+ } else {
3050
+ request.resolve(data);
3051
+ }
3052
+ }
3053
+ function startWorker(url) {
3054
+ return new Promise((resolve, reject) => {
3055
+ const worker = new Worker(url);
3056
+ worker.onmessage = (e) => {
3057
+ if (e.data === "start") {
3058
+ worker.onerror = null;
3059
+ worker.onmessage = null;
3060
+ resolve(worker);
3061
+ } else {
3062
+ reject(new Error(`unexpected message: ${e.data}`));
3063
+ }
3064
+ };
3065
+ worker.onerror = reject;
3066
+ });
3067
+ }
3068
+ var workerHelper = function() {
3069
+ if (isNode) {
3070
+ return {
3071
+ async createWorker(url) {
3072
+ const moduleId = "node:worker_threads";
3073
+ const { Worker: Worker2 } = await import(moduleId);
3074
+ return new Worker2(url);
3075
+ },
3076
+ addEventListener(worker, fn) {
3077
+ worker.on("message", (data) => {
3078
+ fn({ target: worker, data });
3079
+ });
3080
+ },
3081
+ async terminate(worker) {
3082
+ await worker.terminate();
3083
+ }
3084
+ };
3085
+ } else {
3086
+ return {
3087
+ async createWorker(url) {
3088
+ try {
3089
+ const worker = await startWorker(url);
3090
+ return worker;
3091
+ } catch (_e) {
3092
+ console.warn("could not load worker:", url);
3093
+ }
3094
+ let text;
3095
+ try {
3096
+ const req = await fetch(url, { mode: "cors" });
3097
+ if (!req.ok) {
3098
+ throw new Error(`could not load: ${url}`);
3099
+ }
3100
+ text = await req.text();
3101
+ url = URL.createObjectURL(new Blob([text], { type: "application/javascript" }));
3102
+ const worker = await startWorker(url);
3103
+ config.workerURL = url;
3104
+ return worker;
3105
+ } catch (_e) {
3106
+ console.warn("could not load worker via fetch:", url);
3107
+ }
3108
+ if (text !== undefined) {
3109
+ try {
3110
+ url = `data:application/javascript;base64,${btoa(text)}`;
3111
+ const worker = await startWorker(url);
3112
+ config.workerURL = url;
3113
+ return worker;
3114
+ } catch (_e) {
3115
+ console.warn("could not load worker via dataURI");
3116
+ }
3117
+ }
3118
+ console.warn("workers will not be used");
3119
+ throw new Error("can not start workers");
3120
+ },
3121
+ addEventListener(worker, fn) {
3122
+ worker.addEventListener("message", fn);
3123
+ },
3124
+ async terminate(worker) {
3125
+ worker.terminate();
3126
+ }
3127
+ };
3128
+ }
3129
+ }();
3130
+ function makeWorkerAvailable(worker) {
3131
+ availableWorkers.push(worker);
3132
+ processWaitingForWorkerQueue();
3133
+ }
3134
+ async function getAvailableWorker() {
3135
+ if (availableWorkers.length === 0 && numWorkers < config.numWorkers) {
3136
+ ++numWorkers;
3137
+ try {
3138
+ const worker = await workerHelper.createWorker(config.workerURL);
3139
+ workers.push(worker);
3140
+ availableWorkers.push(worker);
3141
+ workerHelper.addEventListener(worker, handleResult);
3142
+ } catch (_e) {
3143
+ canUseWorkers = false;
3144
+ }
3145
+ }
3146
+ return availableWorkers.pop();
3147
+ }
3148
+ async function decompressRaw(src) {
3149
+ const ds = new DecompressionStream("deflate-raw");
3150
+ const writer = ds.writable.getWriter();
3151
+ writer.write(src).then(() => writer.close()).catch(() => {});
3152
+ const chunks = [];
3153
+ const reader = ds.readable.getReader();
3154
+ for (;; ) {
3155
+ const { done, value } = await reader.read();
3156
+ if (done) {
3157
+ break;
3158
+ }
3159
+ chunks.push(value);
3160
+ }
3161
+ const size = chunks.reduce((s, c) => s + c.byteLength, 0);
3162
+ const result = new Uint8Array(size);
3163
+ let offset = 0;
3164
+ for (const chunk of chunks) {
3165
+ result.set(chunk, offset);
3166
+ offset += chunk.byteLength;
3167
+ }
3168
+ return result;
3169
+ }
3170
+ async function inflateRawLocal(src, type, resolve, reject) {
3171
+ try {
3172
+ const dst = await decompressRaw(src);
3173
+ resolve(type ? new Blob([dst], { type }) : dst.buffer);
3174
+ } catch (e) {
3175
+ reject(e);
3176
+ }
3177
+ }
3178
+ async function processWaitingForWorkerQueue() {
3179
+ if (waitingForWorkerQueue.length === 0) {
3180
+ return;
3181
+ }
3182
+ if (config.useWorkers && canUseWorkers) {
3183
+ const worker = await getAvailableWorker();
3184
+ if (canUseWorkers) {
3185
+ if (worker) {
3186
+ if (waitingForWorkerQueue.length === 0) {
3187
+ makeWorkerAvailable(worker);
3188
+ return;
3189
+ }
3190
+ const { id, src, uncompressedSize, type, resolve, reject } = waitingForWorkerQueue.shift();
3191
+ currentlyProcessingIdToRequestMap.set(id, { id, src, uncompressedSize, type, resolve, reject });
3192
+ const transferables = [];
3193
+ worker.postMessage({
3194
+ type: "inflate",
3195
+ data: {
3196
+ id,
3197
+ type,
3198
+ src,
3199
+ uncompressedSize
3200
+ }
3201
+ }, transferables);
3202
+ }
3203
+ return;
3204
+ }
3205
+ }
3206
+ while (waitingForWorkerQueue.length) {
3207
+ const { src, type, resolve, reject } = waitingForWorkerQueue.shift();
3208
+ const data = isBlob(src) ? await readBlobAsUint8Array(src) : src;
3209
+ inflateRawLocal(data, type, resolve, reject);
3210
+ }
3211
+ }
3212
+ function inflateRawAsync(src, uncompressedSize, type) {
3213
+ return new Promise((resolve, reject) => {
3214
+ waitingForWorkerQueue.push({ src, uncompressedSize, type, resolve, reject, id: nextId++ });
3215
+ processWaitingForWorkerQueue();
3216
+ });
3217
+ }
3218
+ function dosDateTimeToDate(date, time) {
3219
+ const day = date & 31;
3220
+ const month = (date >> 5 & 15) - 1;
3221
+ const year = (date >> 9 & 127) + 1980;
3222
+ const millisecond = 0;
3223
+ const second = (time & 31) * 2;
3224
+ const minute = time >> 5 & 63;
3225
+ const hour = time >> 11 & 31;
3226
+ return new Date(year, month, day, hour, minute, second, millisecond);
3227
+ }
3228
+
3229
+ class ZipEntry {
3230
+ constructor(reader, rawEntry) {
3231
+ this._reader = reader;
3232
+ this._rawEntry = rawEntry;
3233
+ this.name = rawEntry.name;
3234
+ this.nameBytes = rawEntry.nameBytes;
3235
+ this.size = rawEntry.uncompressedSize;
3236
+ this.compressedSize = rawEntry.compressedSize;
3237
+ this.comment = rawEntry.comment;
3238
+ this.commentBytes = rawEntry.commentBytes;
3239
+ this.compressionMethod = rawEntry.compressionMethod;
3240
+ this.lastModDate = dosDateTimeToDate(rawEntry.lastModFileDate, rawEntry.lastModFileTime);
3241
+ this.isDirectory = rawEntry.uncompressedSize === 0 && rawEntry.name.endsWith("/");
3242
+ this.encrypted = !!(rawEntry.generalPurposeBitFlag & 1);
3243
+ this.externalFileAttributes = rawEntry.externalFileAttributes;
3244
+ this.versionMadeBy = rawEntry.versionMadeBy;
3245
+ }
3246
+ async blob(type = "application/octet-stream") {
3247
+ return await readEntryDataAsBlob(this._reader, this._rawEntry, type);
3248
+ }
3249
+ async arrayBuffer() {
3250
+ return await readEntryDataAsArrayBuffer(this._reader, this._rawEntry);
3251
+ }
3252
+ async text() {
3253
+ const buffer = await this.arrayBuffer();
3254
+ return decodeBuffer(new Uint8Array(buffer));
3255
+ }
3256
+ async json() {
3257
+ const text = await this.text();
3258
+ return JSON.parse(text);
3259
+ }
3260
+ }
3261
+ var EOCDR_WITHOUT_COMMENT_SIZE = 22;
3262
+ var MAX_COMMENT_SIZE = 65535;
3263
+ var EOCDR_SIGNATURE = 101010256;
3264
+ var ZIP64_EOCDR_SIGNATURE = 101075792;
3265
+ async function readAs(reader, offset, length) {
3266
+ return await reader.read(offset, length);
3267
+ }
3268
+ async function readAsBlobOrTypedArray(reader, offset, length, type) {
3269
+ if (reader.sliceAsBlob) {
3270
+ return await reader.sliceAsBlob(offset, length, type);
3271
+ }
3272
+ return await reader.read(offset, length);
3273
+ }
3274
+ var crc = {
3275
+ unsigned() {
3276
+ return 0;
3277
+ }
3278
+ };
3279
+ function getUint16LE(uint8View, offset) {
3280
+ return uint8View[offset] + uint8View[offset + 1] * 256;
3281
+ }
3282
+ function getUint32LE(uint8View, offset) {
3283
+ return uint8View[offset] + uint8View[offset + 1] * 256 + uint8View[offset + 2] * 65536 + uint8View[offset + 3] * 16777216;
3284
+ }
3285
+ function getUint64LE(uint8View, offset) {
3286
+ return getUint32LE(uint8View, offset) + getUint32LE(uint8View, offset + 4) * 4294967296;
3287
+ }
3288
+ var utf8Decoder = new TextDecoder;
3289
+ function decodeBuffer(uint8View, _isUTF8) {
3290
+ if (isSharedArrayBuffer(uint8View.buffer)) {
3291
+ uint8View = new Uint8Array(uint8View);
3292
+ }
3293
+ return utf8Decoder.decode(uint8View);
3294
+ }
3295
+ async function findEndOfCentralDirector(reader, totalLength) {
3296
+ const size = Math.min(EOCDR_WITHOUT_COMMENT_SIZE + MAX_COMMENT_SIZE, totalLength);
3297
+ const readStart = totalLength - size;
3298
+ const data = await readAs(reader, readStart, size);
3299
+ for (let i = size - EOCDR_WITHOUT_COMMENT_SIZE;i >= 0; --i) {
3300
+ if (getUint32LE(data, i) !== EOCDR_SIGNATURE) {
3301
+ continue;
3302
+ }
3303
+ const eocdr = new Uint8Array(data.buffer, data.byteOffset + i, data.byteLength - i);
3304
+ const diskNumber = getUint16LE(eocdr, 4);
3305
+ if (diskNumber !== 0) {
3306
+ throw new Error(`multi-volume zip files are not supported. This is volume: ${diskNumber}`);
3307
+ }
3308
+ const entryCount = getUint16LE(eocdr, 10);
3309
+ const centralDirectorySize = getUint32LE(eocdr, 12);
3310
+ const centralDirectoryOffset = getUint32LE(eocdr, 16);
3311
+ const commentLength = getUint16LE(eocdr, 20);
3312
+ const expectedCommentLength = eocdr.length - EOCDR_WITHOUT_COMMENT_SIZE;
3313
+ if (commentLength !== expectedCommentLength) {
3314
+ throw new Error(`invalid comment length. expected: ${expectedCommentLength}, actual: ${commentLength}`);
3315
+ }
3316
+ const commentBytes = new Uint8Array(eocdr.buffer, eocdr.byteOffset + 22, commentLength);
3317
+ const comment = decodeBuffer(commentBytes);
3318
+ if (entryCount === 65535 || centralDirectoryOffset === 4294967295) {
3319
+ return await readZip64CentralDirectory(reader, readStart + i, comment, commentBytes);
3320
+ } else {
3321
+ return await readEntries(reader, centralDirectoryOffset, centralDirectorySize, entryCount, comment, commentBytes);
3322
+ }
3323
+ }
3324
+ throw new Error("could not find end of central directory. maybe not zip file");
3325
+ }
3326
+ var END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE = 117853008;
3327
+ async function readZip64CentralDirectory(reader, offset, comment, commentBytes) {
3328
+ const zip64EocdlOffset = offset - 20;
3329
+ const eocdl = await readAs(reader, zip64EocdlOffset, 20);
3330
+ if (getUint32LE(eocdl, 0) !== END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE) {
3331
+ throw new Error("invalid zip64 end of central directory locator signature");
3332
+ }
3333
+ const zip64EocdrOffset = getUint64LE(eocdl, 8);
3334
+ const zip64Eocdr = await readAs(reader, zip64EocdrOffset, 56);
3335
+ if (getUint32LE(zip64Eocdr, 0) !== ZIP64_EOCDR_SIGNATURE) {
3336
+ throw new Error("invalid zip64 end of central directory record signature");
3337
+ }
3338
+ const entryCount = getUint64LE(zip64Eocdr, 32);
3339
+ const centralDirectorySize = getUint64LE(zip64Eocdr, 40);
3340
+ const centralDirectoryOffset = getUint64LE(zip64Eocdr, 48);
3341
+ return readEntries(reader, centralDirectoryOffset, centralDirectorySize, entryCount, comment, commentBytes);
3342
+ }
3343
+ var CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE = 33639248;
3344
+ async function readEntries(reader, centralDirectoryOffset, centralDirectorySize, rawEntryCount, comment, commentBytes) {
3345
+ let readEntryCursor = 0;
3346
+ const allEntriesBuffer = await readAs(reader, centralDirectoryOffset, centralDirectorySize);
3347
+ const rawEntries = [];
3348
+ for (let e = 0;e < rawEntryCount; ++e) {
3349
+ const buffer = allEntriesBuffer.subarray(readEntryCursor, readEntryCursor + 46);
3350
+ const signature = getUint32LE(buffer, 0);
3351
+ if (signature !== CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE) {
3352
+ throw new Error(`invalid central directory file header signature: 0x${signature.toString(16)}`);
3353
+ }
3354
+ const rawEntry = {
3355
+ versionMadeBy: getUint16LE(buffer, 4),
3356
+ versionNeededToExtract: getUint16LE(buffer, 6),
3357
+ generalPurposeBitFlag: getUint16LE(buffer, 8),
3358
+ compressionMethod: getUint16LE(buffer, 10),
3359
+ lastModFileTime: getUint16LE(buffer, 12),
3360
+ lastModFileDate: getUint16LE(buffer, 14),
3361
+ crc32: getUint32LE(buffer, 16),
3362
+ compressedSize: getUint32LE(buffer, 20),
3363
+ uncompressedSize: getUint32LE(buffer, 24),
3364
+ fileNameLength: getUint16LE(buffer, 28),
3365
+ extraFieldLength: getUint16LE(buffer, 30),
3366
+ fileCommentLength: getUint16LE(buffer, 32),
3367
+ internalFileAttributes: getUint16LE(buffer, 36),
3368
+ externalFileAttributes: getUint32LE(buffer, 38),
3369
+ relativeOffsetOfLocalHeader: getUint32LE(buffer, 42)
3370
+ };
3371
+ if (rawEntry.generalPurposeBitFlag & 64) {
3372
+ throw new Error("strong encryption is not supported");
3373
+ }
3374
+ readEntryCursor += 46;
3375
+ const data = allEntriesBuffer.subarray(readEntryCursor, readEntryCursor + rawEntry.fileNameLength + rawEntry.extraFieldLength + rawEntry.fileCommentLength);
3376
+ rawEntry.generalPurposeBitFlag & 2048;
3377
+ rawEntry.nameBytes = data.slice(0, rawEntry.fileNameLength);
3378
+ rawEntry.name = decodeBuffer(rawEntry.nameBytes);
3379
+ const fileCommentStart = rawEntry.fileNameLength + rawEntry.extraFieldLength;
3380
+ const extraFieldBuffer = data.slice(rawEntry.fileNameLength, fileCommentStart);
3381
+ rawEntry.extraFields = [];
3382
+ let i = 0;
3383
+ while (i < extraFieldBuffer.length - 3) {
3384
+ const headerId = getUint16LE(extraFieldBuffer, i + 0);
3385
+ const dataSize = getUint16LE(extraFieldBuffer, i + 2);
3386
+ const dataStart = i + 4;
3387
+ const dataEnd = dataStart + dataSize;
3388
+ if (dataEnd > extraFieldBuffer.length) {
3389
+ throw new Error("extra field length exceeds extra field buffer size");
3390
+ }
3391
+ rawEntry.extraFields.push({
3392
+ id: headerId,
3393
+ data: extraFieldBuffer.slice(dataStart, dataEnd)
3394
+ });
3395
+ i = dataEnd;
3396
+ }
3397
+ rawEntry.commentBytes = data.slice(fileCommentStart, fileCommentStart + rawEntry.fileCommentLength);
3398
+ rawEntry.comment = decodeBuffer(rawEntry.commentBytes);
3399
+ readEntryCursor += data.length;
3400
+ if (rawEntry.uncompressedSize === 4294967295 || rawEntry.compressedSize === 4294967295 || rawEntry.relativeOffsetOfLocalHeader === 4294967295) {
3401
+ const zip64ExtraField = rawEntry.extraFields.find((e2) => e2.id === 1);
3402
+ if (!zip64ExtraField) {
3403
+ throw new Error("expected zip64 extended information extra field");
3404
+ }
3405
+ const zip64EiefBuffer = zip64ExtraField.data;
3406
+ let index = 0;
3407
+ if (rawEntry.uncompressedSize === 4294967295) {
3408
+ if (index + 8 > zip64EiefBuffer.length) {
3409
+ throw new Error("zip64 extended information extra field does not include uncompressed size");
3410
+ }
3411
+ rawEntry.uncompressedSize = getUint64LE(zip64EiefBuffer, index);
3412
+ index += 8;
3413
+ }
3414
+ if (rawEntry.compressedSize === 4294967295) {
3415
+ if (index + 8 > zip64EiefBuffer.length) {
3416
+ throw new Error("zip64 extended information extra field does not include compressed size");
3417
+ }
3418
+ rawEntry.compressedSize = getUint64LE(zip64EiefBuffer, index);
3419
+ index += 8;
3420
+ }
3421
+ if (rawEntry.relativeOffsetOfLocalHeader === 4294967295) {
3422
+ if (index + 8 > zip64EiefBuffer.length) {
3423
+ throw new Error("zip64 extended information extra field does not include relative header offset");
3424
+ }
3425
+ rawEntry.relativeOffsetOfLocalHeader = getUint64LE(zip64EiefBuffer, index);
3426
+ index += 8;
3427
+ }
3428
+ }
3429
+ const nameField = rawEntry.extraFields.find((e2) => e2.id === 28789 && e2.data.length >= 6 && e2.data[0] === 1 && getUint32LE(e2.data, 1), crc.unsigned());
3430
+ if (nameField) {
3431
+ rawEntry.fileName = decodeBuffer(nameField.data.slice(5));
3432
+ }
3433
+ if (rawEntry.compressionMethod === 0) {
3434
+ let expectedCompressedSize = rawEntry.uncompressedSize;
3435
+ if ((rawEntry.generalPurposeBitFlag & 1) !== 0) {
3436
+ expectedCompressedSize += 12;
3437
+ }
3438
+ if (rawEntry.compressedSize !== expectedCompressedSize) {
3439
+ throw new Error(`compressed size mismatch for stored file: ${rawEntry.compressedSize} != ${expectedCompressedSize}`);
3440
+ }
3441
+ }
3442
+ rawEntries.push(rawEntry);
3443
+ }
3444
+ const zip = {
3445
+ comment,
3446
+ commentBytes
3447
+ };
3448
+ return {
3449
+ zip,
3450
+ entries: rawEntries.map((e) => new ZipEntry(reader, e))
3451
+ };
3452
+ }
3453
+ async function readEntryDataHeader(reader, rawEntry) {
3454
+ if (rawEntry.generalPurposeBitFlag & 1) {
3455
+ throw new Error("encrypted entries not supported");
3456
+ }
3457
+ const buffer = await readAs(reader, rawEntry.relativeOffsetOfLocalHeader, 30);
3458
+ const totalLength = await reader.getLength();
3459
+ const signature = getUint32LE(buffer, 0);
3460
+ if (signature !== 67324752) {
3461
+ throw new Error(`invalid local file header signature: 0x${signature.toString(16)}`);
3462
+ }
3463
+ const fileNameLength = getUint16LE(buffer, 26);
3464
+ const extraFieldLength = getUint16LE(buffer, 28);
3465
+ const localFileHeaderEnd = rawEntry.relativeOffsetOfLocalHeader + buffer.length + fileNameLength + extraFieldLength;
3466
+ let decompress;
3467
+ if (rawEntry.compressionMethod === 0) {
3468
+ decompress = false;
3469
+ } else if (rawEntry.compressionMethod === 8) {
3470
+ decompress = true;
3471
+ } else {
3472
+ throw new Error(`unsupported compression method: ${rawEntry.compressionMethod}`);
3473
+ }
3474
+ const fileDataStart = localFileHeaderEnd;
3475
+ const fileDataEnd = fileDataStart + rawEntry.compressedSize;
3476
+ if (rawEntry.compressedSize !== 0) {
3477
+ if (fileDataEnd > totalLength) {
3478
+ throw new Error(`file data overflows file bounds: ${fileDataStart} + ${rawEntry.compressedSize} > ${totalLength}`);
3479
+ }
3480
+ }
3481
+ return {
3482
+ decompress,
3483
+ fileDataStart
3484
+ };
3485
+ }
3486
+ async function readEntryDataAsArrayBuffer(reader, rawEntry) {
3487
+ const { decompress, fileDataStart } = await readEntryDataHeader(reader, rawEntry);
3488
+ if (!decompress) {
3489
+ const dataView = await readAs(reader, fileDataStart, rawEntry.compressedSize);
3490
+ return isTypedArraySameAsArrayBuffer(dataView) ? dataView.buffer : dataView.slice().buffer;
3491
+ }
3492
+ const typedArrayOrBlob = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize);
3493
+ const result = await inflateRawAsync(typedArrayOrBlob instanceof Uint8Array ? typedArrayOrBlob : typedArrayOrBlob, rawEntry.uncompressedSize);
3494
+ return result;
3495
+ }
3496
+ async function readEntryDataAsBlob(reader, rawEntry, type) {
3497
+ const { decompress, fileDataStart } = await readEntryDataHeader(reader, rawEntry);
3498
+ if (!decompress) {
3499
+ const typedArrayOrBlob2 = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize, type);
3500
+ if (isBlob(typedArrayOrBlob2)) {
3501
+ return typedArrayOrBlob2;
3502
+ }
3503
+ return new Blob([typedArrayOrBlob2], { type });
3504
+ }
3505
+ const typedArrayOrBlob = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize);
3506
+ const result = await inflateRawAsync(typedArrayOrBlob instanceof Uint8Array ? typedArrayOrBlob : typedArrayOrBlob, rawEntry.uncompressedSize, type);
3507
+ return result;
3508
+ }
3509
+ async function unzipRaw(source) {
3510
+ let reader;
3511
+ if (typeof Blob !== "undefined" && source instanceof Blob) {
3512
+ reader = new BlobReader(source);
3513
+ } else if (source instanceof ArrayBuffer || source && source.buffer && source.buffer instanceof ArrayBuffer) {
3514
+ reader = new ArrayBufferReader(source);
3515
+ } else if (isSharedArrayBuffer(source) || isSharedArrayBuffer(source.buffer)) {
3516
+ reader = new ArrayBufferReader(source);
3517
+ } else if (typeof source === "string") {
3518
+ const req = await fetch(source);
3519
+ if (!req.ok) {
3520
+ throw new Error(`failed http request ${source}, status: ${req.status}: ${req.statusText}`);
3521
+ }
3522
+ const blob = await req.blob();
3523
+ reader = new BlobReader(blob);
3524
+ } else if (typeof source.getLength === "function" && typeof source.read === "function") {
3525
+ reader = source;
3526
+ } else {
3527
+ throw new Error("unsupported source type");
3528
+ }
3529
+ const totalLength = await reader.getLength();
3530
+ if (totalLength > Number.MAX_SAFE_INTEGER) {
3531
+ throw new Error(`file too large. size: ${totalLength}. Only file sizes up 4503599627370496 bytes are supported`);
3532
+ }
3533
+ return await findEndOfCentralDirector(reader, totalLength);
3534
+ }
3535
+ async function unzip(source) {
3536
+ const { zip, entries } = await unzipRaw(source);
3537
+ return {
3538
+ zip,
3539
+ entries: Object.fromEntries(entries.map((v) => [v.name, v]))
3540
+ };
3541
+ }
3542
+
3543
+ // ../serial/src/vex-device.ts
3544
+ function downloadFileFromInternet(link) {
3545
+ return new Promise((resolve, reject) => {
3546
+ var oReq = new XMLHttpRequest;
3547
+ oReq.open("GET", link, true);
3548
+ oReq.responseType = "arraybuffer";
3549
+ oReq.onload = function(_oEvent) {
3550
+ var arrayBuffer = oReq.response;
3551
+ resolve(arrayBuffer);
3552
+ };
3553
+ oReq.onerror = function(oEvent) {
3554
+ reject(oEvent);
3555
+ };
3556
+ oReq.send(null);
3557
+ });
3558
+ }
3559
+ function sleepUntil(f, timeout, interval = 20) {
3560
+ return new Promise((resolve) => {
3561
+ const timeWas = new Date().getTime();
3562
+ const wait = setInterval(async function() {
3563
+ if (await f()) {
3564
+ clearInterval(wait);
3565
+ resolve(true);
3566
+ } else if (new Date().getTime() - timeWas > timeout) {
3567
+ clearInterval(wait);
3568
+ resolve(false);
3569
+ }
3570
+ }, interval);
3571
+ });
3572
+ }
3573
+ function sleep(ms) {
3574
+ return new Promise((resolve) => setTimeout(resolve, ms));
3575
+ }
3576
+ function shallowEqual(object1, object2) {
3577
+ const keys1 = Object.keys(object1);
3578
+ const keys2 = Object.keys(object2);
3579
+ if (keys1.length !== keys2.length) {
3580
+ return false;
3581
+ }
3582
+ for (let key of keys1) {
3583
+ if (object1[key] !== object2[key]) {
3584
+ return false;
3585
+ }
3586
+ }
3587
+ return true;
3588
+ }
3589
+
3590
+ class VexSerialDevice extends VexEventTarget {
3591
+ connection;
3592
+ defaultSerial;
3593
+ get isConnected() {
3594
+ return this.connection ? this.connection.isConnected : false;
3595
+ }
3596
+ get deviceType() {
3597
+ return this.isConnected ? this.connection?.port?.getInfo().usbProductId : undefined;
3598
+ }
3599
+ constructor(defaultSerial) {
3600
+ super();
3601
+ this.defaultSerial = defaultSerial;
3602
+ }
3603
+ }
3604
+
3605
+ class V5SerialDeviceProxyHandler {
3606
+ device;
3607
+ parent;
3608
+ rootkey;
3609
+ constructor(device, parent, rootkey) {
3610
+ this.device = device;
3611
+ this.parent = parent;
3612
+ this.rootkey = rootkey;
3613
+ }
3614
+ get(target, key) {
3615
+ if (typeof target[key] === "object" && target[key] !== null && (typeof key !== "string" ? true : !key.startsWith("_"))) {
3616
+ return new Proxy(target[key], new V5SerialDeviceProxyHandler(this.device, this, key));
3617
+ } else {
3618
+ return target[key];
3619
+ }
3620
+ }
3621
+ set(target, key, value) {
3622
+ let oldValue = target[key];
3623
+ if (oldValue === value) {
3624
+ return true;
3625
+ } else if (typeof oldValue === "object" && typeof value === "object" && oldValue !== null && value !== null) {
3626
+ if (shallowEqual(oldValue, value))
3627
+ return true;
3628
+ }
3629
+ target[key] = value;
3630
+ this.parent?.childSet(this.rootkey, key, value);
3631
+ return true;
3632
+ }
3633
+ childSet(rootkey, subkey, value) {
3634
+ if (this.parent)
3635
+ this.parent.childSet(this.rootkey, rootkey + "." + subkey, value);
3636
+ }
3637
+ }
3638
+
3639
+ class V5SerialDeviceState {
3640
+ _instance;
3641
+ _isFileTransferring = false;
3642
+ brain = {
3643
+ activeProgram: 0,
3644
+ battery: {
3645
+ batteryPercent: 0,
3646
+ isCharging: false
3647
+ },
3648
+ button: {
3649
+ isPressed: false,
3650
+ isDoublePressed: false
3651
+ },
3652
+ cpu0Version: VexFirmwareVersion.allZero(),
3653
+ cpu1Version: VexFirmwareVersion.allZero(),
3654
+ isAvailable: false,
3655
+ settings: {
3656
+ isScreenReversed: false,
3657
+ isWhiteTheme: false,
3658
+ usingLanguage: 0
3659
+ },
3660
+ systemVersion: VexFirmwareVersion.allZero(),
3661
+ uniqueId: 0
3662
+ };
3663
+ controllers = [
3664
+ {
3665
+ battery: 0,
3666
+ isAvailable: false,
3667
+ isCharging: false
3668
+ },
3669
+ {
3670
+ battery: 0,
3671
+ isAvailable: false
3672
+ }
3673
+ ];
3674
+ devices = [];
3675
+ isFieldControllerConnected = false;
3676
+ matchMode = "disabled";
3677
+ radio = {
3678
+ channel: 0,
3679
+ isAvailable: false,
3680
+ isConnected: false,
3681
+ isVexNet: false,
3682
+ isRadioData: false,
3683
+ latency: 0,
3684
+ signalQuality: 0,
3685
+ signalStrength: 0
3686
+ };
3687
+ constructor(instance) {
3688
+ this._instance = instance;
3689
+ }
3690
+ }
3691
+
3692
+ class V5Brain {
3693
+ state;
3694
+ constructor(state) {
3695
+ this.state = state;
3696
+ }
3697
+ get isRunningProgram() {
3698
+ return this.activeProgram !== 0;
3699
+ }
3700
+ get activeProgram() {
3701
+ return this.state.brain.activeProgram;
3702
+ }
3703
+ set activeProgram(value) {
3704
+ (async () => {
3705
+ if (this.state.brain.activeProgram === value)
3706
+ return;
3707
+ let conn = this.state._instance.connection;
3708
+ if (!conn)
3709
+ return;
3710
+ let fn = value === 0 ? await conn.stopProgram() : await conn.loadProgram(value);
3711
+ if (fn)
3712
+ this.state.brain.activeProgram = value;
3713
+ })();
3714
+ }
3715
+ get battery() {
3716
+ return new V5Battery(this.state);
3717
+ }
3718
+ get button() {
3719
+ return new V5BrainButton(this.state);
3720
+ }
3721
+ get cpu0Version() {
3722
+ return this.state.brain.cpu0Version;
3723
+ }
3724
+ get cpu1Version() {
3725
+ return this.state.brain.cpu1Version;
3726
+ }
3727
+ get isAvailable() {
3728
+ return this.state.brain.isAvailable;
3729
+ }
3730
+ get settings() {
3731
+ return new V5BrainSettings(this.state);
3732
+ }
3733
+ get systemVersion() {
3734
+ return this.state.brain.systemVersion;
3735
+ }
3736
+ get uniqueId() {
3737
+ return this.state.brain.uniqueId;
3738
+ }
3739
+ async getValue(key) {
3740
+ let result = await this.state._instance.connection?.writeDataAsync(new ReadKeyValueH2DPacket(key));
3741
+ return result instanceof ReadKeyValueReplyD2HPacket ? result.value : undefined;
3742
+ }
3743
+ async setValue(key, value) {
3744
+ let result = await this.state._instance.connection?.writeDataAsync(new WriteKeyValueH2DPacket(key, value));
3745
+ return result instanceof WriteKeyValueReplyD2HPacket ? true : false;
3746
+ }
3747
+ async listFiles(vendor = 1 /* USER */) {
3748
+ let conn = this.state._instance.connection;
3749
+ if (!conn)
3750
+ return;
3751
+ let result = await conn.writeDataAsync(new GetDirectoryFileCountH2DPacket(vendor));
3752
+ if (!(result instanceof GetDirectoryFileCountReplyD2HPacket))
3753
+ return;
3754
+ let files = [];
3755
+ for (let i = 0;i < result.count; i++) {
3756
+ let result2 = await conn.writeDataAsync(new GetDirectoryEntryH2DPacket(i));
3757
+ if (!(result2 instanceof GetDirectoryEntryReplyD2HPacket))
3758
+ return;
3759
+ if (result2.file) {
3760
+ files.push({
3761
+ filename: result2.file.filename,
3762
+ vendor,
3763
+ loadAddress: result2.file.loadAddress,
3764
+ size: result2.file.size,
3765
+ crc32: result2.file.crc32,
3766
+ type: result2.file.type,
3767
+ timestamp: result2.file.timestamp,
3768
+ version: result2.file.version
3769
+ });
3770
+ }
3771
+ }
3772
+ return files;
3773
+ }
3774
+ async listProgram() {
3775
+ let conn = this.state._instance.connection;
3776
+ if (!conn?.isConnected)
3777
+ return;
3778
+ let files = await this.listFiles(1 /* USER */);
3779
+ if (files === undefined)
3780
+ return;
3781
+ let programList = [];
3782
+ let iniFiles = files.filter((file) => file && file.filename.search(/.ini$/) > 0);
3783
+ for (let i = 0;i < iniFiles.length; i++) {
3784
+ let ini = iniFiles[i];
3785
+ if (!ini.size)
3786
+ continue;
3787
+ let programName = (/(.+?)(\.[^.]*$|$)/.exec(ini.filename) || "")[1];
3788
+ let bin = files.filter((e) => e && e.filename === programName + ".bin")[0];
3789
+ if (!bin || !bin.timestamp || !bin.size)
3790
+ continue;
3791
+ let n = new Date;
3792
+ n.setTime(1000 * bin.timestamp);
3793
+ let program = {
3794
+ name: programName,
3795
+ binfile: bin.filename,
3796
+ size: ini.size + bin.size,
3797
+ slot: -1,
3798
+ time: n,
3799
+ requestedSlot: -1
3800
+ };
3801
+ let result2 = await conn.writeDataAsync(new GetProgramSlotInfoH2DPacket(1 /* USER */, program.binfile));
3802
+ if (result2 instanceof GetProgramSlotInfoReplyD2HPacket) {
3803
+ program.slot = result2.slot;
3804
+ program.requestedSlot = result2.requestedSlot;
3805
+ }
3806
+ programList.push(program);
3807
+ }
3808
+ return programList;
3809
+ }
3810
+ async readFile(request, downloadTarget = 1 /* FILE_TARGET_QSPI */, progressCallback) {
3811
+ let conn = this.state._instance.connection;
3812
+ if (!conn?.isConnected)
3813
+ return;
3814
+ this.state._isFileTransferring = true;
3815
+ let handle;
3816
+ if (typeof request === "string") {
3817
+ handle = { filename: request, vendor: 1 /* USER */ };
3818
+ } else {
3819
+ handle = request;
3820
+ }
3821
+ try {
3822
+ return conn.downloadFileToHost(handle, downloadTarget, progressCallback);
3823
+ } catch (e) {
3824
+ throw e;
3825
+ } finally {
3826
+ this.state._isFileTransferring = false;
3827
+ }
3828
+ }
3829
+ async removeFile(request) {
3830
+ let conn = this.state._instance.connection;
3831
+ if (!conn?.isConnected)
3832
+ return;
3833
+ let vendor, filename;
3834
+ if (typeof request === "string") {
3835
+ vendor = 1 /* USER */;
3836
+ filename = request;
3837
+ } else {
3838
+ vendor = request.vendor;
3839
+ filename = request.filename;
3840
+ }
3841
+ let result = await conn.writeDataAsync(new EraseFileH2DPacket(vendor, filename));
3842
+ let result2 = await conn.writeDataAsync(new ExitFileTransferH2DPacket(3 /* EXIT_HALT */));
3843
+ if (!(result instanceof EraseFileReplyD2HPacket))
3844
+ return false;
3845
+ if (!(result2 instanceof ExitFileTransferReplyD2HPacket))
3846
+ return false;
3847
+ return true;
3848
+ }
3849
+ async removeAllFiles() {
3850
+ let conn = this.state._instance.connection;
3851
+ if (!conn?.isConnected)
3852
+ return;
3853
+ let result = await conn.writeDataAsync(new FileClearUpH2DPacket(1 /* USER */), 30000);
3854
+ return result instanceof FileClearUpReplyD2HPacket ? true : false;
3855
+ }
3856
+ async uploadFirmware(publicUrl = "https://content.vexrobotics.com/vexos/public/V5/", usingVersion, progressCallback) {
3857
+ let device = this.state._instance;
3858
+ let conn = device.connection;
3859
+ if (!conn?.isConnected)
3860
+ return;
3861
+ const pcb = progressCallback ?? (() => {});
3862
+ let vexos, bootBin, assertBin;
3863
+ try {
3864
+ if (usingVersion === undefined) {
3865
+ pcb("FETCH CATALOG", 0, 1);
3866
+ const catalog = await downloadFileFromInternet(publicUrl + "catalog.txt");
3867
+ let latestVersion = new TextDecoder().decode(catalog);
3868
+ usingVersion = latestVersion;
3869
+ pcb("FETCH CATALOG", 1, 1);
3870
+ console.log("fetched catalog.txt", latestVersion);
3871
+ }
3872
+ pcb("FETCH VEXOS", 0, 1);
3873
+ vexos = await downloadFileFromInternet(publicUrl + usingVersion + ".vexos");
3874
+ pcb("FETCH VEXOS", 1, 1);
3875
+ pcb("UNZIP VEXOS", 0, 1);
3876
+ let { entries } = await unzip(vexos);
3877
+ bootBin = await entries[usingVersion + "/BOOT.bin"].arrayBuffer();
3878
+ assertBin = await entries[usingVersion + "/assets.bin"].arrayBuffer();
3879
+ pcb("UNZIP VEXOS", 1, 1);
3880
+ } catch (e) {
3881
+ return;
3882
+ }
3883
+ try {
3884
+ this.state._isFileTransferring = true;
3885
+ pcb("FACTORY ENB BOOT", 0, 0);
3886
+ let result = await conn.writeDataAsync(new FactoryEnableH2DPacket);
3887
+ if (!(result instanceof FactoryEnableReplyD2HPacket))
3888
+ return false;
3889
+ let bootWriteRequest = {
3890
+ filename: "null.bin",
3891
+ vendor: 1 /* USER */,
3892
+ loadAddress: USER_FLASH_USR_CODE_START,
3893
+ buf: new Uint8Array(bootBin),
3894
+ downloadTarget: 14 /* FILE_TARGET_B1 */,
3895
+ exttype: "bin",
3896
+ autoRun: true,
3897
+ linkedFile: undefined
3898
+ };
3899
+ let result2 = await conn.uploadFileToDevice(bootWriteRequest, (c, t) => pcb("UPLOAD BOOT", c, t));
3900
+ if (!result2)
3901
+ return false;
3902
+ while (true) {
3903
+ let result3 = await conn.writeDataAsync(new FactoryStatusH2DPacket, 1e4);
3904
+ if (result3 instanceof FactoryStatusReplyD2HPacket) {
3905
+ switch (result3.status) {
3906
+ case 2:
3907
+ pcb("ERASE BOOT", result3.percent, 100);
3908
+ break;
3909
+ case 3:
3910
+ pcb("WRITE BOOT", result3.percent, 100);
3911
+ break;
3912
+ case 4:
3913
+ pcb("VERIFY BOOT", result3.percent, 100);
3914
+ break;
3915
+ case 8:
3916
+ pcb("FINISHING BOOT", result3.percent, 100);
3917
+ break;
3918
+ }
3919
+ if (result3.status === 0 && result3.percent === 100)
3920
+ break;
3921
+ } else {
3922
+ return false;
3923
+ }
3924
+ await sleep(500);
3925
+ }
3926
+ pcb("FACTORY ENB ASSERT", 0, 0);
3927
+ let result5 = await conn.writeDataAsync(new FactoryEnableH2DPacket);
3928
+ if (!(result5 instanceof FactoryEnableReplyD2HPacket))
3929
+ return false;
3930
+ let assertWriteRequest = {
3931
+ filename: "null.bin",
3932
+ vendor: 1 /* USER */,
3933
+ loadAddress: USER_FLASH_USR_CODE_START,
3934
+ buf: new Uint8Array(assertBin),
3935
+ downloadTarget: 13 /* FILE_TARGET_A1 */,
3936
+ exttype: "bin",
3937
+ autoRun: true,
3938
+ linkedFile: undefined
3939
+ };
3940
+ let result6 = await conn.uploadFileToDevice(assertWriteRequest, (c, t) => pcb("UPLOAD ASSERT", c, t));
3941
+ if (!result6)
3942
+ return false;
3943
+ while (true) {
3944
+ let result7 = await conn.writeDataAsync(new FactoryStatusH2DPacket, 1e4);
3945
+ if (result7 instanceof FactoryStatusReplyD2HPacket) {
3946
+ switch (result7.status) {
3947
+ case 2:
3948
+ pcb("ERASE ASSERT", result7.percent, 100);
3949
+ break;
3950
+ case 3:
3951
+ pcb("WRITE ASSERT", result7.percent, 100);
3952
+ break;
3953
+ case 4:
3954
+ pcb("VERIFY ASSERT", result7.percent, 100);
3955
+ break;
3956
+ case 8:
3957
+ pcb("FINISHING ASSERT", result7.percent, 100);
3958
+ break;
3959
+ }
3960
+ if (result7.status === 0 && result7.percent === 100)
3961
+ break;
3962
+ } else {
3963
+ return false;
3964
+ }
3965
+ await sleep(500);
3966
+ }
3967
+ } catch (e) {
3968
+ throw e;
3969
+ } finally {
3970
+ this.state._isFileTransferring = false;
3971
+ }
3972
+ return true;
3973
+ }
3974
+ async uploadProgram(iniConfig, binFileBuf, coldFileBuf, progressCallback) {
3975
+ let device = this.state._instance;
3976
+ let conn = device.connection;
3977
+ if (!conn?.isConnected)
3978
+ return;
3979
+ this.state._isFileTransferring = true;
3980
+ try {
3981
+ if (device.isV5Controller) {
3982
+ await sleep(250);
3983
+ if (!device.refresh())
3984
+ return;
3985
+ console.log("Transferring to download channel");
3986
+ let p1 = await device.radio.changeChannel(1 /* DOWNLOAD */);
3987
+ if (!p1)
3988
+ return false;
3989
+ await sleep(250);
3990
+ await sleepUntil(async () => await conn?.getSystemStatus(150), 1e4, 200);
3991
+ console.log("Transferred to download channel");
3992
+ }
3993
+ let p2 = await conn.uploadProgramToDevice(iniConfig, binFileBuf, coldFileBuf, progressCallback);
3994
+ if (!p2)
3995
+ return false;
3996
+ if (device.isV5Controller) {
3997
+ if (!device.brain.isAvailable)
3998
+ return false;
3999
+ console.log("Transferring back to pit channel");
4000
+ let p3 = await device.radio.changeChannel(0 /* PIT */);
4001
+ if (!p3)
4002
+ return false;
4003
+ await sleep(250);
4004
+ await sleepUntil(async () => await conn?.getSystemStatus(150), 1e4, 200);
4005
+ console.log("All done");
4006
+ }
4007
+ return true;
4008
+ } catch (e) {
4009
+ throw e;
4010
+ } finally {
4011
+ this.state._isFileTransferring = false;
4012
+ }
4013
+ }
4014
+ async writeFile(request, progressCallback) {
4015
+ this.state._isFileTransferring = true;
4016
+ let conn = this.state._instance.connection;
4017
+ if (!conn?.isConnected)
4018
+ return;
4019
+ try {
4020
+ return conn.uploadFileToDevice(request, progressCallback);
4021
+ } catch (e) {
4022
+ throw e;
4023
+ } finally {
4024
+ this.state._isFileTransferring = false;
4025
+ }
4026
+ }
4027
+ }
4028
+
4029
+ class V5Battery {
4030
+ state;
4031
+ constructor(state) {
4032
+ this.state = state;
4033
+ }
4034
+ get batteryPercent() {
4035
+ return this.state.brain.battery.batteryPercent;
4036
+ }
4037
+ get isCharging() {
4038
+ return this.state.brain.battery.isCharging;
4039
+ }
4040
+ }
4041
+
4042
+ class V5BrainButton {
4043
+ state;
4044
+ constructor(state) {
4045
+ this.state = state;
4046
+ }
4047
+ get isPressed() {
4048
+ return this.state.brain.button.isPressed;
4049
+ }
4050
+ get isDoublePressed() {
4051
+ return this.state.brain.button.isDoublePressed;
4052
+ }
4053
+ }
4054
+
4055
+ class V5BrainSettings {
4056
+ state;
4057
+ constructor(state) {
4058
+ this.state = state;
4059
+ }
4060
+ get isScreenReversed() {
4061
+ return this.state.brain.settings.isScreenReversed;
4062
+ }
4063
+ get isWhiteTheme() {
4064
+ return this.state.brain.settings.isWhiteTheme;
4065
+ }
4066
+ get usingLanguage() {
4067
+ return this.state.brain.settings.usingLanguage;
4068
+ }
4069
+ }
4070
+
4071
+ class V5Controller {
4072
+ state;
4073
+ controllerIndex;
4074
+ constructor(state, controllerIndex) {
4075
+ this.state = state;
4076
+ this.controllerIndex = controllerIndex;
4077
+ }
4078
+ get batteryPercent() {
4079
+ return this.state.controllers[this.controllerIndex].battery;
4080
+ }
4081
+ get isMasterController() {
4082
+ return this.controllerIndex === 0;
4083
+ }
4084
+ get isAvailable() {
4085
+ return this.state.controllers[this.controllerIndex].isAvailable;
4086
+ }
4087
+ get isCharging() {
4088
+ return this.state.controllers[this.controllerIndex].isCharging;
4089
+ }
4090
+ }
4091
+
4092
+ class V5SmartDevice {
4093
+ state;
4094
+ deviceIndex;
4095
+ constructor(state, index) {
4096
+ this.state = state;
4097
+ this.deviceIndex = index;
4098
+ }
4099
+ get isAvailable() {
4100
+ return this.state.devices[this.deviceIndex] !== undefined;
4101
+ }
4102
+ get port() {
4103
+ return this.deviceIndex;
4104
+ }
4105
+ get type() {
4106
+ return this.isAvailable ? this.state.devices[this.deviceIndex].type : 0 /* EMPTY */;
4107
+ }
4108
+ get version() {
4109
+ return this.isAvailable ? this.state.devices[this.deviceIndex].version : 0;
4110
+ }
4111
+ }
4112
+
4113
+ class V5Radio {
4114
+ state;
4115
+ constructor(state) {
4116
+ this.state = state;
4117
+ }
4118
+ get channel() {
4119
+ return this.state.radio.channel;
4120
+ }
4121
+ get isAvailable() {
4122
+ return this.state.radio.isAvailable;
4123
+ }
4124
+ get isConnected() {
4125
+ return this.state.radio.isConnected;
4126
+ }
4127
+ get isVexNet() {
4128
+ return this.state.radio.isVexNet;
4129
+ }
4130
+ get isRadioData() {
4131
+ return this.state.radio.isRadioData;
4132
+ }
4133
+ get latency() {
4134
+ return this.state.radio.latency;
4135
+ }
4136
+ async changeChannel(channel) {
4137
+ let result = await this.state._instance.connection?.writeDataAsync(new FileControlH2DPacket(1, channel));
4138
+ return result instanceof FileControlReplyD2HPacket ? true : false;
4139
+ }
4140
+ }
4141
+
4142
+ class V5SerialDevice extends VexSerialDevice {
4143
+ autoReconnect = true;
4144
+ autoRefresh = true;
4145
+ pauseRefreshOnFileTransfer = true;
4146
+ _isDisconnecting = false;
4147
+ _isReconnecting = false;
4148
+ _refreshInterval;
4149
+ proxy = new V5SerialDeviceProxyHandler(this);
4150
+ state = new Proxy(new V5SerialDeviceState(this), this.proxy);
4151
+ constructor(defaultSerial) {
4152
+ super(defaultSerial);
4153
+ this.startAutoRefresh();
4154
+ }
4155
+ startAutoRefresh() {
4156
+ if (this._refreshInterval)
4157
+ return;
4158
+ this._refreshInterval = setInterval(() => {
4159
+ if (this.autoRefresh) {
4160
+ if (!this.isConnected) {
4161
+ this.state.brain.isAvailable = false;
4162
+ return;
4163
+ }
4164
+ if (this.pauseRefreshOnFileTransfer && !this.state._isFileTransferring) {
4165
+ this.refresh();
4166
+ }
4167
+ }
4168
+ }, 200);
4169
+ this._refreshInterval.unref?.();
4170
+ }
4171
+ stopAutoRefresh() {
4172
+ if (!this._refreshInterval)
4173
+ return;
4174
+ clearInterval(this._refreshInterval);
4175
+ this._refreshInterval = undefined;
4176
+ }
4177
+ get isV5Controller() {
4178
+ return this.deviceType === 1283 /* V5_CONTROLLER */;
4179
+ }
4180
+ get brain() {
4181
+ return new V5Brain(this.state);
4182
+ }
4183
+ get controllers() {
4184
+ return [new V5Controller(this.state, 0), new V5Controller(this.state, 1)];
4185
+ }
4186
+ get devices() {
4187
+ let rtn = [];
4188
+ for (let i = 1;i <= this.state.devices.length; i++) {
4189
+ if (this.state.devices[i])
4190
+ rtn.push(new V5SmartDevice(this.state, i));
4191
+ }
4192
+ return rtn;
4193
+ }
4194
+ get isFieldControllerConnected() {
4195
+ return this.state.isFieldControllerConnected;
4196
+ }
4197
+ get matchMode() {
4198
+ return this.state.matchMode;
4199
+ }
4200
+ set matchMode(value) {
4201
+ (async () => {
4202
+ if (await this.connection?.setMatchMode(value))
4203
+ this.state.matchMode = value;
4204
+ })();
4205
+ }
4206
+ get radio() {
4207
+ return new V5Radio(this.state);
4208
+ }
4209
+ async mockTouch(x, y, press) {
4210
+ return await this.connection?.mockTouch(x, y, press) ? true : false;
4211
+ }
4212
+ async connect(conn) {
4213
+ if (this.isConnected)
4214
+ return true;
4215
+ this.startAutoRefresh();
4216
+ if (conn?.isConnected) {
4217
+ if (await conn.query1() === null)
4218
+ return false;
4219
+ this.connection = conn;
4220
+ } else {
4221
+ let tryIdx = 0;
4222
+ while (true) {
4223
+ let c = new V5SerialConnection(this.defaultSerial);
4224
+ let result = await c.open(tryIdx++, true);
4225
+ if (result === undefined)
4226
+ return false;
4227
+ if (result === false) {
4228
+ await c.close();
4229
+ continue;
4230
+ }
4231
+ if (await c.query1() === null) {
4232
+ await c.close();
4233
+ continue;
4234
+ }
4235
+ this.connection = c;
4236
+ break;
4237
+ }
4238
+ }
4239
+ if (!this.isConnected)
4240
+ return false;
4241
+ await this.doAfterConnect();
4242
+ return true;
4243
+ }
4244
+ async disconnect() {
4245
+ this._isDisconnecting = true;
4246
+ this.stopAutoRefresh();
4247
+ try {
4248
+ await this.connection?.close();
4249
+ this.connection = undefined;
4250
+ } finally {
4251
+ this._isDisconnecting = false;
4252
+ }
4253
+ }
4254
+ async reconnect(timeout = 0) {
4255
+ if (this.isConnected)
4256
+ return true;
4257
+ if (timeout < 0)
4258
+ return false;
4259
+ let endTime = new Date().getTime() + timeout;
4260
+ if (this._isReconnecting) {
4261
+ let successB4Timeout;
4262
+ do {
4263
+ successB4Timeout = await sleepUntil(() => !this._isReconnecting, timeout || 1000);
4264
+ } while (timeout === 0 && !successB4Timeout);
4265
+ if (this.isConnected)
4266
+ return true;
4267
+ if (!successB4Timeout)
4268
+ return false;
4269
+ }
4270
+ this._isReconnecting = true;
4271
+ while (timeout === 0 || new Date().getTime() > endTime) {
4272
+ let tryIdx = 0;
4273
+ while (true) {
4274
+ let c = new V5SerialConnection(this.defaultSerial);
4275
+ let result = await c.open(tryIdx++, false);
4276
+ if (result === undefined)
4277
+ break;
4278
+ if (result === false) {
4279
+ await c.close();
4280
+ continue;
4281
+ }
4282
+ let result2 = await c.getSystemStatus(200);
4283
+ if (result2 === null) {
4284
+ await c.close();
4285
+ continue;
4286
+ }
4287
+ if (this.brain.uniqueId !== 0 && result2.uniqueId !== this.brain.uniqueId) {
4288
+ await c.close();
4289
+ continue;
4290
+ }
4291
+ this.connection = c;
4292
+ break;
4293
+ }
4294
+ if (this.isConnected)
4295
+ break;
4296
+ let getPortCount = async () => (await this.defaultSerial.getPorts()).length;
4297
+ let portsCount = await getPortCount();
4298
+ await sleepUntil(async () => await getPortCount() !== portsCount, 1000);
4299
+ }
4300
+ this._isReconnecting = false;
4301
+ if (!this.isConnected)
4302
+ return false;
4303
+ this.doAfterConnect();
4304
+ return true;
4305
+ }
4306
+ async doAfterConnect() {
4307
+ if (!this.connection)
4308
+ return;
4309
+ this.connection.on("disconnected", (_data) => {
4310
+ if (this.autoReconnect && !this._isDisconnecting)
4311
+ this.reconnect();
4312
+ });
4313
+ await this.refresh();
4314
+ }
4315
+ async refresh() {
4316
+ let ssPacket = await this.connection?.getSystemStatus();
4317
+ if (!ssPacket) {
4318
+ this.state.brain.isAvailable = false;
4319
+ return false;
4320
+ }
4321
+ this.state.brain.cpu0Version = ssPacket.cpu0Version;
4322
+ this.state.brain.cpu1Version = ssPacket.cpu1Version;
4323
+ this.state.brain.systemVersion = ssPacket.systemVersion;
4324
+ let flags2 = ssPacket.sysflags[2];
4325
+ this.state.controllers[0].isCharging = (flags2 & 128) !== 0;
4326
+ this.state.matchMode = flags2 & 32 ? "disabled" : flags2 & 64 ? "autonomous" : "driver";
4327
+ this.state.isFieldControllerConnected = (flags2 & 16) !== 0;
4328
+ let flags4 = ssPacket.sysflags[4];
4329
+ this.state.brain.settings.usingLanguage = (flags4 & 240) >> 4;
4330
+ this.state.brain.settings.isWhiteTheme = (flags4 & 4) !== 0;
4331
+ this.state.brain.settings.isScreenReversed = (flags4 & 1) === 0;
4332
+ this.state.brain.uniqueId = ssPacket.uniqueId;
4333
+ let sfPacket = await this.connection?.getSystemFlags();
4334
+ if (!sfPacket)
4335
+ return false;
4336
+ let flags5 = sfPacket.flags;
4337
+ this.state.radio.isRadioData = (flags5 & Math.pow(2, 32 - 12)) !== 0;
4338
+ this.state.brain.button.isDoublePressed = (flags5 & Math.pow(2, 32 - 14)) !== 0;
4339
+ this.state.brain.battery.isCharging = (flags5 & Math.pow(2, 32 - 15)) !== 0;
4340
+ this.state.brain.button.isPressed = (flags5 & Math.pow(2, 32 - 17)) !== 0;
4341
+ this.state.radio.isVexNet = (flags5 & Math.pow(2, 32 - 18)) !== 0;
4342
+ this.state.controllers[1].isAvailable = (flags5 & Math.pow(2, 32 - 19)) !== 0;
4343
+ this.state.radio.isConnected = (flags5 & Math.pow(2, 32 - 22)) !== 0;
4344
+ this.state.radio.isAvailable = (flags5 & Math.pow(2, 32 - 23)) !== 0;
4345
+ this.state.brain.battery.batteryPercent = sfPacket.battery || 0;
4346
+ this.state.controllers[0].isAvailable = this.state.radio.isConnected || this.state.controllers[0].isCharging;
4347
+ this.state.controllers[0].battery = sfPacket.controllerBatteryPercent || 0;
4348
+ this.state.controllers[1].battery = sfPacket.partnerControllerBatteryPercent || 0;
4349
+ this.state.brain.activeProgram = sfPacket.currentProgram;
4350
+ this.state.brain.isAvailable = !this.isV5Controller || this.state.radio.isConnected;
4351
+ let rdPacket = await this.connection?.getRadioStatus();
4352
+ if (!rdPacket)
4353
+ return false;
4354
+ this.state.radio.channel = rdPacket.channel;
4355
+ this.state.radio.latency = rdPacket.timeslot;
4356
+ this.state.radio.signalQuality = rdPacket.quality;
4357
+ this.state.radio.signalStrength = rdPacket.strength;
4358
+ let dsPacket = await this.connection?.getDeviceStatus();
4359
+ if (!dsPacket)
4360
+ return false;
4361
+ let missingPorts = this.state.devices.map((d) => d?.port).filter((p) => p !== undefined);
4362
+ for (let i = 0;i < dsPacket.devices.length; i++) {
4363
+ let device = dsPacket.devices[i];
4364
+ this.state.devices[device.port] = device;
4365
+ missingPorts = missingPorts.filter((p) => p !== device.port);
4366
+ }
4367
+ missingPorts.forEach((port) => delete this.state.devices[port]);
4368
+ return true;
4369
+ }
4370
+ }
4371
+ // src/index.ts
4372
+ console.log(import_picocolors.default.redBright(`v5x ${package_default.version}`));
4373
+ console.log("modern cli for v5 development");
4374
+ async function main() {
4375
+ const device = new V5SerialDevice(serial);
4376
+ try {
4377
+ await device.connect();
4378
+ } catch {
4379
+ console.warn(import_picocolors.default.yellow("v5 device not found"));
4380
+ }
4381
+ if (device.isConnected) {
4382
+ console.log("os:", device.brain.systemVersion.toUserString());
4383
+ console.log("name:", await device.brain.getValue("robotname"));
4384
+ console.log("team:", await device.brain.getValue("teamnumber"));
4385
+ console.log("id:", device.brain.uniqueId.toString());
4386
+ await device.disconnect();
4387
+ }
4388
+ }
4389
+ main();