@embedpdf/engine-core 3.0.0-next.15 → 3.0.0-next.16

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 (91) hide show
  1. package/dist/{AnnotationList-CkijRHet.d.cts → AnnotationList-DcyhF2kU.d.cts} +1836 -1308
  2. package/dist/{AnnotationList-CkijRHet.d.ts → AnnotationList-DcyhF2kU.d.ts} +1836 -1308
  3. package/dist/{Change-CjImsrN0.cjs → Change-Ct-dB8D5.cjs} +115 -2
  4. package/dist/Change-Ct-dB8D5.cjs.map +1 -0
  5. package/dist/{Change-CKoxfTNY.js → Change-tMR34hTU.js} +92 -3
  6. package/dist/Change-tMR34hTU.js.map +1 -0
  7. package/dist/{DocumentRenderService-BfFdFSwI.cjs → DocumentRenderService-9IjSQEIU.cjs} +2 -1
  8. package/dist/{DocumentRenderService-BfFdFSwI.cjs.map → DocumentRenderService-9IjSQEIU.cjs.map} +1 -1
  9. package/dist/{DocumentRenderService-DV3J9lMz.js → DocumentRenderService-DFrZ9wfW.js} +2 -1
  10. package/dist/{DocumentRenderService-DV3J9lMz.js.map → DocumentRenderService-DFrZ9wfW.js.map} +1 -1
  11. package/dist/{DocumentSecurityService-e6vp2de8.d.cts → DocumentSecurityService-D2zA4NKi.d.cts} +2 -2
  12. package/dist/{DocumentSecurityService-CU1M6Q7m.d.ts → DocumentSecurityService-YJV9df8P.d.ts} +2 -2
  13. package/dist/{LocalEngine-DFoBm4B3.d.cts → LocalEngine-DBt2-GWF.d.ts} +102 -18
  14. package/dist/{LocalEngine-DPriFujS.d.ts → LocalEngine-IA9zh3Jh.d.cts} +102 -18
  15. package/dist/{authority-DLMNR7ff.cjs → authority-BFp6XM04.cjs} +373 -52
  16. package/dist/authority-BFp6XM04.cjs.map +1 -0
  17. package/dist/{authority-B3BklsB4.js → authority-PuxpGFhJ.js} +320 -53
  18. package/dist/authority-PuxpGFhJ.js.map +1 -0
  19. package/dist/{builders-CNj0POeY.js → builders-DV62HA3I.js} +6 -2
  20. package/dist/builders-DV62HA3I.js.map +1 -0
  21. package/dist/{builders-Cgdp_YCn.cjs → builders-DgTAj_tP.cjs} +6 -2
  22. package/dist/builders-DgTAj_tP.cjs.map +1 -0
  23. package/dist/{calibrate-DJBXnhLE.cjs → calibrate-DJbi1wuK.cjs} +118 -25
  24. package/dist/calibrate-DJbi1wuK.cjs.map +1 -0
  25. package/dist/{calibrate-7T3fnP8-.js → calibrate-nQFgCuki.js} +83 -26
  26. package/dist/calibrate-nQFgCuki.js.map +1 -0
  27. package/dist/charmap-Cprti1ta.js.map +1 -1
  28. package/dist/charmap-aYlefQP9.cjs.map +1 -1
  29. package/dist/conformance.cjs +1744 -75
  30. package/dist/conformance.cjs.map +1 -1
  31. package/dist/conformance.d.cts +105 -10
  32. package/dist/conformance.d.ts +105 -10
  33. package/dist/conformance.js +1738 -76
  34. package/dist/conformance.js.map +1 -1
  35. package/dist/index.cjs +25 -6
  36. package/dist/index.d.cts +2 -2
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +7 -7
  39. package/dist/public.cjs +6 -4
  40. package/dist/public.d.cts +5 -5
  41. package/dist/public.d.ts +5 -5
  42. package/dist/public.js +5 -5
  43. package/dist/{resolver-CzxmD9Ck.js → resolver-BBggAxQc.js} +6 -3
  44. package/dist/resolver-BBggAxQc.js.map +1 -0
  45. package/dist/{resolver-D2OCtE8F.cjs → resolver-BWSWSF6R.cjs} +6 -3
  46. package/dist/resolver-BWSWSF6R.cjs.map +1 -0
  47. package/dist/{runtime-Cl0v56mm.d.ts → runtime-BaDKjxiu.d.ts} +67 -140
  48. package/dist/{runtime-p1WDzDo4.d.cts → runtime-CWEuiwbk.d.cts} +67 -140
  49. package/dist/runtime.cjs +267 -7
  50. package/dist/runtime.cjs.map +1 -1
  51. package/dist/runtime.d.cts +5 -5
  52. package/dist/runtime.d.ts +5 -5
  53. package/dist/runtime.js +246 -8
  54. package/dist/runtime.js.map +1 -1
  55. package/dist/{schema-DzlUNk38.js → schema-6S2VmlAj.js} +8 -2
  56. package/dist/schema-6S2VmlAj.js.map +1 -0
  57. package/dist/{schema-C-gU4vj7.cjs → schema-miH6tWQC.cjs} +13 -1
  58. package/dist/schema-miH6tWQC.cjs.map +1 -0
  59. package/dist/{schemas-D6xOGjqg.js → schemas-BE2QGOit.js} +256 -59
  60. package/dist/schemas-BE2QGOit.js.map +1 -0
  61. package/dist/{schemas-Berf1swF.cjs → schemas-DljJR9ut.cjs} +397 -80
  62. package/dist/schemas-DljJR9ut.cjs.map +1 -0
  63. package/dist/validation.cjs +1 -1
  64. package/dist/validation.d.cts +1 -1
  65. package/dist/validation.d.ts +1 -1
  66. package/dist/validation.js +1 -1
  67. package/dist/{viewport-DlL5Bxbg.cjs → viewport-CHG9qQUb.cjs} +2 -2
  68. package/dist/{viewport-DlL5Bxbg.cjs.map → viewport-CHG9qQUb.cjs.map} +1 -1
  69. package/dist/{viewport-BJW13EGZ.js → viewport-DQR5LyX3.js} +2 -2
  70. package/dist/{viewport-BJW13EGZ.js.map → viewport-DQR5LyX3.js.map} +1 -1
  71. package/dist/wire.cjs +225 -57
  72. package/dist/wire.cjs.map +1 -1
  73. package/dist/wire.d.cts +3548 -1151
  74. package/dist/wire.d.ts +3548 -1151
  75. package/dist/wire.js +198 -53
  76. package/dist/wire.js.map +1 -1
  77. package/package.json +1 -1
  78. package/dist/Change-CKoxfTNY.js.map +0 -1
  79. package/dist/Change-CjImsrN0.cjs.map +0 -1
  80. package/dist/authority-B3BklsB4.js.map +0 -1
  81. package/dist/authority-DLMNR7ff.cjs.map +0 -1
  82. package/dist/builders-CNj0POeY.js.map +0 -1
  83. package/dist/builders-Cgdp_YCn.cjs.map +0 -1
  84. package/dist/calibrate-7T3fnP8-.js.map +0 -1
  85. package/dist/calibrate-DJBXnhLE.cjs.map +0 -1
  86. package/dist/resolver-CzxmD9Ck.js.map +0 -1
  87. package/dist/resolver-D2OCtE8F.cjs.map +0 -1
  88. package/dist/schema-C-gU4vj7.cjs.map +0 -1
  89. package/dist/schema-DzlUNk38.js.map +0 -1
  90. package/dist/schemas-Berf1swF.cjs.map +0 -1
  91. package/dist/schemas-D6xOGjqg.js.map +0 -1
@@ -1,9 +1,9 @@
1
+ import { G as mapLinkTarget, J as pageDestinationOf, K as mapPageActions, M as pageAnnotationOf, Q as applyResolvedPatch, V as mapActionTree, W as mapFieldActions, Y as pdfDestinationOf, c as foldText, gt as resolveBinarySource, kt as pdfRectOf, q as mapTriggerActions, wt as pageBoxOf } from "./calibrate-nQFgCuki.js";
1
2
  import { g as writesScripts } from "./value-Dhc8eYcx.js";
2
3
  import { gt as normalizePdfRect, nt as kindFactsOf, wt as pdfRectTurnedBounds, xt as pdfRectIntersection } from "./resolveAnnotationDraft-CUpf0SMh.js";
3
4
  import { h as EngineError, m as annotationKey, u as encodePageKey, v as _defineProperty, y as EngineErrorCode } from "./format-Dgg428Kb.js";
4
- import { Et as pdfRectOf, J as pageDestinationOf, K as mapPageActions, M as pageAnnotationOf, Q as applyResolvedPatch, W as mapFieldActions, Y as pdfDestinationOf, c as foldText, ht as resolveBinarySource, q as mapTriggerActions, xt as pageBoxOf } from "./calibrate-7T3fnP8-.js";
5
- import { C as lockCovers, E as protectedCapabilities, S as levelFromPermission, T as minLevel, _ as deriveProtection, a as checkFieldAction, i as checkCollab, j as PermissionDenied, n as checkAnyFieldAction, o as checkSetGroup, r as checkCapability, s as collabTargetOf, v as describeProtection, x as levelAllows } from "./resolver-CzxmD9Ck.js";
6
- import { S as AbortablePromise, d as matchLiteral, s as matchRegex, u as foldOptionsFor } from "./viewport-BJW13EGZ.js";
5
+ import { C as lockCovers, E as protectedCapabilities, S as levelFromPermission, T as minLevel, _ as deriveProtection, a as checkFieldAction, i as checkCollab, j as PermissionDenied, n as checkAnyFieldAction, o as checkSetGroup, r as checkCapability, s as collabTargetOf, v as describeProtection, x as levelAllows } from "./resolver-BBggAxQc.js";
6
+ import { S as AbortablePromise, d as matchLiteral, s as matchRegex, u as foldOptionsFor } from "./viewport-DQR5LyX3.js";
7
7
  //#region src/geometry/pageBoxes.ts
8
8
  /** The media box of a page that has none, which the file needs: US Letter. */
9
9
  const DEFAULT_MEDIA_BOX = {
@@ -69,6 +69,40 @@ function resolvePageLayers(options, may) {
69
69
  includeFormFields: includeFormFields ?? (includeAnnotations === false ? false : may.formFields)
70
70
  };
71
71
  }
72
+ /**
73
+ * Check what a render is for. A print picture (`usage: 'print'`) takes a
74
+ * `{ kind: 'dpi', dpi }` viewport with a DPI of 150 or 300, and no `target`,
75
+ * `rotation` or `background`: it is the whole page, upright, on white. A
76
+ * `dpi` viewport is for print pictures only. Anything else is `InvalidArg`,
77
+ * naming the option. With the caller's rights, a print they may not make is
78
+ * refused (`PermissionDenied`): any print without `doc.print`, 300 DPI
79
+ * without `doc.print.high`. Without them (a cloud caller whose rights the
80
+ * client can't know), the server decides.
81
+ */
82
+ function checkRenderUsage(options, may) {
83
+ const { usage, viewport } = options ?? {};
84
+ if (usage === void 0 || usage === "display") {
85
+ if (viewport?.kind === "dpi") invalid("viewport", "a dpi viewport is only for a print picture (usage: \"print\")");
86
+ return;
87
+ }
88
+ if (usage !== "print") invalid("usage", "usage must be \"display\" or \"print\"");
89
+ if (viewport?.kind !== "dpi" || viewport.dpi !== 150 && viewport.dpi !== 300) invalid("viewport", "a print picture needs viewport: { kind: 'dpi', dpi: 150 or 300 }");
90
+ for (const field of [
91
+ "target",
92
+ "rotation",
93
+ "background"
94
+ ]) if (options?.[field] !== void 0) invalid(field, `a print picture takes no ${field}: it is the whole page, upright, on white`);
95
+ if (may === null) return;
96
+ if (!may.print) throw new PermissionDenied("doc.print", "usage");
97
+ if (viewport.dpi === 300 && !may.printHigh) throw new PermissionDenied("doc.print.high", "viewport");
98
+ }
99
+ /** A print picture's DPI: its viewport's, when it is one; otherwise `undefined`. */
100
+ function printDpiOf(options) {
101
+ return options?.usage === "print" && options.viewport?.kind === "dpi" ? options.viewport.dpi : void 0;
102
+ }
103
+ function invalid(field, message) {
104
+ throw new EngineError(EngineErrorCode.InvalidArg, message, { details: { field } });
105
+ }
72
106
  /** `InvalidArg` unless `quality` is absent or between 0 and 1. */
73
107
  function checkImageQuality(quality) {
74
108
  if (quality === void 0 || quality >= 0 && quality <= 1) return;
@@ -116,6 +150,30 @@ function imageSourceOf(blobSource) {
116
150
  };
117
151
  }
118
152
  //#endregion
153
+ //#region src/dto/PageExtract.ts
154
+ /**
155
+ * What `pages.extract()` makes: `null` for a plain copy, else what the
156
+ * flattened copy paints. A plain copy needs `doc.download`; a flattened one
157
+ * `doc.download` or `doc.download.flattened`, and paints only what the caller
158
+ * may read, with the defaults of a page picture (`resolvePageLayers`). The
159
+ * include options belong to `flatten`: given without it, they're refused.
160
+ */
161
+ function resolvePageExtract(options, may) {
162
+ const flatten = options?.flatten;
163
+ if (flatten === void 0) {
164
+ for (const field of ["includeAnnotations", "includeFormFields"]) if (options?.[field] !== void 0) throw new EngineError(EngineErrorCode.InvalidArg, `${field} takes flatten`, { details: { field } });
165
+ if (!may.download) throw new PermissionDenied("doc.download");
166
+ return null;
167
+ }
168
+ const usage = flatten.usage ?? "display";
169
+ if (usage !== "display" && usage !== "print") throw new EngineError(EngineErrorCode.InvalidArg, "usage must be \"display\" or \"print\"", { details: { field: "flatten.usage" } });
170
+ if (!may.download && !may.downloadFlattened) throw new PermissionDenied("doc.download", "flatten", ["doc.download", "doc.download.flattened"]);
171
+ return {
172
+ usage,
173
+ ...resolvePageLayers(options, may)
174
+ };
175
+ }
176
+ //#endregion
119
177
  //#region src/dto/PdfSaveMode.ts
120
178
  const DEFAULT_PDF_SAVE_MODE = "incremental";
121
179
  //#endregion
@@ -464,6 +522,50 @@ function pageFormSnapshotOf(snapshot, boxOf) {
464
522
  };
465
523
  }
466
524
  //#endregion
525
+ //#region src/pageSpace/outline.ts
526
+ /**
527
+ * The outline between the file's coordinates and page space: only the
528
+ * destinations an item goes to change, each measured on the page it goes to.
529
+ */
530
+ /** An item, its target's and its action's destinations converted. */
531
+ function mapOutlineItem(item, convert) {
532
+ return {
533
+ ...item,
534
+ target: item.target && mapLinkTarget(item.target, convert),
535
+ action: item.action && mapActionTree(item.action, convert)
536
+ };
537
+ }
538
+ /** A draft or a patch, its target's destination converted. */
539
+ function mapOutlineWrite(write, convert) {
540
+ const { target, ...rest } = write;
541
+ if (target === void 0) return rest;
542
+ return {
543
+ ...rest,
544
+ target: target && target.kind === "goto" ? {
545
+ ...target,
546
+ destination: convert(target.destination)
547
+ } : target
548
+ };
549
+ }
550
+ /** The outline as a read hands it out: every destination in page space. */
551
+ function pageOutlineOf(outline, boxOf) {
552
+ return {
553
+ ...outline,
554
+ items: outline.items.map((item) => pageOutlineItemOf(item, boxOf))
555
+ };
556
+ }
557
+ function pageOutlineItemOf(item, boxOf) {
558
+ return mapOutlineItem(item, (destination) => pageDestinationOf(destination, boxOf));
559
+ }
560
+ /** A draft in the file's coordinates, as the engine writes it. */
561
+ function pdfOutlineDraftOf(draft, boxOf) {
562
+ return mapOutlineWrite(draft, (destination) => pdfDestinationOf(destination, boxOf));
563
+ }
564
+ /** A patch in the file's coordinates, as the engine writes it. */
565
+ function pdfOutlinePatchOf(patch, boxOf) {
566
+ return mapOutlineWrite(patch, (destination) => pdfDestinationOf(destination, boxOf));
567
+ }
568
+ //#endregion
467
569
  //#region src/forms/draft.ts
468
570
  /**
469
571
  * Whether creating a field from `draft` takes `doc.forms.script`: a script
@@ -1090,7 +1192,7 @@ function indexRoles(s) {
1090
1192
  sigFields
1091
1193
  };
1092
1194
  }
1093
- function edgeKey(e) {
1195
+ function edgeKey$1(e) {
1094
1196
  return `${e.parent}:${e.label}`;
1095
1197
  }
1096
1198
  var StepContext = class {
@@ -1116,7 +1218,7 @@ var StepContext = class {
1116
1218
  }
1117
1219
  claimEdge(c, side, edge, rule, allow = true) {
1118
1220
  if (this.locked.has(c.objectNumber)) return;
1119
- const key = `${c.objectNumber}:${side}:${edgeKey(edge)}`;
1221
+ const key = `${c.objectNumber}:${side}:${edgeKey$1(edge)}`;
1120
1222
  if (!this.claims.has(key)) this.claims.set(key, {
1121
1223
  rule,
1122
1224
  allow
@@ -1132,17 +1234,17 @@ var StepContext = class {
1132
1234
  * anything hang off it.
1133
1235
  */
1134
1236
  claimStable(c, rule, allow = true) {
1135
- const oldKeys = new Set(c.usage.old.map(edgeKey));
1136
- const newKeys = new Set(c.usage.new.map(edgeKey));
1137
- for (const e of c.usage.old) if (newKeys.has(edgeKey(e))) this.claimEdge(c, "old", e, rule, allow);
1138
- for (const e of c.usage.new) if (oldKeys.has(edgeKey(e))) this.claimEdge(c, "new", e, rule, allow);
1237
+ const oldKeys = new Set(c.usage.old.map(edgeKey$1));
1238
+ const newKeys = new Set(c.usage.new.map(edgeKey$1));
1239
+ for (const e of c.usage.old) if (newKeys.has(edgeKey$1(e))) this.claimEdge(c, "old", e, rule, allow);
1240
+ for (const e of c.usage.new) if (oldKeys.has(edgeKey$1(e))) this.claimEdge(c, "new", e, rule, allow);
1139
1241
  }
1140
1242
  isClaimed(c, side, edge) {
1141
- return this.claims.has(`${c.objectNumber}:${side}:${edgeKey(edge)}`);
1243
+ return this.claims.has(`${c.objectNumber}:${side}:${edgeKey$1(edge)}`);
1142
1244
  }
1143
1245
  /** The use was inspected by a rule that allowed it. */
1144
1246
  isAllowed(c, side, edge) {
1145
- return this.claims.get(`${c.objectNumber}:${side}:${edgeKey(edge)}`)?.allow === true;
1247
+ return this.claims.get(`${c.objectNumber}:${side}:${edgeKey$1(edge)}`)?.allow === true;
1146
1248
  }
1147
1249
  permitted(c, rule, detail) {
1148
1250
  if (this.locked.has(c.objectNumber)) return;
@@ -1163,7 +1265,7 @@ var StepContext = class {
1163
1265
  rule,
1164
1266
  verdict: c.value.truncated ? "incomplete" : "forbidden",
1165
1267
  objectNumber: c.objectNumber,
1166
- edge: edge ? edgeKey(edge) : void 0,
1268
+ edge: edge ? edgeKey$1(edge) : void 0,
1167
1269
  detail: c.value.truncated ? `${detail} (judged on missing evidence: not proven)` : detail
1168
1270
  });
1169
1271
  }
@@ -1758,6 +1860,11 @@ const DEFAULT_EDGE_RESOLVER_BUDGET = {
1758
1860
  };
1759
1861
  const USAGE_INCOMPLETE = "incomplete";
1760
1862
  /**
1863
+ * The label segment that stands for a route between two members of a loop.
1864
+ * Fork labels are ASCII (keys are `#`-escaped), so it is never a key.
1865
+ */
1866
+ const LOOP_ROUTE = "…";
1867
+ /**
1761
1868
  * Resolves the raw inbound edges of an object (from the fork's referrer
1762
1869
  * index, which covers every reachable object of a revision) into edges
1763
1870
  * from *anchors*: the changed objects and the structural objects of the
@@ -1767,68 +1874,222 @@ const USAGE_INCOMPLETE = "incomplete";
1767
1874
  * appearance stream under an unchanged indirect `/AP` dictionary reads
1768
1875
  * `widget:AP/N` rather than `apDict:N`.
1769
1876
  *
1770
- * A graph traversal, not a path enumeration: results are memoised per
1771
- * object, so a lattice of shared unchanged objects costs its size, not the
1772
- * number of paths through it. Cycle edges contribute no anchors and are
1773
- * skipped; a result computed while skipping one is not memoised.
1877
+ * A graph traversal, not a path enumeration. The unchanged objects above
1878
+ * an object are read once each and split into strongly connected
1879
+ * components (loops: a structure tree, whose elements point at their
1880
+ * parent with `/P` and at their children with `/K`; an outline, whose
1881
+ * items point at their neighbours; an annotation and its popup), resolved
1882
+ * ancestors first and memoised per object, so a lattice of shared objects
1883
+ * costs its size, not the number of paths through it.
1884
+ *
1885
+ * Every member of a loop reaches every other one, so an edge into a loop
1886
+ * reaches all its members: as it is at the member it enters, and as
1887
+ * `<label>/…` at every other one, the route between them collapsed. The
1888
+ * route consists of unchanged objects, the same in both revisions, so it
1889
+ * carries no evidence; the anchor, the way in and the way out (the labels
1890
+ * either side of `…`) do, and they are kept. Edges whose label collapses
1891
+ * a route are told apart by anchor and label alone.
1774
1892
  */
1775
1893
  var EdgeResolver = class {
1776
1894
  constructor(read, anchors, budget = DEFAULT_EDGE_RESOLVER_BUDGET) {
1777
1895
  this.read = read;
1778
1896
  this.anchors = anchors;
1779
1897
  this.budget = budget;
1780
- _defineProperty(this, "memo", /* @__PURE__ */ new Map());
1898
+ _defineProperty(this, "referrers", /* @__PURE__ */ new Map());
1899
+ _defineProperty(this, "resolved", /* @__PURE__ */ new Map());
1781
1900
  _defineProperty(this, "reads", 0);
1782
1901
  _defineProperty(this, "exhausted", false);
1783
1902
  }
1784
1903
  /** Anchored edges of `objectNumber`, or `incomplete` when a budget was exceeded. */
1785
1904
  resolve(objectNumber) {
1786
- if (this.exhausted) return USAGE_INCOMPLETE;
1787
- const result = this.resolveInner(objectNumber, /* @__PURE__ */ new Set());
1788
- return result === null ? USAGE_INCOMPLETE : result.edges;
1789
- }
1790
- resolveInner(n, active) {
1791
- const hit = this.memo.get(n);
1792
- if (hit) return hit;
1793
- if (active.size >= this.budget.maxDepth) return null;
1794
- if (this.reads >= this.budget.maxReads) {
1905
+ if (!this.resolved.has(objectNumber)) {
1906
+ const components = this.componentsAbove(objectNumber);
1907
+ for (const component of components ?? []) if (!this.resolveComponent(component)) break;
1908
+ }
1909
+ return this.resolved.get(objectNumber) ?? "incomplete";
1910
+ }
1911
+ readReferrers(n) {
1912
+ const known = this.referrers.get(n);
1913
+ if (known) return known;
1914
+ if (this.exhausted || this.reads >= this.budget.maxReads) {
1795
1915
  this.exhausted = true;
1796
1916
  return null;
1797
1917
  }
1798
1918
  this.reads += 1;
1799
1919
  const raw = this.read(n);
1800
- active.add(n);
1920
+ this.referrers.set(n, raw);
1921
+ return raw;
1922
+ }
1923
+ /** The parents of an object still to be resolved: unchanged, non-structural, not resolved yet. */
1924
+ pendingParents(raw) {
1925
+ const out = /* @__PURE__ */ new Set();
1926
+ for (const e of raw) if (!this.anchors.has(e.parent) && !this.resolved.has(e.parent)) out.add(e.parent);
1927
+ return [...out];
1928
+ }
1929
+ /**
1930
+ * The strongly connected components of the unresolved objects above
1931
+ * `start` (Tarjan's algorithm, iterative), ancestors first; null when the
1932
+ * read budget ran out.
1933
+ */
1934
+ componentsAbove(start) {
1935
+ const index = /* @__PURE__ */ new Map();
1936
+ const low = /* @__PURE__ */ new Map();
1937
+ const stack = [];
1938
+ const onStack = /* @__PURE__ */ new Set();
1939
+ const frames = [];
1940
+ const components = [];
1941
+ const enter = (n) => {
1942
+ const raw = this.readReferrers(n);
1943
+ if (!raw) return false;
1944
+ index.set(n, index.size);
1945
+ low.set(n, index.get(n));
1946
+ stack.push(n);
1947
+ onStack.add(n);
1948
+ frames.push({
1949
+ node: n,
1950
+ parents: this.pendingParents(raw),
1951
+ next: 0
1952
+ });
1953
+ return true;
1954
+ };
1955
+ if (!enter(start)) return null;
1956
+ while (frames.length > 0) {
1957
+ const frame = frames[frames.length - 1];
1958
+ if (frame.next < frame.parents.length) {
1959
+ const p = frame.parents[frame.next++];
1960
+ if (!index.has(p)) {
1961
+ if (!enter(p)) return null;
1962
+ } else if (onStack.has(p)) low.set(frame.node, Math.min(low.get(frame.node), index.get(p)));
1963
+ continue;
1964
+ }
1965
+ frames.pop();
1966
+ const n = frame.node;
1967
+ if (frames.length > 0) {
1968
+ const below = frames[frames.length - 1].node;
1969
+ low.set(below, Math.min(low.get(below), low.get(n)));
1970
+ }
1971
+ if (low.get(n) === index.get(n)) {
1972
+ const component = [];
1973
+ let m;
1974
+ do {
1975
+ m = stack.pop();
1976
+ onStack.delete(m);
1977
+ component.push(m);
1978
+ } while (m !== n);
1979
+ components.push(component);
1980
+ }
1981
+ }
1982
+ return components;
1983
+ }
1984
+ /** Resolve one component whose ancestors are all resolved; false when it exceeded the budget. */
1985
+ resolveComponent(component) {
1986
+ const members = new Set(component);
1987
+ const result = component.length === 1 ? this.edgesOfSingle(component[0]) : this.edgesOfLoop(component, members);
1988
+ if (!result) {
1989
+ for (const n of component) this.resolved.set(n, null);
1990
+ return false;
1991
+ }
1992
+ for (const n of component) this.resolved.set(n, result.get(n));
1993
+ return true;
1994
+ }
1995
+ /** An object outside any loop: its raw edges, each resolved through its parent. */
1996
+ edgesOfSingle(n) {
1801
1997
  const edges = [];
1802
- let cyclic = false;
1803
- try {
1804
- for (const e of raw) {
1805
- if (this.anchors.has(e.parent)) edges.push(e);
1806
- else if (active.has(e.parent)) {
1807
- cyclic = true;
1808
- continue;
1809
- } else {
1810
- const up = this.resolveInner(e.parent, active);
1811
- if (up === null) return null;
1812
- cyclic || (cyclic = up.cyclic);
1813
- for (const u of up.edges) edges.push({
1998
+ for (const e of this.referrers.get(n)) {
1999
+ if (e.parent === n) continue;
2000
+ const through = this.through(e);
2001
+ if (!through) return null;
2002
+ edges.push(...through);
2003
+ }
2004
+ const unique = withoutCollapsedDuplicates(edges);
2005
+ return unique.length > this.budget.maxEdgesPerObject ? null : /* @__PURE__ */ new Map([[n, unique]]);
2006
+ }
2007
+ /**
2008
+ * A loop: every anchored edge into it, as it is at the member it enters
2009
+ * and with the route collapsed at every other member.
2010
+ */
2011
+ edgesOfLoop(component, members) {
2012
+ const entering = /* @__PURE__ */ new Map();
2013
+ const routes = /* @__PURE__ */ new Map();
2014
+ for (const s of component) {
2015
+ const own = [];
2016
+ for (const e of this.referrers.get(s)) {
2017
+ if (members.has(e.parent)) continue;
2018
+ const through = this.through(e);
2019
+ if (!through) return null;
2020
+ for (const u of through) {
2021
+ own.push(u);
2022
+ const via = [...u.via ?? [], s];
2023
+ if (via.length >= this.budget.maxDepth) return null;
2024
+ const route = {
1814
2025
  parent: u.parent,
1815
- label: `${u.label}/${e.label}`,
1816
- via: [...u.via ?? [], e.parent]
1817
- });
2026
+ label: `${u.label}/${LOOP_ROUTE}`,
2027
+ via
2028
+ };
2029
+ const known = routes.get(edgeKey(route));
2030
+ if (!known) routes.set(edgeKey(route), [route]);
2031
+ else if (known.length === 1 && entryOf(known[0]) !== s) known.push(route);
1818
2032
  }
1819
- if (edges.length > this.budget.maxEdgesPerObject) return null;
2033
+ if (own.length > this.budget.maxEdgesPerObject) return null;
1820
2034
  }
1821
- } finally {
1822
- active.delete(n);
2035
+ if (own.length > 0) entering.set(s, withoutCollapsedDuplicates(own));
1823
2036
  }
1824
- const resolution = {
1825
- edges,
1826
- cyclic
1827
- };
1828
- if (!cyclic) this.memo.set(n, resolution);
1829
- return resolution;
2037
+ if (routes.size > this.budget.maxEdgesPerObject) return null;
2038
+ const out = /* @__PURE__ */ new Map();
2039
+ const toAny = [...routes.values()].map((entries) => entries[0]);
2040
+ for (const n of component) {
2041
+ const own = entering.get(n);
2042
+ if (!own) {
2043
+ out.set(n, toAny);
2044
+ continue;
2045
+ }
2046
+ const toThis = [];
2047
+ for (const entries of routes.values()) {
2048
+ const route = entries.find((r) => entryOf(r) !== n);
2049
+ if (route) toThis.push(route);
2050
+ }
2051
+ const edges = [...own, ...toThis];
2052
+ if (edges.length > this.budget.maxEdgesPerObject) return null;
2053
+ out.set(n, edges);
2054
+ }
2055
+ return out;
2056
+ }
2057
+ /** The anchored edges one raw edge stands for; null when its parent exceeded the budget. */
2058
+ through(e) {
2059
+ if (this.anchors.has(e.parent)) return [e];
2060
+ const above = this.resolved.get(e.parent);
2061
+ if (!above) return null;
2062
+ const out = [];
2063
+ for (const u of above) {
2064
+ const via = [...u.via ?? [], e.parent];
2065
+ if (via.length >= this.budget.maxDepth) return null;
2066
+ out.push({
2067
+ parent: u.parent,
2068
+ label: `${u.label}/${e.label}`,
2069
+ via
2070
+ });
2071
+ }
2072
+ return out;
1830
2073
  }
1831
2074
  };
2075
+ function edgeKey(e) {
2076
+ return `${e.parent}:${e.label}`;
2077
+ }
2078
+ /** The member a collapsed route enters its loop at: the last object it was resolved through. */
2079
+ function entryOf(route) {
2080
+ return route.via[route.via.length - 1];
2081
+ }
2082
+ /** Edges whose label collapses a route are told apart by anchor and label alone. */
2083
+ function withoutCollapsedDuplicates(edges) {
2084
+ const seen = /* @__PURE__ */ new Set();
2085
+ return edges.filter((e) => {
2086
+ if (!e.label.includes(LOOP_ROUTE)) return true;
2087
+ const key = edgeKey(e);
2088
+ if (seen.has(key)) return false;
2089
+ seen.add(key);
2090
+ return true;
2091
+ });
2092
+ }
1832
2093
  //#endregion
1833
2094
  //#region src/search/types.ts
1834
2095
  /** The query part of a request (or of any object that carries one): its text and flags, set flags only. */
@@ -2030,6 +2291,12 @@ function finish(h1, h2) {
2030
2291
  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
2031
2292
  }
2032
2293
  //#endregion
2294
+ //#region src/mutation/OutlineMutationResults.ts
2295
+ /** What a delete removed, as its `outline.deleted` event names it: the item first. */
2296
+ function deletedOutlineItemsOf(result) {
2297
+ return result.meta.changed;
2298
+ }
2299
+ //#endregion
2033
2300
  //#region src/auth/scope/pdf-bits.ts
2034
2301
  /**
2035
2302
  * ISO 32000 user-access permission bit positions, expressed as integer
@@ -2234,6 +2501,6 @@ function fieldCapability(action) {
2234
2501
  return action === "fill" ? "doc.forms.fill" : "doc.sign";
2235
2502
  }
2236
2503
  //#endregion
2237
- export { pageListOf as $, sameEffectiveValue as A, refsOf as B, searchQueryOf as C, restrictionsFor as D, USAGE_INCOMPLETE as E, worstVerdict as F, pageFormFieldOf as G, placedWidgetOf as H, changedKeys as I, pdfFormFieldDraftOf as J, pageFormSnapshotOf as K, dictEntries as L, combine as M, conclude as N, evaluateStep as O, primaryFinding as P, pageLayoutOf as Q, parsePdfValue as R, matchPageText as S, EdgeResolver as T, draftWritesScripts as U, stableStringify as V, pageFieldActionsOf as W, pageAppearancesOf as X, pdfWidgetPlacementOf as Y, pdfRenderTargetOf as Z, opIdOf as _, DEFAULT_MEDIA_BOX as _t, annotationWriteCapability as a, concatAnnotationLists as at, SEARCH_SNIPPET_CONTEXT as b, authorizeAnnotationUpdate as c, normalizeAttachmentFileSource as ct, authorizeFieldWrite as d, generateUuidV7 as dt, pageSpaceBoxesOf as et, authorizeUnprotected as f, DEFAULT_PDF_SAVE_MODE as ft, isKeptRefusal as g, resolvePageLayers as gt, changeFingerprint as h, imageSourceOfBytes as ht, annotationWriteCapabilities as i, deletedAnnotationsOf as it, assessmentOf as j, restrictionsOf as k, authorizeCapability as l, familyOfSubtype as lt, decodePdfBits as m, createPageImageHandle as mt, allowsFieldWrite as n, annotationPatchBetween as nt, authorizeAnnotationCreate as o, closeExportSelection as ot, PDF_BITS as p, checkImageQuality as pt, pageWidgetOf as q, allowsSomeFieldWrite as r, mergeAnnotationPatch as rt, authorizeAnnotationDelete as s, annotationImportFacts as st, allowsCapability as t, visibleBoxesOf as tt, authorizeFieldGroup as u, generateUuid as ut, canonicalSearchQuery as v, pageBoxesOf as vt, DEFAULT_EDGE_RESOLVER_BUDGET as w, buildSnippet as x, searchContentEpoch as y, pageRotationOf as yt, pdfValueEquals as z };
2504
+ export { pageWidgetOf as $, restrictionsOf as A, pdfValueEquals as B, matchPageText as C, imageSourceOfBytes as Ct, USAGE_INCOMPLETE as D, pageBoxesOf as Dt, EdgeResolver as E, DEFAULT_MEDIA_BOX as Et, primaryFinding as F, mapOutlineItem as G, stableStringify as H, worstVerdict as I, pdfOutlineDraftOf as J, pageOutlineItemOf as K, changedKeys as L, assessmentOf as M, combine as N, restrictionsFor as O, pageRotationOf as Ot, conclude as P, pageFormSnapshotOf as Q, dictEntries as R, buildSnippet as S, createPageImageHandle as St, DEFAULT_EDGE_RESOLVER_BUDGET as T, resolvePageLayers as Tt, placedWidgetOf as U, refsOf as V, draftWritesScripts as W, pageFieldActionsOf as X, pdfOutlinePatchOf as Y, pageFormFieldOf as Z, isKeptRefusal as _, generateUuidV7 as _t, annotationWriteCapability as a, pageListOf as at, searchContentEpoch as b, checkImageQuality as bt, authorizeAnnotationUpdate as c, annotationPatchBetween as ct, authorizeFieldWrite as d, concatAnnotationLists as dt, pdfFormFieldDraftOf as et, authorizeUnprotected as f, closeExportSelection as ft, changeFingerprint as g, generateUuid as gt, deletedOutlineItemsOf as h, familyOfSubtype as ht, annotationWriteCapabilities as i, pageLayoutOf as it, sameEffectiveValue as j, evaluateStep as k, authorizeCapability as l, mergeAnnotationPatch as lt, decodePdfBits as m, normalizeAttachmentFileSource as mt, allowsFieldWrite as n, pageAppearancesOf as nt, authorizeAnnotationCreate as o, pageSpaceBoxesOf as ot, PDF_BITS as p, annotationImportFacts as pt, pageOutlineOf as q, allowsSomeFieldWrite as r, pdfRenderTargetOf as rt, authorizeAnnotationDelete as s, visibleBoxesOf as st, allowsCapability as t, pdfWidgetPlacementOf as tt, authorizeFieldGroup as u, deletedAnnotationsOf as ut, opIdOf as v, DEFAULT_PDF_SAVE_MODE as vt, searchQueryOf as w, printDpiOf as wt, SEARCH_SNIPPET_CONTEXT as x, checkRenderUsage as xt, canonicalSearchQuery as y, resolvePageExtract as yt, parsePdfValue as z };
2238
2505
 
2239
- //# sourceMappingURL=authority-B3BklsB4.js.map
2506
+ //# sourceMappingURL=authority-PuxpGFhJ.js.map