@poe-platform/safe-bash 0.1.839 → 0.1.840

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 (61) hide show
  1. package/dist/mp4-ast/types.d.ts +4 -2
  2. package/dist/pdf-ast/cos/security.d.ts +10 -0
  3. package/dist/pdf-ast/edit/retained-attachment-edits.d.ts +4 -0
  4. package/dist/pdf-ast/edit/retained-graph.d.ts +1 -1
  5. package/dist/pdf-ast/image.js +1 -1
  6. package/dist/pdf-ast/index.d.ts +2 -1
  7. package/dist/pdf-ast/index.js +7 -1
  8. package/dist/pdf-ast/vendor/pdfjs-fonts.d.mts +8 -0
  9. package/dist/pdf-ast/vendor/pdfjs-fonts.mjs +28 -0
  10. package/dist/safe-bash/command-chunks/{chunk-SG2KOOD4.js → chunk-3SAYZFMD.js} +2 -2
  11. package/dist/safe-bash/command-chunks/{chunk-FH5VMAPS.js → chunk-45ZH6CNF.js} +20 -4
  12. package/dist/safe-bash/command-chunks/{chunk-T6OXG7QQ.js → chunk-AAOPVEPF.js} +66 -1
  13. package/dist/safe-bash/command-chunks/{chunk-46GA576V.js → chunk-CPKVUB7S.js} +2 -2
  14. package/dist/safe-bash/command-chunks/{chunk-MBXNG6C3.js → chunk-DLLN3C3Q.js} +1 -1
  15. package/dist/safe-bash/command-chunks/{chunk-ZSQCROFE.js → chunk-DM5T5D2K.js} +5 -1
  16. package/dist/safe-bash/command-chunks/{chunk-3EAZRKI4.js → chunk-G7HQYFIU.js} +10 -1
  17. package/dist/safe-bash/command-chunks/{chunk-GYKQ3IOV.js → chunk-LMYQMJYY.js} +94 -18
  18. package/dist/safe-bash/command-chunks/{chunk-DX7KU6YU.js → chunk-N52AHO6S.js} +1 -1
  19. package/dist/safe-bash/command-chunks/{chunk-4BSD2RGK.js → chunk-QPKL5GWH.js} +102 -42
  20. package/dist/safe-bash/command-chunks/{chunk-Z2T7E4ID.js → chunk-R7QLP5RH.js} +1212 -1119
  21. package/dist/safe-bash/command-chunks/{chunk-RSFKQE2U.js → chunk-T5WFJ44Z.js} +1 -1
  22. package/dist/safe-bash/command-chunks/{chunk-77ROD2TR.js → chunk-X3WNWRVT.js} +11 -5
  23. package/dist/safe-bash/command-chunks/{chunk-TCXM7BSZ.js → chunk-YFMNXPLP.js} +4 -4
  24. package/dist/safe-bash/command-chunks/{chunk-DQVOBGI2.js → chunk-YVFQ5I36.js} +7335 -7162
  25. package/dist/safe-bash-command-exiftool/index.js +25 -1
  26. package/dist/safe-bash-command-ffmpeg/index.js +174 -41
  27. package/dist/safe-bash-command-ffprobe/index.js +2 -2
  28. package/dist/safe-bash-command-ffprobe/media.js +2 -2
  29. package/dist/safe-bash-command-imagemagick/index.js +482 -98
  30. package/dist/safe-bash-command-mdq/index.js +2 -0
  31. package/dist/safe-bash-command-pandoc/citeproc-filters.js +7 -7
  32. package/dist/safe-bash-command-pandoc/command.js +8 -8
  33. package/dist/safe-bash-command-pandoc/index.js +51 -51
  34. package/dist/safe-bash-command-qpdf/index.js +1037 -654
  35. package/dist/safe-bash-command-qpdf/page-range.d.ts +2 -0
  36. package/dist/safe-bash-command-soffice/index.js +28 -8
  37. package/dist/safe-bash-command-sqlite3/btree.d.ts +2 -1
  38. package/dist/safe-bash-command-sqlite3/engine.d.ts +15 -1
  39. package/dist/safe-bash-command-sqlite3/index.js +294 -68
  40. package/dist/safe-bash-command-tar/create.js +2 -2
  41. package/dist/safe-bash-command-tar/extract.js +2 -2
  42. package/dist/safe-bash-command-tar/format.js +1 -1
  43. package/dist/safe-bash-command-tar/index.js +4 -4
  44. package/dist/safe-bash-command-tar/modes.js +4 -4
  45. package/dist/safe-bash-command-unzip/index.js +1 -1
  46. package/dist/safe-bash-command-unzip/unzip.js +1 -1
  47. package/dist/safe-bash-markdown-engine/commonmark-blocks.d.ts +17 -1
  48. package/dist/safe-bash-markdown-engine/commonmark-blocks.js +3 -3
  49. package/dist/safe-bash-markdown-engine/commonmark-inlines.d.ts +1 -1
  50. package/dist/safe-bash-markdown-engine/commonmark-inlines.js +3 -3
  51. package/dist/safe-bash-markdown-engine/commonmark-syntax.d.ts +5 -0
  52. package/dist/safe-bash-markdown-engine/commonmark-syntax.js +5 -1
  53. package/dist/safe-bash-markdown-engine/gfm-syntax.js +2 -2
  54. package/dist/safe-bash-markdown-engine/index.js +4 -4
  55. package/dist/safe-bash-zip-engine/index.js +1 -1
  56. package/dist/safe-bash-zip-engine/zip/repair.js +1 -1
  57. package/dist/safe-bash-zip-engine/zip/sfx.js +1 -1
  58. package/dist/safe-bash-zip-engine/zip-format.d.ts +2 -0
  59. package/dist/safe-bash-zip-engine/zip-format.js +1 -1
  60. package/package.json +2 -2
  61. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +2 -0
@@ -345,8 +345,10 @@ export interface MediaProbeFrame {
345
345
  readonly pkt_dts_time: string;
346
346
  readonly best_effort_timestamp: number;
347
347
  readonly best_effort_timestamp_time: string;
348
- readonly pkt_duration: number;
349
- readonly pkt_duration_time: string;
348
+ readonly duration?: number;
349
+ readonly duration_time?: string;
350
+ readonly pkt_duration?: number;
351
+ readonly pkt_duration_time?: string;
350
352
  readonly pkt_size: string;
351
353
  readonly width?: number | undefined;
352
354
  readonly height?: number | undefined;
@@ -15,6 +15,16 @@ export declare function derivePdfEncryptionKey(encryptDict: PdfCosDict, document
15
15
  resolve?: (node: PdfCosNode) => PdfCosNode | undefined;
16
16
  maxRecursionDepth?: number | undefined;
17
17
  }): PdfEncryptionState;
18
+ /** Inspection metadata from the authenticated security handler. */
19
+ export declare function getPdfEncryptionInfo(state: PdfEncryptionState): {
20
+ permissionsMask: number;
21
+ ownerPasswordMatched: boolean;
22
+ userPasswordMatched: boolean;
23
+ userPassword: string;
24
+ streamMethod: string;
25
+ stringMethod: string;
26
+ fileMethod: string;
27
+ };
18
28
  export declare function decryptPdfBuffer(state: PdfEncryptionState, objectNumber: number, generationNumber: number, data: Uint8Array): Uint8Array;
19
29
  /** Decrypt strings in one retained object's direct COS value. Stream bytes
20
30
  * remain external; signature contents and security references stay plaintext. */
@@ -15,6 +15,10 @@ export declare class PdfDuplicateAttachment extends PdfError {
15
15
  readonly key: string;
16
16
  constructor(key: string);
17
17
  }
18
+ export declare class PdfMissingAttachment extends PdfError {
19
+ readonly key: string;
20
+ constructor(key: string);
21
+ }
18
22
  /** Flatten the edited name tree without collecting its pairs or new payloads. */
19
23
  export declare function editRetainedAttachments(document: PdfRetainedDocument, target: PdfMutableObjectStore, storage: PdfIndexStorage, remove: Iterable<string> | AsyncIterable<string>, additions: Iterable<RetainedAttachmentInput> | AsyncIterable<RetainedAttachmentInput>, signal: AbortSignal, preserveTree?: boolean): Promise<void>;
20
24
  export declare function retainedAttachmentNameTokens(document: PdfRetainedDocument, storage: PdfIndexStorage, root: PdfCosNode | undefined, signal: AbortSignal, recursive?: boolean): AsyncGenerator<PdfCosNode>;
@@ -9,7 +9,7 @@ export type { RetainedStampInput } from "./retained-stamps.js";
9
9
  import { type RetainedInlineImageOptions } from "./retained-inline-images.js";
10
10
  export type { RetainedInlineImageOptions } from "./retained-inline-images.js";
11
11
  import { type RetainedAttachmentInput } from "./retained-attachment-edits.js";
12
- export { PdfDuplicateAttachment, type RetainedAttachmentInput } from "./retained-attachment-edits.js";
12
+ export { PdfDuplicateAttachment, PdfMissingAttachment, type RetainedAttachmentInput } from "./retained-attachment-edits.js";
13
13
  import { type RetainedPageLabel } from "./retained-merge-labels.js";
14
14
  export type { RetainedPageLabel } from "./retained-merge-labels.js";
15
15
  import type { PdfIndexStorage } from "../cos/object-index.js";
@@ -5,7 +5,7 @@ import {
5
5
  PdfRetainedReader,
6
6
  renderPdfPageToPng,
7
7
  renderRetainedPagePixels
8
- } from "../safe-bash/command-chunks/chunk-4BSD2RGK.js";
8
+ } from "../safe-bash/command-chunks/chunk-QPKL5GWH.js";
9
9
  import "../safe-bash/command-chunks/chunk-E6SK3OU2.js";
10
10
  import "../safe-bash/command-chunks/chunk-NUGQQDGE.js";
11
11
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
@@ -75,7 +75,7 @@ export { createRetainedPageCopy, type PdfRetainedPageCopy, copyRetainedPageChunk
75
75
  export { PdfRawTextIndex, type PdfRawTextGlyph, type PdfRawTextIndexOptions, type PdfStoredTextWord, type PdfStoredTextLine, type PdfStoredTextBlock } from "./extract/raw-text-index.js";
76
76
  export { retainedCosObjects, type PdfRetainedObjectsOptions } from "./cos/retained-objects.js";
77
77
  export { saveRetainedDocumentChunks, type SaveRetainedDocumentOptions, type RetainedPageRotation } from "./edit/retained-save.js";
78
- export { editRetainedDocument, PdfDuplicateAttachment, type RetainedAttachmentInput, type EditRetainedDocumentOptions, type RetainedBookmark, type RetainedFormUpdate, type RetainedInfoUpdate, type RetainedStampInput, type RetainedPageLabel } from "./edit/retained-graph.js";
78
+ export { editRetainedDocument, PdfDuplicateAttachment, PdfMissingAttachment, type RetainedAttachmentInput, type EditRetainedDocumentOptions, type RetainedBookmark, type RetainedFormUpdate, type RetainedInfoUpdate, type RetainedStampInput, type RetainedPageLabel } from "./edit/retained-graph.js";
79
79
  export { copyRetainedAttachments } from "./edit/retained-attachment-copies.js";
80
80
  export { retainedObjectOrder } from "./cos/retained-object-order.js";
81
81
  export { encryptRetainedPdfChunks } from "./cos/retained-encryption.js";
@@ -88,3 +88,4 @@ export { streamLogicalTextChunks, type PdfLogicalTextOptions } from "./extract/l
88
88
  export { encodePostscriptPageChunks } from "./render/postscript.js";
89
89
  export { CompactPdfNumber } from "./cos/compact-number.js";
90
90
  export { serializeRetainedCosNodeChunks } from "./cos/retained-node-writer.js";
91
+ export { retainedStampTransform } from "./edit/retained-stamps.js";
@@ -8,6 +8,7 @@ import {
8
8
  PdfDuplicateAttachment,
9
9
  PdfError,
10
10
  PdfFileSource,
11
+ PdfMissingAttachment,
11
12
  PdfMutableObjectStore,
12
13
  PdfNameIndex,
13
14
  PdfObjectIndex,
@@ -164,6 +165,7 @@ import {
164
165
  getBitmapCropRect,
165
166
  getDisplayListCropBox,
166
167
  getDocumentFormFields,
168
+ getPdfEncryptionInfo,
167
169
  glyphNameToUnicode,
168
170
  imageColorSpaceProgram,
169
171
  inflatePdfChunks,
@@ -233,6 +235,7 @@ import {
233
235
  resolveRetainedMaskParameters,
234
236
  retainedCosObjects,
235
237
  retainedObjectOrder,
238
+ retainedStampTransform,
236
239
  rgb,
237
240
  rotateRgbaBitmapQuarterTurns,
238
241
  rotateRgbaBitmapQuarterTurnsSteps,
@@ -257,7 +260,7 @@ import {
257
260
  transformNodeStringsAndStreamsSteps,
258
261
  transformPathSegment,
259
262
  transformPoint
260
- } from "../safe-bash/command-chunks/chunk-4BSD2RGK.js";
263
+ } from "../safe-bash/command-chunks/chunk-QPKL5GWH.js";
261
264
  import "../safe-bash/command-chunks/chunk-E6SK3OU2.js";
262
265
  import "../safe-bash/command-chunks/chunk-NUGQQDGE.js";
263
266
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
@@ -271,6 +274,7 @@ export {
271
274
  PdfDuplicateAttachment,
272
275
  PdfError,
273
276
  PdfFileSource,
277
+ PdfMissingAttachment,
274
278
  PdfMutableObjectStore,
275
279
  PdfNameIndex,
276
280
  PdfObjectIndex,
@@ -428,6 +432,7 @@ export {
428
432
  getBitmapCropRect,
429
433
  getDisplayListCropBox,
430
434
  getDocumentFormFields,
435
+ getPdfEncryptionInfo,
431
436
  glyphNameToUnicode,
432
437
  imageColorSpaceProgram,
433
438
  inflatePdfChunks,
@@ -497,6 +502,7 @@ export {
497
502
  resolveRetainedMaskParameters,
498
503
  retainedCosObjects,
499
504
  retainedObjectOrder,
505
+ retainedStampTransform,
500
506
  rgb,
501
507
  rotateRgbaBitmapQuarterTurns,
502
508
  rotateRgbaBitmapQuarterTurnsSteps,
@@ -157,6 +157,14 @@ export function saslPrep(value: string): string;
157
157
  export function buildPostScriptJsFunction(source: string, domain: readonly number[], range: readonly number[]):
158
158
  (src: readonly number[], srcOffset: number, dest: number[], destOffset: number) => void;
159
159
  export class CipherTransformFactory {
160
+ matchesOwnerPassword(): boolean;
161
+ readonly passwordType: "user" | "owner" | undefined;
162
+ readonly userPasswordBytes: Uint8Array | undefined;
163
+ readonly dict: Dict;
164
+ readonly cf: Dict | null;
165
+ readonly stmf: Name;
166
+ readonly strf: Name;
167
+ readonly eff: Name;
160
168
  constructor(dict: Dict, fileId: string, password?: string);
161
169
  readonly encryptionKey: Uint8Array | null;
162
170
  readonly encryptMetadata: boolean;
@@ -15090,6 +15090,8 @@ function utf8PasswordToBytes(password) {
15090
15090
  }
15091
15091
  var CipherTransformFactory = class _CipherTransformFactory {
15092
15092
  #fileId;
15093
+ passwordType;
15094
+ userPasswordBytes;
15093
15095
  static get _defaultPasswordBytes() {
15094
15096
  return shadow(
15095
15097
  this,
@@ -15130,6 +15132,21 @@ var CipherTransformFactory = class _CipherTransformFactory {
15130
15132
  ])
15131
15133
  );
15132
15134
  }
15135
+ matchesOwnerPassword() {
15136
+ if (this.passwordType === "owner") return true;
15137
+ if (this.passwordType !== "user") return false;
15138
+ const dict = this.dict, revision = dict.get("R");
15139
+ const owner = stringToBytes(dict.get("O"));
15140
+ const user = stringToBytes(dict.get("U"));
15141
+ const password = this.userPasswordBytes;
15142
+ if (revision >= 5) {
15143
+ const algorithm = revision === 6 ? new PDF20() : new PDF17();
15144
+ return algorithm.checkOwnerPassword(password, owner.subarray(32, 40), user.subarray(0, 48), owner.subarray(0, 32));
15145
+ }
15146
+ const keyLength = this.encryptionKey.length * 8;
15147
+ const decoded = this.#decodeUserPassword(password, owner, revision, keyLength);
15148
+ return !!this.#prepareKeyData(stringToBytes(this.#fileId), decoded, owner, user, dict.get("P"), revision, keyLength, this.encryptMetadata);
15149
+ }
15133
15150
  #createEncryptionKey20(revision, password, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms) {
15134
15151
  if (password) {
15135
15152
  const passwordLength = Math.min(127, password.length);
@@ -15139,6 +15156,8 @@ var CipherTransformFactory = class _CipherTransformFactory {
15139
15156
  }
15140
15157
  const pdfAlgorithm = revision === 6 ? new PDF20() : new PDF17();
15141
15158
  if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, userPassword)) {
15159
+ this.passwordType = "user";
15160
+ this.userPasswordBytes = Uint8Array.from(password);
15142
15161
  return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption);
15143
15162
  } else if (password.length && pdfAlgorithm.checkOwnerPassword(
15144
15163
  password,
@@ -15146,6 +15165,7 @@ var CipherTransformFactory = class _CipherTransformFactory {
15146
15165
  uBytes,
15147
15166
  ownerPassword
15148
15167
  )) {
15168
+ this.passwordType = "owner";
15149
15169
  return pdfAlgorithm.getOwnerKey(
15150
15170
  password,
15151
15171
  ownerKeySalt,
@@ -15353,6 +15373,10 @@ var CipherTransformFactory = class _CipherTransformFactory {
15353
15373
  keyLength,
15354
15374
  encryptMetadata
15355
15375
  );
15376
+ if (encryptionKey) {
15377
+ this.passwordType = "user";
15378
+ this.userPasswordBytes = passwordBytes ?? new Uint8Array();
15379
+ }
15356
15380
  } else {
15357
15381
  const ownerValidationSalt = ownerBytes.subarray(32, 40);
15358
15382
  const ownerKeySalt = ownerBytes.subarray(40, 48);
@@ -15413,6 +15437,10 @@ var CipherTransformFactory = class _CipherTransformFactory {
15413
15437
  keyLength,
15414
15438
  encryptMetadata
15415
15439
  );
15440
+ if (encryptionKey) {
15441
+ this.passwordType = "owner";
15442
+ this.userPasswordBytes = decodedPassword;
15443
+ }
15416
15444
  }
15417
15445
  if (!encryptionKey) {
15418
15446
  throw new PasswordException(
@@ -15,7 +15,7 @@ import {
15
15
  numberField,
16
16
  parseHeader,
17
17
  parsePax
18
- } from "./chunk-TCXM7BSZ.js";
18
+ } from "./chunk-YFMNXPLP.js";
19
19
 
20
20
  // packages/safe-bash-command-tar/src/extract.ts
21
21
  import { compareIdentity } from "@poe-platform/safe-fs/contracts";
@@ -381,7 +381,7 @@ async function readArchive(context, source, options, budget, visitor) {
381
381
  if (options.mode === "x") relative = relativeName(effectiveEntryName, options.strip);
382
382
  const name = entry.name.replace(/^\/+/u, "");
383
383
  const normalizedName = name.replace(/^(?:\.\/)+/u, "");
384
- let selected = options.operands.length === 0;
384
+ let selected = options.operands.length === 0 && options.mode !== "delete";
385
385
  let root = resolvePath(options.cwd);
386
386
  for (let index = 0; index < options.operands.length; index++) {
387
387
  const operand = options.operands[index];
@@ -383218,8 +383218,7 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
383218
383218
  pkt_dts_time: dtsTime,
383219
383219
  best_effort_timestamp: s.pts,
383220
383220
  best_effort_timestamp_time: ptsTime,
383221
- pkt_duration: s.duration,
383222
- pkt_duration_time: durTime,
383221
+ ...doc.containerFormat === "gif" ? { duration: s.duration, duration_time: durTime } : { pkt_duration: s.duration, pkt_duration_time: durTime },
383223
383222
  pkt_size: String(s.size),
383224
383223
  width: w,
383225
383224
  height: h,
@@ -387269,7 +387268,7 @@ function gifAst() {
387269
387268
  enabled: true,
387270
387269
  width,
387271
387270
  height,
387272
- codecDescriptions: [{ formatFourCC: "gif ", codecName: "gif", width, height, pixFmt: "rgb8" }],
387271
+ codecDescriptions: [{ formatFourCC: "gif ", codecName: "gif", width, height, pixFmt: "bgra" }],
387273
387272
  samples,
387274
387273
  decodedVideoFrames: frames
387275
387274
  }],
@@ -387299,11 +387298,28 @@ function gifAst() {
387299
387298
  },
387300
387299
  probe(bytes, options) {
387301
387300
  const doc = this.parse(bytes, options);
387302
- return buildProbeResultFromDoc(doc, bytes.byteLength, options?.filename ?? "input.gif", {
387301
+ const result = buildProbeResultFromDoc(doc, bytes.byteLength, options?.filename ?? "input.gif", {
387303
387302
  ...options,
387304
387303
  formatName: "gif",
387305
387304
  formatLongName: "CompuServe Graphics Interchange Format (GIF)"
387306
387305
  });
387306
+ const track = doc.tracks[0];
387307
+ const stream = result.streams[0];
387308
+ if (track.samples.length > 1) {
387309
+ const averageDelay = Math.floor(track.duration / track.samples.length);
387310
+ const averageDivisor = gcd(track.timescale, averageDelay);
387311
+ let interval = 0;
387312
+ for (let index = 1; index < track.samples.length; index++) {
387313
+ interval = gcd(interval, track.samples[index].dts - track.samples[index - 1].dts);
387314
+ }
387315
+ const nominalDivisor = gcd(track.timescale, interval);
387316
+ return { ...result, streams: [{
387317
+ ...stream,
387318
+ avg_frame_rate: `${track.timescale / averageDivisor}/${averageDelay / averageDivisor}`,
387319
+ r_frame_rate: `${track.timescale / nominalDivisor}/${interval / nominalDivisor}`
387320
+ }] };
387321
+ }
387322
+ return result;
387307
387323
  },
387308
387324
  concat(docs, options) {
387309
387325
  return concatMp4(docs, options);
@@ -150,6 +150,69 @@ function readTitle(text, start, context) {
150
150
  i++;
151
151
  }
152
152
  }
153
+ function romanListNumber(label) {
154
+ if (!label || label.length > 15 || label !== label.toLowerCase() && label !== label.toUpperCase()) return;
155
+ const lower = label.toLowerCase();
156
+ const values = { i: 1, v: 5, x: 10, l: 50, c: 100, d: 500, m: 1e3 };
157
+ let number = 0;
158
+ for (let i = 0; i < lower.length; i++) {
159
+ const value = values[lower[i]];
160
+ if (value === void 0) return;
161
+ number += value < (values[lower[i + 1]] ?? 0) ? -value : value;
162
+ }
163
+ if (number < 1 || number > 3999) return;
164
+ let canonical = "", remaining = number;
165
+ for (const [value, numeral] of [[1e3, "m"], [900, "cm"], [500, "d"], [400, "cd"], [100, "c"], [90, "xc"], [50, "l"], [40, "xl"], [10, "x"], [9, "ix"], [5, "v"], [4, "iv"], [1, "i"]]) {
166
+ while (remaining >= value) {
167
+ canonical += numeral;
168
+ remaining -= value;
169
+ }
170
+ }
171
+ return canonical === lower ? number : void 0;
172
+ }
173
+ function fencedDivAttributes(text, context) {
174
+ text = text.trim();
175
+ while (text.endsWith(":")) text = text.slice(0, -1);
176
+ text = text.trimEnd();
177
+ if (!text) return;
178
+ const attr = ["", [], []];
179
+ if (!text.startsWith("{")) {
180
+ for (const char of text) {
181
+ context.checkpoint();
182
+ if (whitespace(char)) return;
183
+ }
184
+ attr[1].push(text);
185
+ return attr;
186
+ }
187
+ if (!text.endsWith("}")) return;
188
+ let at = 1;
189
+ const end = text.length - 1;
190
+ while (at < end) {
191
+ context.checkpoint();
192
+ while (at < end && whitespace(text[at])) at++;
193
+ if (at === end) break;
194
+ const start = at;
195
+ while (at < end && !whitespace(text[at]) && text[at] !== "=") at++;
196
+ const name = text.slice(start, at);
197
+ if (!name) return;
198
+ if (text[at] === "=") {
199
+ at++;
200
+ const quote = text[at] === '"' || text[at] === "'" ? text[at++] : void 0;
201
+ let value = "";
202
+ while (at < end && (quote ? text[at] !== quote : !whitespace(text[at]))) {
203
+ context.checkpoint();
204
+ if (text[at] === "\\" && at + 1 < end && (text[at + 1] === quote || text[at + 1] === "\\")) at++;
205
+ value += text[at++];
206
+ }
207
+ if (quote && text[at++] !== quote) return;
208
+ attr[2].push([name, value]);
209
+ } else if (name.startsWith("#") && name.length > 1) attr[0] = name.slice(1);
210
+ else if (name.startsWith(".") && name.length > 1) attr[1].push(name.slice(1));
211
+ else return;
212
+ if (at < end && !whitespace(text[at])) return;
213
+ }
214
+ return attr;
215
+ }
153
216
 
154
217
  export {
155
218
  asciiPunctuation,
@@ -162,5 +225,7 @@ export {
162
225
  normalizeUri,
163
226
  readLabel,
164
227
  readDestination,
165
- readTitle
228
+ readTitle,
229
+ romanListNumber,
230
+ fencedDivAttributes
166
231
  };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createArchive,
3
3
  manifest
4
- } from "./chunk-MBXNG6C3.js";
4
+ } from "./chunk-DLLN3C3Q.js";
5
5
  import {
6
6
  readArchive
7
- } from "./chunk-SG2KOOD4.js";
7
+ } from "./chunk-3SAYZFMD.js";
8
8
  import {
9
9
  quoteName
10
10
  } from "./chunk-PYIG32ZI.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-LSYPQ2W5.js";
13
13
  import {
14
14
  encodeEntry
15
- } from "./chunk-TCXM7BSZ.js";
15
+ } from "./chunk-YFMNXPLP.js";
16
16
 
17
17
  // packages/safe-bash-command-tar/src/create.ts
18
18
  import { compareIdentity as compareIdentity2, compareFileVersion } from "@poe-platform/safe-fs/contracts";
@@ -288,7 +288,11 @@ function createUnzipCommand(options = {}) {
288
288
  }
289
289
  let parent = await extraction.operation(() => context.fs.lstat(dirname(path), { signal: context.signal }));
290
290
  let existing = await extraction.destination(path, archivePath, archiveStat);
291
- if (parsed.update && existing && Math.ceil(Math.floor(existing.mtimeMs / 1e3) / 2) * 2e3 >= entry.modified.getTime()) continue;
291
+ if (parsed.update && existing) {
292
+ const seconds = Math.floor(existing.mtimeMs / 1e3);
293
+ const modified = entry.extendedTimestamp ? seconds * 1e3 : Math.ceil(seconds / 2) * 2e3;
294
+ if (modified >= entry.modified.getTime()) continue;
295
+ }
292
296
  let skip = false;
293
297
  let prompting = 0;
294
298
  while (existing && overwrite !== "all") {
@@ -246,7 +246,15 @@ function extras(bytes, rawName, comment, central, limits) {
246
246
  }
247
247
  function nameFrom(rawName, flags, metadata, limits) {
248
248
  number(rawName.length, Math.min(limits.maxPathBytes, 65535), "raw path byte");
249
- const raw = flags & 2048 ? text(rawName) : legacyName(rawName);
249
+ let raw;
250
+ if (flags & 2048) raw = text(rawName);
251
+ else {
252
+ try {
253
+ raw = text(rawName);
254
+ } catch {
255
+ raw = legacyName(rawName);
256
+ }
257
+ }
250
258
  pathBytes(raw, limits);
251
259
  if (flags & 2048 && metadata.name !== void 0 && metadata.name !== raw) fail2("ZIP conflicting UTF-8 and Unicode extra names");
252
260
  return metadata.name ?? raw;
@@ -448,6 +456,7 @@ async function openZipDirectory(input, limits, signal, profile = {}) {
448
456
  if (timestamp !== void 0) modified.setTime(timestamp);
449
457
  const entry = { name, data: buffered ? await bytes.subarray(payloadStart, payloadStart + compressedSize) : new Uint8Array(), ...buffered ? {} : { compressedSize, compressedOffset: payloadStart, compressedSource: () => bytes.stream(payloadStart, compressedSize) }, size, method, crc32: checksum, modified, mode, directory, symlink, rawName, localName, comment, localExtra, centralExtra, flags, versionMadeBy, internalAttributes, externalAttributes, dosTime, dosDate };
450
458
  if (aes) entry.aes = aes;
459
+ entry.extendedTimestamp = timestamp !== void 0;
451
460
  entryBounds(entry, limits);
452
461
  if ((profile.grow || !buffered) && (centralMetadata.zip64 || localMetadata.zip64)) entry.zip64 = true;
453
462
  if (profile.grow) {
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  pipeRow
3
- } from "./chunk-DX7KU6YU.js";
3
+ } from "./chunk-N52AHO6S.js";
4
4
  import {
5
- normalizeLabel
6
- } from "./chunk-T6OXG7QQ.js";
5
+ fencedDivAttributes,
6
+ normalizeLabel,
7
+ romanListNumber
8
+ } from "./chunk-AAOPVEPF.js";
7
9
 
8
10
  // packages/safe-bash-markdown-engine/src/commonmark-blocks.ts
9
11
  function spaces(text, offset) {
@@ -77,22 +79,30 @@ function fence(text, offset) {
77
79
  if (end - offset < 3 || char === "`" && text.indexOf("`", end) !== -1) return;
78
80
  return { char, length: end - offset };
79
81
  }
80
- function marker(text, offset) {
82
+ function marker(text, offset, fancy = false) {
81
83
  let end = offset;
82
84
  let start = null;
85
+ let style;
83
86
  let char = text[end];
84
87
  if (char === "-" || char === "+" || char === "*") end++;
85
88
  else {
86
89
  while (text[end] !== void 0 && text[end] >= "0" && text[end] <= "9" && end - offset < 10) end++;
87
- if (end === offset || end - offset > 9 || text[end] !== "." && text[end] !== ")") return;
88
- start = Number(text.slice(offset, end));
90
+ if (end === offset && fancy) {
91
+ while (end - offset < 16 && text[end] && "ivxlcdmIVXLCDM".includes(text[end])) end++;
92
+ const label = text.slice(offset, end), number = romanListNumber(label);
93
+ if (number === void 0) return;
94
+ start = number;
95
+ style = label === label.toLowerCase() ? "LowerRoman" : "UpperRoman";
96
+ }
97
+ if (end === offset || !style && end - offset > 9 || text[end] !== "." && text[end] !== ")") return;
98
+ start ??= Number(text.slice(offset, end));
89
99
  char = text[end++];
90
100
  }
91
101
  if (end !== text.length && text[end] !== " ") return;
92
102
  const padding = spaces(text, end);
93
103
  const empty = end + padding === text.length;
94
104
  const content = end + (empty || padding > 4 ? Math.min(padding, 1) : padding);
95
- return { start, marker: char, content, indent: end - offset + (empty ? 1 : padding > 4 ? 1 : padding), empty };
105
+ return { start, style, marker: char, content, indent: end - offset + (empty ? 1 : padding > 4 ? 1 : padding), empty };
96
106
  }
97
107
  var blockTags = /* @__PURE__ */ new Set([
98
108
  "address",
@@ -227,11 +237,11 @@ function htmlStart(text, offset, interrupt) {
227
237
  if (blockTags.has(name)) return { end: null };
228
238
  if (!interrupt && (closing || !["script", "pre", "style", "textarea"].includes(name)) && completeTag(text, offset)) return { end: null };
229
239
  }
230
- function interrupts(text, offset, rawHtml = true) {
240
+ function interrupts(text, offset, rawHtml = true, fancy = false) {
231
241
  const indent = spaces(text, offset);
232
242
  if (indent > 3) return false;
233
243
  const at = offset + indent;
234
- const item = marker(text, at);
244
+ const item = marker(text, at, fancy);
235
245
  return Boolean(heading(text, at) || rule(text, at) || fence(text, at) || text[at] === ">" || rawHtml && htmlStart(text, at, true) || item && !item.empty && (item.start === null || item.start === 1));
236
246
  }
237
247
  async function parseCommonMarkBlocks(text, context, source = "input", extensions = {}) {
@@ -249,7 +259,7 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
249
259
  const range = (line, offset) => ({ source, start: point(line, offset), end: endPoint(line) });
250
260
  const blocks = () => {
251
261
  const top = stack[stack.length - 1];
252
- return top?.kind === "quote" || top?.kind === "item" || top?.kind === "footnote" ? top.node.blocks : document.blocks;
262
+ return top?.kind === "div" || top?.kind === "quote" || top?.kind === "item" || top?.kind === "footnote" || top?.kind === "definition" ? top.node.blocks : document.blocks;
253
263
  };
254
264
  const add = (node) => {
255
265
  context.bound("depth", stack.length + 1);
@@ -258,6 +268,8 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
258
268
  const item = stack[stack.length - 1];
259
269
  if (item?.kind === "item" && item.blank && item.node.blocks.length > 0) item.list.tight = false;
260
270
  if (item?.kind === "item") item.blank = false;
271
+ if (item?.kind === "definition" && item.blank) item.node.tight = false;
272
+ if (item?.kind === "definition") item.blank = false;
261
273
  blocks().push(node);
262
274
  };
263
275
  const push = (container) => {
@@ -358,7 +370,7 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
358
370
  for (; matched < stack.length; matched++) {
359
371
  context.checkpoint();
360
372
  const container = stack[matched];
361
- if (container.kind === "list") continue;
373
+ if (container.kind === "list" || container.kind === "div") continue;
362
374
  const indent = spaces(line.text, offset);
363
375
  if (container.kind === "quote") {
364
376
  if (indent > 3 || line.text[offset + indent] !== ">") break;
@@ -374,10 +386,11 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
374
386
  if (matched < stack.length) {
375
387
  const failed = stack[matched];
376
388
  const siblingIndent = spaces(line.text, offset);
377
- const sibling = siblingIndent <= 3 ? marker(line.text, offset + siblingIndent) : void 0;
389
+ const sibling = siblingIndent <= 3 ? marker(line.text, offset + siblingIndent, extensions.fancy_lists) : void 0;
378
390
  const siblingItem = failed?.kind === "item" && sibling;
379
391
  const siblingFootnote = failed?.kind === "footnote" && line.text.startsWith("[^", offset + siblingIndent) && line.text.includes("]:", offset + siblingIndent + 2);
380
- if (leaf?.kind === "paragraph" && !blank && !siblingItem && !siblingFootnote && !interrupts(line.text, offset, extensions.raw_html !== false)) {
392
+ const siblingDefinition = extensions.definition_lists && siblingIndent <= 3 && [":", "~"].includes(line.text[offset + siblingIndent] ?? "") && line.text[offset + siblingIndent + 1] === " ";
393
+ if (leaf?.kind === "paragraph" && !blank && !siblingItem && !siblingFootnote && !siblingDefinition && !interrupts(line.text, offset, extensions.raw_html !== false, extensions.fancy_lists)) {
381
394
  leaf.node.inline.lines.push(inlineLine(line, offset + spaces(line.text, offset)));
382
395
  leaf.node.source.end = endPoint(line);
383
396
  for (const container of stack) container.node.source.end = endPoint(line);
@@ -432,6 +445,31 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
432
445
  }
433
446
  finish();
434
447
  }
448
+ if (extensions.fenced_divs && spaces(line.text, offset) <= 3) {
449
+ const at = offset + spaces(line.text, offset);
450
+ let stop = at;
451
+ while (line.text[stop] === ":") stop++;
452
+ if (stop - at >= 3) {
453
+ const tail = rawFrom(line, stop).trim();
454
+ const attributes = fencedDivAttributes(tail, context);
455
+ if (attributes) {
456
+ finish();
457
+ const node = { kind: "div", attributes, blocks: [], source: range(line, at) };
458
+ add(node);
459
+ push({ kind: "div", node });
460
+ continue;
461
+ }
462
+ if (!tail) {
463
+ let index = stack.length - 1;
464
+ while (index >= 0 && stack[index].kind !== "div") index--;
465
+ if (index >= 0) {
466
+ finish();
467
+ stack.length = index;
468
+ continue;
469
+ }
470
+ }
471
+ }
472
+ }
435
473
  if (blank) {
436
474
  finish();
437
475
  let deepest;
@@ -442,10 +480,12 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
442
480
  }
443
481
  }
444
482
  if (deepest) deepest.blank = true;
483
+ const top = stack[stack.length - 1];
484
+ if (top?.kind === "definition") top.blank = true;
445
485
  continue;
446
486
  }
447
487
  if (leaf?.kind === "table") {
448
- const row = !interrupts(line.text, offset, extensions.raw_html !== false) ? pipeRow(rawFrom(line, offset), context) : void 0;
488
+ const row = !interrupts(line.text, offset, extensions.raw_html !== false, extensions.fancy_lists) ? pipeRow(rawFrom(line, offset), context) : void 0;
449
489
  if (row) {
450
490
  context.charge("tableCells", extensions.preserve_table_columns ? row.length : leaf.node.alignments.length);
451
491
  leaf.node.rows.push(extensions.preserve_table_columns ? row : row.slice(0, leaf.node.alignments.length));
@@ -480,6 +520,31 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
480
520
  }
481
521
  }
482
522
  }
523
+ const definitionIndent = spaces(line.text, offset), definitionAt = offset + definitionIndent;
524
+ if (extensions.definition_lists && definitionIndent <= 3 && [":", "~"].includes(line.text[definitionAt] ?? "") && line.text[definitionAt + 1] === " ") {
525
+ if (leaf?.kind === "paragraph") extractDefinitions(leaf.node);
526
+ const siblings = blocks(), previous = siblings[siblings.length - 1];
527
+ if (previous?.kind === "paragraph" || previous?.kind === "definitionList") {
528
+ finish();
529
+ const term = previous.kind === "paragraph" ? previous : void 0;
530
+ if (term) siblings.pop();
531
+ let list = siblings[siblings.length - 1];
532
+ if (list?.kind !== "definitionList") {
533
+ list = { kind: "definitionList", items: [], source: { ...previous.source } };
534
+ add(list);
535
+ }
536
+ if (term) list.items.push({ term: term.inline, definitions: [] });
537
+ const lastDefinition = previous.kind === "definitionList" ? previous.items.at(-1)?.definitions.at(-1) : void 0;
538
+ const previousEnd = lastDefinition?.blocks.at(-1)?.source.end.line ?? previous.source.end.line;
539
+ const definition = { blocks: [], tight: previousEnd + 1 === line.number, source: range(line, definitionAt) };
540
+ context.charge("nodes", 1);
541
+ context.charge("retainedBytes", 128);
542
+ list.items[list.items.length - 1].definitions.push(definition);
543
+ list.source.end = endPoint(line);
544
+ push({ kind: "definition", node: definition, indent: definitionIndent + 4, blank: false, empty: false });
545
+ offset = definitionAt + 1 + Math.min(3, spaces(line.text, definitionAt + 1));
546
+ }
547
+ }
483
548
  const initialIndent = spaces(line.text, offset);
484
549
  const underline = initialIndent <= 3 ? setext(line.text, offset + initialIndent) : 0;
485
550
  if (leaf?.kind === "paragraph" && underline) {
@@ -493,7 +558,7 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
493
558
  }
494
559
  leaf = void 0;
495
560
  }
496
- if (leaf?.kind === "paragraph" && !interrupts(line.text, offset, extensions.raw_html !== false)) {
561
+ if (leaf?.kind === "paragraph" && !interrupts(line.text, offset, extensions.raw_html !== false, extensions.fancy_lists)) {
497
562
  leaf.node.inline.lines.push(inlineLine(line, offset + initialIndent));
498
563
  leaf.node.source.end = endPoint(line);
499
564
  continue;
@@ -516,8 +581,8 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
516
581
  continue;
517
582
  }
518
583
  }
519
- const item = indent <= 3 && !rule(line.text, at) ? marker(line.text, at) : void 0;
520
- if (top?.kind === "list" && (!item || item.start !== null !== (top.node.start !== null) || item.marker !== top.node.marker)) {
584
+ const item = indent <= 3 && !rule(line.text, at) ? marker(line.text, at, extensions.fancy_lists) : void 0;
585
+ if (top?.kind === "list" && (!item || item.start !== null !== (top.node.start !== null) || item.marker !== top.node.marker || item.style !== top.node.style)) {
521
586
  stack.pop();
522
587
  const parent = stack[stack.length - 1];
523
588
  const previous = top.node.items[top.node.items.length - 1];
@@ -534,7 +599,7 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
534
599
  if (item && (!wasParagraph || !item.empty && (item.start === null || item.start === 1))) {
535
600
  let listContainer = stack[stack.length - 1];
536
601
  if (listContainer?.kind !== "list") {
537
- const node3 = { kind: "list", start: item.start, marker: item.marker, tight: true, items: [], source: range(line, at) };
602
+ const node3 = { kind: "list", start: item.start, marker: item.marker, style: item.style, tight: true, items: [], source: range(line, at) };
538
603
  add(node3);
539
604
  listContainer = { kind: "list", node: node3 };
540
605
  push(listContainer);
@@ -550,6 +615,17 @@ async function parseCommonMarkBlocks(text, context, source = "input", extensions
550
615
  if (item.empty) break;
551
616
  continue;
552
617
  }
618
+ if (extensions.fenced_divs && indent <= 3 && line.text.startsWith(":::", at)) {
619
+ let stop = at + 3;
620
+ while (line.text[stop] === ":") stop++;
621
+ const attributes = fencedDivAttributes(rawFrom(line, stop), context);
622
+ if (attributes) {
623
+ const node2 = { kind: "div", attributes, blocks: [], source: range(line, at) };
624
+ add(node2);
625
+ push({ kind: "div", node: node2 });
626
+ break;
627
+ }
628
+ }
553
629
  if (at === line.text.length) break;
554
630
  const level = indent <= 3 ? heading(line.text, at) : 0;
555
631
  if (level) {