@embedpdf/core-acrojs 3.0.0-next.10 → 3.0.0-next.11

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.
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ function javaScriptSourcesFromActionTree(tree) {
7
7
  if (tree.incomplete) throw new Error("Refusing to execute an incomplete PDF action tree");
8
8
  const sources = [];
9
9
  const visit = (node) => {
10
- if (node.type === "javascript" && node.script !== void 0) sources.push(node.script);
10
+ if (node.type === "javascript") sources.push(node.script);
11
11
  for (const child of node.next) visit(child);
12
12
  };
13
13
  if (tree.root) visit(tree.root);
@@ -18,6 +18,324 @@ function javaScriptProgramFromActionTree(tree) {
18
18
  return javaScriptSourcesFromActionTree(tree).join("\n;\n");
19
19
  }
20
20
  //#endregion
21
+ //#region src/color.ts
22
+ /**
23
+ * Host-side Acrobat color-array conversions — the commit sinks and world
24
+ * builders cross the Acrobat-array ↔ renderer-color boundary through these.
25
+ * The PRELUDE inlines its own identical formulas (it must stay
26
+ * self-contained); `prelude.test.ts` pins the two implementations together.
27
+ *
28
+ * Conversion vectors (the documented Acrobat semantics):
29
+ * G → RGB: replicate the gray component.
30
+ * CMYK → RGB: component = 1 − min(1, channel + k).
31
+ * RGB → G: luminosity 0.3r + 0.59g + 0.11b.
32
+ * RGB → CMYK: k = 1 − max(r,g,b); channels = 1 − component − k.
33
+ * T (transparent) converts to itself only.
34
+ */
35
+ function scriptColorToRgb(color) {
36
+ switch (color[0]) {
37
+ case "T": return null;
38
+ case "G": return {
39
+ r: color[1],
40
+ g: color[1],
41
+ b: color[1]
42
+ };
43
+ case "RGB": return {
44
+ r: color[1],
45
+ g: color[2],
46
+ b: color[3]
47
+ };
48
+ case "CMYK": {
49
+ const [, c, m, y, k] = color;
50
+ return {
51
+ r: 1 - Math.min(1, c + k),
52
+ g: 1 - Math.min(1, m + k),
53
+ b: 1 - Math.min(1, y + k)
54
+ };
55
+ }
56
+ }
57
+ }
58
+ const clamp01 = (value) => Math.min(1, Math.max(0, value));
59
+ const hex = (value) => Math.round(clamp01(value) * 255).toString(16).padStart(2, "0");
60
+ /** Acrobat array → CSS hex, or null for transparent. */
61
+ function scriptColorToCss(color) {
62
+ const rgb = scriptColorToRgb(color);
63
+ return rgb === null ? null : `#${hex(rgb.r)}${hex(rgb.g)}${hex(rgb.b)}`;
64
+ }
65
+ /** CSS hex (#rgb/#rrggbb) → Acrobat RGB array; null/undefined → transparent. */
66
+ function cssToScriptColor(css) {
67
+ if (!css) return ["T"];
68
+ const raw = css.trim().replace(/^#/, "");
69
+ const long = raw.length === 3 ? raw.split("").map((ch) => ch + ch).join("") : raw;
70
+ if (!/^[0-9a-fA-F]{6}$/.test(long)) return ["T"];
71
+ const channel = (offset) => parseInt(long.slice(offset, offset + 2), 16) / 255;
72
+ return [
73
+ "RGB",
74
+ channel(0),
75
+ channel(2),
76
+ channel(4)
77
+ ];
78
+ }
79
+ /** Structural validation for values scripts assign. */
80
+ function isScriptColorArray(value) {
81
+ if (!Array.isArray(value) || value.length === 0) return false;
82
+ const [space, ...parts] = value;
83
+ const expected = {
84
+ T: 0,
85
+ G: 1,
86
+ RGB: 3,
87
+ CMYK: 4
88
+ }[String(space)];
89
+ return expected !== void 0 && parts.length === expected && parts.every((part) => typeof part === "number" && Number.isFinite(part));
90
+ }
91
+ //#endregion
92
+ //#region src/types.ts
93
+ /**
94
+ * The writable-property validity matrix, keyed by engine subtype — the ONE
95
+ * exported table (the prelude inlines an identical copy; a parity test pins
96
+ * them together, and plugin-annotation drift-guards this against the kind
97
+ * registry's PropSpecs). Flags + contents are writable everywhere
98
+ * script-addressable; appearance keys vary by kind.
99
+ */
100
+ const ANNOT_WRITABLE_KEYS = Object.freeze({
101
+ square: [
102
+ "strokeColor",
103
+ "fillColor",
104
+ "opacity",
105
+ "width",
106
+ "borderStyle",
107
+ "dash",
108
+ "rect"
109
+ ],
110
+ circle: [
111
+ "strokeColor",
112
+ "fillColor",
113
+ "opacity",
114
+ "width",
115
+ "borderStyle",
116
+ "dash",
117
+ "rect"
118
+ ],
119
+ polygon: [
120
+ "strokeColor",
121
+ "fillColor",
122
+ "opacity",
123
+ "width",
124
+ "borderStyle",
125
+ "dash",
126
+ "rect"
127
+ ],
128
+ polyline: [
129
+ "strokeColor",
130
+ "fillColor",
131
+ "opacity",
132
+ "width",
133
+ "borderStyle",
134
+ "dash",
135
+ "rect"
136
+ ],
137
+ line: [
138
+ "strokeColor",
139
+ "fillColor",
140
+ "opacity",
141
+ "width",
142
+ "borderStyle",
143
+ "dash",
144
+ "rect"
145
+ ],
146
+ ink: [
147
+ "strokeColor",
148
+ "opacity",
149
+ "width",
150
+ "rect"
151
+ ],
152
+ "free-text": [
153
+ "strokeColor",
154
+ "fillColor",
155
+ "opacity",
156
+ "rect"
157
+ ],
158
+ highlight: ["strokeColor", "opacity"],
159
+ underline: ["strokeColor", "opacity"],
160
+ squiggly: ["strokeColor", "opacity"],
161
+ strikeout: ["strokeColor", "opacity"],
162
+ caret: ["strokeColor", "opacity"],
163
+ text: [
164
+ "strokeColor",
165
+ "opacity",
166
+ "rect"
167
+ ],
168
+ stamp: ["rect"],
169
+ "file-attachment": ["strokeColor", "opacity"]
170
+ });
171
+ const DEFAULT_SCRIPT_BUDGET = Object.freeze({
172
+ maxExecutionMs: 50,
173
+ maxMemoryBytes: 16 * 1024 * 1024,
174
+ maxStackBytes: 512 * 1024,
175
+ maxEffects: 256,
176
+ maxOutputBytes: 1024 * 1024
177
+ });
178
+ const DEFAULT_SCRIPT_SECURITY_POLICY = Object.freeze({
179
+ enabled: false,
180
+ executionOwner: "originating-client-only",
181
+ nameTreeBoot: "lazy-first-transaction",
182
+ submitForm: "sink-chain",
183
+ openAction: "execute-lifecycle",
184
+ pageActions: "execute-lifecycle",
185
+ catalogLifecycleActions: "execute-on-verb",
186
+ annotationActions: "execute-full-matrix"
187
+ });
188
+ /** The shipped dispatch matrix; extracted actions outside it remain data
189
+ * only. (Historical note: v1 froze everything beyond K/V/C/F as
190
+ * preserve-only; phases 1–4 executed the rest.) */
191
+ const SCRIPT_EVENT_MATRIX = Object.freeze({
192
+ nameTree: "lazy-first-originating-field-transaction",
193
+ field: Object.freeze({
194
+ keystroke: "execute-on-commit",
195
+ validate: "execute",
196
+ calculate: "execute-in-calculation-order",
197
+ format: "execute-after-value-calculation"
198
+ }),
199
+ openAction: "execute-lifecycle",
200
+ page: "execute-lifecycle",
201
+ catalogLifecycle: "execute-on-verb",
202
+ annotation: Object.freeze({
203
+ widgetActivate: "execute-on-originating-client",
204
+ other: "execute-full-matrix"
205
+ }),
206
+ submitForm: "sink-chain"
207
+ });
208
+ //#endregion
209
+ //#region src/host.ts
210
+ /** FNV-1a over `documentId:sequence` — the deterministic default random seed
211
+ * (ported verbatim from the form controller; exported for callers building
212
+ * `ScriptHostOptions.environment`). */
213
+ function seedFrom(documentId, sequence) {
214
+ let hash = 2166136261;
215
+ for (const char of `${documentId}:${sequence}`) {
216
+ hash ^= char.charCodeAt(0);
217
+ hash = Math.imul(hash, 16777619);
218
+ }
219
+ return hash >>> 0;
220
+ }
221
+ /** Engine JWT/session identity composed under embedder overrides — the
222
+ * standard `ScriptHostOptions.identity` builder. */
223
+ function resolveScriptIdentity(doc, overrides) {
224
+ const claims = doc.security.identity;
225
+ const supplied = typeof overrides === "function" ? overrides() : overrides ?? {};
226
+ return {
227
+ name: supplied.name ?? claims?.display_name ?? claims?.user_id ?? "",
228
+ loginName: supplied.loginName ?? claims?.user_id ?? "",
229
+ corporation: supplied.corporation ?? claims?.group_id ?? "",
230
+ email: supplied.email ?? ""
231
+ };
232
+ }
233
+ function createScriptHost(options) {
234
+ const budget = options.budget ?? DEFAULT_SCRIPT_BUDGET;
235
+ let tail = Promise.resolve();
236
+ const enqueue = (operation) => {
237
+ const result = tail.then(operation, operation);
238
+ tail = result.then(() => void 0, () => void 0);
239
+ return result;
240
+ };
241
+ let sandboxPromise = null;
242
+ let booted = false;
243
+ let pendingBoot = null;
244
+ let bootSourcesCache = null;
245
+ let sequence = 0;
246
+ let disposed = false;
247
+ const ensureSandbox = () => {
248
+ sandboxPromise ?? (sandboxPromise = options.sandboxFactory());
249
+ return sandboxPromise;
250
+ };
251
+ const inputFor = (world) => ({
252
+ document: {
253
+ ...options.document(),
254
+ ...world.pageNumber !== void 0 ? { pageNumber: world.pageNumber } : {}
255
+ },
256
+ identity: options.identity(),
257
+ environment: options.environment(sequence++),
258
+ fields: world.fields,
259
+ ...world.annots ? { annots: world.annots } : {},
260
+ ...world.annotPages ? { annotPages: world.annotPages } : {},
261
+ ...world.annotsCoverDocument !== void 0 ? { annotsCoverDocument: world.annotsCoverDocument } : {},
262
+ event: world.event
263
+ });
264
+ /** A resource fault poisons the realm: rebuild + re-boot lazily NEXT time. */
265
+ const noteFault = (sandbox) => {
266
+ if (!sandbox.disposed) return;
267
+ sandboxPromise = null;
268
+ booted = false;
269
+ pendingBoot = null;
270
+ };
271
+ const bootNow = async (world, runBudget) => {
272
+ if (booted) return null;
273
+ booted = true;
274
+ const sandbox = await ensureSandbox();
275
+ bootSourcesCache ?? (bootSourcesCache = options.bootSources());
276
+ let sources = [];
277
+ try {
278
+ sources = await bootSourcesCache;
279
+ } catch (error) {
280
+ bootSourcesCache = null;
281
+ return {
282
+ event: {
283
+ rc: true,
284
+ value: null,
285
+ change: "",
286
+ selStart: 0,
287
+ selEnd: 0
288
+ },
289
+ formEffects: [],
290
+ annotEffects: [],
291
+ uiEffects: [],
292
+ diagnostics: [{
293
+ code: "script-error",
294
+ message: `Document boot script failed (continuing without it): ${error instanceof Error ? error.message : String(error)}`
295
+ }]
296
+ };
297
+ }
298
+ if (sources.length === 0) return null;
299
+ const output = sandbox.boot(sources, inputFor({
300
+ ...world,
301
+ event: { kind: "name-tree-boot" }
302
+ }), runBudget ?? budget);
303
+ noteFault(sandbox);
304
+ return output;
305
+ };
306
+ const runNow = async (program, world, runBudget) => {
307
+ if (!booted) pendingBoot = await bootNow(world, runBudget);
308
+ const sandbox = await ensureSandbox();
309
+ const output = sandbox.run(program, inputFor(world), runBudget ?? budget);
310
+ noteFault(sandbox);
311
+ return output;
312
+ };
313
+ return {
314
+ transaction(body) {
315
+ if (disposed) return Promise.reject(/* @__PURE__ */ new Error("script host is disposed"));
316
+ return enqueue(() => body({
317
+ boot: async (world, runBudget) => {
318
+ if (pendingBoot) {
319
+ const output = pendingBoot;
320
+ pendingBoot = null;
321
+ return output;
322
+ }
323
+ return bootNow(world, runBudget);
324
+ },
325
+ run: (program, world, runBudget) => runNow(program, world, runBudget)
326
+ }));
327
+ },
328
+ dispose() {
329
+ disposed = true;
330
+ const dying = sandboxPromise;
331
+ sandboxPromise = null;
332
+ booted = false;
333
+ pendingBoot = null;
334
+ dying?.then((sandbox) => sandbox.dispose()).catch(() => void 0);
335
+ }
336
+ };
337
+ }
338
+ //#endregion
21
339
  //#region src/input.ts
22
340
  function valueFromEntry(entry) {
23
341
  switch (entry.kind) {
@@ -145,6 +463,242 @@ function installAcroJs(g) {
145
463
  return wrapper;
146
464
  };
147
465
  const getField = (name) => state?.fieldsByName.get(String(name))?.wrapper ?? null;
466
+ const ANNOT_WRITABLE = {
467
+ square: [
468
+ "strokeColor",
469
+ "fillColor",
470
+ "opacity",
471
+ "width",
472
+ "borderStyle",
473
+ "dash",
474
+ "rect"
475
+ ],
476
+ circle: [
477
+ "strokeColor",
478
+ "fillColor",
479
+ "opacity",
480
+ "width",
481
+ "borderStyle",
482
+ "dash",
483
+ "rect"
484
+ ],
485
+ polygon: [
486
+ "strokeColor",
487
+ "fillColor",
488
+ "opacity",
489
+ "width",
490
+ "borderStyle",
491
+ "dash",
492
+ "rect"
493
+ ],
494
+ polyline: [
495
+ "strokeColor",
496
+ "fillColor",
497
+ "opacity",
498
+ "width",
499
+ "borderStyle",
500
+ "dash",
501
+ "rect"
502
+ ],
503
+ line: [
504
+ "strokeColor",
505
+ "fillColor",
506
+ "opacity",
507
+ "width",
508
+ "borderStyle",
509
+ "dash",
510
+ "rect"
511
+ ],
512
+ ink: [
513
+ "strokeColor",
514
+ "opacity",
515
+ "width",
516
+ "rect"
517
+ ],
518
+ "free-text": [
519
+ "strokeColor",
520
+ "fillColor",
521
+ "opacity",
522
+ "rect"
523
+ ],
524
+ highlight: ["strokeColor", "opacity"],
525
+ underline: ["strokeColor", "opacity"],
526
+ squiggly: ["strokeColor", "opacity"],
527
+ strikeout: ["strokeColor", "opacity"],
528
+ caret: ["strokeColor", "opacity"],
529
+ text: [
530
+ "strokeColor",
531
+ "opacity",
532
+ "rect"
533
+ ],
534
+ stamp: ["rect"],
535
+ "file-attachment": ["strokeColor", "opacity"]
536
+ };
537
+ const ANNOT_FLAG_KEYS = [
538
+ "hidden",
539
+ "print",
540
+ "readOnly",
541
+ "locked",
542
+ "noView",
543
+ "toggleNoView"
544
+ ];
545
+ const ACROBAT_TYPE = {
546
+ square: "Square",
547
+ circle: "Circle",
548
+ line: "Line",
549
+ polygon: "Polygon",
550
+ polyline: "PolyLine",
551
+ ink: "Ink",
552
+ "free-text": "FreeText",
553
+ highlight: "Highlight",
554
+ underline: "Underline",
555
+ squiggly: "Squiggly",
556
+ strikeout: "StrikeOut",
557
+ text: "Text",
558
+ stamp: "Stamp",
559
+ caret: "Caret",
560
+ "file-attachment": "FileAttachment"
561
+ };
562
+ const isColorArray = (value) => {
563
+ if (!Array.isArray(value) || value.length === 0) return false;
564
+ const expected = {
565
+ T: 0,
566
+ G: 1,
567
+ RGB: 3,
568
+ CMYK: 4
569
+ }[String(value[0])];
570
+ return expected !== void 0 && value.length === expected + 1 && value.slice(1).every((part) => typeof part === "number" && isFinite(Number(part)));
571
+ };
572
+ const colorToRgbTriple = (value) => {
573
+ const color = value;
574
+ const space = String(color[0]);
575
+ if (space === "T") return null;
576
+ if (space === "G") return [
577
+ Number(color[1]),
578
+ Number(color[1]),
579
+ Number(color[1])
580
+ ];
581
+ if (space === "RGB") return [
582
+ Number(color[1]),
583
+ Number(color[2]),
584
+ Number(color[3])
585
+ ];
586
+ const c = Number(color[1]);
587
+ const m = Number(color[2]);
588
+ const y = Number(color[3]);
589
+ const k = Number(color[4]);
590
+ return [
591
+ 1 - Math.min(1, c + k),
592
+ 1 - Math.min(1, m + k),
593
+ 1 - Math.min(1, y + k)
594
+ ];
595
+ };
596
+ const sameAnnotValue = (a, b) => {
597
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, index) => item === b[index]);
598
+ return a === b;
599
+ };
600
+ const cloneAnnotValue = (value) => Array.isArray(value) ? [...value] : value;
601
+ const makeAnnot = (record) => {
602
+ const input = record.input;
603
+ const subtype = String(input.subtype);
604
+ const writable = ANNOT_WRITABLE[subtype] ?? [];
605
+ const wrapper = {};
606
+ const stage = (key, value, validate) => {
607
+ if (key !== "contents" && ANNOT_FLAG_KEYS.indexOf(key) < 0 && writable.indexOf(key) < 0) {
608
+ diagnostic("unsupported-api", `Annot.${key} is not writable on subtype '${subtype}' (write ignored)`);
609
+ return;
610
+ }
611
+ if (input.opaqueBody && ANNOT_FLAG_KEYS.indexOf(key) < 0 && key !== "contents") {
612
+ diagnostic("unsupported-api", `Annot.${key}: '${subtype}' has an opaque appearance (write ignored)`);
613
+ return;
614
+ }
615
+ if (!validate(value)) {
616
+ diagnostic("invalid-field-value", `Annot.${key}: invalid value (write ignored)`);
617
+ return;
618
+ }
619
+ record.current[key] = cloneAnnotValue(value);
620
+ };
621
+ const prop = (key, validate) => ({
622
+ enumerable: true,
623
+ get: () => cloneAnnotValue(record.current[key]),
624
+ set: (value) => stage(key, value, validate)
625
+ });
626
+ const isNum = (v) => typeof v === "number" && isFinite(v);
627
+ const isBool = (v) => typeof v === "boolean";
628
+ Object.defineProperties(wrapper, {
629
+ name: {
630
+ enumerable: true,
631
+ get: () => String(input.name ?? "")
632
+ },
633
+ type: {
634
+ enumerable: true,
635
+ get: () => ACROBAT_TYPE[subtype] ?? subtype
636
+ },
637
+ page: {
638
+ enumerable: true,
639
+ get: () => Number(input.page ?? 0)
640
+ },
641
+ author: {
642
+ enumerable: true,
643
+ get: () => String(input.author ?? "")
644
+ },
645
+ subject: {
646
+ enumerable: true,
647
+ get: () => String(input.subject ?? "")
648
+ },
649
+ strokeColor: prop("strokeColor", isColorArray),
650
+ fillColor: prop("fillColor", isColorArray),
651
+ opacity: prop("opacity", (v) => isNum(v) && Number(v) >= 0 && Number(v) <= 1),
652
+ width: prop("width", (v) => isNum(v) && Number(v) >= 0),
653
+ style: prop("borderStyle", (v) => v === "S" || v === "D"),
654
+ dash: prop("dash", (v) => Array.isArray(v) && v.every(isNum)),
655
+ rect: prop("rect", (v) => Array.isArray(v) && v.length === 4 && v.every(isNum)),
656
+ contents: prop("contents", (v) => typeof v === "string"),
657
+ hidden: prop("hidden", isBool),
658
+ print: prop("print", isBool),
659
+ readOnly: prop("readOnly", isBool),
660
+ lock: prop("locked", isBool),
661
+ noView: prop("noView", isBool),
662
+ toggleNoView: prop("toggleNoView", isBool),
663
+ doc: {
664
+ enumerable: false,
665
+ get: () => doc
666
+ }
667
+ });
668
+ wrapper.getProps = () => {
669
+ const out = {};
670
+ for (const key of Object.keys(record.current)) out[key] = cloneAnnotValue(record.current[key]);
671
+ return out;
672
+ };
673
+ wrapper.setProps = (props) => {
674
+ const source = props ?? {};
675
+ for (const key of Object.keys(source)) wrapper[key] = source[key];
676
+ };
677
+ return wrapper;
678
+ };
679
+ const getAnnots = (spec) => {
680
+ if (!state) return null;
681
+ const nPage = spec?.nPage;
682
+ if (nPage === void 0 || nPage === null) {
683
+ if (!state.annotsCoverDocument) diagnostic("unsupported-api", "getAnnots: whole-document search is limited to the prefetched pages (compatibility deviation)");
684
+ return state.annots.length ? state.annots.map((record) => record.wrapper) : null;
685
+ }
686
+ const page = Math.trunc(Number(nPage));
687
+ if (!state.annotPages.has(page)) {
688
+ diagnostic("unsupported-api", `getAnnots: page ${page} is outside the prefetched annots plane (compatibility deviation)`);
689
+ return null;
690
+ }
691
+ const records = state.annotsByPage.get(page) ?? [];
692
+ return records.length ? records.map((record) => record.wrapper) : null;
693
+ };
694
+ const getAnnot = (nPage, name) => {
695
+ const records = getAnnots({ nPage });
696
+ if (!records) return null;
697
+ for (const wrapper of records) if (String(wrapper.name) === String(name)) return wrapper;
698
+ return null;
699
+ };
700
+ doc.getAnnots = getAnnots;
701
+ doc.getAnnot = getAnnot;
148
702
  Object.defineProperties(doc, {
149
703
  documentFileName: {
150
704
  enumerable: true,
@@ -181,7 +735,26 @@ function installAcroJs(g) {
181
735
  }
182
736
  };
183
737
  doc.print = () => state?.uiEffects.push({ kind: "print" });
184
- doc.submitForm = () => blocked("submitForm");
738
+ doc.submitForm = (cUrlOrArgs, bFDF, bEmpty, aFields) => {
739
+ if (!state) return;
740
+ const args = cUrlOrArgs !== null && typeof cUrlOrArgs === "object" ? cUrlOrArgs : {
741
+ cURL: cUrlOrArgs,
742
+ bFDF,
743
+ bEmpty,
744
+ aFields
745
+ };
746
+ const names = Array.isArray(args.aFields) ? args.aFields.map((name) => String(name)) : null;
747
+ const submitAs = args.cSubmitAs === void 0 ? void 0 : String(args.cSubmitAs).toUpperCase();
748
+ const format = submitAs === "FDF" ? "fdf" : submitAs === "XFDF" ? "xfdf" : submitAs === "HTML" ? "html" : submitAs === "PDF" ? "pdf" : args.bFDF === false ? "html" : void 0;
749
+ state.uiEffects.push({
750
+ kind: "submitForm",
751
+ url: args.cURL === void 0 || args.cURL === null ? null : String(args.cURL),
752
+ fieldNames: names,
753
+ includeEmpty: Boolean(args.bEmpty),
754
+ ...format === void 0 ? {} : { format },
755
+ ...args.bGet === void 0 ? {} : { method: args.bGet ? "get" : "post" }
756
+ });
757
+ };
185
758
  doc.mailDoc = () => blocked("mailDoc");
186
759
  doc.getURL = () => blocked("getURL");
187
760
  const app = {
@@ -249,6 +822,7 @@ function installAcroJs(g) {
249
822
  const hour = local.getUTCHours();
250
823
  const minute = local.getUTCMinutes();
251
824
  const second = local.getUTCSeconds();
825
+ const hour12 = hour % 12 === 0 ? 12 : hour % 12;
252
826
  const tokens = {
253
827
  yyyy: String(year),
254
828
  yy: pad(year % 100),
@@ -259,12 +833,15 @@ function installAcroJs(g) {
259
833
  dd: pad(day),
260
834
  d: String(day),
261
835
  HH: pad(hour),
836
+ hh: pad(hour12),
837
+ h: String(hour12),
262
838
  H: String(hour),
263
839
  MM: pad(minute),
264
840
  M: String(minute),
265
- ss: pad(second)
841
+ ss: pad(second),
842
+ tt: hour < 12 ? "am" : "pm"
266
843
  };
267
- return String(format).replace(/yyyy|mmmm|mmm|yy|mm|dd|HH|MM|ss|m|d|H|M/g, (token) => tokens[token]);
844
+ return String(format).replace(/yyyy|mmmm|mmm|yy|mm|dd|HH|hh|MM|ss|tt|m|d|H|h|M/g, (token) => tokens[token]);
268
845
  };
269
846
  const util = {
270
847
  printd,
@@ -294,14 +871,53 @@ function installAcroJs(g) {
294
871
  });
295
872
  const fieldsByName = new Map(fields.map((field) => [String(field.input.name), field]));
296
873
  const fieldsByRef = new Map(fields.map((field) => [refKey(field.input.ref), field]));
874
+ const annots = (input.annots ?? []).map((annot) => {
875
+ const writableSnapshot = () => ({
876
+ strokeColor: cloneAnnotValue(annot.strokeColor ?? ["T"]),
877
+ fillColor: cloneAnnotValue(annot.fillColor ?? ["T"]),
878
+ opacity: Number(annot.opacity ?? 1),
879
+ width: Number(annot.width ?? 1),
880
+ borderStyle: String(annot.borderStyle ?? "S"),
881
+ dash: cloneAnnotValue(annot.dash ?? []),
882
+ rect: cloneAnnotValue(annot.rect ?? [
883
+ 0,
884
+ 0,
885
+ 0,
886
+ 0
887
+ ]),
888
+ contents: String(annot.contents ?? ""),
889
+ hidden: Boolean(annot.hidden),
890
+ print: Boolean(annot.print),
891
+ readOnly: Boolean(annot.readOnly),
892
+ locked: Boolean(annot.locked),
893
+ noView: Boolean(annot.noView),
894
+ toggleNoView: Boolean(annot.toggleNoView)
895
+ });
896
+ const record = {
897
+ input: annot,
898
+ original: writableSnapshot(),
899
+ current: writableSnapshot(),
900
+ wrapper: {}
901
+ };
902
+ record.wrapper = makeAnnot(record);
903
+ return record;
904
+ });
905
+ const annotsByPage = /* @__PURE__ */ new Map();
906
+ for (const record of annots) {
907
+ const page = Number(record.input.page ?? 0);
908
+ const bucket = annotsByPage.get(page);
909
+ if (bucket) bucket.push(record);
910
+ else annotsByPage.set(page, [record]);
911
+ }
297
912
  const eventInput = input.event ?? {};
298
913
  const target = fieldsByRef.get(refKey(eventInput.target));
299
914
  const source = fieldsByRef.get(refKey(eventInput.source));
300
915
  const initialValue = eventInput.value !== void 0 ? cloneValue(eventInput.value) : cloneValue(target?.value ?? null);
916
+ const eventType = eventInput.type !== void 0 ? String(eventInput.type) : eventInput.kind === "name-tree-boot" ? "Doc" : "Field";
301
917
  const event = {
302
- name: eventName(String(eventInput.kind ?? "")),
303
- type: eventInput.kind === "name-tree-boot" ? "Doc" : "Field",
304
- target: target?.wrapper ?? null,
918
+ name: eventInput.name !== void 0 ? String(eventInput.name) : eventName(String(eventInput.kind ?? "")),
919
+ type: eventType,
920
+ target: target?.wrapper ?? (eventType === "Doc" ? doc : null),
305
921
  targetName: String(target?.input.name ?? ""),
306
922
  source: source?.wrapper ?? { source: doc },
307
923
  value: initialValue,
@@ -318,6 +934,10 @@ function installAcroJs(g) {
318
934
  fields,
319
935
  fieldsByName,
320
936
  fieldsByRef,
937
+ annots,
938
+ annotsByPage,
939
+ annotPages: new Set((input.annotPages ?? []).map((page) => Math.trunc(Number(page)))),
940
+ annotsCoverDocument: Boolean(input.annotsCoverDocument),
321
941
  event,
322
942
  resetRefs: [],
323
943
  resetKeys: /* @__PURE__ */ new Set(),
@@ -390,10 +1010,26 @@ function installAcroJs(g) {
390
1010
  ref: target.input.ref,
391
1011
  text: String(state.event.value ?? "")
392
1012
  });
393
- const totalEffects = formEffects.length + state.uiEffects.length;
1013
+ const annotEffects = [];
1014
+ for (const record of state.annots) {
1015
+ const patch = {};
1016
+ const flags = {};
1017
+ for (const key of Object.keys(record.current)) {
1018
+ if (sameAnnotValue(record.current[key], record.original[key])) continue;
1019
+ if (ANNOT_FLAG_KEYS.indexOf(key) >= 0) flags[key] = record.current[key];
1020
+ else patch[key] = cloneAnnotValue(record.current[key]);
1021
+ }
1022
+ if (Object.keys(flags).length > 0) patch.flags = flags;
1023
+ if (Object.keys(patch).length > 0) annotEffects.push({
1024
+ ref: record.input.ref,
1025
+ patch
1026
+ });
1027
+ }
1028
+ const totalEffects = formEffects.length + annotEffects.length + state.uiEffects.length;
394
1029
  if (totalEffects > state.maxEffects) return {
395
1030
  event: eventOutput(),
396
1031
  formEffects: [],
1032
+ annotEffects: [],
397
1033
  uiEffects: [],
398
1034
  diagnostics: [...state.diagnostics],
399
1035
  error: {
@@ -404,6 +1040,7 @@ function installAcroJs(g) {
404
1040
  return {
405
1041
  event: eventOutput(),
406
1042
  formEffects,
1043
+ annotEffects,
407
1044
  uiEffects: [...state.uiEffects],
408
1045
  diagnostics: [...state.diagnostics]
409
1046
  };
@@ -411,6 +1048,7 @@ function installAcroJs(g) {
411
1048
  const failed = (error) => ({
412
1049
  event: eventOutput(),
413
1050
  formEffects: [],
1051
+ annotEffects: [],
414
1052
  uiEffects: [],
415
1053
  diagnostics: [...state?.diagnostics ?? []],
416
1054
  error: {
@@ -460,7 +1098,87 @@ function installAcroJs(g) {
460
1098
  noPrint: 2,
461
1099
  noView: 3
462
1100
  });
1101
+ host.color = Object.freeze({
1102
+ transparent: Object.freeze(["T"]),
1103
+ black: Object.freeze(["G", 0]),
1104
+ white: Object.freeze(["G", 1]),
1105
+ gray: Object.freeze(["G", .5]),
1106
+ ltGray: Object.freeze(["G", .75]),
1107
+ dkGray: Object.freeze(["G", .25]),
1108
+ red: Object.freeze([
1109
+ "RGB",
1110
+ 1,
1111
+ 0,
1112
+ 0
1113
+ ]),
1114
+ green: Object.freeze([
1115
+ "RGB",
1116
+ 0,
1117
+ 1,
1118
+ 0
1119
+ ]),
1120
+ blue: Object.freeze([
1121
+ "RGB",
1122
+ 0,
1123
+ 0,
1124
+ 1
1125
+ ]),
1126
+ cyan: Object.freeze([
1127
+ "CMYK",
1128
+ 1,
1129
+ 0,
1130
+ 0,
1131
+ 0
1132
+ ]),
1133
+ magenta: Object.freeze([
1134
+ "CMYK",
1135
+ 0,
1136
+ 1,
1137
+ 0,
1138
+ 0
1139
+ ]),
1140
+ yellow: Object.freeze([
1141
+ "CMYK",
1142
+ 0,
1143
+ 0,
1144
+ 1,
1145
+ 0
1146
+ ]),
1147
+ convert: (value, space) => {
1148
+ if (!isColorArray(value)) return ["T"];
1149
+ const target = String(space);
1150
+ const rgb = colorToRgbTriple(value);
1151
+ if (target === "T" || rgb === null) return ["T"];
1152
+ if (target === "G") return ["G", .3 * rgb[0] + .59 * rgb[1] + .11 * rgb[2]];
1153
+ if (target === "RGB") return [
1154
+ "RGB",
1155
+ rgb[0],
1156
+ rgb[1],
1157
+ rgb[2]
1158
+ ];
1159
+ if (target === "CMYK") {
1160
+ const k = 1 - Math.max(rgb[0], rgb[1], rgb[2]);
1161
+ return [
1162
+ "CMYK",
1163
+ 1 - rgb[0] - k,
1164
+ 1 - rgb[1] - k,
1165
+ 1 - rgb[2] - k,
1166
+ k
1167
+ ];
1168
+ }
1169
+ return ["T"];
1170
+ },
1171
+ equal: (a, b) => {
1172
+ if (!isColorArray(a) || !isColorArray(b)) return false;
1173
+ const left = colorToRgbTriple(a);
1174
+ const right = colorToRgbTriple(b);
1175
+ if (left === null || right === null) return left === right;
1176
+ return left.every((component, index) => Math.abs(component - right[index]) < 1e-6);
1177
+ }
1178
+ });
463
1179
  host.getField = getField;
1180
+ host.getAnnots = getAnnots;
1181
+ host.getAnnot = getAnnot;
464
1182
  host.resetForm = doc.resetForm;
465
1183
  host.print = doc.print;
466
1184
  host.submitForm = doc.submitForm;
@@ -522,8 +1240,226 @@ function installAcroJs(g) {
522
1240
  const places = Math.max(0, Math.min(10, Math.trunc(Number(decimals))));
523
1241
  state.event.value = `${(numberValue(state.event.value) * 100).toFixed(places)}%`;
524
1242
  };
525
- host.AFDate_FormatEx = (format) => {
526
- if (state) state.event.value = printd(format, new FixedDate(String(state.event.value ?? "")));
1243
+ const DATE_FORMATS = [
1244
+ "m/d",
1245
+ "m/d/yy",
1246
+ "mm/dd/yy",
1247
+ "mm/yy",
1248
+ "d-mmm",
1249
+ "d-mmm-yy",
1250
+ "dd-mmm-yy",
1251
+ "yy-mm-dd",
1252
+ "mmm-yy",
1253
+ "mmmm-yy",
1254
+ "mmm d, yyyy",
1255
+ "mmmm d, yyyy",
1256
+ "m/d/yy h:MM tt",
1257
+ "m/d/yy HH:MM"
1258
+ ];
1259
+ const TIME_FORMATS = [
1260
+ "HH:MM",
1261
+ "h:MM tt",
1262
+ "HH:MM:ss",
1263
+ "h:MM:ss tt"
1264
+ ];
1265
+ const rejectWithAlert = (message) => {
1266
+ if (!state) return;
1267
+ state.uiEffects.push({
1268
+ kind: "alert",
1269
+ message,
1270
+ icon: 0
1271
+ });
1272
+ state.event.rc = false;
1273
+ };
1274
+ const formatMismatch = () => rejectWithAlert(`The value entered does not match the format of the field [ ${String(state?.event.targetName ?? "")} ]`);
1275
+ const dateMismatch = (format) => rejectWithAlert(`Invalid date/time: please ensure that the date/time exists. Field [ ${String(state?.event.targetName ?? "")} ] should match format ${String(format ?? "")}`);
1276
+ const mergeChange = (eventObject) => {
1277
+ const e = eventObject ?? state?.event ?? {};
1278
+ const value = String(e.value ?? "");
1279
+ if (e.willCommit) return value;
1280
+ const start = Math.max(0, Math.trunc(Number(e.selStart ?? 0)));
1281
+ const end = Math.max(start, Math.trunc(Number(e.selEnd ?? 0)));
1282
+ return value.slice(0, start) + String(e.change ?? "") + value.slice(end);
1283
+ };
1284
+ host.AFMergeChange = mergeChange;
1285
+ const makeNumber = (value) => {
1286
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
1287
+ let text = String(value ?? "").trim();
1288
+ if (text === "") return null;
1289
+ text = text.replace(/[^0-9,.\-+eE]/g, "");
1290
+ if (text.includes(",") && text.includes(".")) text = text.lastIndexOf(",") > text.lastIndexOf(".") ? text.replace(/\./g, "").replace(",", ".") : text.replace(/,/g, "");
1291
+ else if (text.includes(",")) text = (text.match(/,/g) ?? []).length === 1 ? text.replace(",", ".") : text.replace(/,/g, "");
1292
+ const parsed = Number(text);
1293
+ return text !== "" && Number.isFinite(parsed) ? parsed : null;
1294
+ };
1295
+ host.AFMakeNumber = makeNumber;
1296
+ host.AFExtractNums = (value) => {
1297
+ const matches = String(value ?? "").match(/\d+/g);
1298
+ return matches && matches.length > 0 ? [...matches] : null;
1299
+ };
1300
+ const validNumberText = (text, separatorStyle) => {
1301
+ const trimmed = text.trim();
1302
+ if (trimmed === "") return true;
1303
+ return (separatorStyle === 2 || separatorStyle === 3 ? /^[+-]?(\d+|\d{1,3}(\.\d{3})+)?(,\d*)?$/ : /^[+-]?(\d+|\d{1,3}(,\d{3})+)?(\.\d*)?$/).test(trimmed) && /\d/.test(trimmed);
1304
+ };
1305
+ host.AFNumber_Keystroke = (_decimals, separatorStyle, _negativeStyle, _currencyStyle, currency) => {
1306
+ if (!state || !state.event.willCommit) return;
1307
+ const proposed = mergeChange(state.event);
1308
+ const cleaned = currency ? proposed.split(String(currency)).join("") : proposed;
1309
+ if (!validNumberText(cleaned, Math.trunc(Number(separatorStyle)))) formatMismatch();
1310
+ };
1311
+ host.AFPercent_Keystroke = (_decimals, separatorStyle) => {
1312
+ if (!state || !state.event.willCommit) return;
1313
+ const cleaned = mergeChange(state.event).replace(/%\s*$/, "");
1314
+ if (!validNumberText(cleaned, Math.trunc(Number(separatorStyle)))) formatMismatch();
1315
+ };
1316
+ const digitsOf = (value) => String(value ?? "").replace(/\D/g, "");
1317
+ const afSpecialFormat = (psf) => {
1318
+ if (!state) return;
1319
+ const digits = digitsOf(state.event.value);
1320
+ const kind = Math.trunc(Number(psf));
1321
+ let formatted = String(state.event.value ?? "");
1322
+ if (kind === 0) formatted = digits.slice(0, 5);
1323
+ else if (kind === 1) formatted = `${digits.slice(0, 5)}-${digits.slice(5, 9)}`;
1324
+ else if (kind === 2) formatted = digits.length >= 10 ? `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}` : `${digits.slice(0, 3)}-${digits.slice(3, 7)}`;
1325
+ else if (kind === 3) formatted = `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5, 9)}`;
1326
+ state.event.value = formatted;
1327
+ };
1328
+ host.AFSpecial_Format = afSpecialFormat;
1329
+ host.AFSpecial_Keystroke = (psf) => {
1330
+ if (!state || !state.event.willCommit) return;
1331
+ const merged = mergeChange(state.event);
1332
+ if (merged.trim() === "") return;
1333
+ const digits = digitsOf(merged).length;
1334
+ const kind = Math.trunc(Number(psf));
1335
+ if (!(kind === 0 ? digits === 5 : kind === 1 ? digits === 9 : kind === 2 ? digits === 7 || digits === 10 : digits === 9)) formatMismatch();
1336
+ };
1337
+ host.AFRange_Validate = (useGreater, greaterThan, useLess, lessThan) => {
1338
+ if (!state) return;
1339
+ const value = makeNumber(state.event.value);
1340
+ if (value === null) return;
1341
+ const hasGreater = Boolean(useGreater);
1342
+ const hasLess = Boolean(useLess);
1343
+ const low = Number(greaterThan);
1344
+ const high = Number(lessThan);
1345
+ if ((!hasGreater || value >= low) && (!hasLess || value <= high)) return;
1346
+ rejectWithAlert(hasGreater && hasLess ? `Invalid value: must be greater than or equal to ${low} and less than or equal to ${high}.` : hasGreater ? `Invalid value: must be greater than or equal to ${low}.` : `Invalid value: must be less than or equal to ${high}.`);
1347
+ };
1348
+ const nowWall = () => {
1349
+ const env = state?.input.environment ?? {};
1350
+ const local = new NativeDate(Number(env.nowMs ?? 0) + Number(env.utcOffsetMinutes ?? 0) * 6e4);
1351
+ return {
1352
+ y: local.getUTCFullYear(),
1353
+ m: local.getUTCMonth() + 1,
1354
+ d: local.getUTCDate(),
1355
+ H: 0,
1356
+ M: 0,
1357
+ S: 0
1358
+ };
1359
+ };
1360
+ /** printd adds the environment offset itself, so a wall time converts back. */
1361
+ const wallDate = (parts) => {
1362
+ const env = state?.input.environment ?? {};
1363
+ return new NativeDate(NativeDate.UTC(parts.y, parts.m - 1, parts.d, parts.H, parts.M, parts.S) - Number(env.utcOffsetMinutes ?? 0) * 6e4);
1364
+ };
1365
+ /** Lenient scand-style parse: numbers mapped by the format's token order,
1366
+ * month names accepted, missing parts defaulted like Acrobat's scand. */
1367
+ const parseDateLoose = (raw, format) => {
1368
+ const text = String(raw ?? "").trim();
1369
+ if (text === "") return null;
1370
+ const lower = text.toLowerCase();
1371
+ let namedMonth = null;
1372
+ for (let index = 0; index < 12; index += 1) if (lower.indexOf(monthShort[index].toLowerCase()) >= 0) {
1373
+ namedMonth = index + 1;
1374
+ break;
1375
+ }
1376
+ const timeMatch = /(\d{1,2}):(\d{2})(?::(\d{2}))?\s*(am|pm)?/i.exec(text);
1377
+ let H = 0;
1378
+ let M = 0;
1379
+ let S = 0;
1380
+ if (timeMatch) {
1381
+ H = Number(timeMatch[1]);
1382
+ M = Number(timeMatch[2]);
1383
+ S = Number(timeMatch[3] ?? 0);
1384
+ const marker = String(timeMatch[4] ?? "").toLowerCase();
1385
+ if (marker === "pm" && H < 12) H += 12;
1386
+ if (marker === "am" && H === 12) H = 0;
1387
+ if (H > 23 || M > 59 || S > 59) return null;
1388
+ }
1389
+ const numbers = ((timeMatch ? text.slice(0, timeMatch.index) + text.slice(timeMatch.index + timeMatch[0].length) : text).match(/\d+/g) ?? []).map((token) => Number(token));
1390
+ const order = [];
1391
+ for (const token of String(format ?? "").match(/yyyy|mmmm|mmm|yy|mm|dd|m|d/g) ?? []) {
1392
+ const kind = token[0] === "y" ? "y" : token[0] === "m" ? "m" : "d";
1393
+ if (order.indexOf(kind) < 0) order.push(kind);
1394
+ }
1395
+ let y = null;
1396
+ let m = namedMonth;
1397
+ let d = null;
1398
+ let cursor = 0;
1399
+ for (const kind of order) {
1400
+ if (kind === "m" && namedMonth !== null) continue;
1401
+ if (cursor >= numbers.length) break;
1402
+ const value = numbers[cursor];
1403
+ cursor += 1;
1404
+ if (kind === "y") y = value;
1405
+ else if (kind === "m") m = value;
1406
+ else d = value;
1407
+ }
1408
+ if (y === null && m === null && d === null && !timeMatch) return null;
1409
+ const today = nowWall();
1410
+ if (y === null) y = today.y;
1411
+ else if (y < 100) y = y < 50 ? 2e3 + y : 1900 + y;
1412
+ if (m === null) m = today.m;
1413
+ if (d === null) d = 1;
1414
+ if (m < 1 || m > 12 || d < 1 || d > 31) return null;
1415
+ const probe = new NativeDate(NativeDate.UTC(y, m - 1, d));
1416
+ if (probe.getUTCFullYear() !== y || probe.getUTCMonth() !== m - 1 || probe.getUTCDate() !== d) return null;
1417
+ return {
1418
+ y,
1419
+ m,
1420
+ d,
1421
+ H,
1422
+ M,
1423
+ S
1424
+ };
1425
+ };
1426
+ const afDateFormatEx = (format) => {
1427
+ if (!state) return;
1428
+ const raw = String(state.event.value ?? "");
1429
+ if (raw.trim() === "") return;
1430
+ let date = new FixedDate(raw);
1431
+ if (Number.isNaN(date.getTime())) {
1432
+ const parts = parseDateLoose(raw, format);
1433
+ if (!parts) return;
1434
+ date = wallDate(parts);
1435
+ }
1436
+ state.event.value = printd(format, date);
1437
+ };
1438
+ host.AFDate_FormatEx = afDateFormatEx;
1439
+ host.AFDate_Format = (index) => afDateFormatEx(DATE_FORMATS[Math.trunc(Number(index))] ?? "m/d/yy");
1440
+ const afDateKeystrokeEx = (format) => {
1441
+ if (!state || !state.event.willCommit) return;
1442
+ const merged = mergeChange(state.event);
1443
+ if (merged.trim() === "") return;
1444
+ if (!parseDateLoose(merged, format)) dateMismatch(format);
1445
+ };
1446
+ host.AFDate_KeystrokeEx = afDateKeystrokeEx;
1447
+ host.AFDate_Keystroke = (index) => afDateKeystrokeEx(DATE_FORMATS[Math.trunc(Number(index))] ?? "m/d/yy");
1448
+ const afTimeFormatEx = (format) => {
1449
+ if (!state) return;
1450
+ const raw = String(state.event.value ?? "");
1451
+ if (raw.trim() === "") return;
1452
+ const parts = parseDateLoose(raw, format);
1453
+ if (!parts) return;
1454
+ state.event.value = printd(format, wallDate(parts));
1455
+ };
1456
+ host.AFTime_FormatEx = afTimeFormatEx;
1457
+ host.AFTime_Format = (index) => afTimeFormatEx(TIME_FORMATS[Math.trunc(Number(index))] ?? "HH:MM");
1458
+ host.AFTime_Keystroke = (index) => {
1459
+ if (!state || !state.event.willCommit) return;
1460
+ const merged = mergeChange(state.event);
1461
+ if (merged.trim() === "") return;
1462
+ if (!parseDateLoose(merged, TIME_FORMATS[Math.trunc(Number(index))] ?? "HH:MM")) dateMismatch(TIME_FORMATS[Math.trunc(Number(index))] ?? "HH:MM");
527
1463
  };
528
1464
  host.fetch = void 0;
529
1465
  host.XMLHttpRequest = void 0;
@@ -532,43 +1468,6 @@ function installAcroJs(g) {
532
1468
  /** The exact self-contained source evaluated in Node parity tests and QuickJS. */
533
1469
  const PRELUDE_SOURCE = `(${installAcroJs.toString()})(globalThis);`;
534
1470
  //#endregion
535
- //#region src/types.ts
536
- const DEFAULT_SCRIPT_BUDGET = Object.freeze({
537
- maxExecutionMs: 50,
538
- maxMemoryBytes: 16 * 1024 * 1024,
539
- maxStackBytes: 512 * 1024,
540
- maxEffects: 256,
541
- maxOutputBytes: 1024 * 1024
542
- });
543
- const DEFAULT_SCRIPT_SECURITY_POLICY = Object.freeze({
544
- enabled: false,
545
- executionOwner: "originating-client-only",
546
- nameTreeBoot: "lazy-first-transaction",
547
- submitForm: "blocked",
548
- openAction: "preserve-only",
549
- pageActions: "preserve-only",
550
- catalogLifecycleActions: "preserve-only",
551
- annotationActions: "widget-activate-only"
552
- });
553
- /** Frozen V1 dispatch matrix; extracted actions outside it remain data only. */
554
- const SCRIPT_EVENT_MATRIX = Object.freeze({
555
- nameTree: "lazy-first-originating-field-transaction",
556
- field: Object.freeze({
557
- keystroke: "execute-on-commit",
558
- validate: "execute",
559
- calculate: "execute-in-calculation-order",
560
- format: "execute-after-value-calculation"
561
- }),
562
- openAction: "preserve-only",
563
- page: "preserve-only",
564
- catalogLifecycle: "preserve-only",
565
- annotation: Object.freeze({
566
- widgetActivate: "execute-on-originating-client",
567
- other: "preserve-only"
568
- }),
569
- submitForm: "blocked"
570
- });
571
- //#endregion
572
- export { DEFAULT_SCRIPT_BUDGET, DEFAULT_SCRIPT_SECURITY_POLICY, PRELUDE_SOURCE, SCRIPT_EVENT_MATRIX, installAcroJs, javaScriptProgramFromActionTree, javaScriptSourcesFromActionTree, scriptFieldsFromSnapshot };
1471
+ export { ANNOT_WRITABLE_KEYS, DEFAULT_SCRIPT_BUDGET, DEFAULT_SCRIPT_SECURITY_POLICY, PRELUDE_SOURCE, SCRIPT_EVENT_MATRIX, createScriptHost, cssToScriptColor, installAcroJs, isScriptColorArray, javaScriptProgramFromActionTree, javaScriptSourcesFromActionTree, resolveScriptIdentity, scriptColorToCss, scriptColorToRgb, scriptFieldsFromSnapshot, seedFrom };
573
1472
 
574
1473
  //# sourceMappingURL=index.js.map