@openpresentation/opf 0.11.4 → 0.12.1

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 (74) hide show
  1. package/README.md +16 -0
  2. package/dist/audit.d.ts +156 -0
  3. package/dist/audit.js +7 -0
  4. package/dist/{catalogs-CUClB3nl.d.ts → catalogs-BnI7JKcn.d.ts} +3 -3
  5. package/dist/catalogs.d.ts +2 -2
  6. package/dist/catalogs.js +2 -1
  7. package/dist/{chunk-KJKASEPE.js → chunk-4LAM3N6S.js} +753 -42
  8. package/dist/chunk-6LZK2IZB.js +1690 -0
  9. package/dist/{chunk-NSVVQ52O.js → chunk-AUM5MXBR.js} +8 -6
  10. package/dist/{chunk-AEUSVEUY.js → chunk-E34DJ5LL.js} +50 -14
  11. package/dist/chunk-FYLJVF7X.js +18448 -0
  12. package/dist/{chunk-HJL64ETN.js → chunk-GJKJL4YY.js} +14 -0
  13. package/dist/{chunk-3H2U7FDR.js → chunk-HOBSL7AJ.js} +1867 -247
  14. package/dist/chunk-JKVKYVWL.js +1332 -0
  15. package/dist/{chunk-3OJN7QAW.js → chunk-MWPMJE6P.js} +18 -4
  16. package/dist/chunk-RUC7L5DJ.js +261 -0
  17. package/dist/chunk-S5W34SIJ.js +1 -0
  18. package/dist/chunk-V2537ENL.js +198 -0
  19. package/dist/{chunk-RXNFDGPC.js → chunk-WXSPETQ6.js} +311 -40
  20. package/dist/{composition-Dl-d9FRj.d.ts → composition-DWbCiMwF.d.ts} +559 -10
  21. package/dist/composition.d.ts +1 -1
  22. package/dist/composition.js +2 -1
  23. package/dist/convert.d.ts +261 -0
  24. package/dist/convert.js +1107 -0
  25. package/dist/diff.d.ts +145 -0
  26. package/dist/diff.js +604 -0
  27. package/dist/docs.js +72 -18
  28. package/dist/examples.d.ts +1 -1
  29. package/dist/examples.js +112 -112
  30. package/dist/font-policy.d.ts +15 -0
  31. package/dist/font-policy.js +1 -1
  32. package/dist/format.d.ts +20 -0
  33. package/dist/format.js +83 -0
  34. package/dist/index.d.ts +173 -24
  35. package/dist/index.js +926 -262
  36. package/dist/lint.d.ts +4 -4
  37. package/dist/lint.js +6 -5
  38. package/dist/markdown.d.ts +74 -0
  39. package/dist/markdown.js +1941 -0
  40. package/dist/pagination.d.ts +1 -1
  41. package/dist/pagination.js +6 -5
  42. package/dist/patch.d.ts +99 -0
  43. package/dist/patch.js +6 -0
  44. package/dist/{presentation-j5PVrqfV.d.ts → presentation-DcF-MZcz.d.ts} +452 -17
  45. package/dist/repo-readme.js +1 -1
  46. package/dist/{schemas-X_NniU4A.d.ts → schemas-BSjlG8-R.d.ts} +28 -0
  47. package/dist/schemas.d.ts +1 -1
  48. package/dist/schemas.js +1 -1
  49. package/dist/spec/catalogs/audiences/customers.json +5 -1
  50. package/dist/spec/catalogs/audiences/executives.json +5 -1
  51. package/dist/spec/catalogs/audiences/index.json +20 -8
  52. package/dist/spec/catalogs/audiences/investors.json +5 -1
  53. package/dist/spec/catalogs/audiences/marketing-team.json +5 -1
  54. package/dist/spec/catalogs/audiences/regulators.json +5 -1
  55. package/dist/spec/catalogs/audiences/sales-team.json +5 -1
  56. package/dist/spec/catalogs/manifest.json +2 -2
  57. package/dist/spec/reference/engine-defaults.json +1 -1
  58. package/dist/spec/reference/font-policy.json +311 -40
  59. package/dist/spec/reference/font-policy.schema.json +40 -0
  60. package/dist/spec/reference/symbol-font-encodings.json +18354 -0
  61. package/dist/spec/reference/symbol-font-encodings.schema.json +156 -0
  62. package/dist/spec/schemas/audience.schema.json +7 -7
  63. package/dist/spec/schemas/narrative.schema.json +1 -1
  64. package/dist/spec/schemas/opf.schema.json +597 -28
  65. package/dist/spec-files.d.ts +1 -1
  66. package/dist/spec-files.js +1 -1
  67. package/dist/symbol-font-encodings.d.ts +128 -0
  68. package/dist/symbol-font-encodings.js +1 -0
  69. package/dist/types.d.ts +4 -4
  70. package/dist/validator-DfG9yxba.d.ts +172 -0
  71. package/dist/validator.d.ts +4 -36
  72. package/dist/validator.js +5 -4
  73. package/package.json +32 -3
  74. package/dist/chunk-FDCWQHWO.js +0 -1366
@@ -1,1366 +0,0 @@
1
- import { MAX_COMPOSITION_DEPTH, tableGrid } from './chunk-3H2U7FDR.js';
2
- import { schemas, schemaEntries } from './chunk-KJKASEPE.js';
3
- import { catalogSchemaNames } from './chunk-AEUSVEUY.js';
4
- import Ajv2020 from 'ajv/dist/2020.js';
5
- import addFormats from 'ajv-formats';
6
-
7
- // src/content-walk.ts
8
- function isRecord(value) {
9
- return typeof value === "object" && value !== null && !Array.isArray(value);
10
- }
11
- function pathFor(parentPath, key) {
12
- return parentPath === "/" ? `/${key}` : `${parentPath}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`;
13
- }
14
- var bareIdPattern = /^[a-z0-9][a-z0-9-]*$/;
15
- var promotedRegionKeys = [
16
- "left",
17
- "center",
18
- "right",
19
- "left+center",
20
- "center+right",
21
- "left+center+right",
22
- "top",
23
- "middle",
24
- "bottom",
25
- "top+middle",
26
- "middle+bottom",
27
- "top+middle+bottom",
28
- "top:left",
29
- "top:center",
30
- "top:right",
31
- "top:left+center",
32
- "top:center+right",
33
- "top:left+center+right",
34
- "middle:left",
35
- "middle:center",
36
- "middle:right",
37
- "middle:left+center",
38
- "middle:center+right",
39
- "middle:left+center+right",
40
- "bottom:left",
41
- "bottom:center",
42
- "bottom:right",
43
- "bottom:left+center",
44
- "bottom:center+right",
45
- "bottom:left+center+right",
46
- "top+middle:left",
47
- "top+middle:center",
48
- "top+middle:right",
49
- "top+middle:left+center",
50
- "top+middle:center+right",
51
- "top+middle:left+center+right",
52
- "middle+bottom:left",
53
- "middle+bottom:center",
54
- "middle+bottom:right",
55
- "middle+bottom:left+center",
56
- "middle+bottom:center+right",
57
- "middle+bottom:left+center+right",
58
- "top+middle+bottom:left",
59
- "top+middle+bottom:center",
60
- "top+middle+bottom:right",
61
- "top+middle+bottom:left+center",
62
- "top+middle+bottom:center+right",
63
- "top+middle+bottom:left+center+right"
64
- ];
65
- function visitContentPayloads(slide, slidePath, visit) {
66
- const walk = (payload, path, depth, ancestors) => {
67
- visit(payload, path);
68
- if (!Array.isArray(payload.blocks) || depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(payload)) return;
69
- const nested = [...ancestors, payload];
70
- const blocksPath = pathFor(path, "blocks");
71
- payload.blocks.forEach((block, index) => {
72
- if (isRecord(block)) walk(block, `${blocksPath}/${index}`, depth + 1, nested);
73
- });
74
- };
75
- if (Array.isArray(slide.blocks)) {
76
- const blocksPath = pathFor(slidePath, "blocks");
77
- slide.blocks.forEach((block, index) => {
78
- if (isRecord(block)) walk(block, `${blocksPath}/${index}`, 0, []);
79
- });
80
- }
81
- for (const key of promotedRegionKeys) {
82
- const region = slide[key];
83
- if (isRecord(region)) walk(region, pathFor(slidePath, key), 0, []);
84
- }
85
- }
86
-
87
- // src/generated/catalog-ids.ts
88
- var catalogIds = {
89
- audiences: [
90
- "executives",
91
- "board",
92
- "engineering-team",
93
- "investors",
94
- "customers",
95
- "sales-team",
96
- "marketing-team",
97
- "all-hands",
98
- "candidates",
99
- "regulators",
100
- "executive",
101
- "investor",
102
- "technical",
103
- "sales",
104
- "marketing",
105
- "academic",
106
- "internal-team",
107
- "customer",
108
- "general-public",
109
- "media",
110
- "partner",
111
- "regulatory"
112
- ],
113
- purposes: [
114
- "inform",
115
- "decide",
116
- "align",
117
- "persuade",
118
- "educate",
119
- "report",
120
- "pitch",
121
- "sell",
122
- "plan"
123
- ],
124
- tones: [
125
- "formal",
126
- "casual",
127
- "inspirational",
128
- "technical",
129
- "persuasive",
130
- "authoritative",
131
- "conversational"
132
- ],
133
- themes: [
134
- "minimal",
135
- "classic",
136
- "dark",
137
- "bold"
138
- ],
139
- layouts: [
140
- "blank",
141
- "chart-1x",
142
- "chart-2x",
143
- "chart-3x",
144
- "code-1x",
145
- "image-1x",
146
- "image-2x",
147
- "image-3x",
148
- "image-bleed",
149
- "list-1x",
150
- "list-2x",
151
- "list-3x",
152
- "list-4x",
153
- "list-5x",
154
- "list-6x",
155
- "media-1x",
156
- "number-1x",
157
- "number-2x",
158
- "number-3x",
159
- "number-4x",
160
- "number-5x",
161
- "number-6x",
162
- "quote-1x",
163
- "table-1x",
164
- "text-1x",
165
- "text-2x",
166
- "text-3x",
167
- "timeline-1x",
168
- "title",
169
- "title-subtitle",
170
- "title-slide",
171
- "two-column",
172
- "image-focus",
173
- "data-visualization",
174
- "quote-highlight",
175
- "section-divider",
176
- "agenda",
177
- "thank-you-cta",
178
- "bullet-list",
179
- "three-column",
180
- "icon-grid",
181
- "faq",
182
- "stats-metrics",
183
- "comparison",
184
- "swot-analysis",
185
- "matrix-quadrant",
186
- "funnel-pyramid",
187
- "timeline",
188
- "process-flow",
189
- "photo-grid",
190
- "before-after",
191
- "testimonial-grid",
192
- "team-bio",
193
- "pricing-table",
194
- "roadmap",
195
- "product-feature",
196
- "executive-summary",
197
- "key-takeaway",
198
- "chapter-recap",
199
- "qa-discussion",
200
- "single-message-statement",
201
- "one-column-explainer",
202
- "case-study",
203
- "pros-cons",
204
- "feature-comparison-matrix",
205
- "venn-overlap",
206
- "decision-tree",
207
- "kpi-scorecard",
208
- "dashboard",
209
- "waterfall-bridge",
210
- "benchmark-target-table",
211
- "heatmap-cohort",
212
- "risk-heatmap",
213
- "forecast-scenario",
214
- "swimlane-process",
215
- "gantt-project-plan",
216
- "circular-lifecycle",
217
- "customer-journey",
218
- "org-chart",
219
- "capability-map",
220
- "logic-tree",
221
- "hub-and-spoke",
222
- "architecture-stack",
223
- "ecosystem-map",
224
- "network-dependency-map",
225
- "wheel-radial",
226
- "geographic-map",
227
- "screenshot-walkthrough",
228
- "market-size",
229
- "persona-grid",
230
- "competitive-landscape",
231
- "business-model-canvas",
232
- "customer-logos",
233
- "executive-decision",
234
- "status-rag",
235
- "raci-matrix",
236
- "action-plan",
237
- "assumptions-dependencies",
238
- "appendix-index",
239
- "detailed-data-table"
240
- ],
241
- chartTypes: [
242
- "100pct-stacked-area-3x",
243
- "100pct-stacked-bar-3x",
244
- "100pct-stacked-column-3x",
245
- "area",
246
- "bar",
247
- "box-and-whisker",
248
- "column",
249
- "doughnut",
250
- "filled-radar",
251
- "funnel",
252
- "histogram",
253
- "line",
254
- "line-with-markers",
255
- "pareto",
256
- "pie",
257
- "radar",
258
- "radar-with-markers",
259
- "scatter",
260
- "stacked-area-3x",
261
- "stacked-bar-3x",
262
- "stacked-column-3x",
263
- "stacked-line-3x",
264
- "stacked-line-with-markers-3x",
265
- "treemap",
266
- "waterfall",
267
- "world",
268
- "100pct-bullet-bar",
269
- "100pct-bullet-bar-2x",
270
- "100pct-bullet-bar-3x",
271
- "100pct-bullet-column",
272
- "100pct-bullet-column-2x",
273
- "100pct-bullet-column-3x",
274
- "100pct-progress-bar",
275
- "100pct-stacked-area-2x",
276
- "100pct-stacked-bar-2x",
277
- "100pct-stacked-column-2x",
278
- "australia",
279
- "box-and-whisker-2x",
280
- "box-and-whisker-3x",
281
- "bullet-bar",
282
- "bullet-bar-2x",
283
- "bullet-bar-3x",
284
- "bullet-column",
285
- "bullet-column-2x",
286
- "bullet-column-3x",
287
- "canada",
288
- "clustered-bar-2x",
289
- "clustered-column",
290
- "dot-plot",
291
- "dot-plot-2x",
292
- "dot-plot-3x",
293
- "dot-plot-4x",
294
- "dot-plot-5x",
295
- "dot-plot-6x",
296
- "dumbbell",
297
- "line-2x",
298
- "line-3x",
299
- "line-with-high-low",
300
- "line-with-high-low-and-markers",
301
- "line-with-markers-2x",
302
- "line-with-markers-3x",
303
- "sparkline",
304
- "sparkline-2x",
305
- "sparkline-3x",
306
- "sparkline-4x",
307
- "sparkline-5x",
308
- "sparkline-6x",
309
- "stacked-area-2x",
310
- "stacked-bar-2x",
311
- "stacked-column-2x",
312
- "stacked-line-2x",
313
- "stacked-line-with-markers-2x",
314
- "treemap-2x",
315
- "treemap-3x",
316
- "united-kingdom",
317
- "united-states"
318
- ],
319
- narratives: [
320
- "problem-solution",
321
- "scqa",
322
- "pyramid-principle",
323
- "situation-complication-resolution",
324
- "what-so-what-now-what",
325
- "strategic-narrative",
326
- "golden-circle",
327
- "conference-talk",
328
- "transformation-arc",
329
- "pitch-deck",
330
- "early-startup-pitch",
331
- "venture-pitch",
332
- "persuasive-sales",
333
- "sparkline",
334
- "company-intro",
335
- "marketing-strategy",
336
- "product-launch",
337
- "strategic-advisory",
338
- "challenge-resolution",
339
- "project-proposal",
340
- "vision-roadmap",
341
- "failure-analysis",
342
- "star-method",
343
- "classic-story",
344
- "heros-journey",
345
- "business-narrative",
346
- "change-story",
347
- "rags-to-riches",
348
- "underdog-victory",
349
- "survival-story",
350
- "educate",
351
- "persuade",
352
- "reveal",
353
- "justice",
354
- "innovation",
355
- "focus",
356
- "qbr",
357
- "business-review",
358
- "board-meeting",
359
- "weekly-progress",
360
- "status-update",
361
- "performance-review",
362
- "survey-analysis",
363
- "trend-analysis",
364
- "data-story",
365
- "employee-review",
366
- "performance-improvement-plan",
367
- "capacity-planning"
368
- ],
369
- socialPlatforms: [
370
- "linkedin",
371
- "x",
372
- "github",
373
- "youtube",
374
- "instagram",
375
- "facebook",
376
- "tiktok",
377
- "threads",
378
- "mastodon",
379
- "bluesky"
380
- ],
381
- languages: [
382
- "afrikaans",
383
- "albanian",
384
- "amharic",
385
- "arabic",
386
- "armenian",
387
- "aymara",
388
- "azerbaijani",
389
- "bengali",
390
- "berber-latin",
391
- "bosnian-latin",
392
- "bulgarian",
393
- "catalan",
394
- "cebuano",
395
- "chinese-simplified",
396
- "chinese-traditional",
397
- "chittagonian",
398
- "croatian",
399
- "czech",
400
- "danish",
401
- "dutch",
402
- "english",
403
- "english-au",
404
- "english-ca",
405
- "english-gb",
406
- "english-in",
407
- "english-us",
408
- "estonian",
409
- "filipino",
410
- "finnish",
411
- "french",
412
- "fulfulde",
413
- "galician",
414
- "georgian",
415
- "german",
416
- "greek",
417
- "gujarati",
418
- "hausa",
419
- "hebrew",
420
- "hindi",
421
- "hungarian",
422
- "igbo",
423
- "indonesian",
424
- "italian",
425
- "japanese",
426
- "kannada",
427
- "kazakh",
428
- "khmer",
429
- "kinyarwanda",
430
- "korean",
431
- "kurmanji",
432
- "latvian",
433
- "lithuanian",
434
- "macedonian",
435
- "malagasy",
436
- "malay",
437
- "malayalam",
438
- "maori",
439
- "marathi",
440
- "mongolian",
441
- "nepali",
442
- "norwegian",
443
- "odia",
444
- "oromo",
445
- "pashto",
446
- "persian",
447
- "polish",
448
- "portuguese",
449
- "punjabi-gurmukhi",
450
- "punjabi-shahmukhi",
451
- "romanian",
452
- "russian",
453
- "serbian-cyrillic",
454
- "serbian-latin",
455
- "shona",
456
- "slovak",
457
- "slovenian",
458
- "somali",
459
- "spanish",
460
- "swahili",
461
- "swedish",
462
- "tagalog",
463
- "tajik",
464
- "tamil",
465
- "telugu",
466
- "thai",
467
- "turkish",
468
- "ukrainian",
469
- "urdu",
470
- "uzbek-latin",
471
- "vietnamese-quoc-ngu",
472
- "xhosa",
473
- "yoruba",
474
- "zulu"
475
- ],
476
- colorSchemes: [
477
- "black-and-white",
478
- "bold-red",
479
- "boost",
480
- "burnt-orange",
481
- "cool-horizon",
482
- "corporate-blue",
483
- "deep-purple",
484
- "forest-green",
485
- "golden-yellow",
486
- "luxury",
487
- "pastel-red",
488
- "slate-gray",
489
- "steel-blue",
490
- "vibes"
491
- ],
492
- fontSchemes: [
493
- "consolas",
494
- "courier-new",
495
- "arial",
496
- "calibri",
497
- "impact",
498
- "lucida-sans",
499
- "segoe-ui",
500
- "segoe-ui-light",
501
- "tahoma",
502
- "trebuchet-ms",
503
- "verdana",
504
- "bookman",
505
- "century-schoolbook",
506
- "constantia",
507
- "garamond",
508
- "rockwell",
509
- "times-new-roman",
510
- "aptos",
511
- "grandview",
512
- "seaford",
513
- "skeena",
514
- "tenorite",
515
- "georgia",
516
- "microsoft-yahei",
517
- "simsun",
518
- "fangsong",
519
- "yu-gothic",
520
- "pmingliu",
521
- "mingliu",
522
- "ms-mincho",
523
- "malgun-gothic",
524
- "batang",
525
- "gungsuh",
526
- "mangal",
527
- "nirmala-ui",
528
- "latha",
529
- "david",
530
- "miriam",
531
- "gisha",
532
- "vrinda",
533
- "shruti",
534
- "tunga",
535
- "kartika",
536
- "kalinga",
537
- "raavi",
538
- "gautami",
539
- "arabic-typesetting",
540
- "microsoft-jhenghei",
541
- "meiryo",
542
- "angsana-new",
543
- "aparajita",
544
- "dilleniaupc",
545
- "sakkal-majalla",
546
- "shonar-bangla",
547
- "sylfaen",
548
- "traditional-arabic",
549
- "montserrat",
550
- "open-sans",
551
- "poppins",
552
- "pt-serif",
553
- "raleway",
554
- "roboto",
555
- "noto-sans-arabic",
556
- "noto-sans-armenian",
557
- "noto-sans-bengali",
558
- "noto-sans-devangari",
559
- "noto-sans-georgian",
560
- "noto-sans-gujarati",
561
- "noto-sans-gurmukhi",
562
- "noto-sans-hebrew",
563
- "noto-sans-jp",
564
- "noto-sans-kannada",
565
- "noto-sans-kr",
566
- "noto-sans-malayalam",
567
- "noto-sans-mongolian",
568
- "noto-sans-oriya",
569
- "noto-sans-sc",
570
- "noto-sans-tamil",
571
- "noto-sans-tc",
572
- "noto-sans-telugu",
573
- "noto-sans",
574
- "noto-sans-thai",
575
- "noto-nastaliq-urdu",
576
- "noto-naksh-arabic",
577
- "noto-sans-ethiopic",
578
- "noto-sans-khmer",
579
- "nyala",
580
- "daunpenh",
581
- "khmer-ui"
582
- ]
583
- };
584
- var deprecatedCatalogIds = {
585
- "chartTypes/100pct-bullet-bar": "100pct-stacked-bar-3x",
586
- "chartTypes/100pct-bullet-bar-2x": "100pct-stacked-bar-3x",
587
- "chartTypes/100pct-bullet-bar-3x": "100pct-stacked-bar-3x",
588
- "chartTypes/100pct-bullet-column": "100pct-stacked-column-3x",
589
- "chartTypes/100pct-bullet-column-2x": "100pct-stacked-column-3x",
590
- "chartTypes/100pct-bullet-column-3x": "100pct-stacked-column-3x",
591
- "chartTypes/100pct-progress-bar": "100pct-stacked-bar-3x",
592
- "chartTypes/100pct-stacked-area-2x": "100pct-stacked-area-3x",
593
- "chartTypes/100pct-stacked-bar-2x": "100pct-stacked-bar-3x",
594
- "chartTypes/100pct-stacked-column-2x": "100pct-stacked-column-3x",
595
- "chartTypes/australia": "world",
596
- "chartTypes/box-and-whisker-2x": "box-and-whisker",
597
- "chartTypes/box-and-whisker-3x": "box-and-whisker",
598
- "chartTypes/bullet-bar": "bar",
599
- "chartTypes/bullet-bar-2x": "bar",
600
- "chartTypes/bullet-bar-3x": "bar",
601
- "chartTypes/bullet-column": "column",
602
- "chartTypes/bullet-column-2x": "column",
603
- "chartTypes/bullet-column-3x": "column",
604
- "chartTypes/canada": "world",
605
- "chartTypes/clustered-bar-2x": "bar",
606
- "chartTypes/clustered-column": "column",
607
- "chartTypes/dot-plot": "scatter",
608
- "chartTypes/dot-plot-2x": "scatter",
609
- "chartTypes/dot-plot-3x": "scatter",
610
- "chartTypes/dot-plot-4x": "scatter",
611
- "chartTypes/dot-plot-5x": "scatter",
612
- "chartTypes/dot-plot-6x": "scatter",
613
- "chartTypes/dumbbell": "scatter",
614
- "chartTypes/line-2x": "line",
615
- "chartTypes/line-3x": "line",
616
- "chartTypes/line-with-high-low": "line",
617
- "chartTypes/line-with-high-low-and-markers": "line-with-markers",
618
- "chartTypes/line-with-markers-2x": "line-with-markers",
619
- "chartTypes/line-with-markers-3x": "line-with-markers",
620
- "chartTypes/sparkline": "line",
621
- "chartTypes/sparkline-2x": "line",
622
- "chartTypes/sparkline-3x": "line",
623
- "chartTypes/sparkline-4x": "line",
624
- "chartTypes/sparkline-5x": "line",
625
- "chartTypes/sparkline-6x": "line",
626
- "chartTypes/stacked-area-2x": "stacked-area-3x",
627
- "chartTypes/stacked-bar-2x": "stacked-bar-3x",
628
- "chartTypes/stacked-column-2x": "stacked-column-3x",
629
- "chartTypes/stacked-line-2x": "stacked-line-3x",
630
- "chartTypes/stacked-line-with-markers-2x": "stacked-line-with-markers-3x",
631
- "chartTypes/treemap-2x": "treemap",
632
- "chartTypes/treemap-3x": "treemap",
633
- "chartTypes/united-kingdom": "world",
634
- "chartTypes/united-states": "world"
635
- };
636
-
637
- // src/validation-definitions.ts
638
- var schemaLocations;
639
- var issueLocations = /* @__PURE__ */ new WeakMap();
640
- function rememberValidationDefinition(issue, parentSchema, keyword) {
641
- if (!parentSchema || typeof parentSchema !== "object") return;
642
- if (!schemaLocations) {
643
- schemaLocations = /* @__PURE__ */ new WeakMap();
644
- for (const entry of schemaEntries) {
645
- const stack = [
646
- { value: entry.schema, pointer: "" }
647
- ];
648
- while (stack.length) {
649
- const current = stack.pop();
650
- if (!current?.value || typeof current.value !== "object")
651
- continue;
652
- schemaLocations.set(current.value, {
653
- schemaName: entry.name,
654
- pointer: current.pointer,
655
- uri: `${entry.schema.$id}#${current.pointer}`
656
- });
657
- for (const [key, value] of Object.entries(current.value)) {
658
- const segment = key.replaceAll("~", "~0").replaceAll("/", "~1");
659
- stack.push({ value, pointer: `${current.pointer}/${segment}` });
660
- }
661
- }
662
- }
663
- }
664
- const parent = schemaLocations.get(parentSchema);
665
- if (!parent) return;
666
- const suffix = `/${keyword.replaceAll("~", "~0").replaceAll("/", "~1")}`;
667
- issueLocations.set(issue, {
668
- ...parent,
669
- pointer: parent.pointer + suffix,
670
- uri: parent.uri + suffix
671
- });
672
- }
673
- function validationDefinition(issue) {
674
- return issueLocations.get(issue);
675
- }
676
-
677
- // src/validator.ts
678
- var OPFValidationError = class extends Error {
679
- issues;
680
- result;
681
- constructor(result) {
682
- const first = result.errors[0];
683
- super(first ? `OPF validation failed at ${first.path}: ${first.message}` : "OPF validation failed");
684
- this.name = "OPFValidationError";
685
- this.issues = result.errors;
686
- this.result = result;
687
- }
688
- };
689
- var schemaNameByCatalogKind = catalogSchemaNames;
690
- var ajv;
691
- var dynamicSchemaCache = /* @__PURE__ */ new WeakMap();
692
- var promotedRegionKeySet = new Set(promotedRegionKeys);
693
- var rootPayloadFields = [
694
- "type",
695
- "text",
696
- "items",
697
- "bullets",
698
- "image",
699
- "video",
700
- "chart",
701
- "table",
702
- "code",
703
- "metric",
704
- "quote",
705
- "timeline",
706
- "blocks"
707
- ];
708
- var contentKindSpecs = {
709
- text: {
710
- fields: ["text", "bullets"],
711
- required: [],
712
- requireAny: ["text", "bullets"]
713
- },
714
- list: {
715
- fields: ["items"],
716
- required: ["items"]
717
- },
718
- image: {
719
- fields: ["image"],
720
- required: ["image"]
721
- },
722
- chart: {
723
- fields: ["chart"],
724
- required: ["chart"]
725
- },
726
- table: {
727
- fields: ["table"],
728
- required: ["table"]
729
- },
730
- video: {
731
- fields: ["video"],
732
- required: ["video"]
733
- },
734
- code: {
735
- fields: ["code"],
736
- required: ["code"]
737
- },
738
- metric: {
739
- fields: ["metric"],
740
- required: ["metric"]
741
- },
742
- quote: {
743
- fields: ["quote"],
744
- required: ["quote"]
745
- },
746
- timeline: {
747
- fields: ["timeline"],
748
- required: ["timeline"]
749
- }
750
- };
751
- var columnSpans = {
752
- left: [0],
753
- center: [1],
754
- right: [2],
755
- "left+center": [0, 1],
756
- "center+right": [1, 2],
757
- "left+center+right": [0, 1, 2]
758
- };
759
- var rowSpans = {
760
- top: [0],
761
- middle: [1],
762
- bottom: [2],
763
- "top+middle": [0, 1],
764
- "middle+bottom": [1, 2],
765
- "top+middle+bottom": [0, 1, 2]
766
- };
767
- function getAjv() {
768
- if (ajv) {
769
- return ajv;
770
- }
771
- const instance = new Ajv2020({
772
- allErrors: true,
773
- verbose: true,
774
- strict: false,
775
- allowUnionTypes: true
776
- });
777
- addFormats(instance);
778
- for (const schema of Object.values(schemas)) {
779
- instance.addSchema(schema);
780
- }
781
- ajv = instance;
782
- return instance;
783
- }
784
- function isSchemaName(value) {
785
- return typeof value === "string" && value in schemas;
786
- }
787
- function isCatalogKind(value) {
788
- return typeof value === "string" && value in schemaNameByCatalogKind;
789
- }
790
- function resolveValidator(schemaOrKind) {
791
- const instance = getAjv();
792
- if (isSchemaName(schemaOrKind)) {
793
- const schema = schemas[schemaOrKind];
794
- const validator2 = instance.getSchema(schema.$id) ?? instance.compile(schema);
795
- return { validate: validator2, schemaName: schemaOrKind };
796
- }
797
- if (isCatalogKind(schemaOrKind)) {
798
- const schemaName = schemaNameByCatalogKind[schemaOrKind];
799
- const schema = schemas[schemaName];
800
- const validator2 = instance.getSchema(schema.$id) ?? instance.compile(schema);
801
- return { validate: validator2, schemaName, catalogKind: schemaOrKind };
802
- }
803
- const cached = dynamicSchemaCache.get(schemaOrKind);
804
- if (cached) {
805
- return { validate: cached };
806
- }
807
- const validator = instance.compile(schemaOrKind);
808
- dynamicSchemaCache.set(schemaOrKind, validator);
809
- return { validate: validator };
810
- }
811
- function toIssue(error) {
812
- const issue = {
813
- path: error.instancePath || "/",
814
- message: error.message ?? "failed validation",
815
- keyword: error.keyword,
816
- schemaPath: error.schemaPath,
817
- params: error.params
818
- };
819
- rememberValidationDefinition(issue, error.parentSchema, error.keyword);
820
- return issue;
821
- }
822
- function semanticIssue(path, message, params = {}) {
823
- return {
824
- path,
825
- message,
826
- keyword: "opf",
827
- schemaPath: "#/x-opf-semantics",
828
- params
829
- };
830
- }
831
- function hasOwn(value, key) {
832
- return Object.hasOwn(value, key);
833
- }
834
- function isEnUkTag(value) {
835
- return typeof value === "string" && value.toLowerCase() === "en-uk";
836
- }
837
- function presentFields(value, fields) {
838
- return fields.filter((field) => hasOwn(value, field));
839
- }
840
- function isContentKind(value) {
841
- return typeof value === "string" && value in contentKindSpecs;
842
- }
843
- function inferredKinds(value) {
844
- const kinds = [];
845
- if (presentFields(value, contentKindSpecs.text.fields).length > 0) kinds.push("text");
846
- if (hasOwn(value, "items")) kinds.push("list");
847
- if (hasOwn(value, "image")) kinds.push("image");
848
- if (hasOwn(value, "video")) kinds.push("video");
849
- if (hasOwn(value, "chart")) kinds.push("chart");
850
- if (hasOwn(value, "table")) kinds.push("table");
851
- if (hasOwn(value, "code")) kinds.push("code");
852
- if (hasOwn(value, "metric")) kinds.push("metric");
853
- if (hasOwn(value, "quote")) kinds.push("quote");
854
- if (hasOwn(value, "timeline")) kinds.push("timeline");
855
- return kinds;
856
- }
857
- function isImplicitBlocksComposition(value, inferred, options) {
858
- if (options.slideRoot !== true || hasOwn(value, "blocks")) {
859
- return false;
860
- }
861
- return inferred.length > 1;
862
- }
863
- function validateContentPayload(value, path, options = {}) {
864
- const issues = [];
865
- const explicitType = value.type;
866
- const payloadFields = presentFields(value, rootPayloadFields);
867
- const hasBlocks = hasOwn(value, "blocks");
868
- if (hasBlocks || explicitType === "group") {
869
- if (explicitType !== void 0 && explicitType !== "group") issues.push(semanticIssue(path, "a group must use type 'group' or omit type"));
870
- const incompatible2 = payloadFields.filter((field) => field !== "blocks" && field !== "type");
871
- if (incompatible2.length) issues.push(semanticIssue(path, "blocks cannot be mixed with leaf payload fields", { fields: incompatible2 }));
872
- if (!Array.isArray(value.blocks) || value.blocks.length === 0 && !options.slideRoot) issues.push(semanticIssue(pathFor(path, "blocks"), "a group requires at least one block"));
873
- if (Array.isArray(value.blocks)) value.blocks.forEach((block, index) => {
874
- if (isRecord(block)) issues.push(...validateContentPayload(block, `${pathFor(path, "blocks")}/${index}`));
875
- });
876
- return issues;
877
- }
878
- if (hasOwn(value, "composition") && !options.slideRoot) issues.push(semanticIssue(pathFor(path, "composition"), "composition is only valid on a group containing blocks"));
879
- if (explicitType !== void 0 && !isContentKind(explicitType)) {
880
- return issues;
881
- }
882
- const kind = isContentKind(explicitType) ? explicitType : void 0;
883
- const inferred = kind ? [kind] : inferredKinds(value);
884
- if (!kind && inferred.length === 0) {
885
- if (payloadFields.length > 0 || path !== "/") {
886
- issues.push(semanticIssue(path, "content payload must include concrete content fields", {
887
- fields: payloadFields
888
- }));
889
- }
890
- return issues;
891
- }
892
- if (!kind && inferred.length > 1) {
893
- if (isImplicitBlocksComposition(value, inferred, options)) {
894
- return issues;
895
- }
896
- issues.push(semanticIssue(path, "content payload mixes fields from incompatible content types", {
897
- inferredTypes: inferred
898
- }));
899
- return issues;
900
- }
901
- const resolvedKind = inferred[0];
902
- if (!resolvedKind) {
903
- return issues;
904
- }
905
- const spec = contentKindSpecs[resolvedKind];
906
- const allowedFields = /* @__PURE__ */ new Set([
907
- "type",
908
- ...spec.fields
909
- ]);
910
- for (const required of spec.required) {
911
- if (!hasOwn(value, required)) {
912
- issues.push(semanticIssue(path, `content payload type '${resolvedKind}' requires '${required}'`, {
913
- type: resolvedKind,
914
- required
915
- }));
916
- }
917
- }
918
- if (spec.requireAny && presentFields(value, spec.requireAny).length === 0) {
919
- issues.push(semanticIssue(path, `content payload type '${resolvedKind}' requires one of: ${spec.requireAny.join(", ")}`, {
920
- type: resolvedKind,
921
- requiredAny: spec.requireAny
922
- }));
923
- }
924
- const incompatible = payloadFields.filter((field) => !allowedFields.has(field));
925
- if (incompatible.length > 0) {
926
- issues.push(semanticIssue(path, `content payload type '${resolvedKind}' cannot include incompatible fields: ${incompatible.join(", ")}`, {
927
- type: resolvedKind,
928
- incompatible
929
- }));
930
- }
931
- return issues;
932
- }
933
- function slideRegion(key) {
934
- if (key.includes(":")) {
935
- const [rowPart, columnPart] = key.split(":");
936
- if (!rowPart || !columnPart) return void 0;
937
- const rows = rowSpans[rowPart];
938
- const columns = columnSpans[columnPart];
939
- return rows && columns ? { rows, columns } : void 0;
940
- }
941
- if (key in columnSpans) {
942
- const columns = columnSpans[key];
943
- return columns ? { rows: [0, 1, 2], columns } : void 0;
944
- }
945
- if (key in rowSpans) {
946
- const rows = rowSpans[key];
947
- return rows ? { rows, columns: [0, 1, 2] } : void 0;
948
- }
949
- return void 0;
950
- }
951
- function intersects(left, right) {
952
- return left.some((value) => right.includes(value));
953
- }
954
- function regionsOverlap(left, right) {
955
- return intersects(left.rows, right.rows) && intersects(left.columns, right.columns);
956
- }
957
- function validateSlideRegions(slide, slidePath) {
958
- const issues = [];
959
- const regionKeys = Object.keys(slide).filter((key) => promotedRegionKeySet.has(key));
960
- const rootFields = presentFields(slide, rootPayloadFields);
961
- if (regionKeys.length > 0 && rootFields.length > 0) {
962
- issues.push(semanticIssue(slidePath, "root content payload fields cannot be mixed with promoted region keys", {
963
- rootFields,
964
- regionKeys
965
- }));
966
- }
967
- if (regionKeys.length === 0 && rootFields.length > 0) {
968
- issues.push(...validateContentPayload(slide, slidePath, { slideRoot: true }));
969
- }
970
- for (const key of regionKeys) {
971
- const value = slide[key];
972
- if (isRecord(value)) {
973
- issues.push(...validateContentPayload(value, pathFor(slidePath, key)));
974
- }
975
- }
976
- for (let leftIndex = 0; leftIndex < regionKeys.length; leftIndex += 1) {
977
- const leftKey = regionKeys[leftIndex];
978
- if (!leftKey) continue;
979
- const leftRegion = slideRegion(leftKey);
980
- if (!leftRegion) continue;
981
- for (let rightIndex = leftIndex + 1; rightIndex < regionKeys.length; rightIndex += 1) {
982
- const rightKey = regionKeys[rightIndex];
983
- if (!rightKey) continue;
984
- const rightRegion = slideRegion(rightKey);
985
- if (!rightRegion) continue;
986
- if (regionsOverlap(leftRegion, rightRegion)) {
987
- issues.push(semanticIssue(slidePath, `promoted region keys '${leftKey}' and '${rightKey}' overlap`, {
988
- regionKeys: [leftKey, rightKey]
989
- }));
990
- }
991
- }
992
- }
993
- return issues;
994
- }
995
- function validatePresentationSemantics(value) {
996
- if (!isRecord(value) || !Array.isArray(value.slides)) {
997
- return [];
998
- }
999
- const issues = [];
1000
- if (isEnUkTag(value.language)) {
1001
- issues.push(semanticIssue("/language", "Use 'en-GB' for UK English; 'en-UK' is not a valid BCP-47 region tag", {
1002
- replacement: "en-GB"
1003
- }));
1004
- } else if (isRecord(value.language) && isEnUkTag(value.language.bcp47)) {
1005
- issues.push(semanticIssue("/language/bcp47", "Use 'en-GB' for UK English; 'en-UK' is not a valid BCP-47 region tag", {
1006
- replacement: "en-GB"
1007
- }));
1008
- }
1009
- const documentIds = /* @__PURE__ */ new Map();
1010
- value.slides.forEach((slide, index) => {
1011
- if (isRecord(slide)) {
1012
- const slidePath = `/slides/${index}`;
1013
- if (typeof slide.id === "string") {
1014
- const seen = documentIds.get(slide.id);
1015
- if (seen === "slide") issues.push(semanticIssue(`${slidePath}/id`, "slide ids must be unique within a presentation", { id: slide.id }));
1016
- else if (seen === "payload") issues.push(semanticIssue(`${slidePath}/id`, "slide id duplicates a content payload id; ids must be unique among slide and payload ids within a presentation", { id: slide.id }));
1017
- else documentIds.set(slide.id, "slide");
1018
- }
1019
- visitContentPayloads(slide, slidePath, (payload, path) => {
1020
- if (typeof payload.id === "string") {
1021
- if (documentIds.has(payload.id)) issues.push(semanticIssue(`${path}/id`, "content payload ids must be unique among slide and payload ids within a presentation", { id: payload.id }));
1022
- else documentIds.set(payload.id, "payload");
1023
- }
1024
- });
1025
- issues.push(...validateSlideRegions(slide, slidePath));
1026
- const payloadTableIssues = (payload, path) => {
1027
- if (isRecord(payload.table)) for (const issue of tableGrid(payload.table).issues) issues.push(semanticIssue(pathFor(path, "table") + issue.path.slice(5).replaceAll(".", "/"), issue.message));
1028
- };
1029
- payloadTableIssues(slide, slidePath);
1030
- visitContentPayloads(slide, slidePath, payloadTableIssues);
1031
- }
1032
- });
1033
- return issues;
1034
- }
1035
- function inlineCatalogEntry(context, kind) {
1036
- const catalogsField = context.document.catalogs;
1037
- if (!isRecord(catalogsField)) {
1038
- return void 0;
1039
- }
1040
- const entry = catalogsField[kind];
1041
- return isRecord(entry) ? entry : void 0;
1042
- }
1043
- function unknownIdWarning(kind, value, path, context) {
1044
- if (typeof value !== "string" || !bareIdPattern.test(value)) {
1045
- return void 0;
1046
- }
1047
- if (context) {
1048
- const entry = inlineCatalogEntry(context, kind);
1049
- if (entry) {
1050
- const inline = Array.isArray(entry.records) ? entry.records.find((record) => isRecord(record) && record.id === value) : void 0;
1051
- if (isRecord(inline)) {
1052
- const replacedBy = isRecord(inline.deprecation) ? inline.deprecation.replacedBy : void 0;
1053
- return typeof replacedBy === "string" ? deprecatedIdWarning(kind, value, replacedBy, path) : void 0;
1054
- }
1055
- if (typeof entry.source === "string" || Array.isArray(entry.source) && entry.source.length > 0) {
1056
- return void 0;
1057
- }
1058
- }
1059
- }
1060
- if (catalogIds[kind].includes(value)) {
1061
- const replacedBy = deprecatedCatalogIds[`${kind}/${value}`];
1062
- return replacedBy === void 0 ? void 0 : deprecatedIdWarning(kind, value, replacedBy, path);
1063
- }
1064
- return semanticIssue(path, `unknown ${kind} catalog id '${value}'`, { kind, id: value });
1065
- }
1066
- function deprecatedIdWarning(kind, id, replacedBy, path) {
1067
- return semanticIssue(path, `deprecated ${kind} catalog id '${id}'; use '${replacedBy}'`, { kind, id, replacedBy });
1068
- }
1069
- function referenceObjectWarning(kind, value, path, context) {
1070
- if (typeof value === "string") {
1071
- return unknownIdWarning(kind, value, path, context);
1072
- }
1073
- if (isRecord(value)) {
1074
- return unknownIdWarning(kind, value.id, pathFor(path, "id"), context);
1075
- }
1076
- return void 0;
1077
- }
1078
- function pushIfDefined(issues, issue) {
1079
- if (issue) {
1080
- issues.push(issue);
1081
- }
1082
- }
1083
- function designReferenceWarnings(design, path, context) {
1084
- if (!isRecord(design)) {
1085
- return [];
1086
- }
1087
- const issues = [];
1088
- pushIfDefined(issues, referenceObjectWarning("themes", design.theme, pathFor(path, "theme"), context));
1089
- pushIfDefined(issues, referenceObjectWarning("colorSchemes", design.colorScheme, pathFor(path, "colorScheme"), context));
1090
- pushIfDefined(issues, referenceObjectWarning("fontSchemes", design.fontScheme, pathFor(path, "fontScheme"), context));
1091
- if (isRecord(design.theme)) {
1092
- const themePath = pathFor(path, "theme");
1093
- pushIfDefined(issues, referenceObjectWarning("colorSchemes", design.theme.colorScheme, pathFor(themePath, "colorScheme"), context));
1094
- pushIfDefined(issues, referenceObjectWarning("fontSchemes", design.theme.fontScheme, pathFor(themePath, "fontScheme"), context));
1095
- }
1096
- return issues;
1097
- }
1098
- function chartTypeWarnings(payload, path, context) {
1099
- if (!isRecord(payload)) {
1100
- return [];
1101
- }
1102
- const issues = [];
1103
- if (isRecord(payload.chart)) {
1104
- pushIfDefined(issues, unknownIdWarning("chartTypes", payload.chart.type, `${pathFor(path, "chart")}/type`, context));
1105
- }
1106
- if (Array.isArray(payload.blocks)) {
1107
- payload.blocks.forEach((block, index) => {
1108
- issues.push(...chartTypeWarnings(block, `${pathFor(path, "blocks")}/${index}`, context));
1109
- });
1110
- }
1111
- return issues;
1112
- }
1113
- var cellBorderEdges = ["top", "right", "bottom", "left"];
1114
- var variableIdPattern = /^[a-z][a-z0-9-]*$/;
1115
- var hexColorPattern = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
1116
- var schemeColorNames = /* @__PURE__ */ new Set([
1117
- "accent1",
1118
- "accent2",
1119
- "accent3",
1120
- "accent4",
1121
- "accent5",
1122
- "accent6",
1123
- "dark1",
1124
- "dark2",
1125
- "light1",
1126
- "light2",
1127
- "hyperlink",
1128
- "followedHyperlink",
1129
- "primary",
1130
- "secondary",
1131
- "accent",
1132
- "background",
1133
- "surface",
1134
- "text",
1135
- "textSecondary"
1136
- ]);
1137
- function variableReferenceWarnings(value) {
1138
- if (!Array.isArray(value.slides)) {
1139
- return [];
1140
- }
1141
- const variables = isRecord(value.variables) ? value.variables : {};
1142
- const issues = [];
1143
- const colorRef = (entry, path) => {
1144
- if (typeof entry !== "string" || !entry.startsWith("var:")) return;
1145
- const id = entry.slice("var:".length);
1146
- if (!variableIdPattern.test(id) || hasOwn(variables, id)) return;
1147
- issues.push(semanticIssue(path, `unknown variable '${id}'; declare it in the top-level variables map`, { id }));
1148
- };
1149
- const runColor = (entry, path) => {
1150
- if (typeof entry !== "string") return;
1151
- if (hexColorPattern.test(entry) || schemeColorNames.has(entry)) return;
1152
- if (entry.startsWith("var:") && variableIdPattern.test(entry.slice("var:".length))) {
1153
- colorRef(entry, path);
1154
- return;
1155
- }
1156
- issues.push(semanticIssue(
1157
- path,
1158
- `run color '${entry}' is not a hex color, a color-scheme name, or a 'var:' reference; renderers fall back to the theme color`,
1159
- { color: entry }
1160
- ));
1161
- };
1162
- const richText = (entry, path) => {
1163
- if (!Array.isArray(entry)) return;
1164
- entry.forEach((run, index) => {
1165
- if (isRecord(run)) runColor(run.color, `${path}/${index}/color`);
1166
- });
1167
- };
1168
- const cellStyle = (style, path) => {
1169
- if (!isRecord(style)) return;
1170
- colorRef(style.fill, pathFor(path, "fill"));
1171
- colorRef(style.color, pathFor(path, "color"));
1172
- if (!isRecord(style.borders)) return;
1173
- const bordersPath = pathFor(path, "borders");
1174
- for (const edge of cellBorderEdges) {
1175
- const border = style.borders[edge];
1176
- if (isRecord(border)) colorRef(border.color, `${pathFor(bordersPath, edge)}/color`);
1177
- }
1178
- };
1179
- const tableCell = (cell, path) => {
1180
- if (Array.isArray(cell)) {
1181
- richText(cell, path);
1182
- return;
1183
- }
1184
- if (!isRecord(cell)) return;
1185
- richText(cell.value, pathFor(path, "value"));
1186
- cellStyle(cell.style, pathFor(path, "style"));
1187
- };
1188
- const table = (node, path) => {
1189
- if (!isRecord(node)) return;
1190
- if (Array.isArray(node.columns)) {
1191
- const columnsPath = pathFor(path, "columns");
1192
- node.columns.forEach((column, index) => {
1193
- tableCell(column, `${columnsPath}/${index}`);
1194
- });
1195
- }
1196
- if (Array.isArray(node.rows)) {
1197
- const rowsPath = pathFor(path, "rows");
1198
- node.rows.forEach((row, rowIndex) => {
1199
- if (!Array.isArray(row)) return;
1200
- row.forEach((cell, cellIndex) => {
1201
- tableCell(cell, `${rowsPath}/${rowIndex}/${cellIndex}`);
1202
- });
1203
- });
1204
- }
1205
- };
1206
- const textEntries = (entries, path) => {
1207
- if (!Array.isArray(entries)) return;
1208
- entries.forEach((entry, index) => {
1209
- const entryPath = `${path}/${index}`;
1210
- if (Array.isArray(entry)) {
1211
- richText(entry, entryPath);
1212
- return;
1213
- }
1214
- if (!isRecord(entry)) return;
1215
- richText(entry.text, pathFor(entryPath, "text"));
1216
- richText(entry.description, pathFor(entryPath, "description"));
1217
- });
1218
- };
1219
- const payload = (node, path) => {
1220
- richText(node.text, pathFor(path, "text"));
1221
- textEntries(node.items, pathFor(path, "items"));
1222
- textEntries(node.bullets, pathFor(path, "bullets"));
1223
- table(node.table, pathFor(path, "table"));
1224
- };
1225
- value.slides.forEach((slide, index) => {
1226
- if (!isRecord(slide)) return;
1227
- const slidePath = `/slides/${index}`;
1228
- payload(slide, slidePath);
1229
- visitContentPayloads(slide, slidePath, payload);
1230
- });
1231
- return issues;
1232
- }
1233
- function presentationReferenceWarnings(value) {
1234
- if (!isRecord(value) || !Array.isArray(value.slides)) {
1235
- return [];
1236
- }
1237
- const context = { document: value };
1238
- const issues = [];
1239
- if (typeof value.narrative === "string") {
1240
- pushIfDefined(issues, unknownIdWarning("narratives", value.narrative, "/narrative", context));
1241
- }
1242
- if (Array.isArray(value.audience)) {
1243
- value.audience.forEach((entry, index) => {
1244
- pushIfDefined(issues, referenceObjectWarning("audiences", entry, `/audience/${index}`, context));
1245
- });
1246
- } else {
1247
- pushIfDefined(issues, unknownIdWarning("audiences", value.audience, "/audience", context));
1248
- }
1249
- issues.push(...designReferenceWarnings(value.design, "/design", context));
1250
- issues.push(...variableReferenceWarnings(value));
1251
- value.slides.forEach((slide, index) => {
1252
- if (!isRecord(slide)) {
1253
- return;
1254
- }
1255
- const slidePath = `/slides/${index}`;
1256
- issues.push(...designReferenceWarnings(slide.design, pathFor(slidePath, "design"), context));
1257
- issues.push(...chartTypeWarnings(slide, slidePath, context));
1258
- for (const key of Object.keys(slide)) {
1259
- if (promotedRegionKeySet.has(key)) {
1260
- issues.push(...chartTypeWarnings(slide[key], pathFor(slidePath, key), context));
1261
- }
1262
- }
1263
- });
1264
- return issues;
1265
- }
1266
- var catalogCrossLinkFields = {
1267
- audience: { recommendedNarratives: "narratives", recommendedTones: "tones" },
1268
- purpose: { recommendedNarratives: "narratives", recommendedTones: "tones" },
1269
- tone: { recommendedNarratives: "narratives" }
1270
- };
1271
- function catalogCrossLinkWarnings(schemaName, value) {
1272
- const fields = catalogCrossLinkFields[schemaName];
1273
- if (!fields || !isRecord(value)) {
1274
- return [];
1275
- }
1276
- const issues = [];
1277
- for (const [field, kind] of Object.entries(fields)) {
1278
- const links = value[field];
1279
- if (!Array.isArray(links)) {
1280
- continue;
1281
- }
1282
- links.forEach((link, index) => {
1283
- pushIfDefined(issues, unknownIdWarning(kind, link, `${pathFor("/", field)}/${index}`));
1284
- });
1285
- }
1286
- return issues;
1287
- }
1288
- function validateLanguageSemantics(value) {
1289
- if (!isRecord(value)) {
1290
- return [];
1291
- }
1292
- if (isEnUkTag(value.bcp47)) {
1293
- return [semanticIssue("/bcp47", "Use 'en-GB' for UK English; 'en-UK' is not a valid BCP-47 region tag", {
1294
- replacement: "en-GB"
1295
- })];
1296
- }
1297
- return [];
1298
- }
1299
- function contentDepthIssues(value) {
1300
- if (!isRecord(value) || !Array.isArray(value.slides)) return [];
1301
- const stack = [];
1302
- value.slides.forEach((slide, index) => {
1303
- if (!isRecord(slide)) return;
1304
- if (Array.isArray(slide.blocks)) slide.blocks.forEach((block, i) => {
1305
- stack.push({ value: block, path: `/slides/${index}/blocks/${i}`, depth: 0, ancestors: [] });
1306
- });
1307
- for (const key of promotedRegionKeys) if (hasOwn(slide, key)) stack.push({ value: slide[key], path: `/slides/${index}/${key}`, depth: 0, ancestors: [] });
1308
- });
1309
- while (stack.length) {
1310
- const entry = stack.pop();
1311
- if (!isRecord(entry.value) || !Array.isArray(entry.value.blocks)) continue;
1312
- if (entry.ancestors.includes(entry.value) || entry.depth >= MAX_COMPOSITION_DEPTH) return [semanticIssue(entry.path, `content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels`)];
1313
- const ancestors = [...entry.ancestors, entry.value];
1314
- entry.value.blocks.forEach((block, i) => {
1315
- stack.push({ value: block, path: `${entry.path}/blocks/${i}`, depth: entry.depth + 1, ancestors });
1316
- });
1317
- }
1318
- return [];
1319
- }
1320
- function validate(value, schemaOrKind = "presentation") {
1321
- const resolved = resolveValidator(schemaOrKind);
1322
- if (resolved.schemaName === "presentation") {
1323
- const errors2 = contentDepthIssues(value);
1324
- if (errors2.length) return { valid: false, errors: errors2, warnings: [], schemaName: resolved.schemaName };
1325
- }
1326
- const valid = resolved.validate(value) === true;
1327
- const errors = valid ? [] : (resolved.validate.errors ?? []).map(toIssue);
1328
- const warnings = [];
1329
- if (resolved.schemaName === "presentation") {
1330
- errors.push(...validatePresentationSemantics(value));
1331
- warnings.push(...presentationReferenceWarnings(value));
1332
- } else if (resolved.schemaName === "language") {
1333
- errors.push(...validateLanguageSemantics(value));
1334
- }
1335
- if (resolved.schemaName) {
1336
- warnings.push(...catalogCrossLinkWarnings(resolved.schemaName, value));
1337
- }
1338
- return {
1339
- valid: errors.length === 0,
1340
- errors,
1341
- warnings,
1342
- schemaName: resolved.schemaName,
1343
- catalogKind: resolved.catalogKind
1344
- };
1345
- }
1346
- function assertValid(value, schemaOrKind = "presentation") {
1347
- const result = validate(value, schemaOrKind);
1348
- if (!result.valid) {
1349
- throw new OPFValidationError(result);
1350
- }
1351
- return value;
1352
- }
1353
- function validatePresentation(value) {
1354
- return validate(value, "presentation");
1355
- }
1356
- function assertValidPresentation(value) {
1357
- assertValid(value, "presentation");
1358
- }
1359
- function validateCatalogRecord(kind, value) {
1360
- return validate(value, kind);
1361
- }
1362
- function assertValidCatalogRecord(kind, value) {
1363
- assertValid(value, kind);
1364
- }
1365
-
1366
- export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, bareIdPattern, isRecord, promotedRegionKeys, validate, validateCatalogRecord, validatePresentation, validationDefinition, visitContentPayloads };