@poe-platform/safe-bash 0.1.619 → 0.1.621

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.
@@ -2127,9 +2127,9 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
2127
2127
  for (const name2 of names) {
2128
2128
  const counts = { l: 0, w: 0, m: 0, c: 0 };
2129
2129
  let inWord = false;
2130
- const word = (whitespace2) => {
2131
- if (!whitespace2 && !inWord) counts.w++;
2132
- inWord = !whitespace2;
2130
+ const word = (whitespace3) => {
2131
+ if (!whitespace3 && !inWord) counts.w++;
2132
+ inWord = !whitespace3;
2133
2133
  };
2134
2134
  const utf82 = wcUtf8((point) => {
2135
2135
  if (point !== void 0) counts.m++;
@@ -2493,13 +2493,13 @@ function sortKey(specification) {
2493
2493
  };
2494
2494
  }
2495
2495
  async function keyBytes(line, key, separator, blanks, work) {
2496
- const fields3 = [];
2496
+ const fields4 = [];
2497
2497
  if (separator !== void 0) {
2498
2498
  let start2 = 0;
2499
2499
  for (let offset = 0; offset <= line.length; offset++) {
2500
2500
  if (offset > 0 && offset % 1024 === 0) await work.charge(1024);
2501
2501
  if (offset === line.length || line[offset] === separator) {
2502
- fields3.push({ start: start2, end: offset });
2502
+ fields4.push({ start: start2, end: offset });
2503
2503
  start2 = offset + 1;
2504
2504
  }
2505
2505
  }
@@ -2515,12 +2515,12 @@ async function keyBytes(line, key, separator, blanks, work) {
2515
2515
  while (offset < line.length && line[offset] !== 32 && line[offset] !== 9) {
2516
2516
  if (++offset % 1024 === 0) await work.charge(1024);
2517
2517
  }
2518
- fields3.push({ start: start2, end: offset });
2518
+ fields4.push({ start: start2, end: offset });
2519
2519
  }
2520
2520
  }
2521
2521
  await work.charge(line.length % 1024);
2522
- const start = (fields3[key.start - 1]?.start ?? line.length) + key.startCharacter - 1;
2523
- const last = key.end === void 0 ? void 0 : fields3[key.end - 1];
2522
+ const start = (fields4[key.start - 1]?.start ?? line.length) + key.startCharacter - 1;
2523
+ const last = key.end === void 0 ? void 0 : fields4[key.end - 1];
2524
2524
  const end = key.end === void 0 ? line.length : last === void 0 ? line.length : key.endCharacter === void 0 ? last.end : Math.min(last.end, last.start + key.endCharacter);
2525
2525
  return line.subarray(Math.min(start, line.length), Math.max(start, end));
2526
2526
  }
@@ -12459,8 +12459,8 @@ function formatted(format3, values, text3, budget) {
12459
12459
  else if (conversion === "g" || conversion === "G") part = general2(amount, precision ?? 6, flags3.includes("#"));
12460
12460
  else {
12461
12461
  const radix = conversion === "o" ? 8 : conversion === "x" || conversion === "X" ? 16 : 10;
12462
- const integer9 = BigInt(Math.trunc(amount));
12463
- part = (/[uoxX]/u.test(conversion) ? BigInt.asUintN(32, integer9) : integer9).toString(radix);
12462
+ const integer10 = BigInt(Math.trunc(amount));
12463
+ part = (/[uoxX]/u.test(conversion) ? BigInt.asUintN(32, integer10) : integer10).toString(radix);
12464
12464
  if (precision !== void 0) {
12465
12465
  const negative = part.startsWith("-");
12466
12466
  admit2(amount === 0 && precision === 0 ? 0 : Math.max(part.length, precision + Number(negative)));
@@ -13320,9 +13320,9 @@ var AwkRuntime = class {
13320
13320
  if (name2 === "NF" && this.store(name2) === this.variables) {
13321
13321
  const length = Math.trunc(number(value2));
13322
13322
  if (!Number.isSafeInteger(length) || length < 0 || length > 1e5) throw new ProgramError("invalid or excessive NF");
13323
- const fields3 = this.fields.slice(0, length);
13324
- while (fields3.length < length) fields3.push(unset);
13325
- this.rebuild(fields3);
13323
+ const fields4 = this.fields.slice(0, length);
13324
+ while (fields4.length < length) fields4.push(unset);
13325
+ this.rebuild(fields4);
13326
13326
  return;
13327
13327
  }
13328
13328
  this.storeScalar(this.store(name2), name2, value2);
@@ -13428,23 +13428,23 @@ var AwkRuntime = class {
13428
13428
  }
13429
13429
  async setRecord(record3) {
13430
13430
  this.budget.check(record3);
13431
- const fields3 = await this.split(record3, this.varText("FS"), this.varText("RS") === "");
13432
- this.replaceRecord(record3, fields3);
13431
+ const fields4 = await this.split(record3, this.varText("FS"), this.varText("RS") === "");
13432
+ this.replaceRecord(record3, fields4);
13433
13433
  }
13434
- replaceRecord(record3, fields3) {
13434
+ replaceRecord(record3, fields4) {
13435
13435
  let fieldBytes = 0;
13436
- for (const field2 of fields3) {
13436
+ for (const field2 of fields4) {
13437
13437
  if (field2.kind === "string" || field2.kind === "numeric") this.budget.check(field2.text);
13438
13438
  fieldBytes += textSize(field2);
13439
13439
  }
13440
13440
  const owned = this.retention.replace(this.record.length + this.fieldBytes, record3.length + fieldBytes, () => ({
13441
13441
  record: import_buffer.Buffer.from(record3, "latin1").toString("latin1"),
13442
- fields: fields3.map((field2, index) => field2 === this.fields[index] ? field2 : ownScalar(field2))
13442
+ fields: fields4.map((field2, index) => field2 === this.fields[index] ? field2 : ownScalar(field2))
13443
13443
  }));
13444
13444
  this.record = owned.record;
13445
13445
  this.fields = owned.fields;
13446
13446
  this.fieldBytes = fieldBytes;
13447
- this.variables.set("NF", numeric(fields3.length));
13447
+ this.variables.set("NF", numeric(fields4.length));
13448
13448
  }
13449
13449
  join(parts, separator, suffix2 = "") {
13450
13450
  this.budget.step(parts.length + 1);
@@ -13462,9 +13462,9 @@ var AwkRuntime = class {
13462
13462
  this.budget.step(this.budget.maxBufferBytes - remaining);
13463
13463
  return parts.join(separator) + suffix2;
13464
13464
  }
13465
- rebuild(fields3) {
13466
- const record3 = this.join(fields3.map((value2) => this.asText(value2)), this.varText("OFS"));
13467
- this.replaceRecord(record3, fields3);
13465
+ rebuild(fields4) {
13466
+ const record3 = this.join(fields4.map((value2) => this.asText(value2)), this.varText("OFS"));
13467
+ this.replaceRecord(record3, fields4);
13468
13468
  }
13469
13469
  async key(items) {
13470
13470
  const pieces = [];
@@ -13480,10 +13480,10 @@ var AwkRuntime = class {
13480
13480
  get: () => index === 0 ? inputValue(this.record) : this.fields[index - 1] ?? unset,
13481
13481
  set: (value2) => {
13482
13482
  if (index === 0) return this.setRecord(this.asText(value2));
13483
- const fields3 = this.fields.slice();
13484
- while (fields3.length < index) fields3.push(unset);
13485
- fields3[index - 1] = value2;
13486
- this.rebuild(fields3);
13483
+ const fields4 = this.fields.slice();
13484
+ while (fields4.length < index) fields4.push(unset);
13485
+ fields4[index - 1] = value2;
13486
+ this.rebuild(fields4);
13487
13487
  }
13488
13488
  };
13489
13489
  }
@@ -21808,14 +21808,14 @@ function flags(args) {
21808
21808
  }
21809
21809
  return result;
21810
21810
  }
21811
- async function comparisonLines(lines3, whitespace2, budget) {
21812
- if (whitespace2 === "exact") return lines3;
21811
+ async function comparisonLines(lines3, whitespace3, budget) {
21812
+ if (whitespace3 === "exact") return lines3;
21813
21813
  const result = [];
21814
21814
  for (const line of lines3) {
21815
21815
  budget.step(1 + line.length);
21816
21816
  await budget.checkpoint();
21817
21817
  const body = line.endsWith("\n") ? line.slice(0, -1) : line;
21818
- const normalized = body.replace(/[ \t\v\f\r]+/gu, whitespace2 === "all" ? "" : " ");
21818
+ const normalized = body.replace(/[ \t\v\f\r]+/gu, whitespace3 === "all" ? "" : " ");
21819
21819
  result.push(normalized.endsWith(" ") ? normalized.slice(0, -1) : normalized);
21820
21820
  }
21821
21821
  return result;
@@ -23382,8 +23382,8 @@ function timestamp2(milliseconds) {
23382
23382
  const value2 = available(milliseconds, "timestamp");
23383
23383
  if (Math.abs(value2) > 864e13) throw new FsError("EIO", { message: "invalid filesystem timestamp" });
23384
23384
  const [coefficient = "0", exponent = "0"] = Math.abs(value2).toString().split("e");
23385
- const [integer9 = "0", fraction = ""] = coefficient.split(".");
23386
- const digits = BigInt(integer9 + fraction);
23385
+ const [integer10 = "0", fraction = ""] = coefficient.split(".");
23386
+ const digits = BigInt(integer10 + fraction);
23387
23387
  const power2 = Number(exponent) - fraction.length + 6;
23388
23388
  const divisor = power2 < 0 ? 10n ** BigInt(-power2) : 1n;
23389
23389
  const magnitude = power2 < 0 ? (digits + divisor / 2n) / divisor : digits * 10n ** BigInt(power2);
@@ -23435,9 +23435,9 @@ function formatField(text3, code, flags3, width, precision, numeric4, epoch2) {
23435
23435
  if (epoch2 && precision) {
23436
23436
  const decimal4 = text3.indexOf(".");
23437
23437
  const integerWidth = width > precision + 2 && !flags3.includes("-") ? width - precision - 1 : 0;
23438
- const integer9 = formatField(text3.slice(0, decimal4), code, flags3, integerWidth, void 0, true, false);
23439
- const trailingWidth = integer9.length < width && 1 < width - integer9.length ? Math.abs(width - integer9.length - 1 - precision) : 0;
23440
- return import_buffer.Buffer.concat([integer9, import_buffer.Buffer.from(text3.slice(decimal4)), import_buffer.Buffer.alloc(trailingWidth, 32)]);
23438
+ const integer10 = formatField(text3.slice(0, decimal4), code, flags3, integerWidth, void 0, true, false);
23439
+ const trailingWidth = integer10.length < width && 1 < width - integer10.length ? Math.abs(width - integer10.length - 1 - precision) : 0;
23440
+ return import_buffer.Buffer.concat([integer10, import_buffer.Buffer.from(text3.slice(decimal4)), import_buffer.Buffer.alloc(trailingWidth, 32)]);
23441
23441
  }
23442
23442
  const encoded2 = import_buffer.Buffer.from(text3);
23443
23443
  const bytes3 = !numeric4 && precision !== void 0 ? encoded2.subarray(0, precision) : encoded2;
@@ -23524,9 +23524,9 @@ async function render(context2, path, name2, stat, format3, escapes, limit) {
23524
23524
  const value2 = times[code.toUpperCase()];
23525
23525
  text3 = code === "w" && value2 === void 0 ? "-" : timestamp2(available(value2, code));
23526
23526
  } else {
23527
- const fields3 = { s: stat.size, a: stat.mode & 4095, f: stat.mode, i: stat.ino, h: stat.nlink, u: stat.uid, g: stat.gid, d: stat.dev, D: stat.dev };
23528
- if (!Object.hasOwn(fields3, code)) throw new FsError("ENOTSUP", { message: `unsupported stat format: %${code}` });
23529
- const value2 = available(fields3[code], code);
23527
+ const fields4 = { s: stat.size, a: stat.mode & 4095, f: stat.mode, i: stat.ino, h: stat.nlink, u: stat.uid, g: stat.gid, d: stat.dev, D: stat.dev };
23528
+ if (!Object.hasOwn(fields4, code)) throw new FsError("ENOTSUP", { message: `unsupported stat format: %${code}` });
23529
+ const value2 = available(fields4[code], code);
23530
23530
  text3 = value2.toString(code === "a" ? 8 : code === "f" || code === "D" ? 16 : 10);
23531
23531
  numeric4 = true;
23532
23532
  }
@@ -26612,6 +26612,216 @@ async function readArchive(context2, source2, options2, budget) {
26612
26612
  // packages/safe-bash/src/commands/archive/zip.ts
26613
26613
  init_platform();
26614
26614
 
26615
+ // packages/safe-bash/src/commands/archive/zip/dates.ts
26616
+ init_platform();
26617
+
26618
+ // packages/safe-bash/src/commands/archive/zip/options.ts
26619
+ init_platform();
26620
+ var ZipFailure = class extends Error {
26621
+ constructor(status2, label, detail) {
26622
+ super(detail);
26623
+ this.status = status2;
26624
+ this.label = label;
26625
+ }
26626
+ status;
26627
+ label;
26628
+ };
26629
+ var longOptions = {
26630
+ "recurse-paths": "r",
26631
+ quiet: "q",
26632
+ "junk-paths": "j",
26633
+ "no-dir-entries": "D",
26634
+ symlinks: "y",
26635
+ test: "T",
26636
+ "names-stdin": "@",
26637
+ update: "u",
26638
+ freshen: "f",
26639
+ delete: "d",
26640
+ include: "i",
26641
+ exclude: "x",
26642
+ suffixes: "n",
26643
+ store: "0",
26644
+ "compression-method": "Z",
26645
+ "compress-1": "1",
26646
+ "compress-2": "2",
26647
+ "compress-3": "3",
26648
+ "compress-4": "4",
26649
+ "compress-5": "5",
26650
+ "compress-6": "6",
26651
+ "compress-7": "7",
26652
+ "compress-8": "8",
26653
+ "compress-9": "9",
26654
+ "force-zip64": "fz",
26655
+ "strip-extra": "X",
26656
+ "force-descriptors": "fd",
26657
+ "no-wild": "nw",
26658
+ "wild-stop-dirs": "ws",
26659
+ "recurse-patterns": "R",
26660
+ "from-date": "t",
26661
+ "before-date": "tt",
26662
+ "copy-entries": "U",
26663
+ "output-file": "O"
26664
+ };
26665
+ var reservedOptions = [
26666
+ "adjust-sfx",
26667
+ "temp-path",
26668
+ "entry-comments",
26669
+ "display-bytes",
26670
+ "display-counts",
26671
+ "display-dots",
26672
+ "display-globaldots",
26673
+ "dot-size",
26674
+ "display-usize",
26675
+ "display-volume",
26676
+ "difference-archive",
26677
+ "encrypt",
26678
+ "fix",
26679
+ "fixfix",
26680
+ "fifo",
26681
+ "filesync",
26682
+ "grow",
26683
+ "help",
26684
+ "more-help",
26685
+ "junk-sfx",
26686
+ "DOS-names",
26687
+ "to-crlf",
26688
+ "from-crlf",
26689
+ "logfile-path",
26690
+ "log-append",
26691
+ "log-info",
26692
+ "license",
26693
+ "move",
26694
+ "must-match",
26695
+ "latest-time",
26696
+ "paths",
26697
+ "password",
26698
+ "regex",
26699
+ "split-size",
26700
+ "split-pause",
26701
+ "split-verbose",
26702
+ "split-bell",
26703
+ "show-command",
26704
+ "show-debug",
26705
+ "show-files",
26706
+ "show-options",
26707
+ "unzip-command",
26708
+ "verbose",
26709
+ "version",
26710
+ "archive-comment"
26711
+ ];
26712
+ function normalizeZipOption(argument2) {
26713
+ if (!argument2.startsWith("--") || argument2 === "--") return argument2;
26714
+ const equal2 = argument2.indexOf("=");
26715
+ const rawName = argument2.slice(2, equal2 < 0 ? void 0 : equal2);
26716
+ const negate2 = rawName.endsWith("-");
26717
+ const name2 = negate2 ? rawName.slice(0, -1) : rawName;
26718
+ const names = [...Object.keys(longOptions), ...reservedOptions];
26719
+ const matches2 = names.includes(name2) ? [name2] : names.filter((option) => option.startsWith(name2));
26720
+ if (matches2.length > 1) throw new ZipFailure(16, "Invalid command arguments", `long option '${name2}' ambiguous`);
26721
+ const matched = matches2[0];
26722
+ const short = matched === void 0 ? void 0 : longOptions[matched];
26723
+ if (!short) throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
26724
+ if (negate2 && short !== "fz" && short !== "X") throw new ZipFailure(16, "Invalid command arguments", `option ${matched} is not negatable`);
26725
+ if (equal2 >= 0 && short !== "i" && short !== "x" && short !== "n" && short !== "Z" && short !== "t" && short !== "tt" && short !== "O") {
26726
+ throw new ZipFailure(16, "Invalid command arguments", `option '${matched}' does not allow a value`);
26727
+ }
26728
+ return `-${short}${negate2 ? "-" : ""}${equal2 < 0 ? "" : argument2.slice(equal2)}`;
26729
+ }
26730
+
26731
+ // packages/safe-bash/src/commands/archive/zip/dates.ts
26732
+ function integer4(input3, start, width) {
26733
+ let offset = start;
26734
+ while (" \r\n\v\f".includes(input3[offset] ?? "\0")) offset++;
26735
+ const end = offset + width;
26736
+ let sign = 1;
26737
+ if (input3[offset] === "+" || input3[offset] === "-") {
26738
+ sign = input3[offset] === "-" ? -1 : 1;
26739
+ offset++;
26740
+ }
26741
+ let digits = 0;
26742
+ let value2 = 0;
26743
+ while (offset < end && input3[offset] !== void 0 && input3[offset] >= "0" && input3[offset] <= "9") {
26744
+ value2 = value2 * 10 + Number(input3[offset++]);
26745
+ digits++;
26746
+ }
26747
+ return digits ? { value: value2 * sign, end: offset } : void 0;
26748
+ }
26749
+ function fields2(input3, iso) {
26750
+ const first = integer4(input3, 0, iso ? 4 : 2);
26751
+ if (!first || iso && input3[first.end] !== "-") return;
26752
+ const second = integer4(input3, first.end + (iso ? 1 : 0), 2);
26753
+ if (!second || iso && input3[second.end] !== "-") return;
26754
+ const third = integer4(input3, second.end + (iso ? 1 : 0), iso ? 2 : 4);
26755
+ if (!third) return;
26756
+ return iso ? [first.value, second.value, third.value] : [third.value, first.value, second.value];
26757
+ }
26758
+ function parseZipDate(input3, option) {
26759
+ const result = fields2(input3, true) ?? fields2(input3, false);
26760
+ if (!result || result[1] < 1 || result[1] > 12 || result[2] < 1 || result[2] > 31) {
26761
+ throw new ZipFailure(16, "Invalid command arguments", `invalid date entered for -${option} option - use mmddyyyy or yyyy-mm-dd`);
26762
+ }
26763
+ const [year, month, day] = result;
26764
+ return year < 1980 ? 2162688 : (year - 1980) * 33554432 + month * 2097152 + day * 65536;
26765
+ }
26766
+ function zipDateMatches(modified, from, until) {
26767
+ if (from === void 0 && until === void 0) return true;
26768
+ const rounded2 = new Date(Math.ceil(Math.floor(modified.getTime() / 1e3) / 2) * 2e3);
26769
+ const key = rounded2.getFullYear() < 1980 ? 2162688 : (rounded2.getFullYear() - 1980) * 33554432 + (rounded2.getMonth() + 1) * 2097152 + rounded2.getDate() * 65536 + rounded2.getHours() * 2048 + rounded2.getMinutes() * 32 + rounded2.getSeconds() / 2;
26770
+ return (from === void 0 || key >= from) && (until === void 0 || key < until);
26771
+ }
26772
+
26773
+ // packages/safe-bash/src/commands/archive/zip/environment.ts
26774
+ init_platform();
26775
+ function whitespace(character) {
26776
+ return character === " " || character === " " || character === "\n" || character === "\r" || character === "\v" || character === "\f";
26777
+ }
26778
+ function zipEnvironmentArguments(env, argv, limits) {
26779
+ let value2 = "";
26780
+ let selectedBytes = 0;
26781
+ for (const key of ["ZIPOPT", "ZIP_OPTS"]) {
26782
+ const candidate = env[key] ?? "";
26783
+ if (import_buffer.Buffer.byteLength(candidate) > limits.maxArgumentBytes) fail("environment argument byte limit exceeded");
26784
+ let start = 0;
26785
+ while (whitespace(candidate[start])) start++;
26786
+ if (start < candidate.length) {
26787
+ value2 = candidate.slice(start);
26788
+ selectedBytes = import_buffer.Buffer.byteLength(candidate);
26789
+ break;
26790
+ }
26791
+ }
26792
+ if (!value2) return argv;
26793
+ if (value2.includes("\0") || import_buffer.Buffer.from(value2).toString("utf8") !== value2) fail("invalid environment argument text");
26794
+ let bytes3 = selectedBytes;
26795
+ for (const argument2 of argv) {
26796
+ bytes3 += import_buffer.Buffer.byteLength(argument2);
26797
+ if (bytes3 > limits.maxArgumentBytes) fail("argument byte limit exceeded");
26798
+ }
26799
+ const defaults = [];
26800
+ let offset = 0;
26801
+ while (offset < value2.length) {
26802
+ let argument2 = "";
26803
+ if (value2[offset] === '"') {
26804
+ offset++;
26805
+ while (offset < value2.length && value2[offset] !== '"') {
26806
+ if (value2[offset] === "\\") {
26807
+ offset++;
26808
+ if (offset === value2.length) break;
26809
+ }
26810
+ argument2 += value2[offset++];
26811
+ }
26812
+ if (value2[offset] === '"') offset++;
26813
+ } else {
26814
+ const start = offset;
26815
+ while (offset < value2.length && !whitespace(value2[offset])) offset++;
26816
+ argument2 = value2.slice(start, offset);
26817
+ }
26818
+ if (defaults.length + argv.length >= limits.maxArgumentBytes) fail("argument count limit exceeded");
26819
+ defaults.push(argument2);
26820
+ while (whitespace(value2[offset])) offset++;
26821
+ }
26822
+ return [...defaults, ...argv];
26823
+ }
26824
+
26615
26825
  // packages/safe-bash/src/commands/archive/zip-format.ts
26616
26826
  init_platform();
26617
26827
 
@@ -27059,7 +27269,7 @@ function updateZipExtras(entry, previous, mode, limits) {
27059
27269
  const fresh = mode === "strip" ? new Uint8Array() : timestampExtra(entry.modified);
27060
27270
  const retained = [];
27061
27271
  for (const [original, central] of [[previous?.localExtra, false], [previous?.centralExtra, true]]) {
27062
- const fields3 = [];
27272
+ const fields4 = [];
27063
27273
  let length = fresh.length;
27064
27274
  if (mode === "all" && original) {
27065
27275
  extras(original, previous.rawName ?? pathBytes(previous.name, limits), previous.comment ?? new Uint8Array(), central, limits);
@@ -27068,7 +27278,7 @@ function updateZipExtras(entry, previous, mode, limits) {
27068
27278
  const identifier = view.getUint16(offset2, true);
27069
27279
  const next = offset2 + 4 + view.getUint16(offset2 + 2, true);
27070
27280
  if (identifier !== 1 && identifier !== 21589 && identifier !== 28789 && identifier !== 25461) {
27071
- fields3.push(original.subarray(offset2, next));
27281
+ fields4.push(original.subarray(offset2, next));
27072
27282
  length += next - offset2;
27073
27283
  }
27074
27284
  offset2 = next;
@@ -27077,7 +27287,7 @@ function updateZipExtras(entry, previous, mode, limits) {
27077
27287
  number3(length, Math.min(limits.maxPaxBytes, 65535), "extra field");
27078
27288
  const bytes3 = new Uint8Array(length);
27079
27289
  let offset = 0;
27080
- for (const field2 of fields3) {
27290
+ for (const field2 of fields4) {
27081
27291
  bytes3.set(field2, offset);
27082
27292
  offset += field2.length;
27083
27293
  }
@@ -27437,18 +27647,23 @@ function parseArguments(context2, limits) {
27437
27647
  checkPath(archive, limits);
27438
27648
  return { list: list && !pipe, pipe, overwrite, destination: destination2, archive, patterns: patterns2 };
27439
27649
  }
27440
- function tokenize2(pattern) {
27650
+ function tokenize2(pattern, noWild, stopAtDirectories) {
27441
27651
  const characters = Array.from(pattern);
27442
27652
  const tokens2 = [];
27443
27653
  for (let index = 0; index < characters.length; index++) {
27444
27654
  const character = characters[index];
27445
- if (character === "*") {
27446
- if (tokens2.at(-1)?.kind !== "star") tokens2.push({ kind: "star" });
27655
+ if (character === "*" && !noWild) {
27656
+ let count2 = 1;
27657
+ while (characters[index + 1] === "*") {
27658
+ count2++;
27659
+ index++;
27660
+ }
27661
+ tokens2.push({ kind: "star", crossDirectories: !stopAtDirectories || count2 > 1 });
27447
27662
  } else if (character === "?") tokens2.push({ kind: "any" });
27448
- else if (character === "\\") {
27663
+ else if (character === "\\" && !noWild) {
27449
27664
  const escaped3 = characters[++index];
27450
27665
  tokens2.push(escaped3 === void 0 ? { kind: "never" } : { kind: "literal", value: escaped3 });
27451
- } else if (character === "[") {
27666
+ } else if (character === "[" && !noWild) {
27452
27667
  const negative = characters[index + 1] === "!" || characters[index + 1] === "^";
27453
27668
  if (negative) index++;
27454
27669
  const ranges = [];
@@ -27474,35 +27689,43 @@ function tokenize2(pattern) {
27474
27689
  return tokens2;
27475
27690
  }
27476
27691
  var Selection = class {
27477
- constructor(patterns2, limits, signal) {
27692
+ constructor(patterns2, limits, signal, options2 = {}) {
27478
27693
  this.limits = limits;
27479
27694
  this.signal = signal;
27480
- this.patterns = patterns2.map(tokenize2);
27695
+ this.options = options2;
27696
+ this.patterns = patterns2.map((pattern) => tokenize2(pattern, options2.noWild === true, options2.stopAtDirectories === true));
27697
+ this.tailComponents = patterns2.map((pattern) => pattern.split("/").length);
27698
+ this.emptyTailMatch = patterns2.map((pattern) => !options2.noWild && (pattern === "*" || options2.stopAtDirectories === true && pattern === "**"));
27481
27699
  }
27482
27700
  limits;
27483
27701
  signal;
27702
+ options;
27484
27703
  work = 0;
27485
27704
  patterns;
27705
+ tailComponents;
27706
+ emptyTailMatch;
27486
27707
  matched = /* @__PURE__ */ new Set();
27487
27708
  step() {
27488
27709
  if (++this.work > this.limits.maxPatternSteps) fail("pattern work limit exceeded");
27489
27710
  }
27490
27711
  async matches(name2, firstMatchOnly = false) {
27491
27712
  if (!this.patterns.length) return true;
27492
- const characters = Array.from(name2);
27713
+ const fullCharacters = Array.from(name2);
27493
27714
  let selected = false;
27494
27715
  for (let pattern = 0; pattern < this.patterns.length; pattern++) {
27495
27716
  this.step();
27717
+ const characters = this.options.trailingComponents ? Array.from(name2.split("/").slice(-this.tailComponents[pattern]).join("/")) : fullCharacters;
27718
+ if (this.options.trailingComponents && !characters.length && !this.emptyTailMatch[pattern]) continue;
27496
27719
  let states = new Uint8Array(characters.length + 1);
27497
27720
  states[0] = 1;
27498
27721
  for (const token of this.patterns[pattern]) {
27499
27722
  const next = new Uint8Array(states.length);
27500
27723
  for (let index = 0; index < states.length; index++) {
27501
27724
  this.step();
27502
- if (token.kind === "star") next[index] = states[index] || (index > 0 ? next[index - 1] : 0);
27725
+ if (token.kind === "star") next[index] = states[index] || (index > 0 && (token.crossDirectories || characters[index - 1] !== "/") ? next[index - 1] : 0);
27503
27726
  else if (states[index] && index < characters.length) {
27504
27727
  const character = characters[index];
27505
- let match = token.kind === "any" || token.kind === "literal" && token.value === character;
27728
+ let match = token.kind === "any" && (!this.options.stopAtDirectories || character !== "/") || token.kind === "literal" && token.value === character;
27506
27729
  if (token.kind === "class") {
27507
27730
  let inRange = false;
27508
27731
  for (const [first, last] of token.ranges) {
@@ -27565,126 +27788,14 @@ var Answers = class {
27565
27788
  }
27566
27789
  };
27567
27790
 
27568
- // packages/safe-bash/src/commands/archive/zip/options.ts
27569
- init_platform();
27570
- var ZipFailure = class extends Error {
27571
- constructor(status2, label, detail) {
27572
- super(detail);
27573
- this.status = status2;
27574
- this.label = label;
27575
- }
27576
- status;
27577
- label;
27578
- };
27579
- var longOptions = {
27580
- "recurse-paths": "r",
27581
- quiet: "q",
27582
- "junk-paths": "j",
27583
- "no-dir-entries": "D",
27584
- symlinks: "y",
27585
- test: "T",
27586
- "names-stdin": "@",
27587
- update: "u",
27588
- freshen: "f",
27589
- delete: "d",
27590
- include: "i",
27591
- exclude: "x",
27592
- suffixes: "n",
27593
- store: "0",
27594
- "compression-method": "Z",
27595
- "compress-1": "1",
27596
- "compress-2": "2",
27597
- "compress-3": "3",
27598
- "compress-4": "4",
27599
- "compress-5": "5",
27600
- "compress-6": "6",
27601
- "compress-7": "7",
27602
- "compress-8": "8",
27603
- "compress-9": "9",
27604
- "force-zip64": "fz",
27605
- "strip-extra": "X",
27606
- "force-descriptors": "fd"
27607
- };
27608
- var reservedOptions = [
27609
- "adjust-sfx",
27610
- "temp-path",
27611
- "entry-comments",
27612
- "display-bytes",
27613
- "display-counts",
27614
- "display-dots",
27615
- "display-globaldots",
27616
- "dot-size",
27617
- "display-usize",
27618
- "display-volume",
27619
- "difference-archive",
27620
- "encrypt",
27621
- "fix",
27622
- "fixfix",
27623
- "fifo",
27624
- "filesync",
27625
- "grow",
27626
- "help",
27627
- "more-help",
27628
- "junk-sfx",
27629
- "DOS-names",
27630
- "to-crlf",
27631
- "from-crlf",
27632
- "logfile-path",
27633
- "log-append",
27634
- "log-info",
27635
- "license",
27636
- "move",
27637
- "must-match",
27638
- "no-wild",
27639
- "latest-time",
27640
- "output-file",
27641
- "paths",
27642
- "password",
27643
- "recurse-patterns",
27644
- "regex",
27645
- "split-size",
27646
- "split-pause",
27647
- "split-verbose",
27648
- "split-bell",
27649
- "show-command",
27650
- "show-debug",
27651
- "show-files",
27652
- "show-options",
27653
- "from-date",
27654
- "before-date",
27655
- "unzip-command",
27656
- "copy-entries",
27657
- "verbose",
27658
- "version",
27659
- "wild-stop-dirs",
27660
- "archive-comment"
27661
- ];
27662
- function normalizeZipOption(argument2) {
27663
- if (!argument2.startsWith("--") || argument2 === "--") return argument2;
27664
- const equal2 = argument2.indexOf("=");
27665
- const rawName = argument2.slice(2, equal2 < 0 ? void 0 : equal2);
27666
- const negate2 = rawName.endsWith("-");
27667
- const name2 = negate2 ? rawName.slice(0, -1) : rawName;
27668
- const names = [...Object.keys(longOptions), ...reservedOptions];
27669
- const matches2 = names.includes(name2) ? [name2] : names.filter((option) => option.startsWith(name2));
27670
- if (matches2.length > 1) throw new ZipFailure(16, "Invalid command arguments", `long option '${name2}' ambiguous`);
27671
- const matched = matches2[0];
27672
- const short = matched === void 0 ? void 0 : longOptions[matched];
27673
- if (!short) throw new ZipFailure(16, "Invalid command arguments", `unsupported option: ${argument2}`);
27674
- if (negate2 && short !== "fz" && short !== "X") throw new ZipFailure(16, "Invalid command arguments", `option ${matched} is not negatable`);
27675
- if (equal2 >= 0 && short !== "i" && short !== "x" && short !== "n" && short !== "Z") {
27676
- throw new ZipFailure(16, "Invalid command arguments", `option '${matched}' does not allow a value`);
27677
- }
27678
- return `-${short}${negate2 ? "-" : ""}${equal2 < 0 ? "" : argument2.slice(equal2)}`;
27679
- }
27680
-
27681
27791
  // packages/safe-bash/src/commands/archive/zip.ts
27682
27792
  var defaultStoreSuffixes = [".Z", ".zip", ".zoo", ".arc", ".lzh", ".arj"];
27683
27793
  async function parse12(scope, limits) {
27684
27794
  const context2 = scope.context;
27685
- if (context2.args.length > limits.maxArgumentBytes) fail("argument count limit exceeded");
27795
+ const args = zipEnvironmentArguments(context2.env, context2.args, limits);
27796
+ if (args.length > limits.maxArgumentBytes) fail("argument count limit exceeded");
27686
27797
  let bytes3 = 0;
27687
- for (const argument2 of context2.args) {
27798
+ for (const argument2 of args) {
27688
27799
  const size = import_buffer.Buffer.byteLength(argument2);
27689
27800
  if (size > limits.maxArgumentBytes - bytes3) fail("argument byte limit exceeded");
27690
27801
  bytes3 += size;
@@ -27700,13 +27811,19 @@ async function parse12(scope, limits) {
27700
27811
  for (const value2 of argumentsValue.values) text2(shellValueBytes(value2));
27701
27812
  }
27702
27813
  let archive;
27814
+ let output2;
27703
27815
  let action = "add";
27704
27816
  let recursive = false;
27817
+ let recursivePatterns = false;
27818
+ let noWild = false;
27819
+ let stopAtDirectories = false;
27705
27820
  let quiet = false;
27706
27821
  let junkPaths = false;
27707
27822
  let omitDirectories = false;
27708
27823
  let storeLinks = false;
27709
27824
  let test = false;
27825
+ let fromDate;
27826
+ let beforeDate;
27710
27827
  let descriptors = false;
27711
27828
  let zip64;
27712
27829
  let metadata3 = "default";
@@ -27719,8 +27836,8 @@ async function parse12(scope, limits) {
27719
27836
  const operands = [];
27720
27837
  const includes = [];
27721
27838
  const excludes = [];
27722
- for (let index = 0; index < context2.args.length; index++) {
27723
- const original = context2.args[index];
27839
+ for (let index = 0; index < args.length; index++) {
27840
+ const original = args[index];
27724
27841
  checkPath(original, limits);
27725
27842
  const argument2 = literal ? original : normalizeZipOption(original);
27726
27843
  if (!literal && argument2 === "--") {
@@ -27729,18 +27846,26 @@ async function parse12(scope, limits) {
27729
27846
  } else if (!literal && argument2.startsWith("-") && argument2 !== "-") {
27730
27847
  for (let offset = 1; offset < argument2.length; offset++) {
27731
27848
  const flag = argument2[offset];
27732
- if (flag === "r") recursive = true;
27733
- else if (flag === "f" && argument2[offset + 1] === "d") {
27849
+ if (flag === "r" || flag === "R") {
27850
+ if (flag === "r") recursive = true;
27851
+ else recursivePatterns = true;
27852
+ if (recursive && recursivePatterns) throw new ZipFailure(16, "Invalid command arguments", "do not specify both -r and -R");
27853
+ } else if (flag === "f" && argument2[offset + 1] === "d") {
27734
27854
  if (argument2[offset + 2] === "-") throw new ZipFailure(16, "Invalid command arguments", "option fd is not negatable");
27735
27855
  descriptors = true;
27736
27856
  offset++;
27737
27857
  } else if (flag === "f" && argument2[offset + 1] === "z") {
27738
27858
  zip64 = argument2[offset + 2] !== "-";
27739
27859
  offset += zip64 ? 1 : 2;
27740
- } else if (flag === "d" || flag === "u" || flag === "f") {
27741
- const next = flag === "d" ? "delete" : flag === "u" ? "update" : "freshen";
27860
+ } else if (flag === "d" || flag === "u" || flag === "f" || flag === "U") {
27861
+ const next = flag === "d" ? "delete" : flag === "u" ? "update" : flag === "U" ? "copy" : "freshen";
27742
27862
  if (action !== "add" && action !== next) throw new ZipFailure(16, "Invalid command arguments", "specify just one action");
27743
27863
  action = next;
27864
+ } else if (flag === "n" && argument2[offset + 1] === "w" || flag === "w" && argument2[offset + 1] === "s") {
27865
+ if (argument2[offset + 2] === "-") throw new ZipFailure(16, "Invalid command arguments", "wildcard control is not negatable");
27866
+ if (flag === "n") noWild = true;
27867
+ else stopAtDirectories = true;
27868
+ offset++;
27744
27869
  } else if (flag === "q") quiet = true;
27745
27870
  else if (flag === "j") junkPaths = true;
27746
27871
  else if (flag === "X") {
@@ -27753,10 +27878,26 @@ async function parse12(scope, limits) {
27753
27878
  else if (flag !== void 0 && flag >= "0" && flag <= "9") {
27754
27879
  level = Number(flag);
27755
27880
  if (level === 0) method = "store";
27881
+ } else if (flag === "O") {
27882
+ let value2 = argument2.slice(offset + 1) || args[++index];
27883
+ if (value2?.startsWith("=")) value2 = value2.slice(1);
27884
+ if (value2 === void 0) throw new ZipFailure(16, "Invalid command arguments", "option O requires a value");
27885
+ output2 = value2;
27886
+ break;
27887
+ } else if (flag === "t") {
27888
+ const option = argument2[offset + 1] === "t" ? "tt" : "t";
27889
+ if (option === "tt") offset++;
27890
+ let value2 = argument2.slice(offset + 1);
27891
+ if (!value2) value2 = args[++index] ?? "";
27892
+ if (value2.startsWith("=")) value2 = value2.slice(1);
27893
+ const date2 = parseZipDate(value2, option);
27894
+ if (option === "t") fromDate = date2;
27895
+ else beforeDate = date2;
27896
+ break;
27756
27897
  } else if (flag === "n" || flag === "Z") {
27757
27898
  let value2 = argument2.slice(offset + 1);
27758
27899
  if (!value2) {
27759
- const next = context2.args[index + 1];
27900
+ const next = args[index + 1];
27760
27901
  if (next === void 0 || next.startsWith("-") && next !== "-") throw new ZipFailure(16, "Invalid command arguments", `option '${flag}' requires a value`);
27761
27902
  value2 = next;
27762
27903
  index++;
@@ -27786,8 +27927,8 @@ async function parse12(scope, limits) {
27786
27927
  const value2 = argument2.slice(offset + 1);
27787
27928
  append(value2.startsWith("=") ? value2.slice(1) : value2);
27788
27929
  }
27789
- while (!attached && index + 1 < context2.args.length) {
27790
- const next = context2.args[index + 1];
27930
+ while (!attached && index + 1 < args.length) {
27931
+ const next = args[index + 1];
27791
27932
  if (next === "@") {
27792
27933
  index++;
27793
27934
  break;
@@ -27808,12 +27949,19 @@ async function parse12(scope, limits) {
27808
27949
  }
27809
27950
  }
27810
27951
  if (archive === void 0) {
27952
+ if (includes.length || excludes.length) throw new ZipFailure(16, "Invalid command arguments", "nothing to select from");
27811
27953
  if (action !== "add") throw new ZipFailure(16, "Invalid command arguments", "expected archive name");
27812
27954
  archive = "-";
27813
27955
  if (!stdinNames) operands.push("-");
27814
27956
  }
27815
27957
  if (archive !== "-" && !archive.slice(archive.lastIndexOf("/") + 1).includes(".")) archive += ".zip";
27816
27958
  checkPath(archive, limits);
27959
+ if (output2 !== void 0) {
27960
+ if (!output2.slice(output2.lastIndexOf("/") + 1).includes(".")) output2 += ".zip";
27961
+ checkPath(output2, limits);
27962
+ if (action === "add" && archive !== "-" && !operands.length && !stdinNames) action = "copy";
27963
+ }
27964
+ if (action === "copy" && output2 === void 0) throw new ZipFailure(16, "Invalid command arguments", "-U (--copy) requires -O (--out)");
27817
27965
  const names = [];
27818
27966
  if (stdinNames) {
27819
27967
  const input3 = await collectBytes(scope.stdin, { maxBytes: limits.maxFilesFromBytes, signal: context2.signal });
@@ -27835,7 +27983,8 @@ async function parse12(scope, limits) {
27835
27983
  start = end + 1;
27836
27984
  }
27837
27985
  }
27838
- return { action, archive, recursive, quiet, junkPaths, omitDirectories, storeLinks, test, descriptors, zip64, metadata: metadata3, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
27986
+ if (recursivePatterns && !names.length && !operands.length) throw new ZipFailure(16, "Invalid command arguments", "nothing to select from");
27987
+ return { args, action, archive, output: output2, recursive, recursivePatterns, noWild, stopAtDirectories, quiet, junkPaths, omitDirectories, storeLinks, test, fromDate, beforeDate, descriptors, zip64, metadata: metadata3, includes, excludes, level, method, suffixes, operands: [...names, ...operands], firstOperand };
27839
27988
  }
27840
27989
  function memberName(path, limits) {
27841
27990
  if (path.startsWith("//") && !path.startsWith("///")) fail("UNC source paths are unsupported");
@@ -27880,7 +28029,7 @@ async function prepare(scope, parsed, budget) {
27880
28029
  if (parsed.archive === "-" && parsed.action !== "add") throw new ZipFailure(16, "Invalid command arguments", "can't use -d, -f, -u, -U, or -g on stdout\n");
27881
28030
  let publication;
27882
28031
  if (parsed.archive !== "-") {
27883
- const outputName = vfsPath(context2.cwd, parsed.archive);
28032
+ const outputName = vfsPath(context2.cwd, parsed.output ?? parsed.archive);
27884
28033
  const parentName = dirname(outputName);
27885
28034
  const parent = await scope.operation(() => context2.fs.realpath(parentName, { signal: context2.signal }));
27886
28035
  const parentStat = await scope.operation(() => context2.fs.lstat(parent, { signal: context2.signal }));
@@ -27890,16 +28039,37 @@ async function prepare(scope, parsed, budget) {
27890
28039
  publication = { output: output3, parentName, parent, parentStat, existing: existing3 };
27891
28040
  }
27892
28041
  const output2 = publication?.output;
27893
- const existing2 = publication?.existing;
28042
+ let input3 = publication?.output;
28043
+ let existing2 = publication?.existing;
28044
+ if (parsed.output !== void 0) {
28045
+ if (parsed.archive === "-") {
28046
+ input3 = void 0;
28047
+ existing2 = void 0;
28048
+ } else {
28049
+ const name2 = vfsPath(context2.cwd, parsed.archive);
28050
+ try {
28051
+ const parent = await scope.operation(() => context2.fs.realpath(dirname(name2), { signal: context2.signal }));
28052
+ input3 = `${parent === "/" ? "" : parent}/${name2.slice(name2.lastIndexOf("/") + 1)}`;
28053
+ existing2 = await scope.stat(input3);
28054
+ } catch (error) {
28055
+ context2.signal.throwIfAborted();
28056
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "EACCES")) throw new ZipFailure(18, "File not found or no read permission", parsed.archive);
28057
+ throw error;
28058
+ }
28059
+ if (input3 === output2 || existing2 && publication?.existing && sameIdentity2(existing2, publication.existing)) throw new ZipFailure(16, "Invalid command arguments", `--out path must be different than in path: ${parsed.archive}`);
28060
+ }
28061
+ }
28062
+ if ((parsed.action === "copy" || parsed.output !== void 0 && parsed.archive !== "-") && !existing2) throw new ZipFailure(18, "File not found or no read permission", parsed.archive);
28063
+ if (publication?.existing && (publication.existing.type !== "file" || !hasIdentity(publication.existing) || publication.existing.nlink !== 1)) fail("output archive requires a regular, single-link file with known backing identity");
27894
28064
  if (parsed.archive === "-" && parsed.test && !parsed.quiet) await budget.output(" zip warning: can't use -T on stdout, -T ignored\n");
27895
28065
  if (existing2 && (existing2.type !== "file" || !hasIdentity(existing2) || existing2.nlink !== 1)) fail("updating archive requires a regular, single-link file with known backing identity; archive aliases are unsupported");
27896
28066
  let archive = { entries: [], comment: new Uint8Array() };
27897
- if (existing2 && publication) {
28067
+ if (existing2 && input3) {
27898
28068
  if (!Number.isSafeInteger(existing2.size) || existing2.size < 0 || existing2.size > limits.maxArchiveBytes) fail("archive byte limit exceeded");
27899
- const bytes4 = await collectBytes(scope.input(publication.output), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
28069
+ const bytes4 = await collectBytes(scope.input(input3), { maxBytes: limits.maxArchiveBytes, signal: context2.signal });
27900
28070
  if (bytes4.length !== existing2.size) fail("archive changed while reading");
27901
28071
  archive = await readZipArchive(bytes4, limits, context2.signal);
27902
- const current = await scope.stat(publication.output);
28072
+ const current = await scope.stat(input3);
27903
28073
  if (!current || !unchanged4(existing2, current)) fail("archive changed while reading");
27904
28074
  }
27905
28075
  const old = new Map(archive.entries.map((entry) => [entry.name, entry]));
@@ -27907,7 +28077,8 @@ async function prepare(scope, parsed, budget) {
27907
28077
  `);
27908
28078
  const selected = /* @__PURE__ */ new Map();
27909
28079
  const deleted = /* @__PURE__ */ new Set();
27910
- const selection = new Selection([...parsed.includes, ...parsed.excludes], limits, context2.signal);
28080
+ const selection = new Selection([...parsed.includes, ...parsed.excludes], limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
28081
+ const recursiveSelection = parsed.recursivePatterns ? new Selection(parsed.operands, limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories, trailingComponents: true }) : void 0;
27911
28082
  const ancestors = [];
27912
28083
  let visits = 0;
27913
28084
  let work = 0;
@@ -27938,6 +28109,7 @@ async function prepare(scope, parsed, budget) {
27938
28109
  if (previous || !await filterName(name2, selection, parsed.includes.length)) return;
27939
28110
  const prior2 = old.get(name2);
27940
28111
  const modified = /* @__PURE__ */ new Date();
28112
+ if (!zipDateMatches(modified, parsed.fromDate, parsed.beforeDate)) return;
27941
28113
  if (parsed.action === "freshen" && !prior2 || prior2 && (parsed.action === "update" || parsed.action === "freshen") && Math.floor(modified.getTime() / 1e3) <= Math.floor(prior2.modified.getTime() / 1e3)) return;
27942
28114
  const bytes4 = await collectBytes(scope.stdin, { maxBytes: Math.min(limits.maxEntryBytes, limits.maxTotalBytes - budget.totalBytes), signal: context2.signal });
27943
28115
  await budget.member(bytes4.length);
@@ -27958,17 +28130,17 @@ async function prepare(scope, parsed, budget) {
27958
28130
  return;
27959
28131
  }
27960
28132
  checkPath(canonical, limits);
27961
- if (canonical === output2 || existing2 && sameIdentity2(existing2, stat)) return;
28133
+ if (canonical === output2 || canonical === input3 || existing2 && sameIdentity2(existing2, stat) || publication?.existing && sameIdentity2(publication.existing, stat)) return;
27962
28134
  const symlink = parsed.storeLinks && stat.type === "symlink";
27963
28135
  if (stat.type !== "file" && stat.type !== "directory" && !symlink) {
27964
28136
  if (!parsed.quiet) await budget.output(` zip warning: ignoring special file: ${source2}
27965
28137
  `);
27966
28138
  return;
27967
28139
  }
27968
- if (existing2 && !hasIdentity(stat)) fail("cannot exclude archive aliases when source backing identity is unknown");
28140
+ if ((existing2 || publication?.existing) && !hasIdentity(stat)) fail("cannot exclude archive aliases when source backing identity is unknown");
27969
28141
  const directory2 = stat.type === "directory";
27970
28142
  if (directory2 && name2 && !name2.endsWith("/")) name2 += "/";
27971
- const included = await filterName(name2, selection, parsed.includes.length);
28143
+ const included = zipDateMatches(new Date(stat.mtimeMs), parsed.fromDate, parsed.beforeDate) && await filterName(name2, selection, parsed.includes.length) && (!recursiveSelection || await recursiveSelection.matches(name2, true));
27972
28144
  const sourceName = name2;
27973
28145
  if (parsed.junkPaths) name2 = directory2 ? "" : name2.slice(name2.lastIndexOf("/") + 1);
27974
28146
  const prior = old.get(name2);
@@ -27999,7 +28171,7 @@ async function prepare(scope, parsed, budget) {
27999
28171
  await encodeSelected(source2, name2, bytes4, { modified: new Date(stat.mtimeMs), mode: stat.mode, directory: directory2, symlink });
28000
28172
  }
28001
28173
  }
28002
- if (directory2 && parsed.recursive) {
28174
+ if (directory2 && (parsed.recursive || parsed.recursivePatterns)) {
28003
28175
  if (ancestors.some((ancestor) => ancestor.path === canonical || sameIdentity2(ancestor.stat, stat))) fail(`directory cycle while archiving: ${source2}`);
28004
28176
  ancestors.push({ path: canonical, stat });
28005
28177
  try {
@@ -28015,14 +28187,22 @@ async function prepare(scope, parsed, budget) {
28015
28187
  }
28016
28188
  }
28017
28189
  };
28018
- if (parsed.action === "delete") {
28190
+ if (parsed.action === "copy") {
28191
+ const operands = new Selection(parsed.operands, limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
28192
+ for (const entry of archive.entries) {
28193
+ if (await operands.matches(entry.name) && await filterName(entry.name, selection, parsed.includes.length) && zipDateMatches(entry.modified, parsed.fromDate, parsed.beforeDate)) {
28194
+ await budget.member(entry.size);
28195
+ selected.set(entry.name, { entry, source: entry.name });
28196
+ }
28197
+ }
28198
+ } else if (parsed.action === "delete") {
28019
28199
  if (!parsed.quiet && parsed.recursive) await budget.output(" zip warning: invalid option(s) used with -d; ignored.\n");
28020
28200
  if (!parsed.quiet && !archive.entries.length) await budget.output(` zip warning: ${parsed.archive} not found or empty
28021
28201
  `);
28022
- const operands = new Selection(parsed.operands, limits, context2.signal);
28023
- if (parsed.operands.length) {
28202
+ const operands = new Selection(parsed.recursivePatterns ? [] : parsed.operands, limits, context2.signal, { noWild: parsed.noWild, stopAtDirectories: parsed.stopAtDirectories });
28203
+ if (parsed.operands.length && !parsed.recursivePatterns) {
28024
28204
  for (const entry of archive.entries) {
28025
- if (await operands.matches(entry.name) && await filterName(entry.name, selection, parsed.includes.length)) deleted.add(entry.name);
28205
+ if (await operands.matches(entry.name) && await filterName(entry.name, selection, parsed.includes.length) && zipDateMatches(entry.modified, parsed.fromDate, parsed.beforeDate)) deleted.add(entry.name);
28026
28206
  }
28027
28207
  }
28028
28208
  if (!parsed.quiet) {
@@ -28033,11 +28213,12 @@ async function prepare(scope, parsed, budget) {
28033
28213
  }
28034
28214
  } else {
28035
28215
  const operands = parsed.operands.length || parsed.action === "add" ? parsed.operands : archive.entries.map((entry) => entry.name);
28036
- for (const operand of operands) await visit(operand, memberName(operand, limits), 0);
28216
+ if (parsed.recursivePatterns) await visit(".", "", 0);
28217
+ else for (const operand of operands) await visit(operand, memberName(operand, limits), 0);
28037
28218
  }
28038
28219
  if (!selected.size && (parsed.action === "freshen" || parsed.action === "update" && (existing2 || !parsed.includes.length))) return void 0;
28039
- if (!selected.size && !deleted.size && (parsed.action === "delete" || !parsed.includes.length)) {
28040
- const detail = parsed.action !== "delete" && parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${context2.args.slice(0, parsed.firstOperand).join(" ")} . -i ${context2.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
28220
+ if (!selected.size && !deleted.size && (parsed.action === "delete" || parsed.action === "copy" || parsed.recursivePatterns || parsed.fromDate !== void 0 || parsed.beforeDate !== void 0 || !parsed.includes.length)) {
28221
+ const detail = parsed.action !== "delete" && parsed.recursive && parsed.firstOperand >= 0 ? `try: zip ${parsed.args.slice(0, parsed.firstOperand).join(" ")} . -i ${parsed.args.slice(parsed.firstOperand).join(" ")}` : parsed.archive;
28041
28222
  throw new ZipFailure(12, "Nothing to do!", detail);
28042
28223
  }
28043
28224
  const entries2 = [];
@@ -28063,6 +28244,15 @@ async function prepare(scope, parsed, budget) {
28063
28244
  continue;
28064
28245
  }
28065
28246
  const replacement = selected.get(entry.name);
28247
+ if (parsed.action === "copy") {
28248
+ if (replacement) {
28249
+ entries2.push(replacement.entry);
28250
+ queue(` copying: ${entry.name}
28251
+ `);
28252
+ selected.delete(entry.name);
28253
+ }
28254
+ continue;
28255
+ }
28066
28256
  if (replacement) {
28067
28257
  entries2.push(replacement.entry);
28068
28258
  append(replacement.entry, true);
@@ -28077,7 +28267,7 @@ async function prepare(scope, parsed, budget) {
28077
28267
  append(entry, false);
28078
28268
  }
28079
28269
  if (!entries2.length) queue(" zip warning: zip file empty\n");
28080
- if (parsed.archive === "-") return { kind: "stream", archive: { entries: entries2, comment: archive.comment }, progress };
28270
+ if (!publication) return { kind: "stream", archive: { entries: entries2, comment: archive.comment }, progress };
28081
28271
  const bytes3 = await writeZipArchive({ entries: entries2, comment: archive.comment }, limits, context2.signal, false, parsed.zip64 === true);
28082
28272
  if (parsed.test && parsed.archive !== "-") {
28083
28273
  for (const message3 of progress) await budget.output(message3);
@@ -29181,13 +29371,13 @@ function parse13(context2, budget) {
29181
29371
  }
29182
29372
  const values = value2.split(/[, \t]+/u);
29183
29373
  budget.check(values.length, budget.limits.maxFields, "field");
29184
- const fields3 = values.map((specification) => {
29374
+ const fields4 = values.map((specification) => {
29185
29375
  if (specification === "0") return { file: 0, index: 0 };
29186
29376
  const match = /^([12])\.([0-9]+)$/u.exec(specification);
29187
29377
  if (!match) fail2(`invalid output field: ${specification}`);
29188
29378
  return { file: Number(match[1]), index: number4(match[2], "output field") - 1 };
29189
29379
  });
29190
- options2.format = [...Array.isArray(options2.format) ? options2.format : [], ...fields3];
29380
+ options2.format = [...Array.isArray(options2.format) ? options2.format : [], ...fields4];
29191
29381
  budget.check(options2.format.length, budget.limits.maxFields, "field");
29192
29382
  }
29193
29383
  };
@@ -29240,10 +29430,10 @@ function parse13(context2, budget) {
29240
29430
  }
29241
29431
  function split3(bytes3, options2, budget) {
29242
29432
  if (options2.whole) return [bytes3];
29243
- const fields3 = [];
29433
+ const fields4 = [];
29244
29434
  const add3 = (start, end) => {
29245
- budget.check(fields3.length + 1, budget.limits.maxFields, "field");
29246
- fields3.push(bytes3.subarray(start, end));
29435
+ budget.check(fields4.length + 1, budget.limits.maxFields, "field");
29436
+ fields4.push(bytes3.subarray(start, end));
29247
29437
  };
29248
29438
  if (options2.delimiter !== void 0) {
29249
29439
  let start = 0;
@@ -29262,7 +29452,7 @@ function split3(bytes3, options2, budget) {
29262
29452
  if (offset > start) add3(start, offset);
29263
29453
  }
29264
29454
  }
29265
- return fields3;
29455
+ return fields4;
29266
29456
  }
29267
29457
  function createJoinCommand(factory = {}) {
29268
29458
  const limits = settings3(factory);
@@ -29277,36 +29467,36 @@ function createJoinCommand(factory = {}) {
29277
29467
  const next = async (file, reset = false) => {
29278
29468
  const bytes3 = await readers[file].next();
29279
29469
  if (bytes3 === void 0) return void 0;
29280
- const fields3 = split3(bytes3, options2, budget), key = fields3[options2.fields[file]] ?? empty;
29470
+ const fields4 = split3(bytes3, options2, budget), key = fields4[options2.fields[file]] ?? empty;
29281
29471
  if (!reset) await order.check(previous[file], key, file + 1, options2.fold);
29282
29472
  previous[file] = key;
29283
- return { bytes: bytes3, fields: fields3, key };
29473
+ return { bytes: bytes3, fields: fields4, key };
29284
29474
  };
29285
29475
  const rows2 = [await next(0), await next(1)];
29286
29476
  const counts = rows2.map((row) => row?.fields.length ?? 0);
29287
29477
  const emit2 = async (left, right) => {
29288
- const pair = [left, right], fields3 = [];
29478
+ const pair = [left, right], fields4 = [];
29289
29479
  const key = (left ?? right)?.key ?? empty;
29290
29480
  if (Array.isArray(options2.format)) {
29291
29481
  for (const field2 of options2.format) {
29292
29482
  await budget.step();
29293
- fields3.push(field2.file === 0 ? key : pair[field2.file - 1]?.fields[field2.index] ?? empty);
29483
+ fields4.push(field2.file === 0 ? key : pair[field2.file - 1]?.fields[field2.index] ?? empty);
29294
29484
  }
29295
29485
  } else {
29296
- fields3.push(key);
29486
+ fields4.push(key);
29297
29487
  for (let file = 0; file < 2; file++) {
29298
29488
  const count2 = options2.format === "auto" ? counts[file] : pair[file]?.fields.length ?? 0;
29299
29489
  for (let index = 0; index < count2; index++) {
29300
29490
  await budget.step();
29301
- if (index !== options2.fields[file]) fields3.push(pair[file]?.fields[index] ?? empty);
29491
+ if (index !== options2.fields[file]) fields4.push(pair[file]?.fields[index] ?? empty);
29302
29492
  }
29303
29493
  }
29304
29494
  }
29305
29495
  const parts = [];
29306
- for (let index = 0; index < fields3.length; index++) {
29496
+ for (let index = 0; index < fields4.length; index++) {
29307
29497
  await budget.step();
29308
29498
  if (index) parts.push(delimiter);
29309
- parts.push(fields3[index].length ? fields3[index] : options2.replacement);
29499
+ parts.push(fields4[index].length ? fields4[index] : options2.replacement);
29310
29500
  }
29311
29501
  parts.push(terminator);
29312
29502
  await budget.output(parts);
@@ -31222,10 +31412,10 @@ function millisecondsInstant(value2) {
31222
31412
  const scale = Number(match[4] ?? 0) - fraction.length + 6;
31223
31413
  return boundedInstant(scale >= 0 ? coefficient * 10n ** BigInt(scale) : floorDivide(coefficient, 10n ** BigInt(-scale)));
31224
31414
  }
31225
- function utcMilliseconds(fields3) {
31415
+ function utcMilliseconds(fields4) {
31226
31416
  const date2 = /* @__PURE__ */ new Date(0);
31227
- date2.setUTCFullYear(fields3.year, fields3.month - 1, fields3.day);
31228
- date2.setUTCHours(fields3.hour, fields3.minute, fields3.second, 0);
31417
+ date2.setUTCFullYear(fields4.year, fields4.month - 1, fields4.day);
31418
+ date2.setUTCHours(fields4.hour, fields4.minute, fields4.second, 0);
31229
31419
  const value2 = date2.getTime();
31230
31420
  if (!Number.isFinite(value2)) throw new CommandFailure("date is outside the supported range");
31231
31421
  return value2;
@@ -31244,8 +31434,8 @@ function utcFields(milliseconds) {
31244
31434
  function sameFields(left, right) {
31245
31435
  return left.year === right.year && left.month === right.month && left.day === right.day && left.hour === right.hour && left.minute === right.minute && left.second === right.second;
31246
31436
  }
31247
- function checkCalendar(fields3, restrictYear = true) {
31248
- if (restrictYear && (fields3.year < 0 || fields3.year > 9999) || fields3.month < 1 || fields3.month > 12 || fields3.day < 1 || fields3.day > 31 || fields3.hour < 0 || fields3.hour > 23 || fields3.minute < 0 || fields3.minute > 59 || fields3.second < 0 || fields3.second > 59 || !sameFields(fields3, utcFields(utcMilliseconds(fields3)))) throw new CommandFailure("invalid calendar date or time");
31437
+ function checkCalendar(fields4, restrictYear = true) {
31438
+ if (restrictYear && (fields4.year < 0 || fields4.year > 9999) || fields4.month < 1 || fields4.month > 12 || fields4.day < 1 || fields4.day > 31 || fields4.hour < 0 || fields4.hour > 23 || fields4.minute < 0 || fields4.minute > 59 || fields4.second < 0 || fields4.second > 59 || !sameFields(fields4, utcFields(utcMilliseconds(fields4)))) throw new CommandFailure("invalid calendar date or time");
31249
31439
  }
31250
31440
  function signedOffset(text3) {
31251
31441
  const match = /^([+-])(\d{2})(?::?(\d{2}))?(?::(\d{2}))?$/.exec(text3);
@@ -31294,15 +31484,15 @@ var TimeZone = class {
31294
31484
  boundedInstant(instant);
31295
31485
  const seconds = floorDivide(instant, nanosecondsPerSecond);
31296
31486
  const milliseconds = Number(seconds * 1000n);
31297
- let fields3, offset, zone;
31487
+ let fields4, offset, zone;
31298
31488
  if (this.fixedOffset !== void 0) {
31299
- fields3 = utcFields(milliseconds + this.fixedOffset * 1e3);
31489
+ fields4 = utcFields(milliseconds + this.fixedOffset * 1e3);
31300
31490
  offset = this.fixedOffset;
31301
31491
  zone = this.label;
31302
31492
  } else {
31303
31493
  const parts = Object.fromEntries(this.formatter.formatToParts(new Date(milliseconds)).map((part) => [part.type, part.value]));
31304
31494
  const year = Number(parts.year);
31305
- fields3 = {
31495
+ fields4 = {
31306
31496
  year: parts.era === "BC" ? 1 - year : year,
31307
31497
  month: Number(parts.month),
31308
31498
  day: Number(parts.day),
@@ -31310,22 +31500,22 @@ var TimeZone = class {
31310
31500
  minute: Number(parts.minute),
31311
31501
  second: Number(parts.second)
31312
31502
  };
31313
- offset = (utcMilliseconds(fields3) - milliseconds) / 1e3;
31503
+ offset = (utcMilliseconds(fields4) - milliseconds) / 1e3;
31314
31504
  zone = parts.timeZoneName;
31315
31505
  }
31316
- checkCalendar(fields3, restrictYear);
31317
- return { ...fields3, offset, zone };
31506
+ checkCalendar(fields4, restrictYear);
31507
+ return { ...fields4, offset, zone };
31318
31508
  }
31319
- instant(fields3, fraction = 0n) {
31320
- checkCalendar(fields3);
31321
- const wall = utcMilliseconds(fields3);
31509
+ instant(fields4, fraction = 0n) {
31510
+ checkCalendar(fields4);
31511
+ const wall = utcMilliseconds(fields4);
31322
31512
  if (this.fixedOffset !== void 0) return boundedInstant(BigInt(wall) * 1000000n - BigInt(this.fixedOffset) * nanosecondsPerSecond + fraction);
31323
31513
  const offsets = /* @__PURE__ */ new Set();
31324
31514
  for (const days of [-2, -1, 0, 1, 2]) offsets.add(this.observedFields(BigInt(wall + days * 864e5) * 1000000n, false).offset);
31325
31515
  const candidates = [];
31326
31516
  for (const offset of offsets) {
31327
31517
  const candidate = BigInt(wall) * 1000000n - BigInt(offset) * nanosecondsPerSecond + fraction;
31328
- if (sameFields(this.observedFields(candidate, false), fields3)) candidates.push(candidate);
31518
+ if (sameFields(this.observedFields(candidate, false), fields4)) candidates.push(candidate);
31329
31519
  }
31330
31520
  if (candidates.length === 0) throw new CommandFailure("nonexistent local time in virtual TZ");
31331
31521
  if (candidates.length !== 1) throw new CommandFailure("ambiguous local time; specify an explicit UTC offset");
@@ -31351,8 +31541,8 @@ function parseDate(text3, zone, now) {
31351
31541
  if (["today", "yesterday", "tomorrow"].includes(value2)) {
31352
31542
  const current = now();
31353
31543
  if (value2 === "today") return current;
31354
- const fields3 = zone.fields(current);
31355
- const changed = utcFields(utcMilliseconds(fields3) + (value2 === "yesterday" ? -864e5 : 864e5));
31544
+ const fields4 = zone.fields(current);
31545
+ const changed = utcFields(utcMilliseconds(fields4) + (value2 === "yesterday" ? -864e5 : 864e5));
31356
31546
  return zone.instant(changed, current - floorDivide(current, nanosecondsPerSecond) * nanosecondsPerSecond);
31357
31547
  }
31358
31548
  const relative = /^(?:now\s+)?([+-]?\d+)\s+(seconds?|minutes?|hours?)(?:\s+(ago))?$/.exec(value2);
@@ -31364,7 +31554,7 @@ function parseDate(text3, zone, now) {
31364
31554
  }
31365
31555
  const iso = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:[.,](\d{1,9}))?)?)?(?:\s*(Z|UTC|GMT|[+-]\d{2}(?::?\d{2})?(?::\d{2})?))?$/.exec(value2);
31366
31556
  if (iso) {
31367
- const fields3 = {
31557
+ const fields4 = {
31368
31558
  year: Number(iso[1]),
31369
31559
  month: Number(iso[2]),
31370
31560
  day: Number(iso[3]),
@@ -31372,11 +31562,11 @@ function parseDate(text3, zone, now) {
31372
31562
  minute: Number(iso[5] ?? 0),
31373
31563
  second: Number(iso[6] ?? 0)
31374
31564
  };
31375
- return parsedZone(iso[8], zone).instant(fields3, BigInt((iso[7] ?? "").padEnd(9, "0")));
31565
+ return parsedZone(iso[8], zone).instant(fields4, BigInt((iso[7] ?? "").padEnd(9, "0")));
31376
31566
  }
31377
31567
  const rfc = /^(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?(\d{1,2})\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+(GMT|UTC|[+-]\d{4})$/.exec(value2);
31378
31568
  if (rfc) {
31379
- const fields3 = {
31569
+ const fields4 = {
31380
31570
  year: Number(rfc[4]),
31381
31571
  month: monthNames.findIndex((name2) => name2.startsWith(rfc[3])) + 1,
31382
31572
  day: Number(rfc[2]),
@@ -31384,8 +31574,8 @@ function parseDate(text3, zone, now) {
31384
31574
  minute: Number(rfc[6]),
31385
31575
  second: Number(rfc[7])
31386
31576
  };
31387
- if (rfc[1] && !weekdayNames[new Date(utcMilliseconds(fields3)).getUTCDay()].startsWith(rfc[1])) throw new CommandFailure("weekday does not match calendar date");
31388
- return parsedZone(rfc[8], zone).instant(fields3);
31577
+ if (rfc[1] && !weekdayNames[new Date(utcMilliseconds(fields4)).getUTCDay()].startsWith(rfc[1])) throw new CommandFailure("weekday does not match calendar date");
31578
+ return parsedZone(rfc[8], zone).instant(fields4);
31389
31579
  }
31390
31580
  throw new CommandFailure(`unsupported or invalid date: ${text3}`);
31391
31581
  }
@@ -31404,18 +31594,18 @@ function offsetText(offset, colons) {
31404
31594
  return { value: `${sign}${hours}`, width: 3 };
31405
31595
  }
31406
31596
  function formatDate(format3, instant, zone, limits) {
31407
- const fields3 = zone.fields(instant);
31408
- const midnight = utcMilliseconds({ ...fields3, hour: 0, minute: 0, second: 0 });
31597
+ const fields4 = zone.fields(instant);
31598
+ const midnight = utcMilliseconds({ ...fields4, hour: 0, minute: 0, second: 0 });
31409
31599
  const weekday = new Date(midnight).getUTCDay();
31410
- const ordinal = Math.floor((midnight - utcMilliseconds({ ...fields3, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 864e5) + 1;
31600
+ const ordinal = Math.floor((midnight - utcMilliseconds({ ...fields4, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 864e5) + 1;
31411
31601
  const thursday = new Date(midnight + (3 - (weekday + 6) % 7) * 864e5);
31412
31602
  const isoYear = thursday.getUTCFullYear();
31413
31603
  const isoWeek = 1 + Math.floor((thursday.getTime() - utcMilliseconds({ year: isoYear, month: 1, day: 1, hour: 0, minute: 0, second: 0 })) / 6048e5);
31414
31604
  const nano = (instant - floorDivide(instant, nanosecondsPerSecond) * nanosecondsPerSecond).toString().padStart(9, "0");
31415
31605
  const number6 = (value2, width = 2, padding = "0") => value2.toString().padStart(width, padding);
31416
- const time = `${number6(fields3.hour)}:${number6(fields3.minute)}:${number6(fields3.second)}`;
31417
- const hour12 = fields3.hour % 12 || 12;
31418
- const meridian = fields3.hour < 12 ? "AM" : "PM";
31606
+ const time = `${number6(fields4.hour)}:${number6(fields4.minute)}:${number6(fields4.second)}`;
31607
+ const hour12 = fields4.hour % 12 || 12;
31608
+ const meridian = fields4.hour < 12 ? "AM" : "PM";
31419
31609
  const pieces = [];
31420
31610
  let size = 0;
31421
31611
  const append = (value2) => {
@@ -31467,34 +31657,34 @@ function formatDate(format3, instant, zone, limits) {
31467
31657
  break;
31468
31658
  case "b":
31469
31659
  case "h":
31470
- value2 = monthNames[fields3.month - 1].slice(0, 3);
31660
+ value2 = monthNames[fields4.month - 1].slice(0, 3);
31471
31661
  break;
31472
31662
  case "B":
31473
- value2 = monthNames[fields3.month - 1];
31663
+ value2 = monthNames[fields4.month - 1];
31474
31664
  break;
31475
31665
  case "c":
31476
- value2 = `${weekdayNames[weekday].slice(0, 3)} ${monthNames[fields3.month - 1].slice(0, 3)} ${number6(fields3.day, 2, " ")} ${time} ${number6(fields3.year, 4)}`;
31666
+ value2 = `${weekdayNames[weekday].slice(0, 3)} ${monthNames[fields4.month - 1].slice(0, 3)} ${number6(fields4.day, 2, " ")} ${time} ${number6(fields4.year, 4)}`;
31477
31667
  break;
31478
31668
  case "C":
31479
- value2 = String(Math.floor(fields3.year / 100));
31669
+ value2 = String(Math.floor(fields4.year / 100));
31480
31670
  defaultWidth = 2;
31481
31671
  break;
31482
31672
  case "d":
31483
31673
  case "e":
31484
- value2 = String(fields3.day);
31674
+ value2 = String(fields4.day);
31485
31675
  defaultWidth = 2;
31486
31676
  if (code === "e") defaultPadding = " ";
31487
31677
  break;
31488
31678
  case "D":
31489
- value2 = `${number6(fields3.month)}/${number6(fields3.day)}/${number6(fields3.year % 100, 2, padding ?? "0")}`;
31679
+ value2 = `${number6(fields4.month)}/${number6(fields4.day)}/${number6(fields4.year % 100, 2, padding ?? "0")}`;
31490
31680
  break;
31491
31681
  case "x":
31492
- value2 = `${number6(fields3.month)}/${number6(fields3.day)}/${number6(fields3.year % 100)}`;
31682
+ value2 = `${number6(fields4.month)}/${number6(fields4.day)}/${number6(fields4.year % 100)}`;
31493
31683
  break;
31494
31684
  case "F": {
31495
31685
  const yearWidth = width === void 0 && padding === void 0 ? 4 : Math.max(0, (width ?? 0) - 6);
31496
- const year = padding === "" ? String(fields3.year) : number6(fields3.year, yearWidth, padding ?? "0");
31497
- append(`${year}-${number6(fields3.month)}-${number6(fields3.day)}`);
31686
+ const year = padding === "" ? String(fields4.year) : number6(fields4.year, yearWidth, padding ?? "0");
31687
+ append(`${year}-${number6(fields4.month)}-${number6(fields4.day)}`);
31498
31688
  continue;
31499
31689
  }
31500
31690
  case "g":
@@ -31507,7 +31697,7 @@ function formatDate(format3, instant, zone, limits) {
31507
31697
  break;
31508
31698
  case "H":
31509
31699
  case "k":
31510
- value2 = String(fields3.hour);
31700
+ value2 = String(fields4.hour);
31511
31701
  defaultWidth = 2;
31512
31702
  if (code === "k") defaultPadding = " ";
31513
31703
  break;
@@ -31522,11 +31712,11 @@ function formatDate(format3, instant, zone, limits) {
31522
31712
  defaultWidth = 3;
31523
31713
  break;
31524
31714
  case "m":
31525
- value2 = String(fields3.month);
31715
+ value2 = String(fields4.month);
31526
31716
  defaultWidth = 2;
31527
31717
  break;
31528
31718
  case "M":
31529
- value2 = String(fields3.minute);
31719
+ value2 = String(fields4.minute);
31530
31720
  defaultWidth = 2;
31531
31721
  break;
31532
31722
  case "n":
@@ -31547,21 +31737,21 @@ function formatDate(format3, instant, zone, limits) {
31547
31737
  value2 = meridian.toLowerCase();
31548
31738
  break;
31549
31739
  case "q":
31550
- value2 = String(Math.ceil(fields3.month / 3));
31740
+ value2 = String(Math.ceil(fields4.month / 3));
31551
31741
  defaultWidth = 1;
31552
31742
  break;
31553
31743
  case "r":
31554
- value2 = `${number6(hour12)}:${number6(fields3.minute)}:${number6(fields3.second)} ${meridian}`;
31744
+ value2 = `${number6(hour12)}:${number6(fields4.minute)}:${number6(fields4.second)} ${meridian}`;
31555
31745
  break;
31556
31746
  case "R":
31557
- value2 = `${number6(fields3.hour)}:${number6(fields3.minute)}`;
31747
+ value2 = `${number6(fields4.hour)}:${number6(fields4.minute)}`;
31558
31748
  break;
31559
31749
  case "s":
31560
31750
  value2 = floorDivide(instant, nanosecondsPerSecond).toString();
31561
31751
  defaultWidth = 1;
31562
31752
  break;
31563
31753
  case "S":
31564
- value2 = String(fields3.second);
31754
+ value2 = String(fields4.second);
31565
31755
  defaultWidth = 2;
31566
31756
  break;
31567
31757
  case "t":
@@ -31592,21 +31782,21 @@ function formatDate(format3, instant, zone, limits) {
31592
31782
  defaultWidth = 2;
31593
31783
  break;
31594
31784
  case "y":
31595
- value2 = String(fields3.year % 100);
31785
+ value2 = String(fields4.year % 100);
31596
31786
  defaultWidth = 2;
31597
31787
  break;
31598
31788
  case "Y":
31599
- value2 = String(fields3.year);
31789
+ value2 = String(fields4.year);
31600
31790
  defaultWidth = 4;
31601
31791
  break;
31602
31792
  case "z": {
31603
- const offset2 = offsetText(fields3.offset, colons);
31793
+ const offset2 = offsetText(fields4.offset, colons);
31604
31794
  value2 = offset2.value;
31605
31795
  defaultWidth = offset2.width;
31606
31796
  break;
31607
31797
  }
31608
31798
  case "Z":
31609
- value2 = fields3.zone;
31799
+ value2 = fields4.zone;
31610
31800
  break;
31611
31801
  default:
31612
31802
  throw new CommandFailure(`unsupported date format directive: %${code}`);
@@ -32412,13 +32602,13 @@ var Walker2 = class {
32412
32602
  const name2 = depth === 0 || this.args.full ? entry.display : entry.name;
32413
32603
  const annotation = entry.error ?? (entry.cycle ? "recursive, not followed" : void 0);
32414
32604
  if (this.args.json) {
32415
- const fields3 = {
32605
+ const fields4 = {
32416
32606
  type: entry.stat?.type === "symlink" ? "link" : entry.stat?.type ?? "unknown",
32417
32607
  name: name2,
32418
32608
  ...entry.target === void 0 ? {} : { target: entry.target },
32419
32609
  ...annotation === void 0 ? {} : { error: annotation }
32420
32610
  };
32421
- await this.write(`${this.padding(depth + 1)}${serialized(fields3, this.budget).slice(0, -1)}`);
32611
+ await this.write(`${this.padding(depth + 1)}${serialized(fields4, this.budget).slice(0, -1)}`);
32422
32612
  if (children.length) {
32423
32613
  await this.write(`,"contents":[${this.newline()}`);
32424
32614
  for (let index = 0; index < children.length; index++) {
@@ -32964,7 +33154,7 @@ init_platform();
32964
33154
 
32965
33155
  // packages/safe-bash/src/commands/column/display.ts
32966
33156
  init_platform();
32967
- function whitespace(character) {
33157
+ function whitespace2(character) {
32968
33158
  return character === " " || character === " " || character === "\r" || character === "\v" || character === "\f";
32969
33159
  }
32970
33160
  function widthOf(point) {
@@ -33002,7 +33192,7 @@ function decode2(bytes3) {
33002
33192
  throw new FsError("EINVAL", { message: "invalid UTF-8 input" });
33003
33193
  }
33004
33194
  }
33005
- async function fields2(text3, separator, budget, remainingCells) {
33195
+ async function fields3(text3, separator, budget, remainingCells) {
33006
33196
  const result = [];
33007
33197
  let start = 0, offset = 0;
33008
33198
  const append = (end) => {
@@ -33012,7 +33202,7 @@ async function fields2(text3, separator, budget, remainingCells) {
33012
33202
  };
33013
33203
  for (const character of text3) {
33014
33204
  await budget.step();
33015
- if (separator ? separator.has(character) : whitespace(character)) {
33205
+ if (separator ? separator.has(character) : whitespace2(character)) {
33016
33206
  if (separator || offset > start) append(offset);
33017
33207
  start = offset + character.length;
33018
33208
  }
@@ -33494,7 +33684,7 @@ function createColumnCommand(options2 = {}) {
33494
33684
  await budget.work(bytes3.length);
33495
33685
  const text3 = decode2(bytes3);
33496
33686
  if (!text3.length) continue;
33497
- const values = parsed.table ? await fields2(text3, parsed.separator, budget, limits.maxCells - cellCount) : [text3];
33687
+ const values = parsed.table ? await fields3(text3, parsed.separator, budget, limits.maxCells - cellCount) : [text3];
33498
33688
  if (parsed.table && !values.length) continue;
33499
33689
  if (!parsed.table) {
33500
33690
  let blank2 = true;
@@ -34318,21 +34508,21 @@ var Renderer = class {
34318
34508
  this.budget.work(1);
34319
34509
  await this.budget.checkpoint();
34320
34510
  if (child.tag !== "text") return false;
34321
- let whitespace2 = this.whitespace.get(child);
34322
- if (whitespace2 === void 0) {
34323
- whitespace2 = true;
34511
+ let whitespace3 = this.whitespace.get(child);
34512
+ if (whitespace3 === void 0) {
34513
+ whitespace3 = true;
34324
34514
  for (const character of child.text) {
34325
34515
  this.budget.work(1);
34326
34516
  await this.budget.checkpoint();
34327
34517
  if (!htmlSpace(character)) {
34328
- whitespace2 = false;
34518
+ whitespace3 = false;
34329
34519
  break;
34330
34520
  }
34331
34521
  }
34332
34522
  this.budget.work(1);
34333
- this.whitespace.set(child, whitespace2);
34523
+ this.whitespace.set(child, whitespace3);
34334
34524
  }
34335
- if (!whitespace2) return false;
34525
+ if (!whitespace3) return false;
34336
34526
  }
34337
34527
  return true;
34338
34528
  }
@@ -35469,13 +35659,13 @@ function numeric3(value2, budget) {
35469
35659
  budget.allocation(value2.length);
35470
35660
  return BigInt(new TextDecoder().decode(value2));
35471
35661
  }
35472
- function integer4(value2, budget) {
35662
+ function integer5(value2, budget) {
35473
35663
  const result = numeric3(value2, budget);
35474
35664
  if (result === void 0) throw new ExprError("non-integer argument");
35475
35665
  return result;
35476
35666
  }
35477
35667
  function arithmetic(operator, left, right, budget) {
35478
- const first = integer4(left, budget), second = integer4(right, budget);
35668
+ const first = integer5(left, budget), second = integer5(right, budget);
35479
35669
  if ((operator === "/" || operator === "%") && second === 0n) throw new ExprError("division by zero");
35480
35670
  const firstDigits = left instanceof Uint8Array ? left.length : left.text.length;
35481
35671
  const secondDigits = right instanceof Uint8Array ? right.length : right.text.length;
@@ -35489,7 +35679,7 @@ function arithmetic(operator, left, right, budget) {
35489
35679
  }
35490
35680
  function compare5(left, right, budget) {
35491
35681
  if (numericShape(left, budget) && numericShape(right, budget)) {
35492
- const first = integer4(left, budget), second = integer4(right, budget);
35682
+ const first = integer5(left, budget), second = integer5(right, budget);
35493
35683
  return first < second ? -1 : first > second ? 1 : 0;
35494
35684
  }
35495
35685
  requireByteCollation(budget.context);
@@ -36078,7 +36268,7 @@ function parseDuration(token) {
36078
36268
  let sawPoint = false;
36079
36269
  let trailingDigits = 0;
36080
36270
  let integerDigits = 0;
36081
- let integer9 = 0;
36271
+ let integer10 = 0;
36082
36272
  let place = 1;
36083
36273
  let placeOverflow = false;
36084
36274
  let integerOverflow = false;
@@ -36095,8 +36285,8 @@ function parseDuration(token) {
36095
36285
  fractionSticky ||= temporary % 10 !== 0;
36096
36286
  } else integerDigits++;
36097
36287
  if (digit3 !== 0) {
36098
- if (placeOverflow || digit3 > Math.floor((quotient - integer9) / place)) integerOverflow = true;
36099
- else integer9 += digit3 * place;
36288
+ if (placeOverflow || digit3 > Math.floor((quotient - integer10) / place)) integerOverflow = true;
36289
+ else integer10 += digit3 * place;
36100
36290
  }
36101
36291
  if (!placeOverflow) {
36102
36292
  if (place > Math.floor(quotient / 10)) placeOverflow = true;
@@ -36108,7 +36298,7 @@ function parseDuration(token) {
36108
36298
  if (sawPoint) invalid3 = true;
36109
36299
  else {
36110
36300
  sawPoint = true;
36111
- integer9 = 0;
36301
+ integer10 = 0;
36112
36302
  place = 1;
36113
36303
  placeOverflow = false;
36114
36304
  integerOverflow = false;
@@ -36121,7 +36311,7 @@ function parseDuration(token) {
36121
36311
  if (invalid3) return { kind: "invalid" };
36122
36312
  if (integerOverflow) return { kind: "overflow" };
36123
36313
  const fraction = sawPoint ? fractionCarry + (fractionSticky ? 1 : 0) : 0;
36124
- const product = integer9 * millisecondsPerUnit;
36314
+ const product = integer10 * millisecondsPerUnit;
36125
36315
  if (fraction > maximumMilliseconds - product) return { kind: "overflow" };
36126
36316
  return { kind: "value", milliseconds: product + fraction };
36127
36317
  }
@@ -37603,7 +37793,7 @@ var precedence = {
37603
37793
  "%": 13,
37604
37794
  "**": 14
37605
37795
  };
37606
- function integer5(text3) {
37796
+ function integer6(text3) {
37607
37797
  if (/^0[xX][\da-fA-F]+$/u.test(text3)) return BigInt(text3);
37608
37798
  if (/^0[0-7]+$/u.test(text3)) return BigInt(`0o${text3.slice(1)}`);
37609
37799
  if (/^0\d+$/u.test(text3)) throw new PublicDiagnostic("Invalid octal constant");
@@ -37661,7 +37851,7 @@ function parseArithmetic(source2, offset = 0, budget = new ParseBudget()) {
37661
37851
  } else {
37662
37852
  budget.admit();
37663
37853
  try {
37664
- left = { kind: "literal", value: BigInt.asIntN(64, integer5(token)) };
37854
+ left = { kind: "literal", value: BigInt.asIntN(64, integer6(token)) };
37665
37855
  } catch {
37666
37856
  error("Invalid arithmetic operand");
37667
37857
  }
@@ -38004,7 +38194,7 @@ async function patternAdmission(pattern, context2) {
38004
38194
  }
38005
38195
  if (bracket) unsupported2("unclosed bracket pattern");
38006
38196
  }
38007
- async function integer6(value2, context2) {
38197
+ async function integer7(value2, context2) {
38008
38198
  await charge(context2, value2.length);
38009
38199
  const text3 = value2.trim();
38010
38200
  if (!text3) return 0n;
@@ -38098,7 +38288,7 @@ async function leaf(node, context2) {
38098
38288
  const order = import_buffer.Buffer.compare(import_buffer.Buffer.from(left), import_buffer.Buffer.from(right));
38099
38289
  return node.operator === "<" ? order < 0 : order > 0;
38100
38290
  }
38101
- const first = await integer6(left, context2), second = await integer6(right, context2);
38291
+ const first = await integer7(left, context2), second = await integer7(right, context2);
38102
38292
  switch (node.operator) {
38103
38293
  case "-eq":
38104
38294
  return first === second;
@@ -39633,7 +39823,7 @@ import { scopeFileSystem } from "@poe-platform/safe-fs/core";
39633
39823
  init_platform();
39634
39824
  var BraceExpansionFailure = class extends Error {
39635
39825
  };
39636
- async function integer7(text3, checkpoint) {
39826
+ async function integer8(text3, checkpoint) {
39637
39827
  let offset = text3.startsWith("-") || text3.startsWith("+") ? 1 : 0;
39638
39828
  if (offset === text3.length) return void 0;
39639
39829
  while (text3[offset] === "0") {
@@ -39707,8 +39897,8 @@ async function* expandBraces(word, budget, signal) {
39707
39897
  const first = pieces[0];
39708
39898
  const last = pieces[1];
39709
39899
  admit2(256);
39710
- let start = await integer7(first, checkpoint);
39711
- let end = await integer7(last, checkpoint);
39900
+ let start = await integer8(first, checkpoint);
39901
+ let end = await integer8(last, checkpoint);
39712
39902
  const numeric4 = start !== void 0 && end !== void 0;
39713
39903
  if (!numeric4) {
39714
39904
  const alphabetic = (value2) => value2.length === 1 && (value2 >= "a" && value2 <= "z" || value2 >= "A" && value2 <= "Z");
@@ -39716,7 +39906,7 @@ async function* expandBraces(word, budget, signal) {
39716
39906
  start = BigInt(first.charCodeAt(0));
39717
39907
  end = BigInt(last.charCodeAt(0));
39718
39908
  }
39719
- let step = pieces.length === 3 ? await integer7(pieces[2], checkpoint) : 1n;
39909
+ let step = pieces.length === 3 ? await integer8(pieces[2], checkpoint) : 1n;
39720
39910
  if (step === void 0) return void 0;
39721
39911
  if (step < 0n) step = -step;
39722
39912
  if (step === 0n) step = 1n;
@@ -40542,7 +40732,7 @@ var GetoptsError = class extends Error {
40542
40732
  function record(value2) {
40543
40733
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
40544
40734
  }
40545
- function integer8(value2, minimum, name2) {
40735
+ function integer9(value2, minimum, name2) {
40546
40736
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < minimum) {
40547
40737
  throw new GetoptsError("INVALID_INPUT", `${name2} must be a safe integer >= ${minimum}`);
40548
40738
  }
@@ -40552,16 +40742,16 @@ function createGetoptsState() {
40552
40742
  }
40553
40743
  function cloneGetoptsState(state) {
40554
40744
  if (!record(state)) throw new GetoptsError("INVALID_INPUT", "Invalid getopts state");
40555
- integer8(state.index, 0, "index");
40745
+ integer9(state.index, 0, "index");
40556
40746
  if (state.active === void 0) return { index: state.index };
40557
40747
  if (!record(state.active)) throw new GetoptsError("INVALID_INPUT", "Invalid getopts active cursor");
40558
- integer8(state.active.argument, 0, "active.argument");
40559
- integer8(state.active.offset, 1, "active.offset");
40748
+ integer9(state.active.argument, 0, "active.argument");
40749
+ integer9(state.active.offset, 1, "active.offset");
40560
40750
  return { index: state.index, active: { argument: state.active.argument, offset: state.active.offset } };
40561
40751
  }
40562
40752
  function withGetoptsIndex(state, index) {
40563
40753
  const copy2 = cloneGetoptsState(state);
40564
- integer8(index, Number.MIN_SAFE_INTEGER, "index");
40754
+ integer9(index, Number.MIN_SAFE_INTEGER, "index");
40565
40755
  return index <= 1 ? createGetoptsState() : { ...copy2, index };
40566
40756
  }
40567
40757
  var ScanWork = class {
@@ -40576,10 +40766,10 @@ var ScanWork = class {
40576
40766
  checkpoint;
40577
40767
  constructor(work) {
40578
40768
  if (!record(work)) throw new GetoptsError("INVALID_INPUT", "Explicit getopts work controls are required");
40579
- integer8(work.maxArguments, 0, "maxArguments");
40580
- integer8(work.maxBytes, 0, "maxBytes");
40581
- integer8(work.maxSteps, 0, "maxSteps");
40582
- integer8(work.yieldEvery, 1, "yieldEvery");
40769
+ integer9(work.maxArguments, 0, "maxArguments");
40770
+ integer9(work.maxBytes, 0, "maxBytes");
40771
+ integer9(work.maxSteps, 0, "maxSteps");
40772
+ integer9(work.yieldEvery, 1, "yieldEvery");
40583
40773
  if (typeof work.checkpoint !== "function") throw new GetoptsError("INVALID_INPUT", "A getopts checkpoint is required");
40584
40774
  if (work.signal !== void 0 && (!record(work.signal) || typeof work.signal.throwIfAborted !== "function" || typeof work.signal.addEventListener !== "function" || typeof work.signal.removeEventListener !== "function")) {
40585
40775
  throw new GetoptsError("INVALID_INPUT", "Invalid getopts signal");
@@ -41287,9 +41477,9 @@ var Admission = class {
41287
41477
  }
41288
41478
  };
41289
41479
  var ArrayLedger = class _ArrayLedger {
41290
- constructor(bytes3, fields3, initialTicket = 0) {
41480
+ constructor(bytes3, fields4, initialTicket = 0) {
41291
41481
  this.bytes = bytes3;
41292
- this.fields = fields3;
41482
+ this.fields = fields4;
41293
41483
  if (!Number.isSafeInteger(initialTicket) || initialTicket < 0) throw new RangeError("Invalid private initial ticket");
41294
41484
  this.#sequence.lastIssued = initialTicket;
41295
41485
  }
@@ -41346,8 +41536,8 @@ var ArrayLedger = class _ArrayLedger {
41346
41536
  }
41347
41537
  derive() {
41348
41538
  const bytes3 = BigInt(this.bytes);
41349
- const fields3 = BigInt(this.fields);
41350
- const values = [fields3, fields3, bytes3, 128n * fields3, 8n * bytes3 + 512n * fields3, 8n * fields3, 32n * bytes3 + 256n * fields3];
41539
+ const fields4 = BigInt(this.fields);
41540
+ const values = [fields4, fields4, bytes3, 128n * fields4, 8n * bytes3 + 512n * fields4, 8n * fields4, 32n * bytes3 + 256n * fields4];
41351
41541
  const result = [0, 0, 0, 0, 0, 0, 0];
41352
41542
  for (let index = 0; index < values.length; index++) {
41353
41543
  const value2 = values[index];
@@ -41900,8 +42090,8 @@ async function mapfileOptions(context2, work, allocation) {
41900
42090
  const numeric4 = async (text3, maximum) => {
41901
42091
  let value2 = 0;
41902
42092
  let index = 0;
41903
- const whitespace2 = (code) => code === 32 || code >= 9 && code <= 13;
41904
- while (index < text3.length && whitespace2(text3.charCodeAt(index))) {
42093
+ const whitespace3 = (code) => code === 32 || code >= 9 && code <= 13;
42094
+ while (index < text3.length && whitespace3(text3.charCodeAt(index))) {
41905
42095
  const pending = stringCheckpoint(work);
41906
42096
  if (pending) await pending;
41907
42097
  index++;
@@ -41921,7 +42111,7 @@ async function mapfileOptions(context2, work, allocation) {
41921
42111
  for (; index < text3.length; index++) {
41922
42112
  const pending = stringCheckpoint(work);
41923
42113
  if (pending) await pending;
41924
- if (!whitespace2(text3.charCodeAt(index))) throw new MapfileUsageError(`${text3}: invalid number`, 1);
42114
+ if (!whitespace3(text3.charCodeAt(index))) throw new MapfileUsageError(`${text3}: invalid number`, 1);
41925
42115
  }
41926
42116
  if (!digits || negative && value2 !== 0) throw new MapfileUsageError(`${text3}: invalid number`, 1);
41927
42117
  return value2;
@@ -42572,12 +42762,12 @@ function* pathTargets(name2, path, limits, signal, fail4) {
42572
42762
  yield name2;
42573
42763
  return;
42574
42764
  }
42575
- let fields3 = 1;
42765
+ let fields4 = 1;
42576
42766
  for (let separator = path.indexOf(":"); separator >= 0; separator = path.indexOf(":", separator + 1)) {
42577
42767
  signal.throwIfAborted();
42578
- if (++fields3 > limits.maxExpansionFields) fail4("maxExpansionFields");
42768
+ if (++fields4 > limits.maxExpansionFields) fail4("maxExpansionFields");
42579
42769
  }
42580
- if (fields3 > limits.maxExpansionFields) fail4("maxExpansionFields");
42770
+ if (fields4 > limits.maxExpansionFields) fail4("maxExpansionFields");
42581
42771
  let start = 0;
42582
42772
  let consulted = 0;
42583
42773
  while (start <= path.length) {
@@ -43502,8 +43692,8 @@ var DirectoryStackWork = class {
43502
43692
  for (let offset = 1; offset < token.length; offset++) {
43503
43693
  await this.charge(1);
43504
43694
  const code = token.charCodeAt(offset);
43505
- const whitespace2 = code === 32 || code >= 9 && code <= 13;
43506
- if (phase === "leading" && whitespace2) continue;
43695
+ const whitespace3 = code === 32 || code >= 9 && code <= 13;
43696
+ if (phase === "leading" && whitespace3) continue;
43507
43697
  if (phase === "leading" && (code === 43 || code === 45)) {
43508
43698
  negative = code === 45;
43509
43699
  phase = "sign";
@@ -43514,7 +43704,7 @@ var DirectoryStackWork = class {
43514
43704
  digits = true;
43515
43705
  value2 = value2 * 10n + BigInt(code - 48);
43516
43706
  if (value2 > (negative ? 9223372036854775808n : 9223372036854775807n)) this.fail("invalid directory stack index", 2);
43517
- } else if (phase === "digits" && whitespace2 || phase === "trailing" && whitespace2) phase = "trailing";
43707
+ } else if (phase === "digits" && whitespace3 || phase === "trailing" && whitespace3) phase = "trailing";
43518
43708
  else this.fail("invalid directory stack index", 2);
43519
43709
  }
43520
43710
  if (!digits) this.fail("invalid directory stack index", 2);
@@ -44369,8 +44559,8 @@ var Runtime = class _Runtime {
44369
44559
  return number6;
44370
44560
  }
44371
44561
  const word = index.word ?? parseArraySubscript(index.source ?? index.decimal, this.budget.parsing, byteLocale(state.variables), state.depth);
44372
- const fields3 = await this.valueWord(word, state, io, false);
44373
- const value2 = fields3.length === 1 ? fields3[0] : concatShellValues(fields3, io[valueScope]);
44562
+ const fields4 = await this.valueWord(word, state, io, false);
44563
+ const value2 = fields4.length === 1 ? fields4[0] : concatShellValues(fields4, io[valueScope]);
44374
44564
  if (shellValueByteLength(value2) === 0) {
44375
44565
  await this.diagnostic(io, "associative array: bad array subscript");
44376
44566
  if (create) throw completedExit(1);
@@ -44454,8 +44644,8 @@ var Runtime = class _Runtime {
44454
44644
  const join = async (values) => values.every((value2) => typeof value2 === "string") ? this.arrayJoin(operation2, values, "") : concatShellValues(values, io[valueScope]);
44455
44645
  if (assignment.kind === "element") {
44456
44646
  const index = await this.arrayIndex(staged, assignment.index, state, io, operation2, true);
44457
- const fields3 = await this.valueWord(assignment.value, state, io, false);
44458
- let value2 = await join(fields3);
44647
+ const fields4 = await this.valueWord(assignment.value, state, io, false);
44648
+ let value2 = await join(fields4);
44459
44649
  if (assignment.append) value2 = await join([staged.values.get(index)?.text.rawValue ?? staged.get(index) ?? "", value2]);
44460
44650
  await insert(index, value2);
44461
44651
  } else for (const entry of assignment.entries) {
@@ -44473,12 +44663,12 @@ var Runtime = class _Runtime {
44473
44663
  }
44474
44664
  if (expandedEntry) continue;
44475
44665
  }
44476
- const fields3 = await this.valueWord(entry.value, state, io, entry.index === void 0);
44666
+ const fields4 = await this.valueWord(entry.value, state, io, entry.index === void 0);
44477
44667
  if (entry.index) {
44478
44668
  const index = numericIndex(entry.index);
44479
- await insert(index, await join(fields3));
44669
+ await insert(index, await join(fields4));
44480
44670
  cursor = index + 1;
44481
- } else for (const value2 of fields3) {
44671
+ } else for (const value2 of fields4) {
44482
44672
  await insert(cursor, value2);
44483
44673
  cursor++;
44484
44674
  }
@@ -45493,8 +45683,8 @@ var Runtime = class _Runtime {
45493
45683
  throw new ArrayFailure("indexed binding cannot be a command prefix");
45494
45684
  }
45495
45685
  await this.arrayZero(state, assignment.name, async () => {
45496
- const fields3 = await this.valueWord(assignment.value, state, io, false);
45497
- return fields3.every((value3) => typeof value3 === "string") ? this.arrayJoin(requireArrays(state).owner, fields3, "") : concatShellValues(fields3, io[valueScope]);
45686
+ const fields4 = await this.valueWord(assignment.value, state, io, false);
45687
+ return fields4.every((value3) => typeof value3 === "string") ? this.arrayJoin(requireArrays(state).owner, fields4, "") : concatShellValues(fields4, io[valueScope]);
45498
45688
  }, assignment.append);
45499
45689
  continue;
45500
45690
  }
@@ -46833,7 +47023,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46833
47023
  }
46834
47024
  async letBuiltin(context2, state) {
46835
47025
  this.signal.throwIfAborted();
46836
- const { maxExpansionBytes: bytes3, maxExpansionFields: fields3 } = this.budget.limits;
47026
+ const { maxExpansionBytes: bytes3, maxExpansionFields: fields4 } = this.budget.limits;
46837
47027
  const admit2 = (value3) => {
46838
47028
  if (typeof value3 !== "string" || value3.includes("\0")) throw new CommandFailure2("let: arguments must be strings without NUL", 2);
46839
47029
  if (value3.length > bytes3 || import_buffer.Buffer.byteLength(value3) > bytes3) this.budget.fail("maxExpansionBytes");
@@ -46845,7 +47035,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46845
47035
  };
46846
47036
  const { args } = context2;
46847
47037
  if (!Array.isArray(args)) throw new CommandFailure2("let: argument array required", 2);
46848
- if (args.length + 1 > fields3) this.budget.fail("maxExpansionFields");
47038
+ if (args.length + 1 > fields4) this.budget.fail("maxExpansionFields");
46849
47039
  admit2(context2.command);
46850
47040
  for (let index = 0; index < args.length; index++) {
46851
47041
  this.signal.throwIfAborted();
@@ -46877,7 +47067,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46877
47067
  }
46878
47068
  async getoptsBuiltin(context2, state) {
46879
47069
  this.signal.throwIfAborted();
46880
- const { maxExpansionBytes: bytes3, maxExpansionFields: fields3 } = this.budget.limits;
47070
+ const { maxExpansionBytes: bytes3, maxExpansionFields: fields4 } = this.budget.limits;
46881
47071
  const admit2 = (value2) => {
46882
47072
  if (typeof value2 !== "string") throw new CommandFailure2("getopts: arguments must be strings without NUL", 2);
46883
47073
  if (value2.length > bytes3 || import_buffer.Buffer.byteLength(value2) > bytes3) this.budget.fail("maxExpansionBytes");
@@ -46889,7 +47079,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46889
47079
  this.signal.throwIfAborted();
46890
47080
  };
46891
47081
  if (!Array.isArray(context2.args)) throw new CommandFailure2("getopts: argument array required", 2);
46892
- if (context2.args.length + 1 > fields3) this.budget.fail("maxExpansionFields");
47082
+ if (context2.args.length + 1 > fields4) this.budget.fail("maxExpansionFields");
46893
47083
  admit2(context2.command);
46894
47084
  for (let index = 0; index < context2.args.length; index++) {
46895
47085
  this.signal.throwIfAborted();
@@ -46912,10 +47102,10 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
46912
47102
  const monitor = explicit ? void 0 : stateMonitor(state);
46913
47103
  const revision = monitor?.positionalRevision;
46914
47104
  const supplied = explicit ? context2.args.slice(offset + 2) : state.positional;
46915
- if (supplied.length > fields3) this.budget.fail("maxExpansionFields");
47105
+ if (supplied.length > fields4) this.budget.fail("maxExpansionFields");
46916
47106
  const maxBytes = saturatedProduct(bytes3, saturatedSum(supplied.length, 1));
46917
47107
  const maxSteps = saturatedSum(saturatedProduct(maxBytes, 2), saturatedSum(supplied.length, 2));
46918
- const work = { maxArguments: fields3, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint };
47108
+ const work = { maxArguments: fields4, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint };
46919
47109
  let input3 = monitor?.getoptsInput;
46920
47110
  let allocation;
46921
47111
  let result;
@@ -47996,27 +48186,27 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
47996
48186
  let position = 0;
47997
48187
  point = 0;
47998
48188
  const separator = () => position < end && !line.escaped.has(point) && separators.includes(String.fromCodePoint(line.value.codePointAt(position)));
47999
- const whitespace2 = () => separator() && " \n".includes(line.value[position]);
48189
+ const whitespace3 = () => separator() && " \n".includes(line.value[position]);
48000
48190
  const advance = () => {
48001
48191
  position += line.value.codePointAt(position) > 65535 ? 2 : 1;
48002
48192
  point++;
48003
48193
  };
48004
- while (position < end && whitespace2()) advance();
48005
- const fields3 = [];
48006
- while (position < end && fields3.length < names.length) {
48194
+ while (position < end && whitespace3()) advance();
48195
+ const fields4 = [];
48196
+ while (position < end && fields4.length < names.length) {
48007
48197
  const start = position;
48008
48198
  while (position < end && !separator()) advance();
48009
- fields3.push({ start, end: position });
48010
- while (position < end && whitespace2()) advance();
48199
+ fields4.push({ start, end: position });
48200
+ while (position < end && whitespace3()) advance();
48011
48201
  if (position < end && separator()) advance();
48012
- while (position < end && whitespace2()) advance();
48202
+ while (position < end && whitespace3()) advance();
48013
48203
  }
48014
48204
  for (let index = 0; index < names.length; index++) {
48015
48205
  if (state.readonlyVariables?.has(names[index])) {
48016
48206
  await this.diagnostic(context2, `${names[index]}: readonly variable`);
48017
48207
  return index === names.length - 1 ? 1 : 2;
48018
48208
  }
48019
- const field2 = fields3[index];
48209
+ const field2 = fields4[index];
48020
48210
  await this.assignVariable(state, names[index], field2 ? line.value.slice(field2.start, index === names.length - 1 && position < end ? end : field2.end) : "");
48021
48211
  }
48022
48212
  }
@@ -48060,13 +48250,13 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48060
48250
  return (await this.valueWords(words, state, io, declaration)).map(shellValueText);
48061
48251
  }
48062
48252
  async valueWords(words, state, io, declaration = false) {
48063
- const fields3 = [];
48253
+ const fields4 = [];
48064
48254
  for (const word of words) {
48065
48255
  const values = await this.valueWord(word, state, io, !(declaration && this.assignment(word)), false, false, false, void 0, true);
48066
- if (values.length > this.budget.limits.maxExpansionFields - fields3.length) this.budget.fail("maxExpansionFields");
48067
- for (const value2 of values) fields3.push(value2);
48256
+ if (values.length > this.budget.limits.maxExpansionFields - fields4.length) this.budget.fail("maxExpansionFields");
48257
+ for (const value2 of values) fields4.push(value2);
48068
48258
  }
48069
- return fields3;
48259
+ return fields4;
48070
48260
  }
48071
48261
  async part(part, state, io, hereString = false) {
48072
48262
  return shellValueText(await this.valuePart(part, state, io, hereString));
@@ -48554,20 +48744,20 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48554
48744
  }
48555
48745
  async valueWord(word, state, io, split4 = true, pattern = false, hereString = false, conditionalPattern = false, regexAppend, braces = split4 && !pattern && !hereString) {
48556
48746
  if (braces && state.braceexpand !== false && word.parts.some((part) => part.kind === "text" && !part.quoted && part.value.includes("{"))) {
48557
- const fields3 = [];
48747
+ const fields4 = [];
48558
48748
  let bytes3 = 0;
48559
48749
  for await (const expanded of expandBraces(word, this.budget, this.signal)) {
48560
48750
  const values = await this.valueWord(expanded, state, io, split4, pattern, hereString, conditionalPattern, regexAppend, false);
48561
- if (values.length > this.budget.limits.maxExpansionFields - fields3.length) this.budget.fail("maxExpansionFields");
48751
+ if (values.length > this.budget.limits.maxExpansionFields - fields4.length) this.budget.fail("maxExpansionFields");
48562
48752
  for (const value2 of values) {
48563
48753
  const size = shellValueByteLength(value2);
48564
48754
  if (size > this.budget.limits.maxExpansionBytes - bytes3) this.budget.fail("maxExpansionBytes");
48565
48755
  bytes3 += size;
48566
48756
  io[valueScope]?.reserve(32 + (typeof value2 === "string" ? value2.length * 2 : 0), 0);
48567
- fields3.push(value2);
48757
+ fields4.push(value2);
48568
48758
  }
48569
48759
  }
48570
- return fields3;
48760
+ return fields4;
48571
48761
  }
48572
48762
  const arrayOwned = word.parts.some((part) => part.kind === "variable" && !part.prefixNames && (getArraySelector(part) !== void 0 || arrayStore(state)?.get(part.name) !== void 0));
48573
48763
  const prefixOwned = word.parts.some((part) => part.kind === "variable" && (part.prefixNames === "@" || part.transform && part.name === "@"));
@@ -48578,14 +48768,14 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48578
48768
  if (owner) await this.prepareArrayObservers(state, owner);
48579
48769
  owner?.reserve({ metadata: 128 + word.parts.length * 32, allocatedSlots: word.parts.length + 1, work: word.parts.length + 5 });
48580
48770
  scratch?.reserve(word.parts.length * 32, 0);
48581
- const fields3 = [];
48771
+ const fields4 = [];
48582
48772
  let emptyNameGroups;
48583
48773
  let quoteGroup;
48584
48774
  const addField = () => {
48585
- if (fields3.length >= this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48775
+ if (fields4.length >= this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48586
48776
  scratch?.reserve(32, 0);
48587
48777
  owner?.reserve({ metadata: 32, allocatedSlots: 1, work: 3 });
48588
- fields3.push({ fragments: [], bytes: false, patterns: void 0, present: false, independentPresence: false });
48778
+ fields4.push({ fragments: [], bytes: false, patterns: void 0, present: false, independentPresence: false });
48589
48779
  };
48590
48780
  addField();
48591
48781
  let expansionBytes = 0;
@@ -48594,7 +48784,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48594
48784
  const size = shellValueByteLength(value2);
48595
48785
  if (size > this.budget.limits.maxExpansionBytes - expansionBytes) this.budget.fail("maxExpansionBytes");
48596
48786
  expansionBytes += size;
48597
- const field2 = fields3.at(-1);
48787
+ const field2 = fields4.at(-1);
48598
48788
  let escapes = 0;
48599
48789
  if (!glob) {
48600
48790
  const special = conditionalPattern ? "\\*?[]-^()|+!@" : "\\*?[]-^";
@@ -48657,9 +48847,9 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48657
48847
  const point = typeof piece === "string" ? piece.codePointAt(0) : void 0;
48658
48848
  if (typeof piece === "string" && point !== void 0 && piece.length === (point > 65535 ? 2 : 1) && points.has(point)) {
48659
48849
  if (!" \n".includes(piece)) {
48660
- fields3.at(-1).present = true;
48850
+ fields4.at(-1).present = true;
48661
48851
  addField();
48662
- } else if (fields3.at(-1).present) boundary = true;
48852
+ } else if (fields4.at(-1).present) boundary = true;
48663
48853
  } else {
48664
48854
  if (boundary) addField();
48665
48855
  boundary = false;
@@ -48723,18 +48913,18 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
48723
48913
  if (position > 0) addField();
48724
48914
  append(stateMonitor(state)?.positionals.get(String(position), state.positional[position]) ?? state.positional[position], false, true);
48725
48915
  }
48726
- if (state.positional.length === 0 && word.parts.every((entry) => entry.kind === "text" && entry.value === "" || entry === part)) fields3[0].present = false;
48916
+ if (state.positional.length === 0 && word.parts.every((entry) => entry.kind === "text" && entry.value === "" || entry === part)) fields4[0].present = false;
48727
48917
  } else {
48728
48918
  const value2 = part.kind === "text" ? part.byteValue ?? part.value : await this.valuePart(part, state, partIO, hereString);
48729
48919
  if (part.quoted || !split4 || state.variables.IFS === "") append(value2, !part.quoted, quotedPresence || !split4 || shellValueByteLength(value2) > 0);
48730
48920
  else await appendSplit(value2);
48731
48921
  }
48732
- if (fields3.length > this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48922
+ if (fields4.length > this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
48733
48923
  if (owner) await owner.ledger.checkpoint(this.signal);
48734
48924
  }
48735
48925
  const result = [];
48736
48926
  let resultBytes = 0;
48737
- for (const field2 of fields3) {
48927
+ for (const field2 of fields4) {
48738
48928
  if (!field2.present && split4) continue;
48739
48929
  if (split4 && !field2.independentPresence && field2.quoteGroups) {
48740
48930
  const work = { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
@@ -52000,7 +52190,7 @@ function* entities2(text3) {
52000
52190
  }
52001
52191
  function* validDeclaration(content, expectedEncoding) {
52002
52192
  let offset = 0;
52003
- const whitespace2 = function* () {
52193
+ const whitespace3 = function* () {
52004
52194
  const start = offset;
52005
52195
  while (offset < content.length && " \n\r".includes(content[offset])) {
52006
52196
  offset++;
@@ -52013,9 +52203,9 @@ function* validDeclaration(content, expectedEncoding) {
52013
52203
  if (content.slice(offset, offset + name2.length).toLowerCase() !== name2) return void 0;
52014
52204
  offset += name2.length;
52015
52205
  yield name2.length;
52016
- yield* whitespace2();
52206
+ yield* whitespace3();
52017
52207
  if (content[offset++] !== "=") return void 0;
52018
- yield* whitespace2();
52208
+ yield* whitespace3();
52019
52209
  const quote5 = content[offset++];
52020
52210
  if (quote5 !== "'" && quote5 !== '"') return void 0;
52021
52211
  const start = offset;
@@ -52027,20 +52217,20 @@ function* validDeclaration(content, expectedEncoding) {
52027
52217
  if (offset >= content.length) return void 0;
52028
52218
  return content.slice(start, offset++);
52029
52219
  };
52030
- if (!(yield* whitespace2()) || (yield* field2("version")) !== "1.0") return false;
52031
- let spacing = yield* whitespace2();
52220
+ if (!(yield* whitespace3()) || (yield* field2("version")) !== "1.0") return false;
52221
+ let spacing = yield* whitespace3();
52032
52222
  if (content.slice(offset, offset + 8).toLowerCase() === "encoding") {
52033
52223
  if (!spacing) return false;
52034
52224
  const encoding = yield* field2("encoding");
52035
52225
  if (encoding === void 0 || encoding.length > 8 || !["utf-8", "utf-16", "utf-16le", "utf-16be"].includes(encoding.toLowerCase())) return false;
52036
52226
  if (expectedEncoding !== void 0 && encoding.toLowerCase() !== expectedEncoding.toLowerCase()) return false;
52037
- spacing = yield* whitespace2();
52227
+ spacing = yield* whitespace3();
52038
52228
  }
52039
52229
  if (content.slice(offset, offset + 10).toLowerCase() === "standalone") {
52040
52230
  if (!spacing) return false;
52041
52231
  const standalone = yield* field2("standalone");
52042
52232
  if (standalone === void 0 || standalone.length > 3 || !["yes", "no"].includes(standalone.toLowerCase())) return false;
52043
- yield* whitespace2();
52233
+ yield* whitespace3();
52044
52234
  }
52045
52235
  return offset === content.length;
52046
52236
  }
@@ -52089,7 +52279,7 @@ function* parseXmlSteps(input3, limits = {}) {
52089
52279
  const admitContent = () => {
52090
52280
  if (++contentNodes > maxContentNodes) throw new XmlLimitError("maxContentNodes", "XML content node limit exceeded");
52091
52281
  };
52092
- const whitespace2 = function* () {
52282
+ const whitespace3 = function* () {
52093
52283
  let work = 0;
52094
52284
  while (offset < source2.length && " \n\r".includes(source2[offset])) {
52095
52285
  offset++;
@@ -52184,7 +52374,7 @@ function* parseXmlSteps(input3, limits = {}) {
52184
52374
  } else if (source2.startsWith("</", offset)) {
52185
52375
  offset += 2;
52186
52376
  const name2 = yield* readName();
52187
- yield* whitespace2();
52377
+ yield* whitespace3();
52188
52378
  if (source2[offset++] !== ">" || stack.pop()?.name !== name2) invalid("mismatched closing tag");
52189
52379
  } else {
52190
52380
  offset++;
@@ -52194,16 +52384,16 @@ function* parseXmlSteps(input3, limits = {}) {
52194
52384
  let ownsNamespaces = stack.length === 0;
52195
52385
  while (true) {
52196
52386
  const beforeSpace = offset;
52197
- yield* whitespace2();
52387
+ yield* whitespace3();
52198
52388
  if (source2[offset] === "/" || source2[offset] === ">") break;
52199
52389
  if (offset === beforeSpace) invalid("attributes require whitespace");
52200
52390
  const attribute = yield* readName();
52201
52391
  if (attributes.has(attribute)) invalid("duplicate attribute");
52202
52392
  if (++attributeCount > maxAttributes) throw new XmlLimitError("maxAttributes", "XML attribute limit exceeded");
52203
52393
  if (attributes.size >= maxAttributesPerElement) throw new XmlLimitError("maxAttributesPerElement", "XML attribute limit exceeded");
52204
- yield* whitespace2();
52394
+ yield* whitespace3();
52205
52395
  if (source2[offset++] !== "=") invalid("missing attribute equals");
52206
- yield* whitespace2();
52396
+ yield* whitespace3();
52207
52397
  const quote5 = source2[offset++];
52208
52398
  if (quote5 !== '"' && quote5 !== "'") invalid("unquoted attribute");
52209
52399
  const end = yield* find2(source2, quote5, offset);