@openpresentation/opf 0.14.0 → 0.16.0
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/README.md +28 -38
- package/dist/catalog-refs-_anZs-Qz.d.ts +128 -0
- package/dist/catalog-schemas-BZCjgAxu.d.ts +12 -0
- package/dist/catalog.d.ts +91 -0
- package/dist/{chunk-XOZ4KMSR.js → catalog.js} +17018 -8816
- package/dist/{chart-data-B_3z9VTb.d.ts → chart-data-BnNqgnC-.d.ts} +1 -1
- package/dist/{chunk-BFLVSVA7.js → chunk-3XDRQYWZ.js} +1 -1
- package/dist/{chunk-6OXY2CP3.js → chunk-5PDN7BN6.js} +503 -239
- package/dist/{chunk-CSQHPVGL.js → chunk-5TO6I3GB.js} +1 -1
- package/dist/{chunk-4LDGKLUC.js → chunk-5UEUAW57.js} +4 -2
- package/dist/{chunk-5ZU6JAPP.js → chunk-6OR326EA.js} +1 -1
- package/dist/{chunk-XIZUK2XM.js → chunk-BSYQDWT4.js} +15 -3
- package/dist/{chunk-UPQQD7MA.js → chunk-FQSIIADJ.js} +15 -6
- package/dist/{chunk-D3TY4TT6.js → chunk-HXHOZ7AH.js} +1407 -154
- package/dist/chunk-K4DQQIT4.js +319 -0
- package/dist/chunk-KINQFU6X.js +51 -0
- package/dist/{chunk-4VJDTF55.js → chunk-NAWQR7MN.js} +1 -1
- package/dist/{chunk-JDJBDYSR.js → chunk-PX5AWL7Y.js} +333 -857
- package/dist/{chunk-Q2TCMN56.js → chunk-SMLMI6IZ.js} +5 -2
- package/dist/chunk-SPFV27O5.js +210 -0
- package/dist/chunk-TRDXRRQK.js +17 -0
- package/dist/{chunk-Z65B2B77.js → chunk-UM24JFUE.js} +2 -2
- package/dist/{chunk-LS2FMPI5.js → chunk-WEDGVC5W.js} +969 -886
- package/dist/{composition-_WEwBe2a.d.ts → composition-D4ADF5c-.d.ts} +319 -115
- package/dist/composition.d.ts +3 -2
- package/dist/composition.js +2 -2
- package/dist/convert.d.ts +14 -17
- package/dist/convert.js +36 -39
- package/dist/data.d.ts +28 -11
- package/dist/data.js +3 -3
- package/dist/deck.d.ts +77 -0
- package/dist/deck.js +12 -0
- package/dist/diff.d.ts +1 -1
- package/dist/diff.js +7 -7
- package/dist/docs.js +33 -33
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +51761 -4783
- package/dist/{finding-C_por275.d.ts → finding-CT_f_vbD.d.ts} +2 -2
- package/dist/format.js +2 -2
- package/dist/index.d.ts +227 -77
- package/dist/index.js +343 -258
- package/dist/json-BFSdESOE.d.ts +19 -0
- package/dist/markdown.d.ts +20 -9
- package/dist/markdown.js +9 -9
- package/dist/{pagination-BZpXLvFL.d.ts → pagination-DzZPFheM.d.ts} +31 -31
- package/dist/pagination.d.ts +4 -5
- package/dist/pagination.js +6 -6
- package/dist/patch.d.ts +1 -1
- package/dist/patch.js +6 -6
- package/dist/{presentation-C5eHkevA.d.ts → presentation-COrFuj2g.d.ts} +398 -558
- package/dist/repo-readme.js +1 -1
- package/dist/schemas.d.ts +298 -1
- package/dist/schemas.js +1 -1
- package/dist/spec/README.md +1 -1
- package/dist/spec/catalogs/font-schemes/angsana-new.json +1 -1
- package/dist/spec/catalogs/font-schemes/aparajita.json +2 -2
- package/dist/spec/catalogs/font-schemes/arabic-typesetting.json +1 -1
- package/dist/spec/catalogs/font-schemes/batang.json +1 -1
- package/dist/spec/catalogs/font-schemes/daunpenh.json +1 -1
- package/dist/spec/catalogs/font-schemes/david.json +1 -1
- package/dist/spec/catalogs/font-schemes/dilleniaupc.json +1 -1
- package/dist/spec/catalogs/font-schemes/fangsong.json +1 -1
- package/dist/spec/catalogs/font-schemes/gautami.json +1 -1
- package/dist/spec/catalogs/font-schemes/gisha.json +2 -2
- package/dist/spec/catalogs/font-schemes/gungsuh.json +1 -1
- package/dist/spec/catalogs/font-schemes/index.json +1 -1
- package/dist/spec/catalogs/font-schemes/kalinga.json +1 -1
- package/dist/spec/catalogs/font-schemes/kartika.json +1 -1
- package/dist/spec/catalogs/font-schemes/khmer-ui.json +1 -1
- package/dist/spec/catalogs/font-schemes/latha.json +1 -1
- package/dist/spec/catalogs/font-schemes/malgun-gothic.json +1 -1
- package/dist/spec/catalogs/font-schemes/mangal.json +3 -3
- package/dist/spec/catalogs/font-schemes/meiryo.json +1 -1
- package/dist/spec/catalogs/font-schemes/microsoft-jhenghei.json +1 -1
- package/dist/spec/catalogs/font-schemes/microsoft-yahei.json +4 -4
- package/dist/spec/catalogs/font-schemes/mingliu.json +1 -1
- package/dist/spec/catalogs/font-schemes/miriam.json +1 -1
- package/dist/spec/catalogs/font-schemes/ms-mincho.json +1 -1
- package/dist/spec/catalogs/font-schemes/nirmala-ui.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-naksh-arabic.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-nastaliq-urdu.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-arabic.json +3 -3
- package/dist/spec/catalogs/font-schemes/noto-sans-armenian.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-bengali.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-devangari.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-ethiopic.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-georgian.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-gujarati.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-gurmukhi.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-hebrew.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-jp.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-kannada.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-khmer.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-kr.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-malayalam.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-mongolian.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-oriya.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-sc.json +4 -4
- package/dist/spec/catalogs/font-schemes/noto-sans-tamil.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-tc.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-telugu.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans-thai.json +1 -1
- package/dist/spec/catalogs/font-schemes/noto-sans.json +4 -4
- package/dist/spec/catalogs/font-schemes/nyala.json +1 -1
- package/dist/spec/catalogs/font-schemes/pmingliu.json +1 -1
- package/dist/spec/catalogs/font-schemes/raavi.json +1 -1
- package/dist/spec/catalogs/font-schemes/sakkal-majalla.json +3 -3
- package/dist/spec/catalogs/font-schemes/shonar-bangla.json +2 -2
- package/dist/spec/catalogs/font-schemes/shruti.json +1 -1
- package/dist/spec/catalogs/font-schemes/simsun.json +1 -1
- package/dist/spec/catalogs/font-schemes/sylfaen.json +2 -2
- package/dist/spec/catalogs/font-schemes/traditional-arabic.json +3 -3
- package/dist/spec/catalogs/font-schemes/tunga.json +1 -1
- package/dist/spec/catalogs/font-schemes/vrinda.json +1 -1
- package/dist/spec/catalogs/font-schemes/yu-gothic.json +1 -1
- package/dist/spec/catalogs/layouts/business-model-canvas.json +66 -1
- package/dist/spec/catalogs/layouts/capability-map.json +53 -6
- package/dist/spec/catalogs/layouts/chart-1x-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/chart-2x-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/chart-2x-vertical-title-left.json +37 -0
- package/dist/spec/catalogs/layouts/chart-2x.json +32 -8
- package/dist/spec/catalogs/layouts/chart-3x-bottom-vertical-title-left.json +52 -0
- package/dist/spec/catalogs/layouts/chart-3x-left-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/chart-3x-left.json +46 -0
- package/dist/spec/catalogs/layouts/chart-3x-right-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/chart-3x-right.json +46 -0
- package/dist/spec/catalogs/layouts/chart-3x-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/chart-3x-top-vertical-title-left.json +52 -0
- package/dist/spec/catalogs/layouts/chart-3x.json +48 -12
- package/dist/spec/catalogs/layouts/competitive-landscape.json +1 -4
- package/dist/spec/catalogs/layouts/customer-journey.json +1 -4
- package/dist/spec/catalogs/layouts/dashboard.json +37 -5
- package/dist/spec/catalogs/layouts/decision-tree.json +1 -4
- package/dist/spec/catalogs/layouts/ecosystem-map.json +1 -4
- package/dist/spec/catalogs/layouts/extract/canonical.json +0 -9
- package/dist/spec/catalogs/layouts/geographic-map.json +1 -4
- package/dist/spec/catalogs/layouts/icon-grid.json +1 -4
- package/dist/spec/catalogs/layouts/image-1x-crop-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/image-1x-crop-title-left.json +32 -0
- package/dist/spec/catalogs/layouts/image-1x-crop.json +27 -0
- package/dist/spec/catalogs/layouts/image-1x-fit-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/image-1x.json +3 -0
- package/dist/spec/catalogs/layouts/image-2x-crop-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/image-2x-crop-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/image-2x-crop-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/image-2x-crop.json +33 -0
- package/dist/spec/catalogs/layouts/image-2x-fit-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/image-2x-fit-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/image-2x-fit-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/image-2x.json +35 -8
- package/dist/spec/catalogs/layouts/image-3x-crop-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/image-3x-crop-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/image-3x-crop-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/image-3x-crop.json +36 -0
- package/dist/spec/catalogs/layouts/image-3x-fit-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/image-3x-fit-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/image-3x-fit-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/image-3x-fit.json +36 -0
- package/dist/spec/catalogs/layouts/image-3x.json +51 -12
- package/dist/spec/catalogs/layouts/image-focus.json +3 -6
- package/dist/spec/catalogs/layouts/image-only-1x-crop-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/image-only-1x-fit-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/image-only-2x-crop-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical-title-left.json +38 -0
- package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical.json +33 -0
- package/dist/spec/catalogs/layouts/image-only-2x-fit-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical-title-left.json +38 -0
- package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical.json +33 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical.json +36 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop.json +35 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical.json +36 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit.json +35 -0
- package/dist/spec/catalogs/layouts/index.json +1041 -151
- package/dist/spec/catalogs/layouts/kpi-scorecard.json +48 -3
- package/dist/spec/catalogs/layouts/list-1x-box-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-center.json +33 -0
- package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-left.json +33 -0
- package/dist/spec/catalogs/layouts/list-1x-box-vertical.json +28 -0
- package/dist/spec/catalogs/layouts/list-1x-box.json +27 -0
- package/dist/spec/catalogs/layouts/list-1x-itemimage-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/list-1x-itemimage-vertical-title-center.json +33 -0
- package/dist/spec/catalogs/layouts/list-1x-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/list-1x-vertical-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/list-2x-box-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-box-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/list-2x-box.json +33 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/list-2x-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/list-2x-vertical-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-vertical-title-left.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-vertical.json +33 -0
- package/dist/spec/catalogs/layouts/list-3x-box-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-center.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-box-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/list-3x-box.json +36 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-center.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage.json +36 -0
- package/dist/spec/catalogs/layouts/list-3x-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/list-3x-vertical-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-vertical.json +36 -0
- package/dist/spec/catalogs/layouts/list-4x-box-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-left.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-box-vertical.json +40 -0
- package/dist/spec/catalogs/layouts/list-4x-box.json +40 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-left.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical.json +40 -0
- package/dist/spec/catalogs/layouts/list-4x-title-center.json +44 -0
- package/dist/spec/catalogs/layouts/list-4x-vertical-title-center.json +44 -0
- package/dist/spec/catalogs/layouts/list-4x-vertical-title-left.json +44 -0
- package/dist/spec/catalogs/layouts/list-4x-vertical.json +39 -0
- package/dist/spec/catalogs/layouts/list-5x-box-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-center.json +50 -0
- package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-left.json +50 -0
- package/dist/spec/catalogs/layouts/list-5x-box-vertical.json +45 -0
- package/dist/spec/catalogs/layouts/list-5x-box.json +43 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-left.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical.json +43 -0
- package/dist/spec/catalogs/layouts/list-5x-title-center.json +47 -0
- package/dist/spec/catalogs/layouts/list-5x-vertical-title-center.json +47 -0
- package/dist/spec/catalogs/layouts/list-5x-vertical-title-left.json +47 -0
- package/dist/spec/catalogs/layouts/list-5x-vertical.json +42 -0
- package/dist/spec/catalogs/layouts/list-6x-box-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-center.json +53 -0
- package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-left.json +53 -0
- package/dist/spec/catalogs/layouts/list-6x-box-vertical.json +48 -0
- package/dist/spec/catalogs/layouts/list-6x-box.json +46 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-left.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical.json +46 -0
- package/dist/spec/catalogs/layouts/list-6x-title-center.json +50 -0
- package/dist/spec/catalogs/layouts/list-6x-vertical-title-center.json +50 -0
- package/dist/spec/catalogs/layouts/list-6x-vertical-title-left.json +50 -0
- package/dist/spec/catalogs/layouts/list-6x-vertical.json +45 -0
- package/dist/spec/catalogs/layouts/logic-tree.json +69 -0
- package/dist/spec/catalogs/layouts/market-size.json +26 -2
- package/dist/spec/catalogs/layouts/network-dependency-map.json +1 -4
- package/dist/spec/catalogs/layouts/number-1x-box-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/number-1x-box.json +25 -0
- package/dist/spec/catalogs/layouts/number-1x-title-center.json +29 -0
- package/dist/spec/catalogs/layouts/number-2x-box-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/number-2x-box.json +31 -0
- package/dist/spec/catalogs/layouts/number-2x-title-center.json +35 -0
- package/dist/spec/catalogs/layouts/number-3x-box-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/number-3x-box.json +34 -0
- package/dist/spec/catalogs/layouts/number-3x-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/number-4x-box-title-center.json +43 -0
- package/dist/spec/catalogs/layouts/number-4x-box.json +38 -0
- package/dist/spec/catalogs/layouts/number-4x-title-center.json +42 -0
- package/dist/spec/catalogs/layouts/number-5x-box-title-center.json +46 -0
- package/dist/spec/catalogs/layouts/number-5x-box.json +41 -0
- package/dist/spec/catalogs/layouts/number-5x-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/number-6x-box-title-center.json +49 -0
- package/dist/spec/catalogs/layouts/number-6x-box.json +44 -0
- package/dist/spec/catalogs/layouts/number-6x-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/org-chart.json +53 -6
- package/dist/spec/catalogs/layouts/persona-grid.json +1 -4
- package/dist/spec/catalogs/layouts/photo-grid.json +1 -4
- package/dist/spec/catalogs/layouts/product-feature.json +1 -4
- package/dist/spec/catalogs/layouts/screenshot-walkthrough.json +1 -4
- package/dist/spec/catalogs/layouts/swimlane-process.json +1 -4
- package/dist/spec/catalogs/layouts/team-bio.json +1 -4
- package/dist/spec/catalogs/layouts/text-1x-box-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-box-title-left.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-center-box-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-center-box-title-left.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-center-box.json +26 -0
- package/dist/spec/catalogs/layouts/text-1x-center-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/text-1x-center-title-left.json +30 -0
- package/dist/spec/catalogs/layouts/text-1x-center.json +25 -0
- package/dist/spec/catalogs/layouts/text-1x-left-box.json +26 -0
- package/dist/spec/catalogs/layouts/text-1x-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/text-2x-box-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-box-vertical-title-left.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-center-box-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-center-box-vertical-title-left.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-center-box.json +32 -0
- package/dist/spec/catalogs/layouts/text-2x-center-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x-center-vertical-title-left.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x-center.json +31 -0
- package/dist/spec/catalogs/layouts/text-2x-left-box.json +32 -0
- package/dist/spec/catalogs/layouts/text-2x-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x-vertical-title-left.json +36 -0
- package/dist/spec/catalogs/layouts/text-3x-box-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x-box-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/text-3x-center-box-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x-center-box-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/text-3x-center-box.json +35 -0
- package/dist/spec/catalogs/layouts/text-3x-center-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/text-3x-center-vertical-title-left.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x-center.json +34 -0
- package/dist/spec/catalogs/layouts/text-3x-left-box.json +35 -0
- package/dist/spec/catalogs/layouts/text-3x-left.json +34 -0
- package/dist/spec/catalogs/layouts/text-3x-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/text-3x-vertical-title-left.json +40 -0
- package/dist/spec/catalogs/layouts/title-center-box.json +27 -0
- package/dist/spec/catalogs/layouts/title-center-image-bottom.json +34 -0
- package/dist/spec/catalogs/layouts/title-center-image-top.json +34 -0
- package/dist/spec/catalogs/layouts/title-center.json +26 -0
- package/dist/spec/catalogs/layouts/title-left-image-bottom.json +34 -0
- package/dist/spec/catalogs/layouts/title-left-image-left.json +34 -0
- package/dist/spec/catalogs/layouts/title-left-image-right.json +34 -0
- package/dist/spec/catalogs/layouts/title-left-image-top.json +34 -0
- package/dist/spec/catalogs/manifest.json +18 -18
- package/dist/spec/catalogs/narratives/heros-journey.json +1 -1
- package/dist/spec/catalogs/narratives/index.json +1 -1
- package/dist/spec/openapi.yaml +3 -3
- package/dist/spec/reference/engine-defaults.json +22 -30
- package/dist/spec/reference/engine-vocabularies.json +1577 -0
- package/dist/spec/schemas/audience.schema.json +5 -26
- package/dist/spec/schemas/catalog-manifest.schema.json +3 -3
- package/dist/spec/schemas/chart-type.schema.json +2 -35
- package/dist/spec/schemas/color-scheme.schema.json +3 -24
- package/dist/spec/schemas/finding.schema.json +1 -1
- package/dist/spec/schemas/font-scheme.schema.json +6 -37
- package/dist/spec/schemas/language.schema.json +7 -28
- package/dist/spec/schemas/layout.schema.json +227 -55
- package/dist/spec/schemas/narrative.schema.json +4 -24
- package/dist/spec/schemas/opf.schema.json +410 -374
- package/dist/spec/schemas/purpose.schema.json +5 -26
- package/dist/spec/schemas/social-platform.schema.json +2 -23
- package/dist/spec/schemas/theme.schema.json +9 -37
- package/dist/spec/schemas/tone.schema.json +4 -25
- package/dist/spec-files.d.ts +1 -1
- package/dist/spec-files.js +1 -1
- package/dist/types.d.ts +1103 -4
- package/dist/{validation-types-zh03LeZy.d.ts → validation-types-HxIgJfKx.d.ts} +7 -7
- package/dist/validator.d.ts +15 -12
- package/dist/validator.js +5 -5
- package/dist/yaml.d.ts +22 -7
- package/dist/yaml.js +9 -321
- package/package.json +9 -9
- package/dist/catalogs-D-yyQWCQ.d.ts +0 -1343
- package/dist/catalogs.d.ts +0 -2
- package/dist/catalogs.js +0 -2
- package/dist/chunk-PIQXLBBJ.js +0 -445
- package/dist/chunk-S5W34SIJ.js +0 -1
- package/dist/previews.d.ts +0 -40
- package/dist/previews.js +0 -1
- package/dist/schemas-DDpqAgyS.d.ts +0 -284
- package/dist/spec/catalogs/layouts/image-bleed.json +0 -20
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { promotedRegionKeys, VARIABLE_KINDS, resolveChartData, chartPaletteForFill, tableGrid, timelineTextColor, visitContentPayloads, readingRows, visualReadingOrder, intrinsicImageSize, textWidthMeasurer, normalizeHexColor, resolveColorRef,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { promotedRegionKeys, VARIABLE_KINDS, resolveChartData, chartPaletteForFill, imageBackground, tableGrid, timelineTextColor, visitContentPayloads, readingRows, visualReadingOrder, intrinsicImageSize, textWidthMeasurer, normalizeHexColor, resolveColorRef, resolveDesignRecords, resolveColorRoles, resolveFontFamilies, resolveCanvasDimensions, defaultSlideBackground, isRecord, hasContentVariables, isTemplate, instantiateForValidation, unusedDatasets, MAX_COMPOSITION_DEPTH, datasetDiagnostics, pathFor, collectCitations, numberingFindings, walkCitationRuns, resolveTableData, resolveChartOptions, chartOptionTarget, codeHighlightLines, chartNumberFixesByCell, MAX_PLACEHOLDER_GROUP_DEPTH, OPFCompositionError, composeSlide, resolveScriptFonts } from './chunk-5PDN7BN6.js';
|
|
2
|
+
import { catalogSchemaNames } from './chunk-TRDXRRQK.js';
|
|
3
|
+
import { resolveReference, checkCatalogsOption, provenanceOf, unresolvedReference, OPFUnresolvedReferenceError, catalogReferenceSites, parseReference, catalogGroupDeclared, pointerPath, catalogRecords, catalogKinds, catalogGroupSource, registeredCatalog } from './chunk-SPFV27O5.js';
|
|
4
|
+
import { schemaEntries, schemas } from './chunk-WEDGVC5W.js';
|
|
4
5
|
import Ajv2020 from 'ajv/dist/2020.js';
|
|
5
6
|
import addFormats from 'ajv-formats';
|
|
6
7
|
import { parseTree, printParseErrorCode, getNodePath } from 'jsonc-parser';
|
|
@@ -71,450 +72,6 @@ function unusedReferenceWarnings(value) {
|
|
|
71
72
|
return value.references.flatMap((reference, index) => isRecord(reference) && typeof reference.id === "string" && unused.includes(reference.id) ? [issue(`/references/${index}`, `reference '${reference.id}' is never cited; cite it with a run's cite field or remove it`, { code: "unused-reference", id: reference.id })] : []);
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
// src/generated/catalog-ids.ts
|
|
75
|
-
var catalogIds = {
|
|
76
|
-
audiences: [
|
|
77
|
-
"board",
|
|
78
|
-
"engineering-team",
|
|
79
|
-
"all-hands",
|
|
80
|
-
"candidates",
|
|
81
|
-
"executive",
|
|
82
|
-
"investor",
|
|
83
|
-
"technical",
|
|
84
|
-
"sales",
|
|
85
|
-
"marketing",
|
|
86
|
-
"academic",
|
|
87
|
-
"internal-team",
|
|
88
|
-
"customer",
|
|
89
|
-
"general-public",
|
|
90
|
-
"media",
|
|
91
|
-
"partner",
|
|
92
|
-
"regulatory"
|
|
93
|
-
],
|
|
94
|
-
purposes: [
|
|
95
|
-
"inform",
|
|
96
|
-
"decide",
|
|
97
|
-
"align",
|
|
98
|
-
"persuade",
|
|
99
|
-
"educate",
|
|
100
|
-
"report",
|
|
101
|
-
"pitch",
|
|
102
|
-
"sell",
|
|
103
|
-
"plan"
|
|
104
|
-
],
|
|
105
|
-
tones: [
|
|
106
|
-
"formal",
|
|
107
|
-
"casual",
|
|
108
|
-
"inspirational",
|
|
109
|
-
"technical",
|
|
110
|
-
"persuasive",
|
|
111
|
-
"authoritative",
|
|
112
|
-
"conversational"
|
|
113
|
-
],
|
|
114
|
-
themes: [
|
|
115
|
-
"minimal",
|
|
116
|
-
"classic",
|
|
117
|
-
"dark",
|
|
118
|
-
"bold"
|
|
119
|
-
],
|
|
120
|
-
layouts: [
|
|
121
|
-
"blank",
|
|
122
|
-
"chart-1x",
|
|
123
|
-
"chart-2x",
|
|
124
|
-
"chart-3x",
|
|
125
|
-
"code-1x",
|
|
126
|
-
"image-1x",
|
|
127
|
-
"image-2x",
|
|
128
|
-
"image-3x",
|
|
129
|
-
"image-bleed",
|
|
130
|
-
"list-1x",
|
|
131
|
-
"list-2x",
|
|
132
|
-
"list-3x",
|
|
133
|
-
"list-4x",
|
|
134
|
-
"list-5x",
|
|
135
|
-
"list-6x",
|
|
136
|
-
"media-1x",
|
|
137
|
-
"number-1x",
|
|
138
|
-
"number-2x",
|
|
139
|
-
"number-3x",
|
|
140
|
-
"number-4x",
|
|
141
|
-
"number-5x",
|
|
142
|
-
"number-6x",
|
|
143
|
-
"quote-1x",
|
|
144
|
-
"table-1x",
|
|
145
|
-
"text-1x",
|
|
146
|
-
"text-2x",
|
|
147
|
-
"text-3x",
|
|
148
|
-
"timeline-1x",
|
|
149
|
-
"title",
|
|
150
|
-
"title-subtitle",
|
|
151
|
-
"title-slide",
|
|
152
|
-
"two-column",
|
|
153
|
-
"image-focus",
|
|
154
|
-
"data-visualization",
|
|
155
|
-
"quote-highlight",
|
|
156
|
-
"section-divider",
|
|
157
|
-
"agenda",
|
|
158
|
-
"thank-you-cta",
|
|
159
|
-
"bullet-list",
|
|
160
|
-
"three-column",
|
|
161
|
-
"icon-grid",
|
|
162
|
-
"faq",
|
|
163
|
-
"stats-metrics",
|
|
164
|
-
"comparison",
|
|
165
|
-
"swot-analysis",
|
|
166
|
-
"matrix-quadrant",
|
|
167
|
-
"funnel-pyramid",
|
|
168
|
-
"timeline",
|
|
169
|
-
"process-flow",
|
|
170
|
-
"photo-grid",
|
|
171
|
-
"before-after",
|
|
172
|
-
"testimonial-grid",
|
|
173
|
-
"team-bio",
|
|
174
|
-
"pricing-table",
|
|
175
|
-
"roadmap",
|
|
176
|
-
"product-feature",
|
|
177
|
-
"executive-summary",
|
|
178
|
-
"key-takeaway",
|
|
179
|
-
"chapter-recap",
|
|
180
|
-
"qa-discussion",
|
|
181
|
-
"single-message-statement",
|
|
182
|
-
"one-column-explainer",
|
|
183
|
-
"case-study",
|
|
184
|
-
"pros-cons",
|
|
185
|
-
"feature-comparison-matrix",
|
|
186
|
-
"venn-overlap",
|
|
187
|
-
"decision-tree",
|
|
188
|
-
"kpi-scorecard",
|
|
189
|
-
"dashboard",
|
|
190
|
-
"waterfall-bridge",
|
|
191
|
-
"benchmark-target-table",
|
|
192
|
-
"heatmap-cohort",
|
|
193
|
-
"risk-heatmap",
|
|
194
|
-
"forecast-scenario",
|
|
195
|
-
"swimlane-process",
|
|
196
|
-
"gantt-project-plan",
|
|
197
|
-
"circular-lifecycle",
|
|
198
|
-
"customer-journey",
|
|
199
|
-
"org-chart",
|
|
200
|
-
"capability-map",
|
|
201
|
-
"logic-tree",
|
|
202
|
-
"hub-and-spoke",
|
|
203
|
-
"architecture-stack",
|
|
204
|
-
"ecosystem-map",
|
|
205
|
-
"network-dependency-map",
|
|
206
|
-
"wheel-radial",
|
|
207
|
-
"geographic-map",
|
|
208
|
-
"screenshot-walkthrough",
|
|
209
|
-
"market-size",
|
|
210
|
-
"persona-grid",
|
|
211
|
-
"competitive-landscape",
|
|
212
|
-
"business-model-canvas",
|
|
213
|
-
"customer-logos",
|
|
214
|
-
"executive-decision",
|
|
215
|
-
"status-rag",
|
|
216
|
-
"raci-matrix",
|
|
217
|
-
"action-plan",
|
|
218
|
-
"assumptions-dependencies",
|
|
219
|
-
"appendix-index",
|
|
220
|
-
"detailed-data-table"
|
|
221
|
-
],
|
|
222
|
-
chartTypes: [
|
|
223
|
-
"100pct-stacked-area",
|
|
224
|
-
"100pct-stacked-bar",
|
|
225
|
-
"100pct-stacked-column",
|
|
226
|
-
"area",
|
|
227
|
-
"bar",
|
|
228
|
-
"box-and-whisker",
|
|
229
|
-
"column",
|
|
230
|
-
"combo",
|
|
231
|
-
"doughnut",
|
|
232
|
-
"filled-radar",
|
|
233
|
-
"funnel",
|
|
234
|
-
"histogram",
|
|
235
|
-
"line",
|
|
236
|
-
"line-with-markers",
|
|
237
|
-
"pareto",
|
|
238
|
-
"pie",
|
|
239
|
-
"radar",
|
|
240
|
-
"radar-with-markers",
|
|
241
|
-
"scatter",
|
|
242
|
-
"stacked-area",
|
|
243
|
-
"stacked-bar",
|
|
244
|
-
"stacked-column",
|
|
245
|
-
"stacked-line",
|
|
246
|
-
"stacked-line-with-markers",
|
|
247
|
-
"treemap",
|
|
248
|
-
"waterfall",
|
|
249
|
-
"world"
|
|
250
|
-
],
|
|
251
|
-
narratives: [
|
|
252
|
-
"problem-solution",
|
|
253
|
-
"scqa",
|
|
254
|
-
"pyramid-principle",
|
|
255
|
-
"situation-complication-resolution",
|
|
256
|
-
"what-so-what-now-what",
|
|
257
|
-
"strategic-narrative",
|
|
258
|
-
"golden-circle",
|
|
259
|
-
"conference-talk",
|
|
260
|
-
"transformation-arc",
|
|
261
|
-
"pitch-deck",
|
|
262
|
-
"early-startup-pitch",
|
|
263
|
-
"venture-pitch",
|
|
264
|
-
"persuasive-sales",
|
|
265
|
-
"sparkline",
|
|
266
|
-
"company-intro",
|
|
267
|
-
"marketing-strategy",
|
|
268
|
-
"product-launch",
|
|
269
|
-
"strategic-advisory",
|
|
270
|
-
"challenge-resolution",
|
|
271
|
-
"project-proposal",
|
|
272
|
-
"vision-roadmap",
|
|
273
|
-
"failure-analysis",
|
|
274
|
-
"star-method",
|
|
275
|
-
"classic-story",
|
|
276
|
-
"heros-journey",
|
|
277
|
-
"business-narrative",
|
|
278
|
-
"change-story",
|
|
279
|
-
"rags-to-riches",
|
|
280
|
-
"underdog-victory",
|
|
281
|
-
"survival-story",
|
|
282
|
-
"educate",
|
|
283
|
-
"persuade",
|
|
284
|
-
"reveal",
|
|
285
|
-
"justice",
|
|
286
|
-
"innovation",
|
|
287
|
-
"focus",
|
|
288
|
-
"qbr",
|
|
289
|
-
"business-review",
|
|
290
|
-
"board-meeting",
|
|
291
|
-
"weekly-progress",
|
|
292
|
-
"status-update",
|
|
293
|
-
"performance-review",
|
|
294
|
-
"survey-analysis",
|
|
295
|
-
"trend-analysis",
|
|
296
|
-
"data-story",
|
|
297
|
-
"employee-review",
|
|
298
|
-
"performance-improvement-plan",
|
|
299
|
-
"capacity-planning"
|
|
300
|
-
],
|
|
301
|
-
socialPlatforms: [
|
|
302
|
-
"linkedin",
|
|
303
|
-
"x",
|
|
304
|
-
"github",
|
|
305
|
-
"youtube",
|
|
306
|
-
"instagram",
|
|
307
|
-
"facebook",
|
|
308
|
-
"tiktok",
|
|
309
|
-
"threads",
|
|
310
|
-
"mastodon",
|
|
311
|
-
"bluesky"
|
|
312
|
-
],
|
|
313
|
-
languages: [
|
|
314
|
-
"afrikaans",
|
|
315
|
-
"albanian",
|
|
316
|
-
"amharic",
|
|
317
|
-
"arabic",
|
|
318
|
-
"armenian",
|
|
319
|
-
"aymara",
|
|
320
|
-
"azerbaijani",
|
|
321
|
-
"bengali",
|
|
322
|
-
"berber-latin",
|
|
323
|
-
"bosnian-latin",
|
|
324
|
-
"bulgarian",
|
|
325
|
-
"catalan",
|
|
326
|
-
"cebuano",
|
|
327
|
-
"chinese-simplified",
|
|
328
|
-
"chinese-traditional",
|
|
329
|
-
"chittagonian",
|
|
330
|
-
"croatian",
|
|
331
|
-
"czech",
|
|
332
|
-
"danish",
|
|
333
|
-
"dutch",
|
|
334
|
-
"english",
|
|
335
|
-
"english-au",
|
|
336
|
-
"english-ca",
|
|
337
|
-
"english-gb",
|
|
338
|
-
"english-in",
|
|
339
|
-
"english-us",
|
|
340
|
-
"estonian",
|
|
341
|
-
"filipino",
|
|
342
|
-
"finnish",
|
|
343
|
-
"french",
|
|
344
|
-
"fulfulde",
|
|
345
|
-
"galician",
|
|
346
|
-
"georgian",
|
|
347
|
-
"german",
|
|
348
|
-
"greek",
|
|
349
|
-
"gujarati",
|
|
350
|
-
"hausa",
|
|
351
|
-
"hebrew",
|
|
352
|
-
"hindi",
|
|
353
|
-
"hungarian",
|
|
354
|
-
"igbo",
|
|
355
|
-
"indonesian",
|
|
356
|
-
"italian",
|
|
357
|
-
"japanese",
|
|
358
|
-
"kannada",
|
|
359
|
-
"kazakh",
|
|
360
|
-
"khmer",
|
|
361
|
-
"kinyarwanda",
|
|
362
|
-
"korean",
|
|
363
|
-
"kurmanji",
|
|
364
|
-
"latvian",
|
|
365
|
-
"lithuanian",
|
|
366
|
-
"macedonian",
|
|
367
|
-
"malagasy",
|
|
368
|
-
"malay",
|
|
369
|
-
"malayalam",
|
|
370
|
-
"maori",
|
|
371
|
-
"marathi",
|
|
372
|
-
"mongolian",
|
|
373
|
-
"nepali",
|
|
374
|
-
"norwegian",
|
|
375
|
-
"odia",
|
|
376
|
-
"oromo",
|
|
377
|
-
"pashto",
|
|
378
|
-
"persian",
|
|
379
|
-
"polish",
|
|
380
|
-
"portuguese",
|
|
381
|
-
"punjabi-gurmukhi",
|
|
382
|
-
"punjabi-shahmukhi",
|
|
383
|
-
"romanian",
|
|
384
|
-
"russian",
|
|
385
|
-
"serbian-cyrillic",
|
|
386
|
-
"serbian-latin",
|
|
387
|
-
"shona",
|
|
388
|
-
"slovak",
|
|
389
|
-
"slovenian",
|
|
390
|
-
"somali",
|
|
391
|
-
"spanish",
|
|
392
|
-
"swahili",
|
|
393
|
-
"swedish",
|
|
394
|
-
"tagalog",
|
|
395
|
-
"tajik",
|
|
396
|
-
"tamil",
|
|
397
|
-
"telugu",
|
|
398
|
-
"thai",
|
|
399
|
-
"turkish",
|
|
400
|
-
"ukrainian",
|
|
401
|
-
"urdu",
|
|
402
|
-
"uzbek-latin",
|
|
403
|
-
"vietnamese-quoc-ngu",
|
|
404
|
-
"xhosa",
|
|
405
|
-
"yoruba",
|
|
406
|
-
"zulu"
|
|
407
|
-
],
|
|
408
|
-
colorSchemes: [
|
|
409
|
-
"black-and-white",
|
|
410
|
-
"bold-red",
|
|
411
|
-
"boost",
|
|
412
|
-
"burnt-orange",
|
|
413
|
-
"cool-horizon",
|
|
414
|
-
"corporate-blue",
|
|
415
|
-
"deep-purple",
|
|
416
|
-
"forest-green",
|
|
417
|
-
"golden-yellow",
|
|
418
|
-
"luxury",
|
|
419
|
-
"pastel-red",
|
|
420
|
-
"slate-gray",
|
|
421
|
-
"steel-blue",
|
|
422
|
-
"vibes"
|
|
423
|
-
],
|
|
424
|
-
fontSchemes: [
|
|
425
|
-
"consolas",
|
|
426
|
-
"courier-new",
|
|
427
|
-
"arial",
|
|
428
|
-
"calibri",
|
|
429
|
-
"impact",
|
|
430
|
-
"lucida-sans",
|
|
431
|
-
"segoe-ui",
|
|
432
|
-
"segoe-ui-light",
|
|
433
|
-
"tahoma",
|
|
434
|
-
"trebuchet-ms",
|
|
435
|
-
"verdana",
|
|
436
|
-
"bookman",
|
|
437
|
-
"century-schoolbook",
|
|
438
|
-
"constantia",
|
|
439
|
-
"garamond",
|
|
440
|
-
"rockwell",
|
|
441
|
-
"times-new-roman",
|
|
442
|
-
"aptos",
|
|
443
|
-
"grandview",
|
|
444
|
-
"seaford",
|
|
445
|
-
"skeena",
|
|
446
|
-
"tenorite",
|
|
447
|
-
"georgia",
|
|
448
|
-
"microsoft-yahei",
|
|
449
|
-
"simsun",
|
|
450
|
-
"fangsong",
|
|
451
|
-
"yu-gothic",
|
|
452
|
-
"pmingliu",
|
|
453
|
-
"mingliu",
|
|
454
|
-
"ms-mincho",
|
|
455
|
-
"malgun-gothic",
|
|
456
|
-
"batang",
|
|
457
|
-
"gungsuh",
|
|
458
|
-
"mangal",
|
|
459
|
-
"nirmala-ui",
|
|
460
|
-
"latha",
|
|
461
|
-
"david",
|
|
462
|
-
"miriam",
|
|
463
|
-
"gisha",
|
|
464
|
-
"vrinda",
|
|
465
|
-
"shruti",
|
|
466
|
-
"tunga",
|
|
467
|
-
"kartika",
|
|
468
|
-
"kalinga",
|
|
469
|
-
"raavi",
|
|
470
|
-
"gautami",
|
|
471
|
-
"arabic-typesetting",
|
|
472
|
-
"microsoft-jhenghei",
|
|
473
|
-
"meiryo",
|
|
474
|
-
"angsana-new",
|
|
475
|
-
"aparajita",
|
|
476
|
-
"dilleniaupc",
|
|
477
|
-
"sakkal-majalla",
|
|
478
|
-
"shonar-bangla",
|
|
479
|
-
"sylfaen",
|
|
480
|
-
"traditional-arabic",
|
|
481
|
-
"montserrat",
|
|
482
|
-
"open-sans",
|
|
483
|
-
"poppins",
|
|
484
|
-
"pt-serif",
|
|
485
|
-
"raleway",
|
|
486
|
-
"roboto",
|
|
487
|
-
"noto-sans-arabic",
|
|
488
|
-
"noto-sans-armenian",
|
|
489
|
-
"noto-sans-bengali",
|
|
490
|
-
"noto-sans-devangari",
|
|
491
|
-
"noto-sans-georgian",
|
|
492
|
-
"noto-sans-gujarati",
|
|
493
|
-
"noto-sans-gurmukhi",
|
|
494
|
-
"noto-sans-hebrew",
|
|
495
|
-
"noto-sans-jp",
|
|
496
|
-
"noto-sans-kannada",
|
|
497
|
-
"noto-sans-kr",
|
|
498
|
-
"noto-sans-malayalam",
|
|
499
|
-
"noto-sans-mongolian",
|
|
500
|
-
"noto-sans-oriya",
|
|
501
|
-
"noto-sans-sc",
|
|
502
|
-
"noto-sans-tamil",
|
|
503
|
-
"noto-sans-tc",
|
|
504
|
-
"noto-sans-telugu",
|
|
505
|
-
"noto-sans",
|
|
506
|
-
"noto-sans-thai",
|
|
507
|
-
"noto-nastaliq-urdu",
|
|
508
|
-
"noto-naksh-arabic",
|
|
509
|
-
"noto-sans-ethiopic",
|
|
510
|
-
"noto-sans-khmer",
|
|
511
|
-
"nyala",
|
|
512
|
-
"daunpenh",
|
|
513
|
-
"khmer-ui"
|
|
514
|
-
]
|
|
515
|
-
};
|
|
516
|
-
var deprecatedCatalogIds = {};
|
|
517
|
-
|
|
518
75
|
// src/validation-definitions.ts
|
|
519
76
|
var schemaLocations;
|
|
520
77
|
var issueLocations = /* @__PURE__ */ new WeakMap();
|
|
@@ -618,6 +175,7 @@ var contentKindSpecs = {
|
|
|
618
175
|
}
|
|
619
176
|
};
|
|
620
177
|
var captionableKinds = /* @__PURE__ */ new Set(["image", "chart", "table", "video"]);
|
|
178
|
+
var imageOptionFields = ["fit", "focus", "aspectRatio", "shape", "cornerRadius", "border", "opacity", "recolor", "overlay", "placement"];
|
|
621
179
|
var columnSpans = {
|
|
622
180
|
left: [0],
|
|
623
181
|
center: [1],
|
|
@@ -733,15 +291,31 @@ function validateContentPayload(value, path, options = {}) {
|
|
|
733
291
|
const payloadFields = presentFields(value, rootPayloadFields);
|
|
734
292
|
const hasBlocks = hasOwn(value, "blocks");
|
|
735
293
|
const captionIssue = (reason, params = {}) => semanticIssue(pathFor(path, "caption"), `caption is only valid on an image, chart, table or video payload; ${reason}`, { code: "caption-unsupported-payload", ...params });
|
|
294
|
+
const imageOptionIssues = (reason, params = {}) => {
|
|
295
|
+
for (const field of imageOptionFields) if (hasOwn(value, field)) issues.push(semanticIssue(pathFor(path, field), `${field} is only valid on an image payload; ${reason}`, { code: "image-option-unsupported-payload", field, ...params }));
|
|
296
|
+
};
|
|
297
|
+
if (hasOwn(value, "placement") && !options.topLevel && !hasBlocks && explicitType !== "group" && inferredKinds(value).includes("image")) {
|
|
298
|
+
issues.push(semanticIssue(pathFor(path, "placement"), "placement is only valid on a top-level block (slides.N.blocks.I); a block inside a group or a promoted region cannot bleed to a slide edge", { code: "image-placement-invalid" }));
|
|
299
|
+
}
|
|
736
300
|
if (hasBlocks || explicitType === "group") {
|
|
737
301
|
if (hasOwn(value, "caption")) issues.push(captionIssue("a group cannot carry one"));
|
|
302
|
+
imageOptionIssues("a group cannot carry them");
|
|
738
303
|
if (explicitType !== void 0 && explicitType !== "group") issues.push(semanticIssue(path, "a group must use type 'group' or omit type"));
|
|
739
304
|
const incompatible2 = payloadFields.filter((field) => field !== "blocks" && field !== "type");
|
|
740
305
|
if (incompatible2.length) issues.push(semanticIssue(path, "blocks cannot be mixed with leaf payload fields", { fields: incompatible2 }));
|
|
741
306
|
if (!Array.isArray(value.blocks) || value.blocks.length === 0 && !options.slideRoot) issues.push(semanticIssue(pathFor(path, "blocks"), "a group requires at least one block"));
|
|
742
307
|
if (Array.isArray(value.blocks)) value.blocks.forEach((block, index) => {
|
|
743
|
-
if (isRecord(block)) issues.push(...validateContentPayload(block, `${pathFor(path, "blocks")}/${index}
|
|
308
|
+
if (isRecord(block)) issues.push(...validateContentPayload(block, `${pathFor(path, "blocks")}/${index}`, { topLevel: options.slideRoot === true }));
|
|
744
309
|
});
|
|
310
|
+
if (options.slideRoot && Array.isArray(value.blocks)) {
|
|
311
|
+
const edges = /* @__PURE__ */ new Map();
|
|
312
|
+
value.blocks.forEach((block, index) => {
|
|
313
|
+
const edge = isRecord(block) && isRecord(block.placement) ? block.placement.edge : void 0;
|
|
314
|
+
if (edge === void 0) return;
|
|
315
|
+
if (edges.has(edge)) issues.push(semanticIssue(`${pathFor(path, "blocks")}/${index}/placement/edge`, `blocks ${edges.get(edge)} and ${index} are both placed on the ${String(edge)} edge; a slide edge takes at most one placed image`, { code: "image-placement-invalid", edge, blocks: [edges.get(edge), index] }));
|
|
316
|
+
else edges.set(edge, index);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
745
319
|
return issues;
|
|
746
320
|
}
|
|
747
321
|
if (hasOwn(value, "composition") && !options.slideRoot) issues.push(semanticIssue(pathFor(path, "composition"), "composition is only valid on a group containing blocks"));
|
|
@@ -774,6 +348,7 @@ function validateContentPayload(value, path, options = {}) {
|
|
|
774
348
|
}
|
|
775
349
|
const spec = contentKindSpecs[resolvedKind];
|
|
776
350
|
if (hasOwn(value, "caption") && !captionableKinds.has(resolvedKind)) issues.push(captionIssue(`this payload is '${resolvedKind}'`, { type: resolvedKind }));
|
|
351
|
+
if (resolvedKind !== "image") imageOptionIssues(`this payload is '${resolvedKind}'`, { type: resolvedKind });
|
|
777
352
|
const allowedFields = /* @__PURE__ */ new Set([
|
|
778
353
|
"type",
|
|
779
354
|
...spec.fields
|
|
@@ -937,77 +512,6 @@ function presentationSemanticIssues(value) {
|
|
|
937
512
|
issues.push(...annotationIssues(value));
|
|
938
513
|
return issues;
|
|
939
514
|
}
|
|
940
|
-
function inlineCatalogEntry(context, kind) {
|
|
941
|
-
const catalogsField = context.document.catalogs;
|
|
942
|
-
if (!isRecord(catalogsField)) {
|
|
943
|
-
return void 0;
|
|
944
|
-
}
|
|
945
|
-
const entry = catalogsField[kind];
|
|
946
|
-
return isRecord(entry) ? entry : void 0;
|
|
947
|
-
}
|
|
948
|
-
function unknownIdWarning(kind, value, path, context) {
|
|
949
|
-
if (typeof value !== "string" || !bareIdPattern.test(value)) {
|
|
950
|
-
return void 0;
|
|
951
|
-
}
|
|
952
|
-
if (context) {
|
|
953
|
-
const entry = inlineCatalogEntry(context, kind);
|
|
954
|
-
if (entry) {
|
|
955
|
-
const inline = Array.isArray(entry.records) ? entry.records.find((record) => isRecord(record) && record.id === value) : void 0;
|
|
956
|
-
if (isRecord(inline)) {
|
|
957
|
-
const replacedBy = isRecord(inline.deprecation) ? inline.deprecation.replacedBy : void 0;
|
|
958
|
-
return typeof replacedBy === "string" ? deprecatedIdWarning(kind, value, replacedBy, path) : void 0;
|
|
959
|
-
}
|
|
960
|
-
if (typeof entry.source === "string" || Array.isArray(entry.source) && entry.source.length > 0) {
|
|
961
|
-
return void 0;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
if (catalogIds[kind].includes(value)) {
|
|
966
|
-
const replacedBy = deprecatedCatalogIds[`${kind}/${value}`];
|
|
967
|
-
return replacedBy === void 0 ? void 0 : deprecatedIdWarning(kind, value, replacedBy, path);
|
|
968
|
-
}
|
|
969
|
-
return semanticIssue(path, `unknown ${kind} catalog id '${value}'`, { kind, id: value });
|
|
970
|
-
}
|
|
971
|
-
function deprecatedIdWarning(kind, id, replacedBy, path) {
|
|
972
|
-
return semanticIssue(path, `deprecated ${kind} catalog id '${id}'; use '${replacedBy}'`, { kind, id, replacedBy });
|
|
973
|
-
}
|
|
974
|
-
function referenceObjectWarning(kind, value, path, context) {
|
|
975
|
-
if (typeof value === "string") {
|
|
976
|
-
return unknownIdWarning(kind, value, path, context);
|
|
977
|
-
}
|
|
978
|
-
if (isRecord(value)) {
|
|
979
|
-
return unknownIdWarning(kind, value.id, pathFor(path, "id"), context);
|
|
980
|
-
}
|
|
981
|
-
return void 0;
|
|
982
|
-
}
|
|
983
|
-
function pushIfDefined(issues, issue2) {
|
|
984
|
-
if (issue2) {
|
|
985
|
-
issues.push(issue2);
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
function designReferenceWarnings(design, path, context) {
|
|
989
|
-
if (!isRecord(design)) {
|
|
990
|
-
return [];
|
|
991
|
-
}
|
|
992
|
-
const issues = [];
|
|
993
|
-
pushIfDefined(issues, referenceObjectWarning("themes", design.theme, pathFor(path, "theme"), context));
|
|
994
|
-
pushIfDefined(issues, referenceObjectWarning("colorSchemes", design.colorScheme, pathFor(path, "colorScheme"), context));
|
|
995
|
-
pushIfDefined(issues, referenceObjectWarning("fontSchemes", design.fontScheme, pathFor(path, "fontScheme"), context));
|
|
996
|
-
if (isRecord(design.theme)) {
|
|
997
|
-
const themePath = pathFor(path, "theme");
|
|
998
|
-
pushIfDefined(issues, referenceObjectWarning("colorSchemes", design.theme.colorScheme, pathFor(themePath, "colorScheme"), context));
|
|
999
|
-
pushIfDefined(issues, referenceObjectWarning("fontSchemes", design.theme.fontScheme, pathFor(themePath, "fontScheme"), context));
|
|
1000
|
-
}
|
|
1001
|
-
return issues;
|
|
1002
|
-
}
|
|
1003
|
-
function themeOf(reference, context) {
|
|
1004
|
-
const id = typeof reference === "string" ? reference : isRecord(reference) ? reference.id : void 0;
|
|
1005
|
-
const entry = inlineCatalogEntry(context, "themes");
|
|
1006
|
-
const inline = typeof id === "string" && Array.isArray(entry?.records) ? entry.records.find((record) => isRecord(record) && record.id === id) : void 0;
|
|
1007
|
-
const base = isRecord(inline) ? inline : typeof id === "string" ? themes.find((record) => isRecord(record) && record.id === id) : void 0;
|
|
1008
|
-
if (isRecord(reference)) return { ...base ?? {}, ...reference };
|
|
1009
|
-
return base;
|
|
1010
|
-
}
|
|
1011
515
|
function canvasSize(dimensions) {
|
|
1012
516
|
try {
|
|
1013
517
|
const { width, height } = resolveCanvasDimensions(dimensions);
|
|
@@ -1016,15 +520,16 @@ function canvasSize(dimensions) {
|
|
|
1016
520
|
return "invalid";
|
|
1017
521
|
}
|
|
1018
522
|
}
|
|
1019
|
-
function slideThemeDimensionsWarnings(document, slide,
|
|
523
|
+
function slideThemeDimensionsWarnings(document, slide, index, catalogs) {
|
|
524
|
+
const slidePath = `/slides/${index}`;
|
|
1020
525
|
const slideDesign = isRecord(slide.design) ? slide.design : void 0;
|
|
1021
|
-
if (!slideDesign || slideDesign.theme
|
|
1022
|
-
const
|
|
1023
|
-
|
|
526
|
+
if (!slideDesign || typeof slideDesign.theme !== "string") return [];
|
|
527
|
+
const options = { catalogs: catalogs ?? [] };
|
|
528
|
+
const slideTheme = resolveDesignRecords(document, index, options);
|
|
529
|
+
if (slideTheme.diagnostics.some((diagnostic) => diagnostic.kind === "themes") || slideTheme.theme.dimensions === void 0) return [];
|
|
1024
530
|
const deckDesign = isRecord(document.design) ? document.design : {};
|
|
1025
|
-
const
|
|
1026
|
-
const
|
|
1027
|
-
const slideSize = canvasSize(slideTheme.dimensions);
|
|
531
|
+
const deckDimensions = deckDesign.dimensions ?? resolveDesignRecords(document, void 0, options).theme.dimensions;
|
|
532
|
+
const slideSize = canvasSize(slideTheme.theme.dimensions);
|
|
1028
533
|
const deckSize = canvasSize(deckDimensions);
|
|
1029
534
|
if (slideSize === deckSize) return [];
|
|
1030
535
|
const explicit = deckDesign.dimensions !== void 0;
|
|
@@ -1034,20 +539,19 @@ function slideThemeDimensionsWarnings(document, slide, slidePath, context) {
|
|
|
1034
539
|
{ code: "slide-theme-dimensions", slideDimensions: slideSize, deckDimensions: deckSize }
|
|
1035
540
|
)];
|
|
1036
541
|
}
|
|
1037
|
-
function chartTypeWarnings(payload, path
|
|
542
|
+
function chartTypeWarnings(payload, path) {
|
|
1038
543
|
if (!isRecord(payload)) {
|
|
1039
544
|
return [];
|
|
1040
545
|
}
|
|
1041
546
|
const issues = [];
|
|
1042
547
|
if (isRecord(payload.chart)) {
|
|
1043
|
-
pushIfDefined(issues, unknownIdWarning("chartTypes", payload.chart.type, `${pathFor(path, "chart")}/type`, context));
|
|
1044
548
|
for (const diagnostic of resolveChartOptions(payload.chart, chartOptionTarget(payload.chart.type)).diagnostics) {
|
|
1045
549
|
issues.push(semanticIssue(diagnostic.option.split(".").reduce(pathFor, pathFor(path, "chart")), diagnostic.message, { code: diagnostic.code, option: diagnostic.option, reason: diagnostic.reason }));
|
|
1046
550
|
}
|
|
1047
551
|
}
|
|
1048
552
|
if (Array.isArray(payload.blocks)) {
|
|
1049
553
|
payload.blocks.forEach((block, index) => {
|
|
1050
|
-
issues.push(...chartTypeWarnings(block, `${pathFor(path, "blocks")}/${index}
|
|
554
|
+
issues.push(...chartTypeWarnings(block, `${pathFor(path, "blocks")}/${index}`));
|
|
1051
555
|
});
|
|
1052
556
|
}
|
|
1053
557
|
return issues;
|
|
@@ -1216,34 +720,19 @@ function variableReferenceWarnings(value) {
|
|
|
1216
720
|
});
|
|
1217
721
|
return issues;
|
|
1218
722
|
}
|
|
1219
|
-
function presentationReferenceWarnings(value) {
|
|
723
|
+
function presentationReferenceWarnings(value, catalogs) {
|
|
1220
724
|
if (!isRecord(value) || !Array.isArray(value.slides)) {
|
|
1221
725
|
return [];
|
|
1222
726
|
}
|
|
1223
|
-
const context = { document: value };
|
|
1224
727
|
const issues = [];
|
|
1225
|
-
if (typeof value.narrative === "string") {
|
|
1226
|
-
pushIfDefined(issues, unknownIdWarning("narratives", value.narrative, "/narrative", context));
|
|
1227
|
-
}
|
|
1228
|
-
if (Array.isArray(value.audience)) {
|
|
1229
|
-
value.audience.forEach((entry, index) => {
|
|
1230
|
-
pushIfDefined(issues, referenceObjectWarning("audiences", entry, `/audience/${index}`, context));
|
|
1231
|
-
});
|
|
1232
|
-
} else if (isRecord(value.audience)) {
|
|
1233
|
-
pushIfDefined(issues, referenceObjectWarning("audiences", value.audience, "/audience", context));
|
|
1234
|
-
} else {
|
|
1235
|
-
pushIfDefined(issues, unknownIdWarning("audiences", value.audience, "/audience", context));
|
|
1236
|
-
}
|
|
1237
|
-
issues.push(...designReferenceWarnings(value.design, "/design", context));
|
|
1238
728
|
issues.push(...variableReferenceWarnings(value));
|
|
1239
729
|
value.slides.forEach((slide, index) => {
|
|
1240
730
|
if (!isRecord(slide)) {
|
|
1241
731
|
return;
|
|
1242
732
|
}
|
|
1243
733
|
const slidePath = `/slides/${index}`;
|
|
1244
|
-
issues.push(...
|
|
1245
|
-
issues.push(...
|
|
1246
|
-
issues.push(...chartTypeWarnings(slide, slidePath, context));
|
|
734
|
+
issues.push(...slideThemeDimensionsWarnings(value, slide, index, catalogs));
|
|
735
|
+
issues.push(...chartTypeWarnings(slide, slidePath));
|
|
1247
736
|
const numberingWarnings = (payload, path) => {
|
|
1248
737
|
for (const finding2 of numberingFindings(payload).warnings) issues.push(semanticIssue(pathFor(path, finding2.key), finding2.message, { ...finding2.params, code: "numbering-start-ignored" }));
|
|
1249
738
|
};
|
|
@@ -1261,34 +750,12 @@ function presentationReferenceWarnings(value) {
|
|
|
1261
750
|
visitContentPayloads(slide, slidePath, highlightWarnings);
|
|
1262
751
|
for (const key of Object.keys(slide)) {
|
|
1263
752
|
if (promotedRegionKeySet.has(key)) {
|
|
1264
|
-
issues.push(...chartTypeWarnings(slide[key], pathFor(slidePath, key)
|
|
753
|
+
issues.push(...chartTypeWarnings(slide[key], pathFor(slidePath, key)));
|
|
1265
754
|
}
|
|
1266
755
|
}
|
|
1267
756
|
});
|
|
1268
757
|
return issues;
|
|
1269
758
|
}
|
|
1270
|
-
var catalogCrossLinkFields = {
|
|
1271
|
-
audience: { recommendedNarratives: "narratives", recommendedTones: "tones" },
|
|
1272
|
-
purpose: { recommendedNarratives: "narratives", recommendedTones: "tones" },
|
|
1273
|
-
tone: { recommendedNarratives: "narratives" }
|
|
1274
|
-
};
|
|
1275
|
-
function catalogCrossLinkWarnings(schemaName, value) {
|
|
1276
|
-
const fields2 = catalogCrossLinkFields[schemaName];
|
|
1277
|
-
if (!fields2 || !isRecord(value)) {
|
|
1278
|
-
return [];
|
|
1279
|
-
}
|
|
1280
|
-
const issues = [];
|
|
1281
|
-
for (const [field, kind] of Object.entries(fields2)) {
|
|
1282
|
-
const links = value[field];
|
|
1283
|
-
if (!Array.isArray(links)) {
|
|
1284
|
-
continue;
|
|
1285
|
-
}
|
|
1286
|
-
links.forEach((link, index) => {
|
|
1287
|
-
pushIfDefined(issues, unknownIdWarning(kind, link, `${pathFor("/", field)}/${index}`));
|
|
1288
|
-
});
|
|
1289
|
-
}
|
|
1290
|
-
return issues;
|
|
1291
|
-
}
|
|
1292
759
|
function validateLanguageSemantics(value) {
|
|
1293
760
|
if (!isRecord(value)) {
|
|
1294
761
|
return [];
|
|
@@ -1397,6 +864,33 @@ function dataUnionErrors(errors, value) {
|
|
|
1397
864
|
return { ...error, message: field === "fields" ? "'fields' applies only to a dataset-backed table; add 'dataset' or remove 'fields'" : datasetTableMessage(field) };
|
|
1398
865
|
});
|
|
1399
866
|
}
|
|
867
|
+
var placeholderHeadings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
|
|
868
|
+
function placeholderGroupIssues(value) {
|
|
869
|
+
const issues = [];
|
|
870
|
+
if (!isRecord(value) || !Array.isArray(value.placeholders)) return issues;
|
|
871
|
+
const walk = (entries, path, depth) => entries.forEach((entry, index) => {
|
|
872
|
+
if (!isRecord(entry)) return;
|
|
873
|
+
const at2 = `${path}/${index}`;
|
|
874
|
+
if (entry.type === "group") {
|
|
875
|
+
if (depth >= MAX_PLACEHOLDER_GROUP_DEPTH) issues.push(semanticIssue(at2, `placeholder groups nest at most ${MAX_PLACEHOLDER_GROUP_DEPTH} levels inside a layout record; this group would be level ${depth + 1}`, { code: "layout-placeholder-group", depth: depth + 1, maxDepth: MAX_PLACEHOLDER_GROUP_DEPTH }));
|
|
876
|
+
else if (Array.isArray(entry.placeholders)) walk(entry.placeholders, `${at2}/placeholders`, depth + 1);
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
if (depth === 0) return;
|
|
880
|
+
if (typeof entry.type === "string" && placeholderHeadings.has(entry.type)) issues.push(semanticIssue(`${at2}/type`, `a placeholder group holds body regions only; a '${entry.type}' placeholder belongs at the record's top level`, { code: "layout-placeholder-group" }));
|
|
881
|
+
if (hasOwn(entry, "placement")) issues.push(semanticIssue(`${at2}/placement`, "placement is only valid on a top-level image placeholder; a region inside a placeholder group cannot bleed to a slide edge", { code: "image-placement-invalid" }));
|
|
882
|
+
});
|
|
883
|
+
walk(value.placeholders, "/placeholders", 0);
|
|
884
|
+
return issues;
|
|
885
|
+
}
|
|
886
|
+
function withPlaceholderGroupIssues(errors, value) {
|
|
887
|
+
const issues = placeholderGroupIssues(value);
|
|
888
|
+
const entries = issues.map((issue2) => issue2.path.replace(/\/(type|placement)$/, ""));
|
|
889
|
+
const covered = (error) => entries.some((entry) => error.path === entry || error.path.startsWith(`${entry}/`));
|
|
890
|
+
const kept = errors.filter((error) => !covered(error));
|
|
891
|
+
const reported = [...kept.filter((error) => error.keyword !== "if"), ...issues].map((error) => error.path);
|
|
892
|
+
return [...kept.filter((error) => error.keyword !== "if" || !reported.some((path) => path === error.path || path.startsWith(`${error.path}/`))), ...issues];
|
|
893
|
+
}
|
|
1400
894
|
function validateAgainstSchema(value, schemaOrKind = "presentation", options = {}) {
|
|
1401
895
|
const resolved = resolveValidator(schemaOrKind);
|
|
1402
896
|
if (resolved.schemaName === "presentation") {
|
|
@@ -1428,20 +922,20 @@ function validateAgainstSchema(value, schemaOrKind = "presentation", options = {
|
|
|
1428
922
|
}
|
|
1429
923
|
const valid = resolved.validate(subject) === true;
|
|
1430
924
|
const ajvErrors = valid ? [] : typedVariableErrors(resolved.validate.errors ?? [], subject);
|
|
1431
|
-
const
|
|
925
|
+
const mapped = (resolved.schemaName === "presentation" ? dataUnionErrors(ajvErrors, subject) : ajvErrors).map(toIssue);
|
|
926
|
+
const errors = resolved.schemaName === "layout" ? withPlaceholderGroupIssues(mapped, subject) : mapped;
|
|
1432
927
|
const warnings = [];
|
|
1433
928
|
if (resolved.schemaName === "presentation") {
|
|
1434
929
|
errors.push(...presentationSemanticIssues(subject));
|
|
1435
930
|
errors.push(...variableIssues.errors);
|
|
1436
931
|
const data = dataIssues(subject);
|
|
1437
932
|
errors.push(...data.errors);
|
|
1438
|
-
warnings.push(...presentationReferenceWarnings(subject));
|
|
933
|
+
warnings.push(...presentationReferenceWarnings(subject, options.catalogs));
|
|
1439
934
|
warnings.push(...data.warnings);
|
|
1440
935
|
warnings.push(...variableIssues.warnings);
|
|
1441
936
|
} else if (resolved.schemaName === "language") {
|
|
1442
937
|
errors.push(...validateLanguageSemantics(value));
|
|
1443
938
|
}
|
|
1444
|
-
warnings.push(...catalogCrossLinkWarnings(resolved.schemaName, value));
|
|
1445
939
|
return {
|
|
1446
940
|
valid: errors.length === 0,
|
|
1447
941
|
errors,
|
|
@@ -1455,24 +949,13 @@ function validateAgainstSchema(value, schemaOrKind = "presentation", options = {
|
|
|
1455
949
|
|
|
1456
950
|
// src/narrative-plan.ts
|
|
1457
951
|
var isRec = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1458
|
-
function resolveNarrative(document,
|
|
952
|
+
function resolveNarrative(document, options = {}) {
|
|
1459
953
|
if (!isRec(document) || typeof document.narrative !== "string") return void 0;
|
|
1460
|
-
const
|
|
1461
|
-
if (
|
|
1462
|
-
const
|
|
1463
|
-
const
|
|
1464
|
-
|
|
1465
|
-
["loaded", loaded],
|
|
1466
|
-
["built-in", catalogs.narratives]
|
|
1467
|
-
];
|
|
1468
|
-
for (const [origin, records] of sources) {
|
|
1469
|
-
const record = records.find((candidate) => isRec(candidate) && candidate.id === id);
|
|
1470
|
-
if (isRec(record)) {
|
|
1471
|
-
const beats = Array.isArray(record.beats) ? record.beats.flatMap((beat) => isRec(beat) && typeof beat.id === "string" ? [beat.id] : []) : [];
|
|
1472
|
-
return { record, origin, beats };
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
return void 0;
|
|
954
|
+
const found = resolveReference(document, "narratives", document.narrative, { catalogs: options.catalogs ?? [] });
|
|
955
|
+
if (!found) return void 0;
|
|
956
|
+
const record = found.record;
|
|
957
|
+
const beats = Array.isArray(record.beats) ? record.beats.flatMap((beat) => isRec(beat) && typeof beat.id === "string" ? [beat.id] : []) : [];
|
|
958
|
+
return { record, origin: found.origin, beats };
|
|
1476
959
|
}
|
|
1477
960
|
function slideBeatReferences(document) {
|
|
1478
961
|
if (!isRec(document) || !Array.isArray(document.slides)) return [];
|
|
@@ -1590,19 +1073,13 @@ function simulateVision(hex, model) {
|
|
|
1590
1073
|
const m = CVD_MATRICES[model];
|
|
1591
1074
|
return toHex(m.map((row) => delinear(row[0] * (rgb[0] ?? 0) + row[1] * (rgb[1] ?? 0) + row[2] * (rgb[2] ?? 0))));
|
|
1592
1075
|
}
|
|
1593
|
-
function createLookup(document, extra) {
|
|
1594
|
-
return (kind, id) => {
|
|
1595
|
-
const inline = rec(rec(document.catalogs)[kind]).records;
|
|
1596
|
-
const found = (Array.isArray(inline) ? inline : []).find((r) => r?.id === id) ?? (extra?.[kind] ?? []).find((r) => rec(r).id === id) ?? catalogs[kind]?.find((r) => rec(r).id === id);
|
|
1597
|
-
return found === void 0 ? void 0 : rec(found);
|
|
1598
|
-
};
|
|
1599
|
-
}
|
|
1600
1076
|
var PAGE = "#FFFFFF";
|
|
1601
1077
|
var colorFrom = (scheme, slot, fallback) => typeof slot === "string" ? slot.startsWith("#") ? normalizeHexColor(slot) ?? fallback : normalizeHexColor(scheme[slot]) ?? fallback : fallback;
|
|
1602
1078
|
function backdropOf(definition, scheme, text, variables) {
|
|
1603
1079
|
const resolve2 = (value, fallback) => backgroundColorRef(value, scheme, variables, fallback);
|
|
1604
1080
|
const canvas = defaultSlideBackground(scheme);
|
|
1605
1081
|
if (!definition) return { kind: "solid", color: canvas };
|
|
1082
|
+
if (imageBackground(definition)) return { kind: "image", opacity: imageBackground(definition)?.opacity ?? 1, base: PAGE };
|
|
1606
1083
|
if (typeof definition === "string") return { kind: "solid", color: colorFrom(scheme, definition, canvas) };
|
|
1607
1084
|
const bg = rec(definition), opacity = typeof bg.opacity === "number" ? Math.max(0, Math.min(1, bg.opacity)) : 1;
|
|
1608
1085
|
switch (bg.type) {
|
|
@@ -1653,6 +1130,7 @@ function decisionColor(definition, scheme, variables = {}) {
|
|
|
1653
1130
|
if (!definition) return void 0;
|
|
1654
1131
|
const canvas = defaultSlideBackground(scheme);
|
|
1655
1132
|
const reference = (value) => backgroundColorRef(value, scheme, variables, PAGE);
|
|
1133
|
+
if (imageBackground(definition)) return void 0;
|
|
1656
1134
|
if (typeof definition === "string") return colorFrom(scheme, definition, canvas);
|
|
1657
1135
|
const bg = rec(definition);
|
|
1658
1136
|
switch (bg.type) {
|
|
@@ -1671,15 +1149,15 @@ function resolveDesign(document, index, context) {
|
|
|
1671
1149
|
const { options, diagnostics, resolved } = context;
|
|
1672
1150
|
const { theme, colorScheme, fontScheme, fontSchemePath } = resolved;
|
|
1673
1151
|
const fontPath = `/${fontSchemePath.split(".").join("/")}`;
|
|
1674
|
-
const fontDiagnostic = diagnostics.find((diagnostic) => diagnostic.
|
|
1152
|
+
const fontDiagnostic = diagnostics.find((diagnostic) => diagnostic.kind === "fontSchemes");
|
|
1675
1153
|
const dimensions = { width: options.width, height: options.height };
|
|
1676
1154
|
const variables = rec(document.variables);
|
|
1677
1155
|
const roles = resolveColorRoles(colorScheme, { background: decisionColor(own2.background ?? deck.background ?? theme.background, colorScheme, variables) });
|
|
1678
1156
|
const dark = roles.dark;
|
|
1679
1157
|
const text = roles.text;
|
|
1680
1158
|
const backdrop = backdropOf(own2.background ?? deck.background ?? theme.background, colorScheme, text, variables);
|
|
1681
|
-
const
|
|
1682
|
-
const backgroundImage =
|
|
1159
|
+
const picture = imageBackground(own2.background ?? deck.background ?? theme.background);
|
|
1160
|
+
const backgroundImage = picture && own2.background !== void 0 ? { source: picture.src, fit: picture.fit, path: `/slides/${index}/design/background` } : picture && deck.background !== void 0 ? { source: picture.src, fit: picture.fit, path: "/design/background" } : void 0;
|
|
1683
1161
|
return {
|
|
1684
1162
|
theme,
|
|
1685
1163
|
colorScheme,
|
|
@@ -1700,7 +1178,7 @@ function resolveDesign(document, index, context) {
|
|
|
1700
1178
|
variables,
|
|
1701
1179
|
...backgroundImage ? { backgroundImage } : {},
|
|
1702
1180
|
fontSchemePath: fontPath,
|
|
1703
|
-
...fontDiagnostic ? { unresolvedFontScheme: fontDiagnostic.
|
|
1181
|
+
...fontDiagnostic ? { unresolvedFontScheme: fontDiagnostic.reference } : {}
|
|
1704
1182
|
};
|
|
1705
1183
|
}
|
|
1706
1184
|
function resolveTextColor(reference, design, fallback) {
|
|
@@ -1896,9 +1374,6 @@ function assetRefs(document, slide, slidePath, includeDeck) {
|
|
|
1896
1374
|
if (rec(payload.node.quote).photo !== void 0) out.push({ path: at2("quote", "photo"), value: rec(payload.node.quote).photo, kind: "quote-photo" });
|
|
1897
1375
|
}
|
|
1898
1376
|
const designRefs = (design, base) => {
|
|
1899
|
-
const slideImage = design.slideImage;
|
|
1900
|
-
if (slideImage && (typeof slideImage === "string" || typeof slideImage.src === "string"))
|
|
1901
|
-
out.push({ path: `${base}/slideImage`, value: slideImage, kind: "slide-image" });
|
|
1902
1377
|
const logo = design.logo;
|
|
1903
1378
|
if (typeof logo === "string" || logo && typeof logo.src === "string") out.push({ path: `${base}/logo`, value: logo, kind: "logo" });
|
|
1904
1379
|
else if (logo && typeof logo === "object") {
|
|
@@ -1940,10 +1415,10 @@ var isLarge = (sizePx, bold) => {
|
|
|
1940
1415
|
};
|
|
1941
1416
|
function slideBackdrop(context, box) {
|
|
1942
1417
|
const { design, composition } = context;
|
|
1943
|
-
const image = composition?.
|
|
1944
|
-
if (image
|
|
1945
|
-
const overlay = image.overlay && image.overlay.
|
|
1946
|
-
return backdropColors({ kind: "image", opacity: image.opacity ?? 1, base:
|
|
1418
|
+
const image = composition?.backgroundImage;
|
|
1419
|
+
if (image) {
|
|
1420
|
+
const overlay = image.overlay && !image.overlay.edge ? { color: resolveTextColor(image.overlay.color, design, "#000000") ?? "#000000", opacity: image.overlay.opacity } : void 0;
|
|
1421
|
+
return backdropColors({ kind: "image", opacity: image.opacity ?? 1, base: "#FFFFFF" }, box, design.dimensions, { overlay });
|
|
1947
1422
|
}
|
|
1948
1423
|
return backdropColors(design.backdrop, box, design.dimensions);
|
|
1949
1424
|
}
|
|
@@ -2055,7 +1530,7 @@ var onImageRule = rule(
|
|
|
2055
1530
|
standard: "WCAG 2.2 SC 1.4.3 Contrast (Minimum), level AA",
|
|
2056
1531
|
thresholds: ["contrastNormal", "contrastLarge"],
|
|
2057
1532
|
cost: "composition",
|
|
2058
|
-
approximations: "Core never reads picture pixels. The picture is bounded by a grey ramp from black to white, composited through the image opacity and a full-frame design.
|
|
1533
|
+
approximations: "Core never reads picture pixels. The picture is bounded by a grey ramp from black to white, composited through the image opacity and a full-frame design.background overlay; the text passes only when every step of that ramp passes. An edge-banded overlay is not counted."
|
|
2059
1534
|
}
|
|
2060
1535
|
);
|
|
2061
1536
|
var contrastRules = [
|
|
@@ -2078,7 +1553,7 @@ var contrastRules = [
|
|
|
2078
1553
|
path: sample.path,
|
|
2079
1554
|
slide,
|
|
2080
1555
|
message: `${sample.label} sits on a background picture. Contrast cannot be guaranteed from the document (against the lightest or darkest possible pixels it is as low as ${worst.ratio.toFixed(1)}:1; ${needed}:1 is needed at this size).`,
|
|
2081
|
-
help: "Add a full-frame overlay to design.
|
|
1556
|
+
help: "Add a full-frame overlay to the image background (design.background.overlay: a colour and an opacity high enough that text passes on any picture), use a solid or gradient background behind text, or place text on a card.",
|
|
2082
1557
|
measured: { ratio: round(worst.ratio), needed, textColor: sample.color }
|
|
2083
1558
|
});
|
|
2084
1559
|
}
|
|
@@ -2126,7 +1601,7 @@ var altRule = rule(
|
|
|
2126
1601
|
'People using a screen reader get nothing for a picture without alternative text. A picture that is purely decorative should say so with an empty alt (alt: ""), which is an explicit, reviewed choice instead of an omission.',
|
|
2127
1602
|
{
|
|
2128
1603
|
standard: "WCAG 2.2 SC 1.1.1 Non-text Content, level A",
|
|
2129
|
-
approximations: "Checks the alt field of images,
|
|
1604
|
+
approximations: "Checks the alt field of images (image blocks, Slide.image and region images, placed or not), video, logos (design.logo and each LogoSet variant, organization.logo), header/footer images, quote photos and speaker photos, following asset: references to the assets registry. Whether the text describes the picture well is not judged here (see opf/poor-alt-text). Charts carry `chart.alt` and are checked by opf/chart-text-alternative. Picture backgrounds are decorative unless they carry their own alt, and watermarks are decorative, so neither is checked."
|
|
2130
1605
|
}
|
|
2131
1606
|
);
|
|
2132
1607
|
var poorAltRule = rule(
|
|
@@ -2140,7 +1615,7 @@ var poorAltRule = rule(
|
|
|
2140
1615
|
var GENERIC_ALT = /^(image|picture|photo|photograph|graphic|img|icon|figure|screenshot|untitled|alt|alt text|logo)$/i;
|
|
2141
1616
|
var FILE_ALT = /(\.(png|jpe?g|gif|svg|webp|bmp|tiff?|heic|avif)$)|^(img|dsc|image|screenshot|screen shot|photo|pic)[ _-]?\d+/i;
|
|
2142
1617
|
var GENERIC_CHART_ALT = /^((a|an|the)\s+)?([a-z-]+\s+){0,2}(chart|graph|plot|diagram|figure)$/i;
|
|
2143
|
-
var kindLabel = (kind) => ({ chart: "Chart", image: "Image", video: "Video",
|
|
1618
|
+
var kindLabel = (kind) => ({ chart: "Chart", image: "Image", video: "Video", logo: "Logo", furniture: "Header/footer image", speaker: "Speaker photo", "quote-photo": "Quote photo", organization: "Organization logo" })[kind] ?? "Picture";
|
|
2144
1619
|
function altFixes(path, value) {
|
|
2145
1620
|
const decorative = typeof value === "string" ? { id: "mark-decorative", title: "Mark as decorative (empty alt)", kind: "patch", safe: false, patch: [{ op: "replace", path, value: { src: value, alt: "" } }] } : { id: "mark-decorative", title: "Mark as decorative (empty alt)", kind: "patch", safe: false, patch: [{ op: "add", path: `${path}/alt`, value: "" }] };
|
|
2146
1621
|
return [{ id: "focus-alt", title: "Write alt text", kind: "focus", safe: true, focus: { path, field: "alt", value } }, decorative];
|
|
@@ -2471,7 +1946,7 @@ var languageRule = rule(
|
|
|
2471
1946
|
"info",
|
|
2472
1947
|
"The presentation does not declare its language.",
|
|
2473
1948
|
"Screen readers and text-to-speech choose pronunciation and hyphenation from the declared language; spell checkers and translation tools use it too.",
|
|
2474
|
-
{ standard: "WCAG 2.2 SC 3.1.1 Language of Page, level A", approximations: "Only the presentation-level `language` is checked, not the language of individual runs (
|
|
1949
|
+
{ standard: "WCAG 2.2 SC 3.1.1 Language of Page, level A", approximations: "Only the presentation-level `language` is checked, not the language of individual runs (`TextRun.lang`; opf/language-tag checks how those tags are written)." }
|
|
2475
1950
|
);
|
|
2476
1951
|
var languageRules = [
|
|
2477
1952
|
{
|
|
@@ -2481,7 +1956,7 @@ var languageRules = [
|
|
|
2481
1956
|
context.report(languageRule, {
|
|
2482
1957
|
path: "",
|
|
2483
1958
|
message: "The presentation has no language set.",
|
|
2484
|
-
help: 'Set `language` to a
|
|
1959
|
+
help: 'Set `language` to a BCP 47 tag, for example "en-US".',
|
|
2485
1960
|
fixes: [{ id: "focus-language", title: "Set the language", kind: "focus", safe: true, focus: { path: "/language", field: "language" } }]
|
|
2486
1961
|
});
|
|
2487
1962
|
}
|
|
@@ -2497,6 +1972,105 @@ var accessibilityRules = [
|
|
|
2497
1972
|
...languageRules
|
|
2498
1973
|
];
|
|
2499
1974
|
|
|
1975
|
+
// src/language-tag.ts
|
|
1976
|
+
var REGION_ALIASES = { UK: "GB" };
|
|
1977
|
+
var privateRegion = /^(?:AA|Q[M-Z]|X[A-Z]|ZZ)$/;
|
|
1978
|
+
var regionNames;
|
|
1979
|
+
var assignedRegion = (region) => {
|
|
1980
|
+
if (privateRegion.test(region)) return true;
|
|
1981
|
+
regionNames ??= new Intl.DisplayNames(["en"], { type: "region", fallback: "code" });
|
|
1982
|
+
try {
|
|
1983
|
+
return regionNames.of(region) !== region;
|
|
1984
|
+
} catch {
|
|
1985
|
+
return false;
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
var canonical = (tag) => {
|
|
1989
|
+
try {
|
|
1990
|
+
return Intl.getCanonicalLocales(tag)[0];
|
|
1991
|
+
} catch {
|
|
1992
|
+
return void 0;
|
|
1993
|
+
}
|
|
1994
|
+
};
|
|
1995
|
+
function regionSubtag(tag) {
|
|
1996
|
+
const subtags = tag.split("-");
|
|
1997
|
+
for (let index = 1; index < subtags.length; index++) {
|
|
1998
|
+
const subtag = subtags[index];
|
|
1999
|
+
if (/^(?:[a-z]{2}|\d{3})$/i.test(subtag)) return { region: subtag.toUpperCase(), index };
|
|
2000
|
+
if (!/^[a-z]{3,4}$/i.test(subtag)) return void 0;
|
|
2001
|
+
}
|
|
2002
|
+
return void 0;
|
|
2003
|
+
}
|
|
2004
|
+
function languageTagProblem(tag) {
|
|
2005
|
+
if (/^[ix]-/i.test(tag)) return void 0;
|
|
2006
|
+
const parsed = canonical(tag);
|
|
2007
|
+
if (parsed === void 0) return { message: `'${tag}' is not a well-formed BCP 47 language tag (subtags are letters and digits joined by hyphens, such as 'en-US' or 'zh-Hans').`, caseOnly: false };
|
|
2008
|
+
const found = regionSubtag(tag);
|
|
2009
|
+
if (found) {
|
|
2010
|
+
const alias = REGION_ALIASES[found.region];
|
|
2011
|
+
if (alias || !assignedRegion(found.region)) {
|
|
2012
|
+
const subtags = tag.split("-");
|
|
2013
|
+
subtags[found.index] = alias ?? found.region;
|
|
2014
|
+
const suggestion = alias ? canonical(subtags.join("-")) : void 0;
|
|
2015
|
+
return {
|
|
2016
|
+
message: `'${tag}' names the region '${found.region}', which is not an assigned region${suggestion ? `; '${suggestion}' is the tag for ${new Intl.DisplayNames(["en"], { type: "region" }).of(alias)}` : ""}.`,
|
|
2017
|
+
...suggestion ? { suggestion } : {},
|
|
2018
|
+
caseOnly: false
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
if (parsed === tag) return void 0;
|
|
2023
|
+
if (parsed.toLowerCase() === tag.toLowerCase())
|
|
2024
|
+
return { message: `'${tag}' is not in canonical case; the canonical form is '${parsed}' (language lower case, script title case, region upper case).`, suggestion: parsed, caseOnly: true };
|
|
2025
|
+
const replacement = found && regionSubtag(parsed)?.region;
|
|
2026
|
+
if (found && replacement && replacement !== found.region) {
|
|
2027
|
+
const subtags = tag.split("-");
|
|
2028
|
+
subtags[found.index] = replacement;
|
|
2029
|
+
return { message: `'${tag}' names the region '${found.region}', which is deprecated; use '${replacement}'.`, suggestion: subtags.join("-"), caseOnly: false };
|
|
2030
|
+
}
|
|
2031
|
+
return void 0;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
// src/rules-language.ts
|
|
2035
|
+
var languageTagRule = rule(
|
|
2036
|
+
"language-tag",
|
|
2037
|
+
"content",
|
|
2038
|
+
"warning",
|
|
2039
|
+
"A language tag is malformed, uses an unassigned region or is not in canonical case.",
|
|
2040
|
+
"Engines read the deck language and each run's `lang` as BCP 47 tags to choose script fonts, text direction, proofing language and the PowerPoint `lang` attribute. A tag such as `en-a`, or a region that does not exist (`en-UK`; the United Kingdom is `GB`), is guessed at or dropped, and a wrong-case tag (`EN-us`) is not what a locale lookup expects.",
|
|
2041
|
+
{
|
|
2042
|
+
standard: "BCP 47 (RFC 5646, section 2.1) and the platform locale data (Intl.getCanonicalLocales, Intl.DisplayNames)",
|
|
2043
|
+
approximations: "Checks the root `language` (a tag string, or the `bcp47` of an inline Language object) and `lang` on the TextRun objects of titles, subtitles, tags, text, lists, tables, quotes, metrics and timelines. A region is assigned when the runtime's CLDR data names it (ISO 3166-1 codes and UN M.49 areas such as 419); private-use regions (`AA`, `QM`-`QZ`, `XA`-`XZ`) and `ZZ` are accepted, as are private-use (`x-...`) tags. Only the spelling of a tag is checked, not whether the language subtag is assigned or whether the language suits the text. The schema rejects tags with characters other than letters, digits and hyphens (`en_US` is a schema error, with no suggestion), and `en-UK` as the deck language is already an error of the schema rule, so those are not reported twice."
|
|
2044
|
+
}
|
|
2045
|
+
);
|
|
2046
|
+
var report = (context, tag, path, slide) => {
|
|
2047
|
+
if (typeof tag !== "string") return;
|
|
2048
|
+
const problem = languageTagProblem(tag);
|
|
2049
|
+
if (!problem) return;
|
|
2050
|
+
context.report(languageTagRule, {
|
|
2051
|
+
path,
|
|
2052
|
+
slide,
|
|
2053
|
+
message: problem.message,
|
|
2054
|
+
help: problem.suggestion ? `Write '${problem.suggestion}'.` : 'Write a well-formed BCP 47 tag with an assigned region, such as "en-US", "pt-BR" or "es-419".',
|
|
2055
|
+
...problem.suggestion ? { fixes: [{ id: "use-canonical-tag", title: `Use '${problem.suggestion}'`, kind: "patch", safe: problem.caseOnly, patch: [{ op: "replace", path, value: problem.suggestion }] }] } : {}
|
|
2056
|
+
});
|
|
2057
|
+
};
|
|
2058
|
+
var isEnUk = (tag) => typeof tag === "string" && tag.toLowerCase() === "en-uk";
|
|
2059
|
+
var languageTagRules = [
|
|
2060
|
+
{
|
|
2061
|
+
info: languageTagRule,
|
|
2062
|
+
run(context) {
|
|
2063
|
+
const language = context.document.language;
|
|
2064
|
+
if (typeof language === "string") {
|
|
2065
|
+
if (!isEnUk(language)) report(context, language, "/language");
|
|
2066
|
+
} else if (language !== void 0 && !isEnUk(rec(language).bcp47)) report(context, rec(language).bcp47, "/language/bcp47");
|
|
2067
|
+
for (const slide of context.slides)
|
|
2068
|
+
for (const tv of slide.texts)
|
|
2069
|
+
if (typeof tv.value !== "string") for (const run of runsOf(tv)) report(context, run.style.lang, `${run.path}/lang`, slide);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
];
|
|
2073
|
+
|
|
2500
2074
|
// src/rules-layout-content.ts
|
|
2501
2075
|
var PX_TO_PT2 = 0.75;
|
|
2502
2076
|
var round2 = (value, places = 1) => Math.round(value * 10 ** places) / 10 ** places;
|
|
@@ -2641,7 +2215,7 @@ var resolutionRule = rule(
|
|
|
2641
2215
|
{
|
|
2642
2216
|
cost: "composition",
|
|
2643
2217
|
thresholds: ["minImagePpi"],
|
|
2644
|
-
approximations: "Only embedded data: images (and asset: references to them) have readable pixel sizes; URLs and files are never fetched, so they are not checked. The displayed size is the composed
|
|
2218
|
+
approximations: "Only embedded data: images (and asset: references to them) have readable pixel sizes; URLs and files are never fetched, so they are not checked. The displayed size is the composed frame (cover and stretch are measured as the cover scale, contain as the contain scale). Effective ppi is the image pixels per inch of the 96 px/inch reference slide. SVG is vector and exempt."
|
|
2645
2219
|
}
|
|
2646
2220
|
);
|
|
2647
2221
|
var resolutionRules = [
|
|
@@ -2669,12 +2243,10 @@ var resolutionRules = [
|
|
|
2669
2243
|
for (const slide of context.slides) {
|
|
2670
2244
|
const composition = slide.composition;
|
|
2671
2245
|
if (composition) {
|
|
2672
|
-
const
|
|
2673
|
-
for (const item of composition.items) if (item.field === "image") check(pointerOfDotted(item.path), item.value, item.box, fill === "crop", slide);
|
|
2674
|
-
if (composition.slideImage) check(pointerOfDotted(composition.slideImage.sourcePath), composition.slideImage.value, composition.slideImage.box, composition.slideImage.fill === "crop", slide);
|
|
2246
|
+
for (const item of composition.items) if (item.field === "image") check(pointerOfDotted(item.path), item.value, item.image?.box ?? item.box, item.image?.fit !== "contain", slide);
|
|
2675
2247
|
}
|
|
2676
2248
|
const background = slide.design.backgroundImage;
|
|
2677
|
-
if (background && background.fit !== "tile") check(background.path, rec({ src: background.source }), slide.design.dimensions, background.fit
|
|
2249
|
+
if (background && background.fit !== "tile") check(background.path, rec({ src: background.source }), slide.design.dimensions, background.fit !== "contain", background.path.startsWith("/slides/") ? slide : void 0);
|
|
2678
2250
|
}
|
|
2679
2251
|
}
|
|
2680
2252
|
}
|
|
@@ -2708,7 +2280,7 @@ var unusedBeatRule = rule(
|
|
|
2708
2280
|
"A beat of the narrative has no slide that references it.",
|
|
2709
2281
|
"The narrative is the plan and the slides are the product. When some slides name a beat (slides[].beat) and a beat of the plan has none, the deck skips a step of the story or the plan is out of date.",
|
|
2710
2282
|
{
|
|
2711
|
-
approximations: "Resolved
|
|
2283
|
+
approximations: "Resolved like every content reference: the document's catalogs groups, then the registered catalogs. A narrative that resolves nowhere is not checked. A deck in which no slide references any beat is not checked either, because it has not linked its slides to the plan. A slide that lists several beats covers each of them."
|
|
2712
2284
|
}
|
|
2713
2285
|
);
|
|
2714
2286
|
var PLACEHOLDERS = [
|
|
@@ -2758,7 +2330,7 @@ var contentRules = [
|
|
|
2758
2330
|
{
|
|
2759
2331
|
info: unusedBeatRule,
|
|
2760
2332
|
run(context) {
|
|
2761
|
-
const narrative = resolveNarrative(context.document, context.options
|
|
2333
|
+
const narrative = resolveNarrative(context.document, context.options);
|
|
2762
2334
|
if (!narrative) return;
|
|
2763
2335
|
const id = String(context.document.narrative);
|
|
2764
2336
|
for (const { beat, index } of unreferencedBeats(context.document, narrative))
|
|
@@ -2778,8 +2350,8 @@ var contentRules = [
|
|
|
2778
2350
|
const has = (value) => value !== void 0 && value !== null && !(typeof value === "string" && value.trim() === "") && !(Array.isArray(value) && value.length === 0);
|
|
2779
2351
|
const hasText = slide.texts.some((tv) => plainText(tv.value).trim() !== "");
|
|
2780
2352
|
const hasObject = slidePayloads(slide.slide, slide.path).some((p) => ["image", "video", "chart", "table", "code", "metric", "quote", "timeline"].some((field) => has(p.node[field])));
|
|
2781
|
-
const
|
|
2782
|
-
if (hasText || hasObject ||
|
|
2353
|
+
const hasBackgroundImage = imageBackground(rec(slide.slide.design).background) !== void 0;
|
|
2354
|
+
if (hasText || hasObject || hasBackgroundImage) continue;
|
|
2783
2355
|
context.report(emptySlideRule, { path: slide.path, slide, message: `Slide ${slide.index + 1} has no title and no content.`, help: "Add content, delete the slide, or give it the blank layout if it is intentionally empty." });
|
|
2784
2356
|
}
|
|
2785
2357
|
}
|
|
@@ -2840,6 +2412,9 @@ var formatRules = [
|
|
|
2840
2412
|
rule("cite-unknown-reference", "format", "error", "A citation names a reference that does not exist.", "A cited id with no entry in `references` has nothing to show in the footnote area.", { standard: SCHEMA }),
|
|
2841
2413
|
rule("cite-unsupported-location", "format", "error", "A citation or footnote sits where no engine draws it.", "`cite` and `footnote` apply to runs in text, bullets and list items; table cells, captions, and reference and footnote texts have no marker.", { standard: SCHEMA }),
|
|
2842
2414
|
rule("caption-unsupported-payload", "format", "error", "A caption is on a payload that cannot carry one.", "A caption belongs to exactly one image, chart, table or video; a group, text or code block has no place to draw it.", { standard: SCHEMA }),
|
|
2415
|
+
rule("image-option-unsupported-payload", "format", "error", "An image option is on a payload that is not an image.", "`fit`, `focus`, the image treatments (`shape`, `cornerRadius`, `border`, `opacity`, `recolor`, `overlay`, `aspectRatio`) and `placement` describe how a picture is drawn; a group, text or chart block has no picture for them to apply to.", { standard: SCHEMA }),
|
|
2416
|
+
rule("image-placement-invalid", "format", "error", "An image placement cannot be honoured.", "A placed image bleeds to a slide edge and the rest of the slide composes beside it. Only a top-level block (slides.N.blocks.I) can do that, and a slide edge holds one placed image; a block in a group or a promoted region, or a second block on the same edge, has nowhere to go.", { standard: SCHEMA }),
|
|
2417
|
+
rule("layout-placeholder-group", "format", "error", "A layout record's placeholder group breaks a nesting rule.", "A placeholder group arranges body regions inside one cell of its layout record. Groups nest at most three levels inside a record, and a group holds body regions and groups only: the headings (title, subtitle, tag) stay at the record's top level, where the engine places them. Composition cannot use a record that breaks either rule.", { standard: SCHEMA }),
|
|
2843
2418
|
rule("dataset-unknown", "format", "error", "A chart or table names a dataset that does not exist.", "The data cannot be drawn without the dataset it refers to.", { standard: SCHEMA }),
|
|
2844
2419
|
rule("dataset-field-unknown", "format", "error", "A table asks a dataset for a column it does not have.", "The column cannot be shown when the dataset has no column of that name.", { standard: SCHEMA }),
|
|
2845
2420
|
rule("data-column-duplicate", "format", "error", "A dataset or table has two columns with the same name.", "Series, mappings and fields address columns by name, so a repeated name makes them ambiguous.", { standard: SCHEMA }),
|
|
@@ -2876,23 +2451,30 @@ var referenceRules = [
|
|
|
2876
2451
|
"catalog-record",
|
|
2877
2452
|
"references",
|
|
2878
2453
|
"error",
|
|
2879
|
-
"
|
|
2880
|
-
"A record that fails its
|
|
2454
|
+
"An embedded or registered catalog record is invalid.",
|
|
2455
|
+
"A record that fails its companion schema cannot be resolved. Invalid records are left out of the lookup, so the references to them are reported too.",
|
|
2881
2456
|
{ standard: "spec/schemas/<kind>.schema.json" }
|
|
2882
2457
|
),
|
|
2883
2458
|
rule(
|
|
2884
|
-
"
|
|
2459
|
+
"unresolved-reference",
|
|
2885
2460
|
"references",
|
|
2886
2461
|
"warning",
|
|
2887
|
-
"A
|
|
2888
|
-
"A theme,
|
|
2889
|
-
{ approximations: "Resolved
|
|
2462
|
+
"A content reference resolves nowhere.",
|
|
2463
|
+
"A layout, theme, colour scheme, font scheme, narrative, audience, purpose or tone reference that neither the document embeds nor a registered catalog defines falls back: a slide composes automatically, a design uses the engine default. A strict export fails instead. A slide with no layout is automatic composition and is never reported.",
|
|
2464
|
+
{ standard: SCHEMA, approximations: "Resolved like every engine resolves it: catalogs.custom, then the records embedded under catalogs.default, then the catalog registered for its source (the first registered catalog when `default` is omitted); `name:id` in catalogs.<name>, then the catalog registered for its source. Nothing is fetched. Free-form audience and purpose text is not a reference." }
|
|
2890
2465
|
),
|
|
2891
|
-
rule(
|
|
2892
|
-
|
|
2466
|
+
rule(
|
|
2467
|
+
"catalog-record-not-in-source",
|
|
2468
|
+
"references",
|
|
2469
|
+
"warning",
|
|
2470
|
+
"A record embedded under a catalog group is not in that catalog.",
|
|
2471
|
+
"A record under catalogs.default or a named group says it came from the catalog its source names. When the catalog the host registered for that source has no record of that kind and id, the record is the document's own and belongs in catalogs.custom, where an update from the catalog never looks for it. Rendering is unchanged: the embedded record still wins.",
|
|
2472
|
+
{ standard: SCHEMA, approximations: "Checked only against a catalog the host registered for the group's source (the first registered catalog for an omitted default.source); with none registered for it the check is silent. A record the catalog has with different content is an update difference (updateFromCatalog), not this finding. catalogs.custom is never checked." }
|
|
2473
|
+
),
|
|
2474
|
+
rule("undeclared-catalog", "format", "error", "A reference names a catalog group the document does not declare.", "The prefix of a `name:id` reference names the group of `catalogs` it resolves in. A prefix with no group can never resolve, whatever the host registers, so it is a format error: engines reject the document at their format check instead of drawing a fallback.", { standard: SCHEMA }),
|
|
2893
2475
|
rule("unused-reference", "references", "warning", "A reference is never cited.", "A listed reference that no run cites is not drawn anywhere.", { standard: SCHEMA }),
|
|
2894
2476
|
rule("unused-dataset", "references", "warning", "A dataset is never used.", "A dataset no chart or table references is not drawn anywhere.", { standard: SCHEMA }),
|
|
2895
|
-
rule("unknown-beat", "references", "warning", "A slide names a beat its narrative does not define.", "`slides[].beat` links a slide to a step of the narrative plan. A beat id the narrative does not have links to nothing; nothing is drawn from a beat.", { standard: SCHEMA, approximations: "The narrative resolves
|
|
2477
|
+
rule("unknown-beat", "references", "warning", "A slide names a beat its narrative does not define.", "`slides[].beat` links a slide to a step of the narrative plan. A beat id the narrative does not have links to nothing; nothing is drawn from a beat.", { standard: SCHEMA, approximations: "The narrative resolves like every content reference: the document's catalogs groups, then the registered catalogs. A narrative that resolves nowhere is not checked." }),
|
|
2896
2478
|
rule("slide-theme-dimensions", "references", "warning", "A slide theme sets a slide size that differs from the deck.", "A PPTX has one slide size. The size a slide-level theme carries is never used: design.dimensions of the deck (or of its theme) wins in every engine, and without them the exporter stops with mixed slide sizes.", { standard: SCHEMA }),
|
|
2897
2479
|
rule("variable-unknown", "references", "warning", "A `{{token}}` names a variable that is not declared.", "An undeclared token is shown literally.", { standard: SCHEMA }),
|
|
2898
2480
|
rule("variable-unknown-value", "references", "warning", "A value was supplied for a variable that is not declared.", "The value is never used.", { standard: SCHEMA }),
|
|
@@ -2927,7 +2509,7 @@ var dataRules = [
|
|
|
2927
2509
|
rule("duration-outside-narrative", "content", "warning", "The target duration is outside the range the narrative suits.", "A narrative records the talk lengths it suits. A deck whose duration is outside that range probably needs a different narrative or a different length; nothing is drawn or exported differently.", { standard: SCHEMA }),
|
|
2928
2510
|
rule("narrative-duration-range", "content", "warning", "An inline narrative duration range has min greater than max.", "A range with its bounds swapped matches no duration, so the duration check cannot help.", { standard: "spec/schemas/narrative.schema.json" })
|
|
2929
2511
|
];
|
|
2930
|
-
var implementations = [...accessibilityRules, ...layoutContentRules];
|
|
2512
|
+
var implementations = [...accessibilityRules, ...layoutContentRules, ...languageTagRules];
|
|
2931
2513
|
var ruleImplementations = implementations;
|
|
2932
2514
|
var infos = [
|
|
2933
2515
|
...formatRules,
|
|
@@ -2972,12 +2554,7 @@ function at(value, path) {
|
|
|
2972
2554
|
);
|
|
2973
2555
|
}
|
|
2974
2556
|
function checkDocumentOptions(options) {
|
|
2975
|
-
|
|
2976
|
-
([kind, records]) => !catalogKinds.includes(kind) || !Array.isArray(records)
|
|
2977
|
-
)))
|
|
2978
|
-
throw new TypeError(
|
|
2979
|
-
"Validate catalogs must map known catalog kinds to arrays of loaded records."
|
|
2980
|
-
);
|
|
2557
|
+
checkCatalogsOption(options.catalogs, "validate");
|
|
2981
2558
|
if (options.contracts !== void 0 && !Array.isArray(options.contracts))
|
|
2982
2559
|
throw new TypeError("Validate contracts must be an array.");
|
|
2983
2560
|
for (const contract of options.contracts ?? []) {
|
|
@@ -3094,36 +2671,6 @@ function active(cursor, value) {
|
|
|
3094
2671
|
const selected = candidates.sort((a, b) => score(b.schema, value) - score(a.schema, value))[0];
|
|
3095
2672
|
return selected ? { ...selected, baseSchemas: [...selected.baseSchemas ?? [], resolved] } : resolved;
|
|
3096
2673
|
}
|
|
3097
|
-
function catalogIn(schema) {
|
|
3098
|
-
const text = String(schema.description ?? "");
|
|
3099
|
-
if (/\bfont-scheme id\b/.test(text)) return "fontSchemes";
|
|
3100
|
-
return catalogKinds.find(
|
|
3101
|
-
(kind) => text.includes(`catalogs.${kind}`) || new RegExp(`\\b${kind}['\u2019]? catalog`).test(text)
|
|
3102
|
-
);
|
|
3103
|
-
}
|
|
3104
|
-
var languageTagSyntax = new RegExp(
|
|
3105
|
-
"^(?:(?:[a-z]{2,3}(?:-[a-z]{3}){0,3}|[a-z]{4}|[a-z]{5,8})(?:-[a-z]{4})?(?:-(?:[a-z]{2}|[0-9]{3}))?(?:-(?:[a-z0-9]{5,8}|[0-9][a-z0-9]{3}))*(?:-[0-9a-wy-z](?:-[a-z0-9]{2,8})+)*(?:-x(?:-[a-z0-9]{1,8})+)?|x(?:-[a-z0-9]{1,8})+)$",
|
|
3106
|
-
"i"
|
|
3107
|
-
);
|
|
3108
|
-
var irregularLanguageTags = /* @__PURE__ */ new Set([
|
|
3109
|
-
"en-gb-oed",
|
|
3110
|
-
"i-ami",
|
|
3111
|
-
"i-bnn",
|
|
3112
|
-
"i-default",
|
|
3113
|
-
"i-enochian",
|
|
3114
|
-
"i-hak",
|
|
3115
|
-
"i-klingon",
|
|
3116
|
-
"i-lux",
|
|
3117
|
-
"i-mingo",
|
|
3118
|
-
"i-navajo",
|
|
3119
|
-
"i-pwn",
|
|
3120
|
-
"i-tao",
|
|
3121
|
-
"i-tay",
|
|
3122
|
-
"i-tsu",
|
|
3123
|
-
"sgn-be-fr",
|
|
3124
|
-
"sgn-be-nl",
|
|
3125
|
-
"sgn-ch-de"
|
|
3126
|
-
]);
|
|
3127
2674
|
function childCursor(cursors, key) {
|
|
3128
2675
|
for (const keyword of [
|
|
3129
2676
|
"properties",
|
|
@@ -3164,7 +2711,7 @@ function fields(document) {
|
|
|
3164
2711
|
const entry = stack.pop();
|
|
3165
2712
|
if (!entry) break;
|
|
3166
2713
|
if (entry.ancestors.includes(entry.value)) continue;
|
|
3167
|
-
const resolved = resolve(entry.cursor), selected = active(entry.cursor, entry.value)
|
|
2714
|
+
const resolved = resolve(entry.cursor), selected = active(entry.cursor, entry.value);
|
|
3168
2715
|
const assetReference = [resolved, selected].some(
|
|
3169
2716
|
(cursor) => cursor.root.$id === schemas.presentation.$id && (cursor.path === "/$defs/Asset" || cursor.path === "/$defs/Asset/oneOf/0" || cursor.path === "/$defs/Watermark/properties/src") || String(cursor.schema.description ?? "").includes("asset:") || Array.isArray(cursor.schema.examples) && cursor.schema.examples.some(
|
|
3170
2717
|
(example) => typeof example === "string" && example.startsWith("asset:")
|
|
@@ -3174,8 +2721,6 @@ function fields(document) {
|
|
|
3174
2721
|
path: pointer3(entry.path),
|
|
3175
2722
|
value: entry.value,
|
|
3176
2723
|
cursor: resolved,
|
|
3177
|
-
kind: catalogIn(resolved.schema),
|
|
3178
|
-
description,
|
|
3179
2724
|
assetReference
|
|
3180
2725
|
});
|
|
3181
2726
|
const ancestors = [...entry.ancestors, entry.value];
|
|
@@ -3209,74 +2754,39 @@ function fields(document) {
|
|
|
3209
2754
|
}
|
|
3210
2755
|
return result;
|
|
3211
2756
|
}
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
{
|
|
3243
|
-
records: Array.isArray(local.records) ? local.records : [],
|
|
3244
|
-
origin: "document",
|
|
3245
|
-
scope: "document",
|
|
3246
|
-
path: `/catalogs/${kind}/records`
|
|
2757
|
+
var recordKey = (group, kind, id) => `${group}/${kind}/${id}`;
|
|
2758
|
+
function recordIssues(kind, id, value) {
|
|
2759
|
+
const schemaName = catalogSchemaNames[kind];
|
|
2760
|
+
return validateAgainstSchema(object(value) ? { $schema: schemas[schemaName].$id, id, ...value } : value, kind);
|
|
2761
|
+
}
|
|
2762
|
+
function embeddedRecordFindings(document, options, findings) {
|
|
2763
|
+
const invalid = /* @__PURE__ */ new Set();
|
|
2764
|
+
if (!object(document) || !object(document.catalogs)) return invalid;
|
|
2765
|
+
for (const [group, value] of Object.entries(document.catalogs)) {
|
|
2766
|
+
if (!object(value)) continue;
|
|
2767
|
+
for (const kind of catalogKinds)
|
|
2768
|
+
for (const [id, record] of Object.entries(object(value[kind]) ? value[kind] : {})) {
|
|
2769
|
+
const path = pointer3(["catalogs", group, kind, id]);
|
|
2770
|
+
if (object(record) && (Object.hasOwn(record, "$schema") || Object.hasOwn(record, "id"))) continue;
|
|
2771
|
+
const validation = recordIssues(kind, id, record);
|
|
2772
|
+
for (const issue2 of validation.errors) findings.push(issueFinding(issue2, "opf/catalog-record", catalogSchemaNames[kind], path, "document"));
|
|
2773
|
+
if (!validation.valid) invalid.add(recordKey(group, kind, id));
|
|
2774
|
+
if (group === "custom") continue;
|
|
2775
|
+
const source = catalogGroupSource(document, group, options);
|
|
2776
|
+
const registered = registeredCatalog(source, options);
|
|
2777
|
+
if (!registered || Object.hasOwn(registered[kind] ?? {}, id)) continue;
|
|
2778
|
+
findings.push(
|
|
2779
|
+
finding("opf/catalog-record-not-in-source", {
|
|
2780
|
+
path,
|
|
2781
|
+
message: `Record ${JSON.stringify(id)} is embedded under catalogs.${group}.${kind}, but the catalog registered for ${source} has no ${kind} record ${JSON.stringify(id)}; move it to catalogs.custom.`,
|
|
2782
|
+
help: `Move the record to catalogs.custom (and drop the ${group === "default" ? "" : `${group}:`}prefix from its references), or use the id the catalog publishes. The embedded record still renders.`,
|
|
2783
|
+
definition: `${schemas.presentation.$id}#/$defs/Catalogs`,
|
|
2784
|
+
lookup: ["opf", "catalog", kind]
|
|
2785
|
+
})
|
|
2786
|
+
);
|
|
3247
2787
|
}
|
|
3248
|
-
]) {
|
|
3249
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3250
|
-
group.records.forEach((value, index) => {
|
|
3251
|
-
const path = `${group.path}/${index}`, schemaName = catalogSchemaNames[kind], record = object(value) ? { $schema: schemas[schemaName].$id, ...value } : value;
|
|
3252
|
-
const validation = validateAgainstSchema(record, kind);
|
|
3253
|
-
for (const issue2 of validation.errors)
|
|
3254
|
-
findings.push(issueFinding(issue2, "opf/catalog-record", schemaName, path, group.scope));
|
|
3255
|
-
if (!object(value) || typeof value.id !== "string") return;
|
|
3256
|
-
if (seen.has(value.id))
|
|
3257
|
-
findings.push(
|
|
3258
|
-
finding("opf/catalog-record", {
|
|
3259
|
-
scope: group.scope,
|
|
3260
|
-
path: `${path}/id`,
|
|
3261
|
-
message: `Duplicate ${kind} record id ${JSON.stringify(value.id)} in this catalog.`,
|
|
3262
|
-
help: "Give distinct records distinct IDs, or combine the intended override explicitly. Preserve their authored content."
|
|
3263
|
-
})
|
|
3264
|
-
);
|
|
3265
|
-
seen.add(value.id);
|
|
3266
|
-
if (!validation.valid) {
|
|
3267
|
-
map.delete(value.id);
|
|
3268
|
-
return;
|
|
3269
|
-
}
|
|
3270
|
-
map.set(value.id, {
|
|
3271
|
-
value: value.id,
|
|
3272
|
-
label: typeof value.name === "string" ? value.name : value.id,
|
|
3273
|
-
origin: group.origin,
|
|
3274
|
-
definition: `${group.scope}#${path}`
|
|
3275
|
-
});
|
|
3276
|
-
});
|
|
3277
|
-
}
|
|
3278
2788
|
}
|
|
3279
|
-
return
|
|
2789
|
+
return invalid;
|
|
3280
2790
|
}
|
|
3281
2791
|
function distance(a, b) {
|
|
3282
2792
|
a = a.slice(0, 128);
|
|
@@ -3411,14 +2921,59 @@ function variableFindings(document, engine, schemaValid) {
|
|
|
3411
2921
|
walk(document, [], 0);
|
|
3412
2922
|
return findings;
|
|
3413
2923
|
}
|
|
3414
|
-
function
|
|
3415
|
-
|
|
3416
|
-
const
|
|
3417
|
-
|
|
2924
|
+
function undeclaredCatalogFindings(document) {
|
|
2925
|
+
const findings = [];
|
|
2926
|
+
const reported = /* @__PURE__ */ new Set();
|
|
2927
|
+
for (const site of catalogReferenceSites(document)) {
|
|
2928
|
+
const parsed = parseReference(site.reference);
|
|
2929
|
+
if (parsed?.group === void 0 || catalogGroupDeclared(document, parsed.group)) continue;
|
|
2930
|
+
const path = pointerPath(site.path);
|
|
2931
|
+
if (reported.has(path)) continue;
|
|
2932
|
+
reported.add(path);
|
|
2933
|
+
findings.push(
|
|
2934
|
+
finding("opf/undeclared-catalog", {
|
|
2935
|
+
path,
|
|
2936
|
+
message: `Reference ${JSON.stringify(site.reference)} names catalog group ${JSON.stringify(parsed.group)}, which the document does not declare, so it can never resolve.`,
|
|
2937
|
+
help: `Declare catalogs.${parsed.group} with the catalog's source (and embed the record), or write the reference without the prefix.`,
|
|
2938
|
+
definition: `${schemas.presentation.$id}#/$defs/CatalogReference`,
|
|
2939
|
+
lookup: ["opf", "schema", "presentation", "/$defs/CatalogReference"]
|
|
2940
|
+
})
|
|
2941
|
+
);
|
|
2942
|
+
}
|
|
2943
|
+
return findings;
|
|
2944
|
+
}
|
|
2945
|
+
function contentReferenceFindings(document, options, findings) {
|
|
2946
|
+
const invalid = embeddedRecordFindings(document, options, findings);
|
|
2947
|
+
const registeredChecked = /* @__PURE__ */ new Set();
|
|
2948
|
+
for (const site of catalogReferenceSites(document)) {
|
|
2949
|
+
const path = pointerPath(site.path);
|
|
2950
|
+
const parsed = parseReference(site.reference);
|
|
2951
|
+
if (parsed?.group !== void 0 && !catalogGroupDeclared(document, parsed.group)) continue;
|
|
2952
|
+
const found = resolveReference(document, site.kind, site.reference, { ...options, ...site.group !== void 0 ? { group: site.group } : {} });
|
|
2953
|
+
if (found?.origin === "host" && !registeredChecked.has(recordKey(found.group, site.kind, found.id))) {
|
|
2954
|
+
registeredChecked.add(recordKey(found.group, site.kind, found.id));
|
|
2955
|
+
for (const issue2 of recordIssues(site.kind, found.id, found.record).errors)
|
|
2956
|
+
findings.push(issueFinding(issue2, "opf/catalog-record", catalogSchemaNames[site.kind], pointer3(["catalogs", found.group, site.kind, found.id]), "context"));
|
|
2957
|
+
}
|
|
2958
|
+
if (found && !(found.origin === "document" && invalid.has(recordKey(found.group, site.kind, found.id)))) continue;
|
|
2959
|
+
const diagnostic = unresolvedReference(document, site.kind, site.reference, path, options);
|
|
2960
|
+
const suggestions = catalogRecords(document, site.kind, options).map((entry) => ({ value: entry.reference, label: typeof entry.record.name === "string" ? entry.record.name : entry.reference, origin: entry.origin === "host" ? "registered" : "document", definition: entry.origin === "document" ? `document#${pointer3(["catalogs", entry.group, site.kind, entry.id])}` : `${entry.source ?? "context"}#/${site.kind}/${entry.id}` })).sort((a, b) => distance(site.reference, a.value) - distance(site.reference, b.value) || (a.value < b.value ? -1 : a.value > b.value ? 1 : 0)).slice(0, 5);
|
|
2961
|
+
findings.push(
|
|
2962
|
+
finding("opf/unresolved-reference", {
|
|
2963
|
+
path,
|
|
2964
|
+
message: diagnostic.message,
|
|
2965
|
+
help: site.kind === "layouts" ? "Embed the layout record (embed(), or opf embed), register the catalog that defines it, choose one of the suggested layouts, or remove the reference to compose the slide automatically." : "Embed the record (embed(), or opf embed), register the catalog that defines it, or choose one of the suggested records.",
|
|
2966
|
+
definition: `${schemas.presentation.$id}#/$defs/Catalogs`,
|
|
2967
|
+
lookup: ["opf", "catalog", site.kind],
|
|
2968
|
+
suggestions
|
|
2969
|
+
})
|
|
2970
|
+
);
|
|
2971
|
+
}
|
|
3418
2972
|
}
|
|
3419
2973
|
function referenceFindings(document, engine, options) {
|
|
3420
2974
|
const findings = [];
|
|
3421
|
-
const
|
|
2975
|
+
const catalogs = { catalogs: options.catalogs ?? [] };
|
|
2976
|
+
contentReferenceFindings(document, catalogs, findings);
|
|
3422
2977
|
const assetValues = object(document) && object(document.assets) ? document.assets : {};
|
|
3423
2978
|
for (const field of fields(document)) {
|
|
3424
2979
|
if (typeof field.value === "string" && field.value.startsWith("asset:") && field.assetReference) {
|
|
@@ -3442,30 +2997,6 @@ function referenceFindings(document, engine, options) {
|
|
|
3442
2997
|
})
|
|
3443
2998
|
);
|
|
3444
2999
|
}
|
|
3445
|
-
if (!field.path || !field.kind) continue;
|
|
3446
|
-
const { kind } = field;
|
|
3447
|
-
if (kind === "languages" && field.path === "/language" && typeof field.value === "string" && (languageTagSyntax.test(field.value) || irregularLanguageTags.has(field.value.toLowerCase())))
|
|
3448
|
-
continue;
|
|
3449
|
-
if (kind !== "layouts" && /free-form/i.test(field.description)) continue;
|
|
3450
|
-
const value = object(field.value) ? field.value.id : field.value, path = object(field.value) ? `${field.path}/id` : field.path;
|
|
3451
|
-
if (typeof value !== "string" || !value || /^(?:https?:|pkg:)/i.test(value) || catalogs2.get(kind)?.has(value) || seen.has(path))
|
|
3452
|
-
continue;
|
|
3453
|
-
seen.add(path);
|
|
3454
|
-
if (!options.catalogs?.[kind]?.length && hasExternalSource(document, kind)) continue;
|
|
3455
|
-
const suggestions = [...catalogs2.get(kind)?.values() ?? []].sort(
|
|
3456
|
-
(a, b) => distance(value, String(a.value)) - distance(value, String(b.value)) || (String(a.value) < String(b.value) ? -1 : String(a.value) > String(b.value) ? 1 : 0)
|
|
3457
|
-
).slice(0, 5);
|
|
3458
|
-
const definition = String(field.cursor.root.$id) + `#${field.cursor.path}`;
|
|
3459
|
-
findings.push(
|
|
3460
|
-
finding("opf/catalog-reference", {
|
|
3461
|
-
path,
|
|
3462
|
-
message: `Unknown ${kind} catalog id ${JSON.stringify(value)} in the available local context.`,
|
|
3463
|
-
help: kind === "layouts" ? "Choose an available layout or supply the intended custom record. Engine-defined layouts may be valid; preview with the target renderer before changing content." : "Choose an available record or supply the intended custom catalog context. External references and native rendering are not verified by this check.",
|
|
3464
|
-
definition,
|
|
3465
|
-
lookup: ["opf", "catalog", kind],
|
|
3466
|
-
suggestions
|
|
3467
|
-
})
|
|
3468
|
-
);
|
|
3469
3000
|
}
|
|
3470
3001
|
const reportedCycles = /* @__PURE__ */ new Set();
|
|
3471
3002
|
for (const id of Object.keys(assetValues)) {
|
|
@@ -3492,33 +3023,7 @@ function referenceFindings(document, engine, options) {
|
|
|
3492
3023
|
current = typeof source === "string" && source.startsWith("asset:") ? source.slice(6) : void 0;
|
|
3493
3024
|
}
|
|
3494
3025
|
}
|
|
3495
|
-
|
|
3496
|
-
if (typeof issue2.params.code === "string") continue;
|
|
3497
|
-
const kind = issue2.params.kind, id = issue2.params.id, replacedBy = issue2.params.replacedBy;
|
|
3498
|
-
if (kind === void 0) continue;
|
|
3499
|
-
if (typeof replacedBy === "string" && typeof id === "string") {
|
|
3500
|
-
const target = catalogs2.get(kind)?.get(replacedBy);
|
|
3501
|
-
findings.push({
|
|
3502
|
-
...issueFinding(issue2, "opf/deprecated-catalog-id"),
|
|
3503
|
-
message: `Deprecated ${kind} catalog id ${JSON.stringify(id)}; use ${JSON.stringify(replacedBy)} instead.`,
|
|
3504
|
-
help: "The deprecated id still resolves to its original record, so nothing breaks. Switch to the replacement when you next edit this reference.",
|
|
3505
|
-
lookup: ["opf", "catalog", kind],
|
|
3506
|
-
...target ? { suggestions: [target] } : {}
|
|
3507
|
-
});
|
|
3508
|
-
continue;
|
|
3509
|
-
}
|
|
3510
|
-
if (seen.has(issue2.path) || typeof id === "string" && catalogs2.get(kind)?.has(id))
|
|
3511
|
-
continue;
|
|
3512
|
-
const dir = catalogEntries.find((entry) => entry.kind === kind)?.dir;
|
|
3513
|
-
findings.push({
|
|
3514
|
-
...issueFinding(issue2, "opf/catalog-reference"),
|
|
3515
|
-
message: `Unknown ${kind} catalog id ${JSON.stringify(id)} in the available local context.`,
|
|
3516
|
-
help: "Inspect the referenced catalog and supply the intended record if this is a custom context.",
|
|
3517
|
-
...dir ? { definition: `spec/${dir}/index.json` } : {},
|
|
3518
|
-
lookup: ["opf", "catalog", kind]
|
|
3519
|
-
});
|
|
3520
|
-
}
|
|
3521
|
-
findings.push(...narrativeFindings(document, options));
|
|
3026
|
+
findings.push(...narrativeFindings(document, catalogs));
|
|
3522
3027
|
for (const issue2 of unusedReferenceWarnings(document))
|
|
3523
3028
|
findings.push(
|
|
3524
3029
|
finding("opf/unused-reference", {
|
|
@@ -3545,16 +3050,16 @@ function referenceFindings(document, engine, options) {
|
|
|
3545
3050
|
function narrativeFindings(document, options) {
|
|
3546
3051
|
const findings = [];
|
|
3547
3052
|
if (!object(document)) return findings;
|
|
3548
|
-
const narrative = resolveNarrative(document, options
|
|
3053
|
+
const narrative = resolveNarrative(document, options);
|
|
3549
3054
|
if (narrative) {
|
|
3550
3055
|
const id = String(document.narrative);
|
|
3551
|
-
const beatSuggestions = (beat) => narrative.beats.slice().sort((a, b) => distance(beat, a) - distance(beat, b) || (a < b ? -1 : a > b ? 1 : 0)).slice(0, 5).map((value) => ({ value, label: value, origin: narrative.origin
|
|
3056
|
+
const beatSuggestions = (beat) => narrative.beats.slice().sort((a, b) => distance(beat, a) - distance(beat, b) || (a < b ? -1 : a > b ? 1 : 0)).slice(0, 5).map((value) => ({ value, label: value, origin: narrative.origin, definition: `narratives/${id}#/beats` }));
|
|
3552
3057
|
for (const reference of unknownBeatReferences(document, narrative))
|
|
3553
3058
|
findings.push(
|
|
3554
3059
|
finding("opf/unknown-beat", {
|
|
3555
3060
|
path: reference.path,
|
|
3556
3061
|
message: `Slide ${reference.slide + 1} names beat ${JSON.stringify(reference.beat)}, which narrative ${JSON.stringify(id)} does not define.`,
|
|
3557
|
-
help: `Use one of the narrative's beat ids (${narrative.beats.join(", ")}), add the beat to the narrative record (
|
|
3062
|
+
help: `Use one of the narrative's beat ids (${narrative.beats.join(", ")}), add the beat to the narrative record (a record the document embeds or defines in catalogs.custom.narratives), or remove the beat link. Nothing is drawn from a beat.`,
|
|
3558
3063
|
definition: schemas.presentation.$id + "#/$defs/Slide/properties/beat",
|
|
3559
3064
|
lookup: ["opf", "catalog", "narratives"],
|
|
3560
3065
|
suggestions: beatSuggestions(reference.beat)
|
|
@@ -3572,20 +3077,19 @@ function narrativeFindings(document, options) {
|
|
|
3572
3077
|
})
|
|
3573
3078
|
);
|
|
3574
3079
|
}
|
|
3575
|
-
const
|
|
3576
|
-
|
|
3577
|
-
inlineNarratives.forEach((record, index) => {
|
|
3080
|
+
for (const [group, value] of Object.entries(object(document.catalogs) ? document.catalogs : {}))
|
|
3081
|
+
for (const [id, record] of Object.entries(object(value) && object(value.narratives) ? value.narratives : {})) {
|
|
3578
3082
|
if (durationRangeInverted(record))
|
|
3579
3083
|
findings.push(
|
|
3580
3084
|
finding("opf/narrative-duration-range", {
|
|
3581
|
-
path:
|
|
3085
|
+
path: pointer3(["catalogs", group, "narratives", id, "duration"]),
|
|
3582
3086
|
message: "The narrative duration range has min greater than max.",
|
|
3583
3087
|
help: "Swap the bounds so min is the shortest and max the longest talk length, in minutes.",
|
|
3584
3088
|
definition: schemas.narrative.$id + "#/properties/duration",
|
|
3585
3089
|
lookup: ["opf", "schema", "narrative", "/properties/duration"]
|
|
3586
3090
|
})
|
|
3587
3091
|
);
|
|
3588
|
-
}
|
|
3092
|
+
}
|
|
3589
3093
|
return findings;
|
|
3590
3094
|
}
|
|
3591
3095
|
function contractFindings(document, contracts) {
|
|
@@ -3742,52 +3246,27 @@ function parseSource(source) {
|
|
|
3742
3246
|
}
|
|
3743
3247
|
|
|
3744
3248
|
// src/slide-context.ts
|
|
3745
|
-
var DEFAULT_THEME = "minimal";
|
|
3746
|
-
var DEFAULT_COLOR_SCHEME = "cool-horizon";
|
|
3747
3249
|
var rec2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
3748
3250
|
function resolveSlideContext(presentation, index, options = {}) {
|
|
3749
3251
|
const deck = rec2(presentation);
|
|
3750
3252
|
const slides = Array.isArray(deck.slides) ? deck.slides : [];
|
|
3751
3253
|
if (!Number.isInteger(index) || index < 0 || index >= slides.length) throw new RangeError(`Slide index ${String(index)} is outside the presentation's ${slides.length} slides.`);
|
|
3752
3254
|
const slide = rec2(slides[index]);
|
|
3753
|
-
const
|
|
3754
|
-
const
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
return found === void 0 ? void 0 : rec2(found);
|
|
3758
|
-
};
|
|
3255
|
+
const catalogs = { catalogs: checkCatalogsOption(options.catalogs, "resolveSlideContext") };
|
|
3256
|
+
const records = resolveDesignRecords(presentation, index, catalogs);
|
|
3257
|
+
const diagnostics = [...records.diagnostics];
|
|
3258
|
+
const { theme, colorScheme, fontScheme } = records;
|
|
3759
3259
|
const design = { ...rec2(deck.design), ...rec2(slide.design) };
|
|
3760
|
-
const own2 = rec2(slide.design), shared = rec2(deck.design);
|
|
3761
|
-
const resolveReference = (kind, reference, path, code, fallbackId) => {
|
|
3762
|
-
const object2 = typeof reference === "object" && reference !== null && !Array.isArray(reference) ? rec2(reference) : {};
|
|
3763
|
-
const id = typeof reference === "string" ? reference : typeof object2.id === "string" ? object2.id : void 0;
|
|
3764
|
-
if (id === void 0 && typeof reference === "object" && reference !== null && !Array.isArray(reference)) return { ...lookup(kind, fallbackId), ...object2 };
|
|
3765
|
-
const found = id === void 0 ? void 0 : lookup(kind, id);
|
|
3766
|
-
const inline = Object.keys(object2).some((key) => key !== "id");
|
|
3767
|
-
if (id !== void 0 && found === void 0 && !inline) {
|
|
3768
|
-
diagnostics.push({
|
|
3769
|
-
code,
|
|
3770
|
-
path,
|
|
3771
|
-
id,
|
|
3772
|
-
fallback: fallbackId,
|
|
3773
|
-
message: `${kind === "themes" ? "Theme" : "Colour scheme"} '${id}' is not in the inline, host or bundled catalogs; using '${fallbackId}'.`
|
|
3774
|
-
});
|
|
3775
|
-
return { ...lookup(kind, fallbackId), ...object2 };
|
|
3776
|
-
}
|
|
3777
|
-
return { ...found, ...object2 };
|
|
3778
|
-
};
|
|
3779
|
-
const themePath = own2.theme !== void 0 ? `slides.${index}.design.theme` : "design.theme";
|
|
3780
|
-
const theme = resolveReference("themes", design.theme ?? DEFAULT_THEME, themePath, "unresolved-theme", DEFAULT_THEME);
|
|
3781
|
-
const colorSchemePath = own2.colorScheme !== void 0 ? `slides.${index}.design.colorScheme` : shared.colorScheme !== void 0 ? "design.colorScheme" : themePath;
|
|
3782
|
-
const colorScheme = resolveReference("colorSchemes", design.colorScheme ?? theme.colorScheme ?? DEFAULT_COLOR_SCHEME, colorSchemePath, "unresolved-color-scheme", DEFAULT_COLOR_SCHEME);
|
|
3783
|
-
const fontSchemePath = own2.fontScheme !== void 0 ? `slides.${index}.design.fontScheme` : shared.fontScheme !== void 0 ? "design.fontScheme" : themePath;
|
|
3784
|
-
const font = resolveFontSchemeReference(design.fontScheme ?? theme.fontScheme ?? DEFAULT_FONT_SCHEME, (id) => lookup("fontSchemes", id), fontSchemePath);
|
|
3785
|
-
if (font.diagnostic) diagnostics.push(font.diagnostic);
|
|
3786
3260
|
let layout;
|
|
3261
|
+
let layoutProvenance;
|
|
3787
3262
|
if (typeof slide.layout === "string") {
|
|
3788
|
-
|
|
3789
|
-
if (
|
|
3263
|
+
const found = resolveReference(presentation, "layouts", slide.layout, catalogs);
|
|
3264
|
+
if (found) {
|
|
3265
|
+
layout = { ...found.record };
|
|
3266
|
+
layoutProvenance = provenanceOf(found);
|
|
3267
|
+
} else diagnostics.push(unresolvedReference(presentation, "layouts", slide.layout, `slides.${index}.layout`, catalogs));
|
|
3790
3268
|
}
|
|
3269
|
+
if (options.strictReferences && diagnostics.length) throw new OPFUnresolvedReferenceError(diagnostics);
|
|
3791
3270
|
const composeOptions = {
|
|
3792
3271
|
...resolveCanvasDimensions(design.dimensions ?? theme.dimensions),
|
|
3793
3272
|
...layout ? { layout } : {},
|
|
@@ -3795,13 +3274,13 @@ function resolveSlideContext(presentation, index, options = {}) {
|
|
|
3795
3274
|
slideIndex: index,
|
|
3796
3275
|
slideNumber: options.slideNumber ?? index + 1,
|
|
3797
3276
|
slideCount: options.slideCount ?? slides.length,
|
|
3798
|
-
fontFamilies: resolveFontFamilies(
|
|
3277
|
+
fontFamilies: resolveFontFamilies(fontScheme),
|
|
3799
3278
|
darkBackground: resolveColorRoles(colorScheme, { background: decisionColor(design.background ?? theme.background, colorScheme, rec2(deck.variables)) }).dark,
|
|
3800
|
-
|
|
3279
|
+
...theme.background !== void 0 ? { themeBackground: theme.background } : {},
|
|
3801
3280
|
...options.fonts?.textMeasurement ? { textMeasurement: options.fonts.textMeasurement } : {},
|
|
3802
3281
|
...options.date !== void 0 ? { date: options.date } : {}
|
|
3803
3282
|
};
|
|
3804
|
-
return { options: composeOptions, diagnostics, resolved: { theme, colorScheme, fontScheme:
|
|
3283
|
+
return { options: composeOptions, diagnostics, resolved: { theme, colorScheme, fontScheme, fontSchemePath: records.fontSchemePath, ...layout ? { layout } : {}, provenance: { ...layoutProvenance ? { layout: layoutProvenance } : {}, ...records.provenance } } };
|
|
3805
3284
|
}
|
|
3806
3285
|
|
|
3807
3286
|
// src/rule-slides.ts
|
|
@@ -3897,12 +3376,12 @@ var OPFValidationError = class extends Error {
|
|
|
3897
3376
|
report;
|
|
3898
3377
|
/** The error-severity findings of the report. */
|
|
3899
3378
|
findings;
|
|
3900
|
-
constructor(
|
|
3901
|
-
const errors =
|
|
3379
|
+
constructor(report2) {
|
|
3380
|
+
const errors = report2.findings.filter((entry) => entry.severity === "error");
|
|
3902
3381
|
const first = errors[0];
|
|
3903
3382
|
super(first ? `OPF validation failed at ${first.path || "/"}: ${first.message}` : "OPF validation failed");
|
|
3904
3383
|
this.name = "OPFValidationError";
|
|
3905
|
-
this.report =
|
|
3384
|
+
this.report = report2;
|
|
3906
3385
|
this.findings = errors;
|
|
3907
3386
|
}
|
|
3908
3387
|
};
|
|
@@ -4023,7 +3502,7 @@ function syntaxReport(parsed, run) {
|
|
|
4023
3502
|
return { valid: tally.error === 0, schemaValid: null, findings, counts: tally, checks };
|
|
4024
3503
|
}
|
|
4025
3504
|
function validateDocument(document, run, parsed) {
|
|
4026
|
-
const engine = validateAgainstSchema(document, "presentation", { template: run.options.template, values: run.options.values });
|
|
3505
|
+
const engine = validateAgainstSchema(document, "presentation", { template: run.options.template, values: run.options.values, ...run.options.catalogs ? { catalogs: run.options.catalogs } : {} });
|
|
4027
3506
|
const schemaValid = engine.errors.length === 0;
|
|
4028
3507
|
const slides = isObject(document) && Array.isArray(document.slides) ? document.slides : [];
|
|
4029
3508
|
const auditWanted = auditInfos.some((info) => run.enabled(info));
|
|
@@ -4032,6 +3511,7 @@ function validateDocument(document, run, parsed) {
|
|
|
4032
3511
|
const findings = [];
|
|
4033
3512
|
findings.push(...engineFindings(document, engine, (ruleId) => enabledRule(findValidationRule(ruleId))));
|
|
4034
3513
|
if (enabledRule(findValidationRule("opf/variable-unfilled"))) findings.push(...variableFindings(document, engine, schemaValid));
|
|
3514
|
+
if (enabledRule(findValidationRule("opf/undeclared-catalog"))) findings.push(...undeclaredCatalogFindings(document));
|
|
4035
3515
|
if (parsed) {
|
|
4036
3516
|
findings.push(...parsed.duplicates.filter((entry) => enabledRule(findValidationRule(entry.ruleId))));
|
|
4037
3517
|
}
|
|
@@ -4048,13 +3528,11 @@ function validateDocument(document, run, parsed) {
|
|
|
4048
3528
|
const auditRan = /* @__PURE__ */ new Set();
|
|
4049
3529
|
if (schemaValid && auditWanted) {
|
|
4050
3530
|
const doc = document;
|
|
4051
|
-
const lookup = createLookup(doc, run.options.catalogs);
|
|
4052
3531
|
const context = {
|
|
4053
3532
|
document: doc,
|
|
4054
3533
|
slides: buildSlides(doc, run.options),
|
|
4055
3534
|
thresholds: run.thresholds,
|
|
4056
3535
|
options: run.options,
|
|
4057
|
-
lookup,
|
|
4058
3536
|
chartPalette: run.chartPalette,
|
|
4059
3537
|
report(info, input) {
|
|
4060
3538
|
const severity = run.severity(info) ?? input.severity ?? info.severity;
|
|
@@ -4136,16 +3614,14 @@ function validate(input, options = {}) {
|
|
|
4136
3614
|
}
|
|
4137
3615
|
function assertValid(value, options = {}) {
|
|
4138
3616
|
if (typeof value === "string") throw new TypeError("assertValid takes a parsed presentation. Use validate(text) for JSON text.");
|
|
4139
|
-
const
|
|
4140
|
-
if (!
|
|
3617
|
+
const report2 = validate(value, options);
|
|
3618
|
+
if (!report2.valid) throw new OPFValidationError(report2);
|
|
4141
3619
|
}
|
|
4142
3620
|
function validateCatalogRecord(kind, value) {
|
|
4143
|
-
|
|
3621
|
+
const kinds = Object.keys(catalogSchemaNames);
|
|
3622
|
+
if (!kinds.includes(kind)) throw new TypeError(`Unknown catalog kind ${JSON.stringify(kind)}. Kinds: ${kinds.join(", ")}.`);
|
|
4144
3623
|
const engine = validateAgainstSchema(value, kind);
|
|
4145
|
-
const findings =
|
|
4146
|
-
...engine.errors.map((issue2) => issueFinding(issue2, issueRuleId(issue2), engine.schemaName)),
|
|
4147
|
-
...engine.warnings.map((issue2) => issueFinding(issue2, "opf/catalog-reference", engine.schemaName, "", "document", "warning"))
|
|
4148
|
-
];
|
|
3624
|
+
const findings = engine.errors.map((issue2) => issueFinding(issue2, issueRuleId(issue2), engine.schemaName));
|
|
4149
3625
|
const tally = counts(findings);
|
|
4150
3626
|
const checks = {
|
|
4151
3627
|
syntax: "not-applicable",
|
|
@@ -4160,8 +3636,8 @@ function validateCatalogRecord(kind, value) {
|
|
|
4160
3636
|
return { valid: tally.error === 0, schemaValid: engine.valid, findings, counts: tally, checks };
|
|
4161
3637
|
}
|
|
4162
3638
|
function assertValidCatalogRecord(kind, value) {
|
|
4163
|
-
const
|
|
4164
|
-
if (!
|
|
3639
|
+
const report2 = validateCatalogRecord(kind, value);
|
|
3640
|
+
if (!report2.valid) throw new OPFValidationError(report2);
|
|
4165
3641
|
}
|
|
4166
3642
|
|
|
4167
|
-
export { DEFAULT_CHART_PALETTE, DEFAULT_VALIDATION_THRESHOLDS, OPFValidationError, assertValid, assertValidCatalogRecord, findValidationRule, resolveSlideContext, validate, validateCatalogRecord, validationCategories, validationRules };
|
|
3643
|
+
export { DEFAULT_CHART_PALETTE, DEFAULT_VALIDATION_THRESHOLDS, OPFValidationError, assertValid, assertValidCatalogRecord, findValidationRule, parseSource, resolveSlideContext, validate, validateCatalogRecord, validationCategories, validationRules };
|