@poe-platform/safe-bash 0.1.535 → 0.1.537

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/safe-bash/chunks/chunk-JWUT4LBW.js +617 -0
  2. package/dist/safe-bash/chunks/chunk-JWUT4LBW.js.map +7 -0
  3. package/dist/safe-bash/chunks/chunk-PY37EOPJ.js +1236 -0
  4. package/dist/safe-bash/chunks/chunk-PY37EOPJ.js.map +7 -0
  5. package/dist/safe-bash/commands/pr/command.d.ts +4 -0
  6. package/dist/safe-bash/commands/pr/command.d.ts.map +1 -0
  7. package/dist/safe-bash/commands/pr/command.js +117 -0
  8. package/dist/safe-bash/commands/pr/command.js.map +1 -0
  9. package/dist/safe-bash/commands/pr/format.d.ts +52 -0
  10. package/dist/safe-bash/commands/pr/format.d.ts.map +1 -0
  11. package/dist/safe-bash/commands/pr/format.js +527 -0
  12. package/dist/safe-bash/commands/pr/format.js.map +1 -0
  13. package/dist/safe-bash/commands/pr/index.browser.js +13 -0
  14. package/dist/safe-bash/commands/pr/index.browser.js.map +7 -0
  15. package/dist/safe-bash/commands/pr/index.d.ts +7 -0
  16. package/dist/safe-bash/commands/pr/index.d.ts.map +1 -0
  17. package/dist/safe-bash/commands/pr/index.js +13 -0
  18. package/dist/safe-bash/commands/pr/index.js.map +1 -0
  19. package/dist/safe-bash/commands/pr/internal.d.ts +61 -0
  20. package/dist/safe-bash/commands/pr/internal.d.ts.map +1 -0
  21. package/dist/safe-bash/commands/pr/internal.js +181 -0
  22. package/dist/safe-bash/commands/pr/internal.js.map +1 -0
  23. package/dist/safe-bash/commands/pr/io.d.ts +37 -0
  24. package/dist/safe-bash/commands/pr/io.d.ts.map +1 -0
  25. package/dist/safe-bash/commands/pr/io.js +210 -0
  26. package/dist/safe-bash/commands/pr/io.js.map +1 -0
  27. package/dist/safe-bash/commands/pr/options.d.ts +36 -0
  28. package/dist/safe-bash/commands/pr/options.d.ts.map +1 -0
  29. package/dist/safe-bash/commands/pr/options.js +250 -0
  30. package/dist/safe-bash/commands/pr/options.js.map +1 -0
  31. package/dist/safe-bash/commands/tsort/command.d.ts +4 -0
  32. package/dist/safe-bash/commands/tsort/command.d.ts.map +1 -0
  33. package/dist/safe-bash/commands/tsort/command.js +72 -0
  34. package/dist/safe-bash/commands/tsort/command.js.map +1 -0
  35. package/dist/safe-bash/commands/tsort/graph.d.ts +3 -0
  36. package/dist/safe-bash/commands/tsort/graph.d.ts.map +1 -0
  37. package/dist/safe-bash/commands/tsort/graph.js +183 -0
  38. package/dist/safe-bash/commands/tsort/graph.js.map +1 -0
  39. package/dist/safe-bash/commands/tsort/index.browser.js +13 -0
  40. package/dist/safe-bash/commands/tsort/index.browser.js.map +7 -0
  41. package/dist/safe-bash/commands/tsort/index.d.ts +7 -0
  42. package/dist/safe-bash/commands/tsort/index.d.ts.map +1 -0
  43. package/dist/safe-bash/commands/tsort/index.js +13 -0
  44. package/dist/safe-bash/commands/tsort/index.js.map +1 -0
  45. package/dist/safe-bash/commands/tsort/internal.d.ts +50 -0
  46. package/dist/safe-bash/commands/tsort/internal.d.ts.map +1 -0
  47. package/dist/safe-bash/commands/tsort/internal.js +176 -0
  48. package/dist/safe-bash/commands/tsort/internal.js.map +1 -0
  49. package/dist/safe-bash/commands/tsort/io.d.ts +29 -0
  50. package/dist/safe-bash/commands/tsort/io.d.ts.map +1 -0
  51. package/dist/safe-bash/commands/tsort/io.js +192 -0
  52. package/dist/safe-bash/commands/tsort/io.js.map +1 -0
  53. package/dist/safe-bash/core.browser.js +46 -5
  54. package/dist/safe-bash/core.browser.js.map +3 -3
  55. package/dist/safe-bash/core.d.ts +2 -0
  56. package/dist/safe-bash/core.d.ts.map +1 -1
  57. package/dist/safe-bash/core.js +2 -0
  58. package/dist/safe-bash/core.js.map +1 -1
  59. package/dist/safe-bash/plugins/composition.d.ts +4 -0
  60. package/dist/safe-bash/plugins/composition.d.ts.map +1 -1
  61. package/dist/safe-bash/plugins/composition.js +7 -1
  62. package/dist/safe-bash/plugins/composition.js.map +1 -1
  63. package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
  64. package/dist/safe-bash/shell/runtime.js +28 -3
  65. package/dist/safe-bash/shell/runtime.js.map +1 -1
  66. package/package.json +14 -2
@@ -0,0 +1,1236 @@
1
+ import {
2
+ createOutputOperation
3
+ } from "./chunk-PPVCI2F2.js";
4
+ import {
5
+ FsError,
6
+ PublicDiagnostic,
7
+ getCommandArguments,
8
+ init_platform,
9
+ publicDiagnosticMessage,
10
+ resolvePath,
11
+ shellValueByteLength,
12
+ shellValueBytes,
13
+ yieldTurn
14
+ } from "./chunk-L2GZSOSJ.js";
15
+
16
+ // packages/safe-bash/src/commands/pr/index.ts
17
+ init_platform();
18
+
19
+ // packages/safe-bash/src/commands/pr/command.ts
20
+ init_platform();
21
+
22
+ // packages/safe-bash/src/commands/pr/internal.ts
23
+ init_platform();
24
+ function settings(options) {
25
+ const limits = {
26
+ maxArguments: 4096,
27
+ maxArgumentBytes: 65536,
28
+ maxFiles: 128,
29
+ maxColumns: 128,
30
+ maxPageLines: 65536,
31
+ maxPageWidth: 65536,
32
+ maxPages: 65536,
33
+ maxInputBytes: 33554432,
34
+ maxBufferedBytes: 16777216,
35
+ maxLineBytes: 1048576,
36
+ maxLines: 1048576,
37
+ maxOutputBytes: 67108864,
38
+ maxDiagnosticBytes: 65536,
39
+ maxWork: 134217728,
40
+ maxEmptyChunks: 4096,
41
+ ...options.limits
42
+ };
43
+ for (const [name, value] of Object.entries(limits)) {
44
+ if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`Invalid pr limit: ${name}`);
45
+ }
46
+ if (options.clock !== void 0 && typeof options.clock !== "function") throw new TypeError("pr clock must be a function");
47
+ return Object.freeze(limits);
48
+ }
49
+ var PrError = class extends PublicDiagnostic {
50
+ constructor(message, usage = false) {
51
+ super(message);
52
+ this.usage = usage;
53
+ }
54
+ usage;
55
+ };
56
+ var PrReadError = class extends PrError {
57
+ };
58
+ function raw(value) {
59
+ let text = "";
60
+ for (const byte of value) text += String.fromCharCode(byte);
61
+ return text;
62
+ }
63
+ function bytes(value) {
64
+ return Uint8Array.from(value, (character) => character.charCodeAt(0));
65
+ }
66
+ function pathText(value) {
67
+ try {
68
+ return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes(value));
69
+ } catch {
70
+ throw new PrError("filesystem paths must be valid UTF-8");
71
+ }
72
+ }
73
+ function quote(value) {
74
+ const escapes = { "\x07": "\\a", "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", " ": "\\t", "\v": "\\v", "\\": "\\\\", "'": "\\'" };
75
+ let result = "'";
76
+ for (const character of value) {
77
+ const code = character.charCodeAt(0);
78
+ result += escapes[character] ?? (code >= 32 && code < 127 ? character : `\\${code.toString(8).padStart(3, "0")}`);
79
+ }
80
+ return `${result}'`;
81
+ }
82
+ function fileQuote(value) {
83
+ let safe = value.length > 0, escaped = false;
84
+ for (const character of value) {
85
+ const code = character.charCodeAt(0);
86
+ if (!(character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character >= "0" && character <= "9" || "_./-".includes(character))) safe = false;
87
+ if (code < 32 || code >= 127) escaped = true;
88
+ }
89
+ if (safe) return value;
90
+ if (!escaped) {
91
+ if (value.includes("'") && !["$", "`", "\\", '"'].some((character) => value.includes(character))) return `"${value}"`;
92
+ return `'${value.split("'").join("'\\''")}'`;
93
+ }
94
+ let result = "'", inEscape = false;
95
+ for (const character of value) {
96
+ const code = character.charCodeAt(0);
97
+ if (code < 32 || code >= 127) {
98
+ if (!inEscape) {
99
+ result += "'$'";
100
+ inEscape = true;
101
+ }
102
+ result += quote(character).slice(1, -1);
103
+ } else {
104
+ if (inEscape) {
105
+ result += "''";
106
+ inEscape = false;
107
+ }
108
+ result += character === "'" ? "'\\''" : character;
109
+ }
110
+ }
111
+ return `${result}'`;
112
+ }
113
+ var Budget = class {
114
+ constructor(context, limits, signal) {
115
+ this.context = context;
116
+ this.limits = limits;
117
+ this.signal = signal;
118
+ }
119
+ context;
120
+ limits;
121
+ signal;
122
+ work = 0;
123
+ checkpoint = 0;
124
+ retained = 0;
125
+ input = 0;
126
+ lines = 0;
127
+ pages = 0;
128
+ output = 0;
129
+ diagnostics = 0;
130
+ check(value, maximum, label) {
131
+ if (!Number.isSafeInteger(value) || value < 0 || value > maximum) throw new PrError(`${label} limit exceeded`);
132
+ }
133
+ charge(amount = 1) {
134
+ this.signal.throwIfAborted();
135
+ this.work += amount;
136
+ this.check(this.work, this.limits.maxWork, "work");
137
+ }
138
+ async checkpointWork() {
139
+ this.signal.throwIfAborted();
140
+ if (this.work - this.checkpoint >= 4096) {
141
+ this.checkpoint = this.work;
142
+ await yieldTurn(this.signal);
143
+ }
144
+ }
145
+ retain(amount) {
146
+ this.check(this.retained + amount, this.limits.maxBufferedBytes, "buffered bytes");
147
+ this.retained += amount;
148
+ }
149
+ admitString(length) {
150
+ this.signal.throwIfAborted();
151
+ this.check(length, this.limits.maxWork - this.work, "work");
152
+ this.check(this.retained + length * 2, this.limits.maxBufferedBytes, "buffered bytes");
153
+ }
154
+ inputBytes(amount) {
155
+ this.input += amount;
156
+ this.check(this.input, this.limits.maxInputBytes, "input bytes");
157
+ }
158
+ line() {
159
+ this.check(++this.lines, this.limits.maxLines, "input lines");
160
+ }
161
+ page() {
162
+ this.check(++this.pages, this.limits.maxPages, "pages");
163
+ this.charge();
164
+ }
165
+ emitted(amount, diagnostic) {
166
+ if (diagnostic) {
167
+ this.diagnostics += amount;
168
+ this.check(this.diagnostics, this.limits.maxDiagnosticBytes, "diagnostic bytes");
169
+ } else {
170
+ this.output += amount;
171
+ this.check(this.output, this.limits.maxOutputBytes, "output bytes");
172
+ }
173
+ if (!diagnostic) this.charge(amount);
174
+ }
175
+ arguments() {
176
+ this.check(this.context.args.length, this.limits.maxArguments, "argument count");
177
+ let total = 0;
178
+ for (const argument of this.context.args) {
179
+ total += argument.length;
180
+ this.check(total, this.limits.maxArgumentBytes, "argument bytes");
181
+ for (let offset = 0; offset < argument.length; offset++) {
182
+ const unit = argument.charCodeAt(offset);
183
+ if (unit >= 55296 && unit <= 56319) {
184
+ const next = argument.charCodeAt(++offset);
185
+ if (!(next >= 56320 && next <= 57343)) throw new PrError("arguments must contain well-formed Unicode");
186
+ } else if (unit >= 56320 && unit <= 57343) throw new PrError("arguments must contain well-formed Unicode");
187
+ }
188
+ }
189
+ total = 0;
190
+ return getCommandArguments(this.context).values.map((argument) => {
191
+ total += shellValueByteLength(argument);
192
+ this.check(total, this.limits.maxArgumentBytes, "argument bytes");
193
+ const value = shellValueBytes(argument);
194
+ this.charge(value.length);
195
+ if (value.includes(0)) throw new PrError("NUL is not supported in arguments");
196
+ return raw(value);
197
+ });
198
+ }
199
+ };
200
+
201
+ // packages/safe-bash/src/commands/pr/io.ts
202
+ init_platform();
203
+ var Lifecycle = class {
204
+ constructor(budget, output) {
205
+ this.budget = budget;
206
+ output.registerCleanup(() => this.close());
207
+ }
208
+ budget;
209
+ pending = /* @__PURE__ */ new Set();
210
+ cleanups = [];
211
+ closing;
212
+ cleanup(action) {
213
+ this.assertOpen();
214
+ this.cleanups.push(action);
215
+ }
216
+ assertOpen() {
217
+ this.budget.signal.throwIfAborted();
218
+ if (this.closing) throw new PrError("command is closed");
219
+ }
220
+ async operation(action, diagnostic = false) {
221
+ this.assertOpen();
222
+ if (!diagnostic) this.budget.charge();
223
+ const pending = Promise.resolve().then(() => {
224
+ this.assertOpen();
225
+ return action();
226
+ });
227
+ this.pending.add(pending);
228
+ try {
229
+ const value = await pending;
230
+ this.assertOpen();
231
+ return value;
232
+ } finally {
233
+ this.pending.delete(pending);
234
+ }
235
+ }
236
+ close() {
237
+ return this.closing ??= Promise.resolve().then(async () => {
238
+ while (this.pending.size) await Promise.allSettled([...this.pending]);
239
+ const failures = [];
240
+ for (const cleanup of this.cleanups) {
241
+ try {
242
+ await cleanup();
243
+ } catch (error) {
244
+ failures.push(error);
245
+ }
246
+ }
247
+ if (failures.length === 1) throw failures[0];
248
+ if (failures.length > 1) throw new AggregateError(failures, "pr cleanup failed");
249
+ });
250
+ }
251
+ async write(value, diagnostic = false) {
252
+ const { budget } = this;
253
+ budget.emitted(value.length, diagnostic);
254
+ await this.operation(async () => {
255
+ if (!diagnostic) budget.retain(value.length * 3);
256
+ try {
257
+ const sink = diagnostic ? budget.context.stderr : budget.context.stdout;
258
+ await (sink.ownedOutput ?? sink).write(bytes(value));
259
+ } finally {
260
+ if (!diagnostic) budget.retain(-value.length * 3);
261
+ }
262
+ }, diagnostic);
263
+ }
264
+ };
265
+ var Reader = class {
266
+ constructor(name, lifecycle) {
267
+ this.name = name;
268
+ this.lifecycle = lifecycle;
269
+ lifecycle.cleanup(async () => {
270
+ try {
271
+ if (!this.ended) await this.iterator?.return?.();
272
+ } finally {
273
+ this.iterator = void 0;
274
+ this.releaseSnapshot();
275
+ lifecycle.budget.retain(-this.chunk.length);
276
+ this.chunk = new Uint8Array();
277
+ }
278
+ });
279
+ }
280
+ name;
281
+ lifecycle;
282
+ iterator;
283
+ chunk = new Uint8Array();
284
+ offset = 0;
285
+ pushed = -1;
286
+ ended = false;
287
+ empties = 0;
288
+ length = 0;
289
+ snapshotBytes = 0;
290
+ path;
291
+ stat;
292
+ releaseSnapshot = () => {
293
+ this.lifecycle.budget.retain(-this.snapshotBytes);
294
+ this.snapshotBytes = 0;
295
+ };
296
+ async open() {
297
+ if (this.name === "-") return;
298
+ const { budget } = this.lifecycle;
299
+ this.path = resolvePath(budget.context.cwd, pathText(this.name));
300
+ this.stat = await this.lifecycle.operation(() => budget.context.fs.stat(this.path, { signal: budget.signal }));
301
+ if (this.stat.type !== "file" && this.stat.type !== "directory" && this.stat.type !== "character") throw new FsError("ENOTSUP", { path: this.path });
302
+ }
303
+ async acquire() {
304
+ const { budget } = this.lifecycle;
305
+ const { fs, stdin } = budget.context;
306
+ await this.lifecycle.operation(async () => {
307
+ let source;
308
+ if (this.path === void 0) source = stdin;
309
+ else {
310
+ const capabilities = await fs.capabilitiesFor?.(this.path, { signal: budget.signal }) ?? fs.capabilities;
311
+ budget.signal.throwIfAborted();
312
+ if (fs.readStream && capabilities.streamingRead !== false) source = fs.readStream(this.path, { signal: budget.signal, chunkSize: 16384 });
313
+ else {
314
+ const maximum = Math.min(budget.limits.maxInputBytes, Math.floor(budget.limits.maxBufferedBytes / 2));
315
+ budget.check(this.stat.size, maximum, "buffered input bytes");
316
+ budget.retain(maximum);
317
+ this.snapshotBytes = maximum;
318
+ const content = await fs.readFile(this.path, { signal: budget.signal, maxBytes: maximum });
319
+ if (!(content instanceof Uint8Array)) throw new TypeError("pr input requires bytes");
320
+ budget.check(content.length, maximum, "buffered input bytes");
321
+ budget.retain(content.length - maximum);
322
+ this.snapshotBytes = content.length;
323
+ const { releaseSnapshot } = this;
324
+ source = { async *[Symbol.asyncIterator]() {
325
+ try {
326
+ yield content;
327
+ } finally {
328
+ releaseSnapshot();
329
+ }
330
+ } };
331
+ }
332
+ }
333
+ this.iterator = source[Symbol.asyncIterator]();
334
+ });
335
+ }
336
+ unget(value) {
337
+ this.pushed = value;
338
+ }
339
+ async get() {
340
+ const { budget } = this.lifecycle;
341
+ budget.charge();
342
+ await budget.checkpointWork();
343
+ if (this.stat?.type === "directory") throw new PrReadError(`${fileQuote(this.name)}: Is a directory`);
344
+ if (this.pushed >= 0) {
345
+ const value2 = this.pushed;
346
+ this.pushed = -1;
347
+ return value2;
348
+ }
349
+ while (this.offset === this.chunk.length) {
350
+ if (this.ended) return -1;
351
+ let next;
352
+ try {
353
+ if (!this.iterator) await this.acquire();
354
+ next = await this.lifecycle.operation(() => this.iterator.next());
355
+ } catch (error) {
356
+ if (error instanceof FsError) throw new PrReadError(`${fileQuote(this.name === "-" ? "standard input" : this.name)}: ${fsDetail(error)}`);
357
+ throw error;
358
+ }
359
+ budget.retain(-this.chunk.length);
360
+ this.chunk = new Uint8Array();
361
+ this.offset = 0;
362
+ if (next.done) {
363
+ this.ended = true;
364
+ this.iterator = void 0;
365
+ if (this.length > 0) {
366
+ this.length = 0;
367
+ budget.line();
368
+ }
369
+ return -1;
370
+ }
371
+ if (!(next.value instanceof Uint8Array)) throw new TypeError("pr input requires bytes");
372
+ budget.inputBytes(next.value.length);
373
+ budget.retain(next.value.length);
374
+ this.chunk = Uint8Array.from(next.value);
375
+ if (!this.chunk.length) budget.check(++this.empties, budget.limits.maxEmptyChunks, "empty input chunks");
376
+ }
377
+ const value = this.chunk[this.offset++];
378
+ if (value === 10 || value === 12) {
379
+ this.length = 0;
380
+ budget.line();
381
+ } else budget.check(++this.length, budget.limits.maxLineBytes, "input line bytes");
382
+ return value;
383
+ }
384
+ };
385
+ function fsDetail(error) {
386
+ const details = {
387
+ EACCES: "Permission denied",
388
+ EPERM: "Operation not permitted",
389
+ ENOENT: "No such file or directory",
390
+ EISDIR: "Is a directory",
391
+ ENOTDIR: "Not a directory",
392
+ EIO: "Input/output error",
393
+ ELOOP: "Too many levels of symbolic links",
394
+ ENAMETOOLONG: "File name too long",
395
+ ENOTSUP: "Operation not supported"
396
+ };
397
+ return details[error.code] ?? error.message;
398
+ }
399
+
400
+ // packages/safe-bash/src/commands/pr/options.ts
401
+ init_platform();
402
+ function digit(value) {
403
+ return value >= "0" && value <= "9";
404
+ }
405
+ function integer(value, minimum, label) {
406
+ let offset = 0;
407
+ while (" \r\n\v\f".includes(value[offset] ?? "!") && offset < value.length) offset++;
408
+ if (value[offset] === "+" || value[offset] === "-") offset++;
409
+ const start = offset;
410
+ while (offset < value.length && digit(value[offset])) offset++;
411
+ if (offset !== value.length || offset === start) throw new PrError(`${label}: ${quote(value)}`);
412
+ const result = Number(value);
413
+ if (result < minimum || result > 2147483647 || !Number.isSafeInteger(result)) throw new PrError(`${label}: ${quote(value)}: Numerical result out of range`);
414
+ return result;
415
+ }
416
+ function parseOptions(args, budget) {
417
+ const options = {
418
+ files: [],
419
+ columns: 1,
420
+ explicitColumns: false,
421
+ merge: false,
422
+ across: false,
423
+ length: 66,
424
+ width: 72,
425
+ header: void 0,
426
+ extremities: true,
427
+ keepFF: false,
428
+ formFeed: false,
429
+ numbered: false,
430
+ digits: 5,
431
+ numberSeparator: " ",
432
+ startNumber: 1,
433
+ separator: "",
434
+ useSeparator: false,
435
+ truncate: false,
436
+ join: false,
437
+ doubleSpace: false,
438
+ margin: 0,
439
+ expand: false,
440
+ tabify: false,
441
+ inputTab: " ",
442
+ inputTabWidth: 8,
443
+ outputTab: " ",
444
+ outputTabWidth: 8,
445
+ control: false,
446
+ octal: false,
447
+ quiet: false,
448
+ information: void 0
449
+ };
450
+ const long = {
451
+ columns: "#",
452
+ across: "a",
453
+ "show-control-chars": "c",
454
+ "double-space": "d",
455
+ "expand-tabs": "e",
456
+ "form-feed": "f",
457
+ header: "h",
458
+ "output-tabs": "i",
459
+ "join-lines": "J",
460
+ length: "l",
461
+ merge: "m",
462
+ "number-lines": "n",
463
+ "first-line-number": "N",
464
+ indent: "o",
465
+ "no-file-warnings": "r",
466
+ separator: "s",
467
+ "sep-string": "S",
468
+ "omit-header": "t",
469
+ "omit-pagination": "T",
470
+ "show-nonprinting": "v",
471
+ width: "w",
472
+ "page-width": "W"
473
+ };
474
+ let oldWidth = false, oldSeparator = false, oldOptions = false, stop = false;
475
+ let columnDigits;
476
+ let accumulating = false;
477
+ for (let index = 0; index < args.length; index++) {
478
+ const argument = args[index];
479
+ budget.charge(argument.length);
480
+ if (stop) {
481
+ options.files.push(argument);
482
+ continue;
483
+ }
484
+ if (argument === "--") {
485
+ stop = true;
486
+ continue;
487
+ }
488
+ if (argument === "--help" || argument === "--version") {
489
+ options.information = argument === "--help" ? "help" : "version";
490
+ return options;
491
+ }
492
+ if (!argument.startsWith("-") || argument === "-") {
493
+ accumulating = false;
494
+ options.files.push(argument);
495
+ continue;
496
+ }
497
+ const isLong = argument.startsWith("--");
498
+ let switches = argument.slice(1), attached;
499
+ if (isLong) {
500
+ const equal = argument.indexOf("=");
501
+ const name = argument.slice(2, equal < 0 ? void 0 : equal);
502
+ const candidates = Object.keys(long).filter((candidate) => candidate.startsWith(name));
503
+ if (!Object.hasOwn(long, name) && candidates.length > 1) throw new PrError(`option ${quote(argument)} is ambiguous; possibilities:${candidates.map((candidate) => ` '--${candidate}'`).join("")}`, true);
504
+ switches = long[name] ?? (candidates.length === 1 ? long[candidates[0]] : void 0) ?? "";
505
+ if (!switches) throw new PrError(`unrecognized option ${quote(argument)}`, true);
506
+ if (equal >= 0) attached = argument.slice(equal + 1);
507
+ }
508
+ for (let offset = 0; offset < switches.length; offset++) {
509
+ const option = switches[offset];
510
+ if (digit(option)) {
511
+ columnDigits = (accumulating ? columnDigits ?? "" : "") + option;
512
+ accumulating = true;
513
+ continue;
514
+ }
515
+ accumulating = false;
516
+ const required = "#hlwWNo".includes(option);
517
+ const optional = "nseiS".includes(option);
518
+ let value = attached;
519
+ if (required || optional) {
520
+ if (!isLong && offset + 1 < switches.length) value = switches.slice(offset + 1);
521
+ if (required && value === void 0) {
522
+ value = args[++index];
523
+ if (value === void 0) throw new PrError(isLong ? `option ${quote(argument)} requires an argument` : `option requires an argument -- '${option}'`, true);
524
+ }
525
+ offset = switches.length;
526
+ } else if (attached !== void 0) throw new PrError(`option ${quote(argument.slice(0, argument.indexOf("=")))} doesn't allow an argument`, true);
527
+ switch (option) {
528
+ case "#":
529
+ options.columns = integer(value, 1, "invalid number of columns");
530
+ options.explicitColumns = true;
531
+ columnDigits = void 0;
532
+ break;
533
+ case "h":
534
+ options.header = value;
535
+ break;
536
+ case "l":
537
+ options.length = integer(value, 1, "'-l PAGE_LENGTH' invalid number of lines");
538
+ break;
539
+ case "w":
540
+ oldWidth = true;
541
+ oldOptions = true;
542
+ {
543
+ const width = integer(value, 1, "'-w PAGE_WIDTH' invalid number of characters");
544
+ if (!options.truncate) options.width = width;
545
+ }
546
+ break;
547
+ case "W":
548
+ oldWidth = false;
549
+ options.truncate = true;
550
+ options.width = integer(value, 1, "'-W PAGE_WIDTH' invalid number of characters");
551
+ break;
552
+ case "m":
553
+ options.merge = true;
554
+ break;
555
+ case "a":
556
+ options.across = true;
557
+ break;
558
+ case "b":
559
+ break;
560
+ case "d":
561
+ options.doubleSpace = true;
562
+ break;
563
+ case "f":
564
+ case "F":
565
+ options.formFeed = true;
566
+ break;
567
+ case "J":
568
+ options.join = true;
569
+ break;
570
+ case "N":
571
+ options.startNumber = integer(value, -2147483648, "'-N NUMBER' invalid starting line number");
572
+ break;
573
+ case "o":
574
+ options.margin = integer(value, 0, "'-o MARGIN' invalid line offset");
575
+ break;
576
+ case "r":
577
+ options.quiet = true;
578
+ break;
579
+ case "s":
580
+ oldOptions = true;
581
+ oldSeparator = true;
582
+ if (!options.useSeparator && value !== void 0) options.separator = value;
583
+ break;
584
+ case "S":
585
+ oldSeparator = false;
586
+ options.useSeparator = true;
587
+ options.separator = value ?? "";
588
+ break;
589
+ case "t":
590
+ options.extremities = false;
591
+ options.keepFF = true;
592
+ break;
593
+ case "T":
594
+ options.extremities = false;
595
+ options.keepFF = false;
596
+ break;
597
+ case "c":
598
+ options.control = true;
599
+ break;
600
+ case "v":
601
+ options.octal = true;
602
+ break;
603
+ case "n":
604
+ case "e":
605
+ case "i": {
606
+ if (option === "n") options.numbered = true;
607
+ if (option === "e") options.expand = true;
608
+ if (option === "i") options.tabify = true;
609
+ if (value === void 0 || !value.length) break;
610
+ let character;
611
+ if (!digit(value[0])) {
612
+ character = value[0];
613
+ value = value.slice(1);
614
+ }
615
+ let count;
616
+ if (value.length) {
617
+ try {
618
+ count = integer(value, 1, "invalid number");
619
+ } catch {
620
+ throw new PrError(`'-${option}' extra characters or invalid number in the argument: ${quote(value)}${Number(value) > 2147483647 ? ": Value too large for defined data type" : ""}`, true);
621
+ }
622
+ }
623
+ if (option === "n") {
624
+ options.numberSeparator = character ?? options.numberSeparator;
625
+ options.digits = count ?? options.digits;
626
+ }
627
+ if (option === "e") {
628
+ options.inputTab = character ?? options.inputTab;
629
+ options.inputTabWidth = count ?? options.inputTabWidth;
630
+ }
631
+ if (option === "i") {
632
+ options.outputTab = character ?? options.outputTab;
633
+ options.outputTabWidth = count ?? options.outputTabWidth;
634
+ }
635
+ break;
636
+ }
637
+ default:
638
+ throw new PrError(`invalid option -- '${option}'`, true);
639
+ }
640
+ }
641
+ }
642
+ if (columnDigits !== void 0) {
643
+ options.columns = integer(columnDigits, 1, "invalid number of columns");
644
+ options.explicitColumns = true;
645
+ }
646
+ if (options.merge && options.explicitColumns) throw new PrError("cannot specify number of columns when printing in parallel");
647
+ if (options.merge && options.across) throw new PrError("cannot specify both printing across and printing in parallel");
648
+ if (oldOptions) {
649
+ if (oldWidth) {
650
+ if (options.merge || options.explicitColumns) {
651
+ options.truncate = true;
652
+ if (oldSeparator) options.useSeparator = true;
653
+ } else options.join = true;
654
+ } else if (!options.useSeparator && oldSeparator && (options.merge || options.explicitColumns)) {
655
+ if (!options.truncate) {
656
+ options.join = true;
657
+ if (options.separator.length) options.useSeparator = true;
658
+ } else options.useSeparator = true;
659
+ }
660
+ }
661
+ const { limits } = budget;
662
+ budget.check(options.files.length, limits.maxFiles, "input files");
663
+ budget.check(options.merge ? Math.max(1, options.files.length) : options.columns, limits.maxColumns, "columns");
664
+ budget.check(options.length, limits.maxPageLines, "page lines");
665
+ for (const width of [options.width, options.margin, options.digits, options.inputTabWidth, options.outputTabWidth]) budget.check(width, limits.maxPageWidth, "page width");
666
+ return options;
667
+ }
668
+
669
+ // packages/safe-bash/src/commands/pr/format.ts
670
+ init_platform();
671
+ var Formatter = class {
672
+ constructor(options, lifecycle, count) {
673
+ this.options = options;
674
+ this.lifecycle = lifecycle;
675
+ this.budget = lifecycle.budget;
676
+ if (options.length <= 10) {
677
+ options.extremities = false;
678
+ options.keepFF = true;
679
+ }
680
+ this.body = Math.floor((options.extremities ? options.length - 10 : options.length) / (options.doubleSpace ? 2 : 1));
681
+ if (this.body < 1) throw new PrError("page has no text lines");
682
+ options.columns = options.merge ? count : options.columns;
683
+ if (options.columns > 1) {
684
+ if (!options.useSeparator) {
685
+ options.useSeparator = true;
686
+ options.separator = options.join ? " " : " ";
687
+ } else if (!options.join && options.separator === " ") options.separator = " ";
688
+ options.truncate = true;
689
+ options.tabify = true;
690
+ }
691
+ if (options.join) options.truncate = false;
692
+ this.numberWidth = options.numberSeparator === " " ? options.digits + 8 - options.digits % 8 : options.digits + 1;
693
+ this.columnWidth = Math.trunc((options.width - (options.merge && options.numbered ? this.numberWidth : 0) - (options.columns - 1) * options.separator.length) / options.columns);
694
+ if (this.columnWidth < 1) throw new PrError("page width too narrow");
695
+ this.store = options.columns > 1 && !options.merge && !options.across;
696
+ this.lineNumber = options.startNumber;
697
+ lifecycle.cleanup(async () => {
698
+ this.budget.retain(-this.pageRetained - this.rendered.length * 2);
699
+ this.pageRetained = 0;
700
+ this.rendered = "";
701
+ this.columns = [];
702
+ });
703
+ }
704
+ options;
705
+ lifecycle;
706
+ budget;
707
+ body;
708
+ columnWidth;
709
+ numberWidth;
710
+ store;
711
+ columns = [];
712
+ lineNumber;
713
+ pageNumber = 1;
714
+ inputPosition = 0;
715
+ outputPosition = 0;
716
+ spaces = 0;
717
+ separators = 0;
718
+ padding = 0;
719
+ vertical = false;
720
+ empty = true;
721
+ alignEmpty = false;
722
+ feedOnly = false;
723
+ printFeed = false;
724
+ needHeader = false;
725
+ storing = false;
726
+ stored = "";
727
+ rendered = "";
728
+ pageRetained = 0;
729
+ append(value) {
730
+ this.budget.charge(value.length);
731
+ this.budget.retain(value.length * 2);
732
+ this.rendered += value;
733
+ }
734
+ repeat(value, count, construction = false) {
735
+ this.budget.admitString(value.length * count);
736
+ if (construction) this.budget.charge(value.length * count);
737
+ return value.repeat(count);
738
+ }
739
+ async flush() {
740
+ const text = this.rendered;
741
+ this.rendered = "";
742
+ this.budget.retain(-text.length * 2);
743
+ if (text) await this.lifecycle.write(text);
744
+ }
745
+ white() {
746
+ let position = this.outputPosition;
747
+ const goal = position + this.spaces;
748
+ this.budget.check(Math.max(0, this.spaces), this.budget.limits.maxBufferedBytes, "horizontal padding");
749
+ while (goal - position > 1) {
750
+ const next = position + this.options.outputTabWidth - position % this.options.outputTabWidth;
751
+ if (next > goal) break;
752
+ this.append(this.options.outputTab);
753
+ position = next;
754
+ }
755
+ if (goal > position) this.append(this.repeat(" ", goal - position));
756
+ this.outputPosition = goal;
757
+ this.spaces = 0;
758
+ }
759
+ pad(position) {
760
+ if (this.options.tabify) this.spaces = position - this.outputPosition;
761
+ else {
762
+ if (position > this.outputPosition) this.append(this.repeat(" ", position - this.outputPosition));
763
+ this.outputPosition = position;
764
+ }
765
+ }
766
+ separator() {
767
+ if (this.separators <= 0) {
768
+ if (this.spaces > 0) this.white();
769
+ return;
770
+ }
771
+ let offset = 0;
772
+ for (; this.separators > 0; this.separators--) {
773
+ while (offset < this.options.separator.length) {
774
+ const character = this.options.separator[offset++];
775
+ if (character === " ") this.spaces++;
776
+ else {
777
+ if (this.spaces > 0) this.white();
778
+ this.append(character);
779
+ this.outputPosition++;
780
+ }
781
+ }
782
+ if (this.spaces > 0) this.white();
783
+ }
784
+ }
785
+ character(character) {
786
+ if (this.storing) {
787
+ this.budget.charge(character.length);
788
+ this.budget.retain(character.length * 2);
789
+ this.pageRetained += character.length * 2;
790
+ this.stored += character;
791
+ return;
792
+ }
793
+ if (this.options.tabify) {
794
+ if (character === " ") {
795
+ this.spaces++;
796
+ return;
797
+ }
798
+ if (this.spaces > 0) this.white();
799
+ if (character >= " " && character <= "~") this.outputPosition++;
800
+ else if (character === "\b") this.outputPosition--;
801
+ }
802
+ this.append(character);
803
+ }
804
+ number(column) {
805
+ this.budget.admitString(this.options.digits);
806
+ const text = String(this.lineNumber++).padStart(this.options.digits, " ").slice(-this.options.digits);
807
+ for (const character of text) this.character(character);
808
+ if (this.columns.length > 1 && this.options.numberSeparator === " ") {
809
+ for (let count = this.numberWidth - this.options.digits; count > 0; count--) this.character(" ");
810
+ } else {
811
+ this.character(this.options.numberSeparator);
812
+ if (this.columns.length === 1 && this.options.numberSeparator === " ") this.outputPosition += this.options.outputTabWidth - this.outputPosition % this.options.outputTabWidth;
813
+ }
814
+ if (this.options.truncate && !this.options.merge) this.inputPosition += this.numberWidth;
815
+ this.budget.charge(column.numbered ? 1 : 0);
816
+ }
817
+ align(column) {
818
+ this.padding = column.start;
819
+ if (this.options.separator.length < this.padding) {
820
+ this.pad(this.padding - this.options.separator.length);
821
+ this.padding = 0;
822
+ }
823
+ if (this.options.useSeparator) this.separator();
824
+ if (column.numbered) this.number(column);
825
+ }
826
+ clump(byte) {
827
+ const character = String.fromCharCode(byte);
828
+ let width;
829
+ let text = character;
830
+ if (character === this.options.inputTab || byte === 9) {
831
+ const tab = character === this.options.inputTab ? this.options.inputTabWidth : 8;
832
+ width = tab - this.inputPosition % tab;
833
+ if (this.options.expand) text = this.repeat(" ", width, true);
834
+ } else if (byte < 32 || byte > 126) {
835
+ if (this.options.octal || this.options.control && byte >= 128) {
836
+ text = `\\${byte.toString(8).padStart(3, "0")}`;
837
+ width = 4;
838
+ } else if (this.options.control) {
839
+ text = `^${String.fromCharCode(byte ^ 64)}`;
840
+ width = 2;
841
+ } else width = byte === 8 ? -1 : 0;
842
+ } else width = 1;
843
+ if (width < 0 && this.inputPosition === 0) return "";
844
+ this.inputPosition = Math.max(0, this.inputPosition + width);
845
+ return text;
846
+ }
847
+ close(column) {
848
+ for (const current of this.options.merge ? [column] : this.columns) {
849
+ current.status = "closed";
850
+ if (!current.lines.length) current.remaining = 0;
851
+ }
852
+ }
853
+ hold(column) {
854
+ for (const current of this.options.merge ? [column] : this.columns) current.status = this.store ? "feed" : "held";
855
+ column.remaining = 0;
856
+ }
857
+ async feed(column) {
858
+ const next = await column.reader.get();
859
+ if (next !== 10) column.reader.unget(next);
860
+ this.hold(column);
861
+ }
862
+ async rest(column) {
863
+ for (; ; ) {
864
+ const byte = await column.reader.get();
865
+ if (byte === 10) return;
866
+ if (byte === 12) {
867
+ await this.feed(column);
868
+ if (this.options.keepFF) this.printFeed = true;
869
+ return;
870
+ }
871
+ if (byte < 0) {
872
+ this.close(column);
873
+ return;
874
+ }
875
+ }
876
+ }
877
+ header(date, name) {
878
+ const { env } = this.budget.context;
879
+ if (![void 0, "", "UTC", "UTC0", ":UTC", "GMT", "GMT0"].includes(env.TZ)) throw new PrError("only UTC timezones are supported for headers");
880
+ const ctype = env.LC_ALL || env.LC_CTYPE || env.LANG || "C";
881
+ if (ctype === "C.UTF-8" || ctype === "C.utf8") {
882
+ for (const character of name) if (character.charCodeAt(0) >= 128) throw new PrError("non-ASCII headers require the C locale");
883
+ }
884
+ this.outputPosition = 0;
885
+ this.pad(this.options.margin);
886
+ this.white();
887
+ const width = (text) => {
888
+ this.budget.charge(text.length);
889
+ let result = 0;
890
+ for (const character of text) if (character >= " " && character !== "\x7F") result++;
891
+ return result;
892
+ };
893
+ const page = `Page ${this.pageNumber}`;
894
+ const available = Math.max(0, this.options.width - width(date) - width(name) - width(page));
895
+ const left = Math.floor(available / 2);
896
+ this.budget.admitString(5 + this.options.margin + date.length + name.length + page.length + Math.max(1, left) + Math.max(1, available - left));
897
+ this.append(`
898
+
899
+ ${this.repeat(" ", this.options.margin)}${date}${this.repeat(" ", Math.max(1, left))}${name}${this.repeat(" ", Math.max(1, available - left))}${page}
900
+
901
+
902
+ `);
903
+ this.needHeader = false;
904
+ this.outputPosition = 0;
905
+ }
906
+ async read(column, date, name) {
907
+ let byte = await column.reader.get();
908
+ if (byte === 12 && column.full) {
909
+ byte = await column.reader.get();
910
+ if (byte === 10) byte = await column.reader.get();
911
+ }
912
+ column.full = false;
913
+ if (byte === 12) {
914
+ await this.feed(column);
915
+ this.feedOnly = true;
916
+ if (this.needHeader && !this.store) {
917
+ this.vertical = true;
918
+ this.header(date, name);
919
+ } else if (this.options.keepFF) this.printFeed = true;
920
+ return;
921
+ }
922
+ if (byte < 0) {
923
+ this.close(column);
924
+ return;
925
+ }
926
+ let clump = byte === 10 ? "" : this.clump(byte);
927
+ if (this.options.truncate && this.inputPosition > this.columnWidth) {
928
+ this.inputPosition = 0;
929
+ await this.rest(column);
930
+ return;
931
+ }
932
+ if (!this.storing) {
933
+ this.vertical = true;
934
+ if (this.needHeader && !this.store) this.header(date, name);
935
+ if (this.options.merge && this.alignEmpty) {
936
+ const pending = this.separators;
937
+ this.separators = 0;
938
+ for (let index = 0; index < pending; index++) {
939
+ this.align(this.columns[index]);
940
+ this.separators++;
941
+ }
942
+ this.padding = column.start;
943
+ this.spaces = this.options.truncate ? this.columnWidth : 0;
944
+ this.alignEmpty = false;
945
+ }
946
+ if (this.options.separator.length < this.padding) {
947
+ this.pad(this.padding - this.options.separator.length);
948
+ this.padding = 0;
949
+ }
950
+ if (this.options.useSeparator) this.separator();
951
+ }
952
+ if (column.numbered) this.number(column);
953
+ this.empty = false;
954
+ if (byte === 10) return;
955
+ for (const character of clump) this.character(character);
956
+ for (; ; ) {
957
+ byte = await column.reader.get();
958
+ if (byte === 10) return;
959
+ if (byte === 12) {
960
+ await this.feed(column);
961
+ if (this.options.keepFF) this.printFeed = true;
962
+ return;
963
+ }
964
+ if (byte < 0) {
965
+ this.close(column);
966
+ return;
967
+ }
968
+ const previous = this.inputPosition;
969
+ clump = this.clump(byte);
970
+ if (this.options.truncate && this.inputPosition > this.columnWidth) {
971
+ this.inputPosition = previous;
972
+ await this.rest(column);
973
+ return;
974
+ }
975
+ for (const character of clump) this.character(character);
976
+ }
977
+ }
978
+ ready() {
979
+ return this.columns.some((column) => column.status === "open" || column.status === "feed" || this.store && column.remaining > 0 && column.lines.length > 0);
980
+ }
981
+ async storePage(date, name) {
982
+ this.budget.retain(-this.pageRetained);
983
+ this.pageRetained = 0;
984
+ const lines = [];
985
+ this.storing = true;
986
+ for (const column of this.columns) {
987
+ column.lines = [];
988
+ column.current = 0;
989
+ }
990
+ try {
991
+ for (const column of this.columns) {
992
+ for (let count = 0; count < this.body && column.status === "open"; count++) {
993
+ this.stored = "";
994
+ this.inputPosition = 0;
995
+ await this.read(column, date, name);
996
+ if (column.status === "open" || this.stored.length) {
997
+ this.budget.retain(32);
998
+ this.pageRetained += 32;
999
+ lines.push({ text: this.stored, end: this.inputPosition });
1000
+ }
1001
+ }
1002
+ }
1003
+ } finally {
1004
+ this.storing = false;
1005
+ }
1006
+ let start = 0;
1007
+ for (let index = 0; index < this.columns.length; index++) {
1008
+ const column = this.columns[index];
1009
+ const count = Math.floor(lines.length / this.columns.length) + (index < lines.length % this.columns.length ? 1 : 0);
1010
+ column.lines = lines.slice(start, start + count);
1011
+ column.remaining = count;
1012
+ start += count;
1013
+ }
1014
+ }
1015
+ storedLine(column, date, name) {
1016
+ this.vertical = true;
1017
+ if (this.needHeader) this.header(date, name);
1018
+ if (column.status === "feed") {
1019
+ for (const current of this.columns) current.status = "held";
1020
+ if (this.columns[0].remaining <= 0) {
1021
+ if (!this.options.extremities) this.vertical = false;
1022
+ return;
1023
+ }
1024
+ }
1025
+ const line = column.lines[column.current++];
1026
+ if (!line) return;
1027
+ if (this.options.separator.length < this.padding) {
1028
+ this.pad(this.padding - this.options.separator.length);
1029
+ this.padding = 0;
1030
+ }
1031
+ if (this.options.useSeparator) this.separator();
1032
+ for (const character of line.text) this.character(character);
1033
+ if (this.spaces === 0) {
1034
+ this.outputPosition = column.start + line.end;
1035
+ if (column.start - this.options.separator.length === this.options.margin) this.outputPosition -= this.options.separator.length;
1036
+ }
1037
+ }
1038
+ async run(readers, date, name) {
1039
+ const count = this.options.merge ? readers.length : this.options.columns;
1040
+ for (let index = 0; index < count; index++) {
1041
+ const start = index === 0 ? this.options.margin + this.options.separator.length : this.options.truncate ? this.options.margin + index * (this.columnWidth + this.options.separator.length) + (this.options.merge && this.options.numbered ? this.numberWidth : 0) : 0;
1042
+ this.columns.push({
1043
+ reader: readers[this.options.merge ? index : 0],
1044
+ status: "open",
1045
+ full: false,
1046
+ numbered: this.options.numbered && (!this.options.merge || index === 0),
1047
+ start,
1048
+ lines: [],
1049
+ current: 0,
1050
+ remaining: 0
1051
+ });
1052
+ }
1053
+ try {
1054
+ await this.pages(date, name);
1055
+ } catch (error) {
1056
+ if (error instanceof PrReadError) await this.flush();
1057
+ throw error;
1058
+ }
1059
+ }
1060
+ async pages(date, name) {
1061
+ for (; ; ) {
1062
+ if (this.store) await this.storePage(date, name);
1063
+ else for (const column of this.columns) column.remaining = column.status === "open" ? this.body : 0;
1064
+ if (!this.ready()) return;
1065
+ this.budget.page();
1066
+ this.needHeader = this.options.extremities;
1067
+ let printed = false;
1068
+ let left = this.body * (this.options.doubleSpace ? 2 : 1);
1069
+ while (left > 0 && this.ready()) {
1070
+ this.outputPosition = 0;
1071
+ this.spaces = 0;
1072
+ this.separators = 0;
1073
+ this.vertical = false;
1074
+ this.alignEmpty = false;
1075
+ this.empty = true;
1076
+ for (const column of this.columns) {
1077
+ this.budget.charge();
1078
+ this.inputPosition = 0;
1079
+ if (column.remaining > 0 || column.status === "feed") {
1080
+ this.feedOnly = false;
1081
+ this.padding = column.start;
1082
+ if (this.store) this.storedLine(column, date, name);
1083
+ else await this.read(column, date, name);
1084
+ printed ||= this.vertical;
1085
+ column.remaining--;
1086
+ if (column.remaining <= 0 && !this.ready()) break;
1087
+ if (this.options.merge && column.status !== "open") {
1088
+ if (this.empty) this.alignEmpty = true;
1089
+ else if (column.status === "closed" || this.feedOnly) this.align(column);
1090
+ }
1091
+ } else if (this.options.merge) {
1092
+ if (this.empty) this.alignEmpty = true;
1093
+ else this.align(column);
1094
+ }
1095
+ if (this.options.useSeparator) this.separators++;
1096
+ }
1097
+ if (this.vertical) {
1098
+ this.append("\n");
1099
+ left--;
1100
+ }
1101
+ if (!this.ready() && !this.options.extremities) {
1102
+ await this.flush();
1103
+ break;
1104
+ }
1105
+ if (this.options.doubleSpace && printed) {
1106
+ this.append("\n");
1107
+ left--;
1108
+ }
1109
+ await this.flush();
1110
+ }
1111
+ if (left === 0) {
1112
+ for (const column of this.columns) if (column.status === "open") column.full = true;
1113
+ }
1114
+ if (printed && this.options.extremities) this.append(this.options.formFeed ? "\f" : this.repeat("\n", left + 5));
1115
+ else if (this.options.keepFF && this.printFeed) {
1116
+ this.append("\f");
1117
+ this.printFeed = false;
1118
+ }
1119
+ await this.flush();
1120
+ this.pageNumber++;
1121
+ for (const column of this.columns) if (column.status === "held") column.status = "open";
1122
+ }
1123
+ }
1124
+ };
1125
+
1126
+ // packages/safe-bash/src/commands/pr/command.ts
1127
+ function createPrCommand(options = {}) {
1128
+ const limits = settings(options);
1129
+ return { name: "pr", description: "Paginate files and print balanced or merged columns", async execute(context) {
1130
+ const output = createOutputOperation(context, context.stdout);
1131
+ const budget = new Budget(context, limits, output.signal);
1132
+ let lifecycle;
1133
+ let failure;
1134
+ let primary;
1135
+ let exitCode = 0;
1136
+ try {
1137
+ lifecycle = new Lifecycle(budget, output);
1138
+ const parsed = parseOptions(budget.arguments(), budget);
1139
+ if (parsed.information) {
1140
+ await lifecycle.write(parsed.information === "version" ? "pr (virtual-bash)\n" : "Usage: pr [OPTION]... [FILE]...\nPaginate or columnate files for printing.\nOptions: -COLUMNS -h HEADER -l LENGTH -w WIDTH -t -n[SEP[DIGITS]] -m -s[SEP]\n");
1141
+ } else {
1142
+ const ctype = context.env.LC_ALL || context.env.LC_CTYPE || context.env.LANG || "C";
1143
+ const timeLocale = context.env.LC_ALL || context.env.LC_TIME || context.env.LANG || "C";
1144
+ for (const locale of [ctype, timeLocale]) if (!["C", "POSIX", "C.UTF-8", "C.utf8"].includes(locale)) throw new PrError(`unsupported locale ${quote(locale)}`);
1145
+ let sampled;
1146
+ const date = (reader) => {
1147
+ let milliseconds;
1148
+ if (reader?.stat) milliseconds = reader.stat.mtimeMs;
1149
+ else milliseconds = sampled ??= (options.clock ?? Date.now)();
1150
+ const value = new Date(milliseconds);
1151
+ if (!Number.isFinite(milliseconds) || Number.isNaN(value.getTime())) throw new PrError("invalid header timestamp");
1152
+ const year = String(value.getUTCFullYear()).padStart(4, "0");
1153
+ const month = String(value.getUTCMonth() + 1).padStart(2, "0");
1154
+ const day = String(value.getUTCDate()).padStart(2, "0");
1155
+ const time = `${String(value.getUTCHours()).padStart(2, "0")}:${String(value.getUTCMinutes()).padStart(2, "0")}`;
1156
+ if (context.env.POSIXLY_CORRECT !== void 0 && (timeLocale === "C" || timeLocale === "POSIX")) return `${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][value.getUTCMonth()]} ${String(value.getUTCDate()).padStart(2, " ")} ${time} ${year}`;
1157
+ return `${year}-${month}-${day} ${time}`;
1158
+ };
1159
+ let stdin;
1160
+ const open = async (name) => {
1161
+ if (name === "-" && stdin) return stdin;
1162
+ const reader = new Reader(name, lifecycle);
1163
+ try {
1164
+ await reader.open();
1165
+ } catch (error) {
1166
+ if (!(error instanceof FsError)) throw error;
1167
+ exitCode = 1;
1168
+ if (!parsed.quiet) {
1169
+ await lifecycle.write(`pr: ${fileQuote(name)}: ${fsDetail(error)}
1170
+ `, true);
1171
+ }
1172
+ return void 0;
1173
+ }
1174
+ if (name === "-") stdin = reader;
1175
+ return reader;
1176
+ };
1177
+ const names = parsed.files.length ? parsed.files : ["-"];
1178
+ if (!parsed.files.length) parsed.merge = false;
1179
+ const groups = parsed.merge ? [names] : names.map((name) => [name]);
1180
+ for (const group of groups) {
1181
+ const formatter = new Formatter({ ...parsed }, lifecycle, group.length);
1182
+ const readers = [];
1183
+ for (const name of group) {
1184
+ const reader = await open(name);
1185
+ if (reader) readers.push(reader);
1186
+ }
1187
+ if (!readers.length) continue;
1188
+ const title = parsed.header ?? (parsed.merge || readers[0].name === "-" ? "" : readers[0].name);
1189
+ await formatter.run(readers, date(parsed.merge ? void 0 : readers[0]), title);
1190
+ }
1191
+ }
1192
+ } catch (error) {
1193
+ primary = { reason: error };
1194
+ failure = { reason: error };
1195
+ if (!output.signal.aborted && lifecycle && error instanceof PrError) {
1196
+ exitCode = 1;
1197
+ try {
1198
+ await lifecycle.write(`pr: ${publicDiagnosticMessage(error, context.onInternalError)}
1199
+ `, true);
1200
+ if (error.usage) await lifecycle.write("Try 'pr --help' for more information.\n", true);
1201
+ failure = void 0;
1202
+ } catch (reporting) {
1203
+ failure = { reason: new AggregateError([error, reporting], "pr failure reporting failed") };
1204
+ }
1205
+ }
1206
+ }
1207
+ try {
1208
+ await output.close();
1209
+ } catch (cleanup) {
1210
+ const previous = failure ?? primary;
1211
+ failure = { reason: previous ? new AggregateError([previous.reason, cleanup], "pr execution and cleanup failed") : cleanup };
1212
+ }
1213
+ context.signal.throwIfAborted();
1214
+ output.signal.throwIfAborted();
1215
+ if (failure) throw failure.reason;
1216
+ return { exitCode };
1217
+ } };
1218
+ }
1219
+
1220
+ // packages/safe-bash/src/commands/pr/index.ts
1221
+ function createPrCommands(options = {}) {
1222
+ return [createPrCommand(options)];
1223
+ }
1224
+ function prCommands(options = {}) {
1225
+ const commands = createPrCommands(options);
1226
+ return { name: "pr-commands", setup(host) {
1227
+ for (const command of commands) host.commands.register(command, { replace: options.replace ?? false });
1228
+ } };
1229
+ }
1230
+
1231
+ export {
1232
+ createPrCommand,
1233
+ createPrCommands,
1234
+ prCommands
1235
+ };
1236
+ //# sourceMappingURL=chunk-PY37EOPJ.js.map