@openpresentation/opf 0.18.3 → 0.19.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 +18 -17
- package/dist/browser.js +18 -20
- package/dist/{catalog-refs-BSfGELpt.d.ts → catalog-refs-CSHevLn1.d.ts} +1 -1
- package/dist/{chunk-KA3ZPFVT.js → chunk-65GDO6TJ.js} +96 -40
- package/dist/{chunk-JCOSZTOI.js → chunk-A6COIVTD.js} +7 -2
- package/dist/{chunk-ZCFSDSUX.js → chunk-AK4UXIRP.js} +1 -1
- package/dist/{chunk-WXSPETQ6.js → chunk-F7PLNWHQ.js} +25 -3
- package/dist/{chunk-MSFE2HUK.js → chunk-FGUQHD37.js} +16 -13
- package/dist/{chunk-GVOLSWAJ.js → chunk-GRN3U5JT.js} +5 -5
- package/dist/{chunk-TRELE6I6.js → chunk-HBFRNOP4.js} +1 -1
- package/dist/{chunk-R7KIASS4.js → chunk-LRPSMQ62.js} +1 -1
- package/dist/chunk-OOT5AY4V.js +16 -0
- package/dist/{chunk-FO3WGS4R.js → chunk-OVBGGGKO.js} +25 -16
- package/dist/{chunk-2PEWUUBR.js → chunk-R5T4H4ZV.js} +350 -314
- package/dist/{chunk-L5YACLWK.js → chunk-SEUJIS55.js} +2 -2
- package/dist/{chunk-ECP7QPGK.js → chunk-SIQWYDFF.js} +6 -6
- package/dist/chunk-UJSAR6GF.js +181 -0
- package/dist/{chunk-IM337HP5.js → chunk-V3RGXJJS.js} +4 -5
- package/dist/{chunk-WHHLGDCQ.js → chunk-WHKFIFN7.js} +1 -1
- package/dist/{chunk-K5EG3UMS.js → chunk-XWMKAJSS.js} +46 -17
- package/dist/{chunk-PNINP5IF.js → chunk-YAHPQRVU.js} +1 -1
- package/dist/{chunk-MBU42S5Y.js → chunk-ZPCKGGI6.js} +1152 -273
- package/dist/{composition-C-OoqvAr.d.ts → composition-DilAHoWM.d.ts} +385 -99
- package/dist/composition.d.ts +2 -2
- package/dist/composition.js +1 -2
- package/dist/conversion-NJQHH4QW.js +19 -0
- package/dist/{conversion-BxZbBd_0.d.ts → conversion-k9l5pQsq.d.ts} +11 -11
- package/dist/convert.d.ts +3 -3
- package/dist/convert.js +7 -9
- package/dist/data.d.ts +1 -1
- package/dist/data.js +2 -3
- package/dist/{deck-report-DiDf_Vew.d.ts → deck-report-D19fyuNu.d.ts} +3 -3
- package/dist/deck.d.ts +6 -6
- package/dist/deck.js +10 -12
- package/dist/diff.js +5 -7
- package/dist/docs.js +27 -21
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +23853 -20994
- package/dist/font-policy.js +1 -1
- package/dist/format.js +2 -2
- package/dist/index.d.ts +22 -21
- package/dist/index.js +24 -27
- package/dist/markdown.d.ts +4 -4
- package/dist/markdown.js +7 -9
- package/dist/node-engine.d.ts +26 -9
- package/dist/node-engine.js +23 -24
- package/dist/{pagination-BaUjDrTz.d.ts → pagination-BNj5UQn5.d.ts} +3 -3
- package/dist/pagination.d.ts +3 -3
- package/dist/pagination.js +4 -6
- package/dist/patch.js +4 -6
- package/dist/{presentation-81rNihF0.d.ts → presentation-B_e2Djga.d.ts} +35 -19
- package/dist/repo-readme.js +1 -1
- package/dist/schemas.d.ts +2 -18
- package/dist/schemas.js +1 -1
- package/dist/spec/README.md +12 -19
- package/dist/spec/reference/engine-vocabularies.json +1 -1
- package/dist/spec/reference/font-policy.json +25 -3
- package/dist/spec/schemas/catalog-index.schema.json +3 -3
- package/dist/spec/schemas/catalog-manifest.schema.json +1 -1
- package/dist/spec/schemas/chart-type.schema.json +2 -2
- package/dist/spec/schemas/language.schema.json +1 -1
- package/dist/spec/schemas/layout-preview-index.schema.json +25 -11
- package/dist/spec/schemas/layout.schema.json +193 -272
- package/dist/spec/schemas/opf.schema.json +63 -18
- package/dist/spec/schemas/social-platform.schema.json +1 -1
- package/dist/spec/schemas/theme.schema.json +60 -0
- package/dist/spec-files.d.ts +2 -2
- package/dist/spec-files.js +1 -1
- package/dist/types.d.ts +115 -40
- package/dist/{validation-types-PbGDrNUr.d.ts → validation-types-CWhPuYUt.d.ts} +2 -2
- package/dist/validator-Cse-AD32.d.ts +73 -0
- package/dist/validator.d.ts +6 -60
- package/dist/validator.js +3 -5
- package/dist/yaml.d.ts +4 -4
- package/dist/yaml.js +7 -9
- package/package.json +6 -9
- package/dist/catalog-schemas-CinPh5WA.d.ts +0 -12
- package/dist/catalog.d.ts +0 -91
- package/dist/catalog.js +0 -3
- package/dist/chunk-HXHOZ7AH.js +0 -4937
- package/dist/chunk-SPFV27O5.js +0 -210
- package/dist/chunk-TRDXRRQK.js +0 -17
- package/dist/chunk-WCG3THTD.js +0 -23712
- package/dist/conversion-4CLOEG6O.js +0 -21
- package/dist/spec/catalogs/audiences/academic.json +0 -24
- package/dist/spec/catalogs/audiences/all-hands.json +0 -25
- package/dist/spec/catalogs/audiences/board.json +0 -24
- package/dist/spec/catalogs/audiences/candidates.json +0 -23
- package/dist/spec/catalogs/audiences/customer.json +0 -25
- package/dist/spec/catalogs/audiences/engineering-team.json +0 -23
- package/dist/spec/catalogs/audiences/executive.json +0 -24
- package/dist/spec/catalogs/audiences/general-public.json +0 -25
- package/dist/spec/catalogs/audiences/index.json +0 -105
- package/dist/spec/catalogs/audiences/internal-team.json +0 -25
- package/dist/spec/catalogs/audiences/investor.json +0 -25
- package/dist/spec/catalogs/audiences/marketing.json +0 -25
- package/dist/spec/catalogs/audiences/media.json +0 -24
- package/dist/spec/catalogs/audiences/partner.json +0 -25
- package/dist/spec/catalogs/audiences/regulatory.json +0 -25
- package/dist/spec/catalogs/audiences/sales.json +0 -25
- package/dist/spec/catalogs/audiences/technical.json +0 -25
- package/dist/spec/catalogs/chart-types/100pct-stacked-area.json +0 -21
- package/dist/spec/catalogs/chart-types/100pct-stacked-bar.json +0 -22
- package/dist/spec/catalogs/chart-types/100pct-stacked-column.json +0 -22
- package/dist/spec/catalogs/chart-types/area.json +0 -20
- package/dist/spec/catalogs/chart-types/bar.json +0 -22
- package/dist/spec/catalogs/chart-types/box-and-whisker.json +0 -21
- package/dist/spec/catalogs/chart-types/column.json +0 -22
- package/dist/spec/catalogs/chart-types/combo.json +0 -37
- package/dist/spec/catalogs/chart-types/doughnut.json +0 -20
- package/dist/spec/catalogs/chart-types/filled-radar.json +0 -21
- package/dist/spec/catalogs/chart-types/funnel.json +0 -21
- package/dist/spec/catalogs/chart-types/histogram.json +0 -21
- package/dist/spec/catalogs/chart-types/index.json +0 -171
- package/dist/spec/catalogs/chart-types/line-with-markers.json +0 -21
- package/dist/spec/catalogs/chart-types/line.json +0 -20
- package/dist/spec/catalogs/chart-types/pareto.json +0 -22
- package/dist/spec/catalogs/chart-types/pie.json +0 -20
- package/dist/spec/catalogs/chart-types/radar-with-markers.json +0 -21
- package/dist/spec/catalogs/chart-types/radar.json +0 -21
- package/dist/spec/catalogs/chart-types/scatter.json +0 -21
- package/dist/spec/catalogs/chart-types/stacked-area.json +0 -21
- package/dist/spec/catalogs/chart-types/stacked-bar.json +0 -22
- package/dist/spec/catalogs/chart-types/stacked-column.json +0 -22
- package/dist/spec/catalogs/chart-types/stacked-line-with-markers.json +0 -22
- package/dist/spec/catalogs/chart-types/stacked-line.json +0 -21
- package/dist/spec/catalogs/chart-types/treemap.json +0 -21
- package/dist/spec/catalogs/chart-types/waterfall.json +0 -21
- package/dist/spec/catalogs/chart-types/world.json +0 -21
- package/dist/spec/catalogs/color-schemes/black-and-white.json +0 -26
- package/dist/spec/catalogs/color-schemes/bold-red.json +0 -26
- package/dist/spec/catalogs/color-schemes/boost.json +0 -26
- package/dist/spec/catalogs/color-schemes/burnt-orange.json +0 -26
- package/dist/spec/catalogs/color-schemes/cool-horizon.json +0 -26
- package/dist/spec/catalogs/color-schemes/corporate-blue.json +0 -26
- package/dist/spec/catalogs/color-schemes/deep-purple.json +0 -26
- package/dist/spec/catalogs/color-schemes/forest-green.json +0 -26
- package/dist/spec/catalogs/color-schemes/golden-yellow.json +0 -26
- package/dist/spec/catalogs/color-schemes/index.json +0 -79
- package/dist/spec/catalogs/color-schemes/luxury.json +0 -26
- package/dist/spec/catalogs/color-schemes/pastel-red.json +0 -26
- package/dist/spec/catalogs/color-schemes/slate-gray.json +0 -26
- package/dist/spec/catalogs/color-schemes/steel-blue.json +0 -26
- package/dist/spec/catalogs/color-schemes/vibes.json +0 -26
- package/dist/spec/catalogs/font-schemes/angsana-new.json +0 -15
- package/dist/spec/catalogs/font-schemes/aparajita.json +0 -16
- package/dist/spec/catalogs/font-schemes/aptos.json +0 -13
- package/dist/spec/catalogs/font-schemes/arabic-typesetting.json +0 -15
- package/dist/spec/catalogs/font-schemes/arial.json +0 -13
- package/dist/spec/catalogs/font-schemes/batang.json +0 -15
- package/dist/spec/catalogs/font-schemes/bookman.json +0 -13
- package/dist/spec/catalogs/font-schemes/calibri.json +0 -13
- package/dist/spec/catalogs/font-schemes/century-schoolbook.json +0 -13
- package/dist/spec/catalogs/font-schemes/consolas.json +0 -14
- package/dist/spec/catalogs/font-schemes/constantia.json +0 -13
- package/dist/spec/catalogs/font-schemes/courier-new.json +0 -14
- package/dist/spec/catalogs/font-schemes/daunpenh.json +0 -15
- package/dist/spec/catalogs/font-schemes/david.json +0 -15
- package/dist/spec/catalogs/font-schemes/dilleniaupc.json +0 -15
- package/dist/spec/catalogs/font-schemes/fangsong.json +0 -15
- package/dist/spec/catalogs/font-schemes/garamond.json +0 -13
- package/dist/spec/catalogs/font-schemes/gautami.json +0 -15
- package/dist/spec/catalogs/font-schemes/georgia.json +0 -13
- package/dist/spec/catalogs/font-schemes/gisha.json +0 -16
- package/dist/spec/catalogs/font-schemes/grandview.json +0 -13
- package/dist/spec/catalogs/font-schemes/gungsuh.json +0 -15
- package/dist/spec/catalogs/font-schemes/impact.json +0 -13
- package/dist/spec/catalogs/font-schemes/index.json +0 -454
- package/dist/spec/catalogs/font-schemes/kalinga.json +0 -15
- package/dist/spec/catalogs/font-schemes/kartika.json +0 -15
- package/dist/spec/catalogs/font-schemes/khmer-ui.json +0 -15
- package/dist/spec/catalogs/font-schemes/latha.json +0 -15
- package/dist/spec/catalogs/font-schemes/lucida-sans.json +0 -13
- package/dist/spec/catalogs/font-schemes/malgun-gothic.json +0 -15
- package/dist/spec/catalogs/font-schemes/mangal.json +0 -17
- package/dist/spec/catalogs/font-schemes/meiryo.json +0 -15
- package/dist/spec/catalogs/font-schemes/microsoft-jhenghei.json +0 -15
- package/dist/spec/catalogs/font-schemes/microsoft-yahei.json +0 -18
- package/dist/spec/catalogs/font-schemes/mingliu.json +0 -15
- package/dist/spec/catalogs/font-schemes/miriam.json +0 -15
- package/dist/spec/catalogs/font-schemes/montserrat.json +0 -13
- package/dist/spec/catalogs/font-schemes/ms-mincho.json +0 -15
- package/dist/spec/catalogs/font-schemes/nirmala-ui.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-naksh-arabic.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-nastaliq-urdu.json +0 -16
- package/dist/spec/catalogs/font-schemes/noto-sans-arabic.json +0 -17
- package/dist/spec/catalogs/font-schemes/noto-sans-armenian.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-bengali.json +0 -16
- package/dist/spec/catalogs/font-schemes/noto-sans-devangari.json +0 -16
- package/dist/spec/catalogs/font-schemes/noto-sans-ethiopic.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-georgian.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-gujarati.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-gurmukhi.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-hebrew.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-jp.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-kannada.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-khmer.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-kr.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-malayalam.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-mongolian.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-oriya.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-sc.json +0 -18
- package/dist/spec/catalogs/font-schemes/noto-sans-tamil.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-tc.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-telugu.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans-thai.json +0 -15
- package/dist/spec/catalogs/font-schemes/noto-sans.json +0 -18
- package/dist/spec/catalogs/font-schemes/nyala.json +0 -15
- package/dist/spec/catalogs/font-schemes/open-sans.json +0 -13
- package/dist/spec/catalogs/font-schemes/pmingliu.json +0 -15
- package/dist/spec/catalogs/font-schemes/poppins.json +0 -13
- package/dist/spec/catalogs/font-schemes/pt-serif.json +0 -13
- package/dist/spec/catalogs/font-schemes/raavi.json +0 -15
- package/dist/spec/catalogs/font-schemes/raleway.json +0 -13
- package/dist/spec/catalogs/font-schemes/roboto.json +0 -13
- package/dist/spec/catalogs/font-schemes/rockwell.json +0 -13
- package/dist/spec/catalogs/font-schemes/sakkal-majalla.json +0 -17
- package/dist/spec/catalogs/font-schemes/seaford.json +0 -13
- package/dist/spec/catalogs/font-schemes/segoe-ui-light.json +0 -13
- package/dist/spec/catalogs/font-schemes/segoe-ui.json +0 -13
- package/dist/spec/catalogs/font-schemes/shonar-bangla.json +0 -16
- package/dist/spec/catalogs/font-schemes/shruti.json +0 -15
- package/dist/spec/catalogs/font-schemes/simsun.json +0 -15
- package/dist/spec/catalogs/font-schemes/skeena.json +0 -13
- package/dist/spec/catalogs/font-schemes/sylfaen.json +0 -16
- package/dist/spec/catalogs/font-schemes/tahoma.json +0 -13
- package/dist/spec/catalogs/font-schemes/tenorite.json +0 -13
- package/dist/spec/catalogs/font-schemes/times-new-roman.json +0 -13
- package/dist/spec/catalogs/font-schemes/traditional-arabic.json +0 -17
- package/dist/spec/catalogs/font-schemes/trebuchet-ms.json +0 -13
- package/dist/spec/catalogs/font-schemes/tunga.json +0 -15
- package/dist/spec/catalogs/font-schemes/verdana.json +0 -13
- package/dist/spec/catalogs/font-schemes/vrinda.json +0 -15
- package/dist/spec/catalogs/font-schemes/yu-gothic.json +0 -15
- package/dist/spec/catalogs/languages/afrikaans.json +0 -12
- package/dist/spec/catalogs/languages/albanian.json +0 -12
- package/dist/spec/catalogs/languages/amharic.json +0 -12
- package/dist/spec/catalogs/languages/arabic.json +0 -12
- package/dist/spec/catalogs/languages/armenian.json +0 -12
- package/dist/spec/catalogs/languages/aymara.json +0 -12
- package/dist/spec/catalogs/languages/azerbaijani.json +0 -12
- package/dist/spec/catalogs/languages/bengali.json +0 -12
- package/dist/spec/catalogs/languages/berber-latin.json +0 -12
- package/dist/spec/catalogs/languages/bosnian-latin.json +0 -12
- package/dist/spec/catalogs/languages/bulgarian.json +0 -12
- package/dist/spec/catalogs/languages/catalan.json +0 -12
- package/dist/spec/catalogs/languages/cebuano.json +0 -12
- package/dist/spec/catalogs/languages/chinese-simplified.json +0 -12
- package/dist/spec/catalogs/languages/chinese-traditional.json +0 -12
- package/dist/spec/catalogs/languages/chittagonian.json +0 -12
- package/dist/spec/catalogs/languages/croatian.json +0 -12
- package/dist/spec/catalogs/languages/czech.json +0 -12
- package/dist/spec/catalogs/languages/danish.json +0 -12
- package/dist/spec/catalogs/languages/dutch.json +0 -12
- package/dist/spec/catalogs/languages/english-au.json +0 -12
- package/dist/spec/catalogs/languages/english-ca.json +0 -12
- package/dist/spec/catalogs/languages/english-gb.json +0 -12
- package/dist/spec/catalogs/languages/english-in.json +0 -12
- package/dist/spec/catalogs/languages/english-us.json +0 -12
- package/dist/spec/catalogs/languages/english.json +0 -12
- package/dist/spec/catalogs/languages/estonian.json +0 -12
- package/dist/spec/catalogs/languages/filipino.json +0 -12
- package/dist/spec/catalogs/languages/finnish.json +0 -12
- package/dist/spec/catalogs/languages/french.json +0 -12
- package/dist/spec/catalogs/languages/fulfulde.json +0 -12
- package/dist/spec/catalogs/languages/galician.json +0 -12
- package/dist/spec/catalogs/languages/georgian.json +0 -12
- package/dist/spec/catalogs/languages/german.json +0 -12
- package/dist/spec/catalogs/languages/greek.json +0 -12
- package/dist/spec/catalogs/languages/gujarati.json +0 -12
- package/dist/spec/catalogs/languages/hausa.json +0 -12
- package/dist/spec/catalogs/languages/hebrew.json +0 -12
- package/dist/spec/catalogs/languages/hindi.json +0 -12
- package/dist/spec/catalogs/languages/hungarian.json +0 -12
- package/dist/spec/catalogs/languages/igbo.json +0 -12
- package/dist/spec/catalogs/languages/index.json +0 -567
- package/dist/spec/catalogs/languages/indonesian.json +0 -12
- package/dist/spec/catalogs/languages/italian.json +0 -12
- package/dist/spec/catalogs/languages/japanese.json +0 -12
- package/dist/spec/catalogs/languages/kannada.json +0 -12
- package/dist/spec/catalogs/languages/kazakh.json +0 -12
- package/dist/spec/catalogs/languages/khmer.json +0 -12
- package/dist/spec/catalogs/languages/kinyarwanda.json +0 -12
- package/dist/spec/catalogs/languages/korean.json +0 -12
- package/dist/spec/catalogs/languages/kurmanji.json +0 -12
- package/dist/spec/catalogs/languages/latvian.json +0 -12
- package/dist/spec/catalogs/languages/lithuanian.json +0 -12
- package/dist/spec/catalogs/languages/macedonian.json +0 -12
- package/dist/spec/catalogs/languages/malagasy.json +0 -12
- package/dist/spec/catalogs/languages/malay.json +0 -12
- package/dist/spec/catalogs/languages/malayalam.json +0 -12
- package/dist/spec/catalogs/languages/maori.json +0 -12
- package/dist/spec/catalogs/languages/marathi.json +0 -12
- package/dist/spec/catalogs/languages/mongolian.json +0 -12
- package/dist/spec/catalogs/languages/nepali.json +0 -12
- package/dist/spec/catalogs/languages/norwegian.json +0 -12
- package/dist/spec/catalogs/languages/odia.json +0 -12
- package/dist/spec/catalogs/languages/oromo.json +0 -12
- package/dist/spec/catalogs/languages/pashto.json +0 -12
- package/dist/spec/catalogs/languages/persian.json +0 -12
- package/dist/spec/catalogs/languages/polish.json +0 -12
- package/dist/spec/catalogs/languages/portuguese.json +0 -12
- package/dist/spec/catalogs/languages/punjabi-gurmukhi.json +0 -12
- package/dist/spec/catalogs/languages/punjabi-shahmukhi.json +0 -12
- package/dist/spec/catalogs/languages/romanian.json +0 -12
- package/dist/spec/catalogs/languages/russian.json +0 -12
- package/dist/spec/catalogs/languages/serbian-cyrillic.json +0 -12
- package/dist/spec/catalogs/languages/serbian-latin.json +0 -12
- package/dist/spec/catalogs/languages/shona.json +0 -12
- package/dist/spec/catalogs/languages/slovak.json +0 -12
- package/dist/spec/catalogs/languages/slovenian.json +0 -12
- package/dist/spec/catalogs/languages/somali.json +0 -12
- package/dist/spec/catalogs/languages/spanish.json +0 -12
- package/dist/spec/catalogs/languages/swahili.json +0 -12
- package/dist/spec/catalogs/languages/swedish.json +0 -12
- package/dist/spec/catalogs/languages/tagalog.json +0 -12
- package/dist/spec/catalogs/languages/tajik.json +0 -12
- package/dist/spec/catalogs/languages/tamil.json +0 -12
- package/dist/spec/catalogs/languages/telugu.json +0 -12
- package/dist/spec/catalogs/languages/thai.json +0 -12
- package/dist/spec/catalogs/languages/turkish.json +0 -12
- package/dist/spec/catalogs/languages/ukrainian.json +0 -12
- package/dist/spec/catalogs/languages/urdu.json +0 -12
- package/dist/spec/catalogs/languages/uzbek-latin.json +0 -12
- package/dist/spec/catalogs/languages/vietnamese-quoc-ngu.json +0 -12
- package/dist/spec/catalogs/languages/xhosa.json +0 -12
- package/dist/spec/catalogs/languages/yoruba.json +0 -12
- package/dist/spec/catalogs/languages/zulu.json +0 -12
- package/dist/spec/catalogs/layouts/action-plan.json +0 -29
- package/dist/spec/catalogs/layouts/agenda.json +0 -28
- package/dist/spec/catalogs/layouts/appendix-index.json +0 -30
- package/dist/spec/catalogs/layouts/architecture-stack.json +0 -29
- package/dist/spec/catalogs/layouts/assumptions-dependencies.json +0 -29
- package/dist/spec/catalogs/layouts/before-after.json +0 -35
- package/dist/spec/catalogs/layouts/benchmark-target-table.json +0 -29
- package/dist/spec/catalogs/layouts/blank.json +0 -16
- package/dist/spec/catalogs/layouts/bullet-list.json +0 -32
- package/dist/spec/catalogs/layouts/business-model-canvas.json +0 -94
- package/dist/spec/catalogs/layouts/capability-map.json +0 -80
- package/dist/spec/catalogs/layouts/case-study.json +0 -29
- package/dist/spec/catalogs/layouts/chapter-recap.json +0 -28
- package/dist/spec/catalogs/layouts/chart-1x-title-center.json +0 -30
- package/dist/spec/catalogs/layouts/chart-1x.json +0 -34
- package/dist/spec/catalogs/layouts/chart-2x-title-center.json +0 -36
- package/dist/spec/catalogs/layouts/chart-2x-vertical-title-left.json +0 -37
- package/dist/spec/catalogs/layouts/chart-2x.json +0 -65
- package/dist/spec/catalogs/layouts/chart-3x-bottom-vertical-title-left.json +0 -52
- package/dist/spec/catalogs/layouts/chart-3x-left-title-center.json +0 -51
- package/dist/spec/catalogs/layouts/chart-3x-left.json +0 -46
- package/dist/spec/catalogs/layouts/chart-3x-right-title-center.json +0 -51
- package/dist/spec/catalogs/layouts/chart-3x-right.json +0 -46
- package/dist/spec/catalogs/layouts/chart-3x-title-center.json +0 -39
- package/dist/spec/catalogs/layouts/chart-3x-top-vertical-title-left.json +0 -52
- package/dist/spec/catalogs/layouts/chart-3x.json +0 -83
- package/dist/spec/catalogs/layouts/circular-lifecycle.json +0 -29
- package/dist/spec/catalogs/layouts/code-1x.json +0 -29
- package/dist/spec/catalogs/layouts/comparison.json +0 -35
- package/dist/spec/catalogs/layouts/competitive-landscape.json +0 -30
- package/dist/spec/catalogs/layouts/customer-journey.json +0 -30
- package/dist/spec/catalogs/layouts/customer-logos.json +0 -32
- package/dist/spec/catalogs/layouts/dashboard.json +0 -67
- package/dist/spec/catalogs/layouts/data-visualization.json +0 -39
- package/dist/spec/catalogs/layouts/decision-tree.json +0 -30
- package/dist/spec/catalogs/layouts/detailed-data-table.json +0 -35
- package/dist/spec/catalogs/layouts/ecosystem-map.json +0 -30
- package/dist/spec/catalogs/layouts/executive-decision.json +0 -32
- package/dist/spec/catalogs/layouts/executive-summary.json +0 -32
- package/dist/spec/catalogs/layouts/extract/canonical.json +0 -575
- package/dist/spec/catalogs/layouts/faq.json +0 -29
- package/dist/spec/catalogs/layouts/feature-comparison-matrix.json +0 -29
- package/dist/spec/catalogs/layouts/forecast-scenario.json +0 -39
- package/dist/spec/catalogs/layouts/funnel-pyramid.json +0 -32
- package/dist/spec/catalogs/layouts/gantt-project-plan.json +0 -32
- package/dist/spec/catalogs/layouts/geographic-map.json +0 -30
- package/dist/spec/catalogs/layouts/heatmap-cohort.json +0 -32
- package/dist/spec/catalogs/layouts/hub-and-spoke.json +0 -29
- package/dist/spec/catalogs/layouts/icon-grid.json +0 -30
- package/dist/spec/catalogs/layouts/image-1x-crop-title-center.json +0 -32
- package/dist/spec/catalogs/layouts/image-1x-crop-title-left.json +0 -32
- package/dist/spec/catalogs/layouts/image-1x-crop.json +0 -27
- package/dist/spec/catalogs/layouts/image-1x-fit-title-center.json +0 -32
- package/dist/spec/catalogs/layouts/image-1x.json +0 -32
- package/dist/spec/catalogs/layouts/image-2x-crop-title-center.json +0 -38
- package/dist/spec/catalogs/layouts/image-2x-crop-vertical-title-left.json +0 -39
- package/dist/spec/catalogs/layouts/image-2x-crop-vertical.json +0 -34
- package/dist/spec/catalogs/layouts/image-2x-crop.json +0 -33
- package/dist/spec/catalogs/layouts/image-2x-fit-title-center.json +0 -38
- package/dist/spec/catalogs/layouts/image-2x-fit-vertical-title-left.json +0 -39
- package/dist/spec/catalogs/layouts/image-2x-fit-vertical.json +0 -34
- package/dist/spec/catalogs/layouts/image-2x.json +0 -63
- package/dist/spec/catalogs/layouts/image-3x-crop-title-center.json +0 -41
- package/dist/spec/catalogs/layouts/image-3x-crop-vertical-title-left.json +0 -42
- package/dist/spec/catalogs/layouts/image-3x-crop-vertical.json +0 -37
- package/dist/spec/catalogs/layouts/image-3x-crop.json +0 -36
- package/dist/spec/catalogs/layouts/image-3x-fit-title-center.json +0 -41
- package/dist/spec/catalogs/layouts/image-3x-fit-vertical-title-left.json +0 -42
- package/dist/spec/catalogs/layouts/image-3x-fit-vertical.json +0 -37
- package/dist/spec/catalogs/layouts/image-3x-fit.json +0 -36
- package/dist/spec/catalogs/layouts/image-3x.json +0 -81
- package/dist/spec/catalogs/layouts/image-focus.json +0 -30
- package/dist/spec/catalogs/layouts/image-only-1x-crop-title-center.json +0 -31
- package/dist/spec/catalogs/layouts/image-only-1x-fit-title-center.json +0 -31
- package/dist/spec/catalogs/layouts/image-only-2x-crop-title-center.json +0 -37
- package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical-title-left.json +0 -38
- package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical.json +0 -33
- package/dist/spec/catalogs/layouts/image-only-2x-fit-title-center.json +0 -37
- package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical-title-left.json +0 -38
- package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical.json +0 -33
- package/dist/spec/catalogs/layouts/image-only-3x-crop-title-center.json +0 -40
- package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical-title-left.json +0 -41
- package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical.json +0 -36
- package/dist/spec/catalogs/layouts/image-only-3x-crop.json +0 -35
- package/dist/spec/catalogs/layouts/image-only-3x-fit-title-center.json +0 -40
- package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical-title-left.json +0 -41
- package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical.json +0 -36
- package/dist/spec/catalogs/layouts/image-only-3x-fit.json +0 -35
- package/dist/spec/catalogs/layouts/index.json +0 -1399
- package/dist/spec/catalogs/layouts/key-takeaway.json +0 -25
- package/dist/spec/catalogs/layouts/kpi-scorecard.json +0 -83
- package/dist/spec/catalogs/layouts/list-1x-box-title-center.json +0 -32
- package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-center.json +0 -33
- package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-left.json +0 -33
- package/dist/spec/catalogs/layouts/list-1x-box-vertical.json +0 -28
- package/dist/spec/catalogs/layouts/list-1x-box.json +0 -27
- package/dist/spec/catalogs/layouts/list-1x-itemimage-title-center.json +0 -32
- package/dist/spec/catalogs/layouts/list-1x-itemimage-vertical-title-center.json +0 -33
- package/dist/spec/catalogs/layouts/list-1x-title-center.json +0 -31
- package/dist/spec/catalogs/layouts/list-1x-vertical-title-center.json +0 -32
- package/dist/spec/catalogs/layouts/list-1x.json +0 -29
- package/dist/spec/catalogs/layouts/list-2x-box-title-center.json +0 -38
- package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-center.json +0 -39
- package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-left.json +0 -39
- package/dist/spec/catalogs/layouts/list-2x-box-vertical.json +0 -34
- package/dist/spec/catalogs/layouts/list-2x-box.json +0 -33
- package/dist/spec/catalogs/layouts/list-2x-itemimage-title-center.json +0 -38
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-center.json +0 -39
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-left.json +0 -39
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical.json +0 -34
- package/dist/spec/catalogs/layouts/list-2x-title-center.json +0 -37
- package/dist/spec/catalogs/layouts/list-2x-vertical-title-center.json +0 -38
- package/dist/spec/catalogs/layouts/list-2x-vertical-title-left.json +0 -38
- package/dist/spec/catalogs/layouts/list-2x-vertical.json +0 -33
- package/dist/spec/catalogs/layouts/list-2x.json +0 -35
- package/dist/spec/catalogs/layouts/list-3x-box-title-center.json +0 -41
- package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-center.json +0 -42
- package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-left.json +0 -42
- package/dist/spec/catalogs/layouts/list-3x-box-vertical.json +0 -37
- package/dist/spec/catalogs/layouts/list-3x-box.json +0 -36
- package/dist/spec/catalogs/layouts/list-3x-itemimage-title-center.json +0 -41
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-center.json +0 -42
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-left.json +0 -42
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical.json +0 -37
- package/dist/spec/catalogs/layouts/list-3x-itemimage.json +0 -36
- package/dist/spec/catalogs/layouts/list-3x-title-center.json +0 -40
- package/dist/spec/catalogs/layouts/list-3x-vertical-title-center.json +0 -41
- package/dist/spec/catalogs/layouts/list-3x-vertical-title-left.json +0 -41
- package/dist/spec/catalogs/layouts/list-3x-vertical.json +0 -36
- package/dist/spec/catalogs/layouts/list-3x.json +0 -38
- package/dist/spec/catalogs/layouts/list-4x-box-title-center.json +0 -45
- package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-center.json +0 -45
- package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-left.json +0 -45
- package/dist/spec/catalogs/layouts/list-4x-box-vertical.json +0 -40
- package/dist/spec/catalogs/layouts/list-4x-box.json +0 -40
- package/dist/spec/catalogs/layouts/list-4x-itemimage-title-center.json +0 -45
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-center.json +0 -45
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-left.json +0 -45
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical.json +0 -40
- package/dist/spec/catalogs/layouts/list-4x-title-center.json +0 -44
- package/dist/spec/catalogs/layouts/list-4x-vertical-title-center.json +0 -44
- package/dist/spec/catalogs/layouts/list-4x-vertical-title-left.json +0 -44
- package/dist/spec/catalogs/layouts/list-4x-vertical.json +0 -39
- package/dist/spec/catalogs/layouts/list-4x.json +0 -42
- package/dist/spec/catalogs/layouts/list-5x-box-title-center.json +0 -48
- package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-center.json +0 -50
- package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-left.json +0 -50
- package/dist/spec/catalogs/layouts/list-5x-box-vertical.json +0 -45
- package/dist/spec/catalogs/layouts/list-5x-box.json +0 -43
- package/dist/spec/catalogs/layouts/list-5x-itemimage-title-center.json +0 -48
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-center.json +0 -48
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-left.json +0 -48
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical.json +0 -43
- package/dist/spec/catalogs/layouts/list-5x-title-center.json +0 -47
- package/dist/spec/catalogs/layouts/list-5x-vertical-title-center.json +0 -47
- package/dist/spec/catalogs/layouts/list-5x-vertical-title-left.json +0 -47
- package/dist/spec/catalogs/layouts/list-5x-vertical.json +0 -42
- package/dist/spec/catalogs/layouts/list-5x.json +0 -45
- package/dist/spec/catalogs/layouts/list-6x-box-title-center.json +0 -51
- package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-center.json +0 -53
- package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-left.json +0 -53
- package/dist/spec/catalogs/layouts/list-6x-box-vertical.json +0 -48
- package/dist/spec/catalogs/layouts/list-6x-box.json +0 -46
- package/dist/spec/catalogs/layouts/list-6x-itemimage-title-center.json +0 -51
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-center.json +0 -51
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-left.json +0 -51
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical.json +0 -46
- package/dist/spec/catalogs/layouts/list-6x-title-center.json +0 -50
- package/dist/spec/catalogs/layouts/list-6x-vertical-title-center.json +0 -50
- package/dist/spec/catalogs/layouts/list-6x-vertical-title-left.json +0 -50
- package/dist/spec/catalogs/layouts/list-6x-vertical.json +0 -45
- package/dist/spec/catalogs/layouts/list-6x.json +0 -48
- package/dist/spec/catalogs/layouts/logic-tree.json +0 -98
- package/dist/spec/catalogs/layouts/market-size.json +0 -53
- package/dist/spec/catalogs/layouts/matrix-quadrant.json +0 -42
- package/dist/spec/catalogs/layouts/media-1x.json +0 -29
- package/dist/spec/catalogs/layouts/network-dependency-map.json +0 -30
- package/dist/spec/catalogs/layouts/number-1x-box-title-center.json +0 -30
- package/dist/spec/catalogs/layouts/number-1x-box.json +0 -25
- package/dist/spec/catalogs/layouts/number-1x-title-center.json +0 -29
- package/dist/spec/catalogs/layouts/number-1x.json +0 -28
- package/dist/spec/catalogs/layouts/number-2x-box-title-center.json +0 -36
- package/dist/spec/catalogs/layouts/number-2x-box.json +0 -31
- package/dist/spec/catalogs/layouts/number-2x-title-center.json +0 -35
- package/dist/spec/catalogs/layouts/number-2x.json +0 -34
- package/dist/spec/catalogs/layouts/number-3x-box-title-center.json +0 -39
- package/dist/spec/catalogs/layouts/number-3x-box.json +0 -34
- package/dist/spec/catalogs/layouts/number-3x-title-center.json +0 -38
- package/dist/spec/catalogs/layouts/number-3x.json +0 -37
- package/dist/spec/catalogs/layouts/number-4x-box-title-center.json +0 -43
- package/dist/spec/catalogs/layouts/number-4x-box.json +0 -38
- package/dist/spec/catalogs/layouts/number-4x-title-center.json +0 -42
- package/dist/spec/catalogs/layouts/number-4x.json +0 -41
- package/dist/spec/catalogs/layouts/number-5x-box-title-center.json +0 -46
- package/dist/spec/catalogs/layouts/number-5x-box.json +0 -41
- package/dist/spec/catalogs/layouts/number-5x-title-center.json +0 -45
- package/dist/spec/catalogs/layouts/number-5x.json +0 -44
- package/dist/spec/catalogs/layouts/number-6x-box-title-center.json +0 -49
- package/dist/spec/catalogs/layouts/number-6x-box.json +0 -44
- package/dist/spec/catalogs/layouts/number-6x-title-center.json +0 -48
- package/dist/spec/catalogs/layouts/number-6x.json +0 -47
- package/dist/spec/catalogs/layouts/one-column-explainer.json +0 -29
- package/dist/spec/catalogs/layouts/org-chart.json +0 -86
- package/dist/spec/catalogs/layouts/persona-grid.json +0 -30
- package/dist/spec/catalogs/layouts/photo-grid.json +0 -43
- package/dist/spec/catalogs/layouts/pricing-table.json +0 -29
- package/dist/spec/catalogs/layouts/process-flow.json +0 -29
- package/dist/spec/catalogs/layouts/product-feature.json +0 -30
- package/dist/spec/catalogs/layouts/pros-cons.json +0 -35
- package/dist/spec/catalogs/layouts/qa-discussion.json +0 -30
- package/dist/spec/catalogs/layouts/quote-1x.json +0 -23
- package/dist/spec/catalogs/layouts/quote-highlight.json +0 -29
- package/dist/spec/catalogs/layouts/raci-matrix.json +0 -29
- package/dist/spec/catalogs/layouts/risk-heatmap.json +0 -29
- package/dist/spec/catalogs/layouts/roadmap.json +0 -29
- package/dist/spec/catalogs/layouts/screenshot-walkthrough.json +0 -30
- package/dist/spec/catalogs/layouts/section-divider.json +0 -28
- package/dist/spec/catalogs/layouts/single-message-statement.json +0 -25
- package/dist/spec/catalogs/layouts/stats-metrics.json +0 -39
- package/dist/spec/catalogs/layouts/status-rag.json +0 -29
- package/dist/spec/catalogs/layouts/swimlane-process.json +0 -30
- package/dist/spec/catalogs/layouts/swot-analysis.json +0 -42
- package/dist/spec/catalogs/layouts/table-1x.json +0 -29
- package/dist/spec/catalogs/layouts/team-bio.json +0 -30
- package/dist/spec/catalogs/layouts/testimonial-grid.json +0 -38
- package/dist/spec/catalogs/layouts/text-1x-box-title-center.json +0 -31
- package/dist/spec/catalogs/layouts/text-1x-box-title-left.json +0 -31
- package/dist/spec/catalogs/layouts/text-1x-center-box-title-center.json +0 -31
- package/dist/spec/catalogs/layouts/text-1x-center-box-title-left.json +0 -31
- package/dist/spec/catalogs/layouts/text-1x-center-box.json +0 -26
- package/dist/spec/catalogs/layouts/text-1x-center-title-center.json +0 -30
- package/dist/spec/catalogs/layouts/text-1x-center-title-left.json +0 -30
- package/dist/spec/catalogs/layouts/text-1x-center.json +0 -25
- package/dist/spec/catalogs/layouts/text-1x-left-box.json +0 -26
- package/dist/spec/catalogs/layouts/text-1x-title-center.json +0 -30
- package/dist/spec/catalogs/layouts/text-1x.json +0 -23
- package/dist/spec/catalogs/layouts/text-2x-box-title-center.json +0 -37
- package/dist/spec/catalogs/layouts/text-2x-box-vertical-title-left.json +0 -37
- package/dist/spec/catalogs/layouts/text-2x-center-box-title-center.json +0 -37
- package/dist/spec/catalogs/layouts/text-2x-center-box-vertical-title-left.json +0 -37
- package/dist/spec/catalogs/layouts/text-2x-center-box.json +0 -32
- package/dist/spec/catalogs/layouts/text-2x-center-title-center.json +0 -36
- package/dist/spec/catalogs/layouts/text-2x-center-vertical-title-left.json +0 -36
- package/dist/spec/catalogs/layouts/text-2x-center.json +0 -31
- package/dist/spec/catalogs/layouts/text-2x-left-box.json +0 -32
- package/dist/spec/catalogs/layouts/text-2x-title-center.json +0 -36
- package/dist/spec/catalogs/layouts/text-2x-vertical-title-left.json +0 -36
- package/dist/spec/catalogs/layouts/text-2x.json +0 -29
- package/dist/spec/catalogs/layouts/text-3x-box-title-center.json +0 -40
- package/dist/spec/catalogs/layouts/text-3x-box-vertical-title-left.json +0 -41
- package/dist/spec/catalogs/layouts/text-3x-center-box-title-center.json +0 -40
- package/dist/spec/catalogs/layouts/text-3x-center-box-vertical-title-left.json +0 -41
- package/dist/spec/catalogs/layouts/text-3x-center-box.json +0 -35
- package/dist/spec/catalogs/layouts/text-3x-center-title-center.json +0 -39
- package/dist/spec/catalogs/layouts/text-3x-center-vertical-title-left.json +0 -40
- package/dist/spec/catalogs/layouts/text-3x-center.json +0 -34
- package/dist/spec/catalogs/layouts/text-3x-left-box.json +0 -35
- package/dist/spec/catalogs/layouts/text-3x-left.json +0 -34
- package/dist/spec/catalogs/layouts/text-3x-title-center.json +0 -39
- package/dist/spec/catalogs/layouts/text-3x-vertical-title-left.json +0 -40
- package/dist/spec/catalogs/layouts/text-3x.json +0 -32
- package/dist/spec/catalogs/layouts/thank-you-cta.json +0 -28
- package/dist/spec/catalogs/layouts/three-column.json +0 -39
- package/dist/spec/catalogs/layouts/timeline-1x.json +0 -23
- package/dist/spec/catalogs/layouts/timeline.json +0 -32
- package/dist/spec/catalogs/layouts/title-center-box.json +0 -27
- package/dist/spec/catalogs/layouts/title-center-image-bottom.json +0 -34
- package/dist/spec/catalogs/layouts/title-center-image-top.json +0 -34
- package/dist/spec/catalogs/layouts/title-center.json +0 -26
- package/dist/spec/catalogs/layouts/title-left-image-bottom.json +0 -34
- package/dist/spec/catalogs/layouts/title-left-image-left.json +0 -34
- package/dist/spec/catalogs/layouts/title-left-image-right.json +0 -34
- package/dist/spec/catalogs/layouts/title-left-image-top.json +0 -34
- package/dist/spec/catalogs/layouts/title-slide.json +0 -28
- package/dist/spec/catalogs/layouts/title-subtitle.json +0 -23
- package/dist/spec/catalogs/layouts/title.json +0 -20
- package/dist/spec/catalogs/layouts/two-column.json +0 -36
- package/dist/spec/catalogs/layouts/venn-overlap.json +0 -29
- package/dist/spec/catalogs/layouts/waterfall-bridge.json +0 -39
- package/dist/spec/catalogs/layouts/wheel-radial.json +0 -29
- package/dist/spec/catalogs/manifest.json +0 -111
- package/dist/spec/catalogs/narratives/board-meeting.json +0 -192
- package/dist/spec/catalogs/narratives/business-narrative.json +0 -87
- package/dist/spec/catalogs/narratives/business-review.json +0 -119
- package/dist/spec/catalogs/narratives/capacity-planning.json +0 -88
- package/dist/spec/catalogs/narratives/challenge-resolution.json +0 -80
- package/dist/spec/catalogs/narratives/change-story.json +0 -64
- package/dist/spec/catalogs/narratives/classic-story.json +0 -78
- package/dist/spec/catalogs/narratives/company-intro.json +0 -96
- package/dist/spec/catalogs/narratives/conference-talk.json +0 -54
- package/dist/spec/catalogs/narratives/data-story.json +0 -65
- package/dist/spec/catalogs/narratives/early-startup-pitch.json +0 -119
- package/dist/spec/catalogs/narratives/educate.json +0 -95
- package/dist/spec/catalogs/narratives/employee-review.json +0 -87
- package/dist/spec/catalogs/narratives/failure-analysis.json +0 -104
- package/dist/spec/catalogs/narratives/focus.json +0 -120
- package/dist/spec/catalogs/narratives/golden-circle.json +0 -50
- package/dist/spec/catalogs/narratives/heros-journey.json +0 -64
- package/dist/spec/catalogs/narratives/index.json +0 -1041
- package/dist/spec/catalogs/narratives/innovation.json +0 -96
- package/dist/spec/catalogs/narratives/justice.json +0 -112
- package/dist/spec/catalogs/narratives/marketing-strategy.json +0 -111
- package/dist/spec/catalogs/narratives/performance-improvement-plan.json +0 -87
- package/dist/spec/catalogs/narratives/performance-review.json +0 -111
- package/dist/spec/catalogs/narratives/persuade.json +0 -94
- package/dist/spec/catalogs/narratives/persuasive-sales.json +0 -87
- package/dist/spec/catalogs/narratives/pitch-deck.json +0 -107
- package/dist/spec/catalogs/narratives/problem-solution.json +0 -61
- package/dist/spec/catalogs/narratives/product-launch.json +0 -104
- package/dist/spec/catalogs/narratives/project-proposal.json +0 -104
- package/dist/spec/catalogs/narratives/pyramid-principle.json +0 -48
- package/dist/spec/catalogs/narratives/qbr.json +0 -85
- package/dist/spec/catalogs/narratives/rags-to-riches.json +0 -80
- package/dist/spec/catalogs/narratives/reveal.json +0 -87
- package/dist/spec/catalogs/narratives/scqa.json +0 -55
- package/dist/spec/catalogs/narratives/situation-complication-resolution.json +0 -56
- package/dist/spec/catalogs/narratives/sparkline.json +0 -56
- package/dist/spec/catalogs/narratives/star-method.json +0 -56
- package/dist/spec/catalogs/narratives/status-update.json +0 -72
- package/dist/spec/catalogs/narratives/strategic-advisory.json +0 -85
- package/dist/spec/catalogs/narratives/strategic-narrative.json +0 -61
- package/dist/spec/catalogs/narratives/survey-analysis.json +0 -104
- package/dist/spec/catalogs/narratives/survival-story.json +0 -103
- package/dist/spec/catalogs/narratives/transformation-arc.json +0 -50
- package/dist/spec/catalogs/narratives/trend-analysis.json +0 -79
- package/dist/spec/catalogs/narratives/underdog-victory.json +0 -87
- package/dist/spec/catalogs/narratives/venture-pitch.json +0 -109
- package/dist/spec/catalogs/narratives/vision-roadmap.json +0 -65
- package/dist/spec/catalogs/narratives/weekly-progress.json +0 -103
- package/dist/spec/catalogs/narratives/what-so-what-now-what.json +0 -48
- package/dist/spec/catalogs/purposes/align.json +0 -16
- package/dist/spec/catalogs/purposes/decide.json +0 -16
- package/dist/spec/catalogs/purposes/educate.json +0 -16
- package/dist/spec/catalogs/purposes/index.json +0 -63
- package/dist/spec/catalogs/purposes/inform.json +0 -16
- package/dist/spec/catalogs/purposes/persuade.json +0 -16
- package/dist/spec/catalogs/purposes/pitch.json +0 -16
- package/dist/spec/catalogs/purposes/plan.json +0 -16
- package/dist/spec/catalogs/purposes/report.json +0 -16
- package/dist/spec/catalogs/purposes/sell.json +0 -16
- package/dist/spec/catalogs/social-platforms/bluesky.json +0 -14
- package/dist/spec/catalogs/social-platforms/facebook.json +0 -14
- package/dist/spec/catalogs/social-platforms/github.json +0 -15
- package/dist/spec/catalogs/social-platforms/index.json +0 -69
- package/dist/spec/catalogs/social-platforms/instagram.json +0 -13
- package/dist/spec/catalogs/social-platforms/linkedin.json +0 -15
- package/dist/spec/catalogs/social-platforms/mastodon.json +0 -14
- package/dist/spec/catalogs/social-platforms/threads.json +0 -13
- package/dist/spec/catalogs/social-platforms/tiktok.json +0 -14
- package/dist/spec/catalogs/social-platforms/x.json +0 -14
- package/dist/spec/catalogs/social-platforms/youtube.json +0 -14
- package/dist/spec/catalogs/themes/bold.json +0 -13
- package/dist/spec/catalogs/themes/classic.json +0 -13
- package/dist/spec/catalogs/themes/dark.json +0 -13
- package/dist/spec/catalogs/themes/index.json +0 -33
- package/dist/spec/catalogs/themes/minimal.json +0 -13
- package/dist/spec/catalogs/tones/authoritative.json +0 -31
- package/dist/spec/catalogs/tones/casual.json +0 -31
- package/dist/spec/catalogs/tones/conversational.json +0 -31
- package/dist/spec/catalogs/tones/formal.json +0 -31
- package/dist/spec/catalogs/tones/index.json +0 -51
- package/dist/spec/catalogs/tones/inspirational.json +0 -31
- package/dist/spec/catalogs/tones/persuasive.json +0 -32
- package/dist/spec/catalogs/tones/technical.json +0 -31
- package/dist/spec/previews/layouts/action-plan.html +0 -1
- package/dist/spec/previews/layouts/agenda.html +0 -1
- package/dist/spec/previews/layouts/appendix-index.html +0 -1
- package/dist/spec/previews/layouts/architecture-stack.html +0 -1
- package/dist/spec/previews/layouts/assumptions-dependencies.html +0 -1
- package/dist/spec/previews/layouts/before-after.html +0 -1
- package/dist/spec/previews/layouts/benchmark-target-table.html +0 -1
- package/dist/spec/previews/layouts/bullet-list.html +0 -1
- package/dist/spec/previews/layouts/business-model-canvas.html +0 -1
- package/dist/spec/previews/layouts/capability-map.html +0 -1
- package/dist/spec/previews/layouts/case-study.html +0 -1
- package/dist/spec/previews/layouts/chapter-recap.html +0 -1
- package/dist/spec/previews/layouts/circular-lifecycle.html +0 -1
- package/dist/spec/previews/layouts/comparison.html +0 -1
- package/dist/spec/previews/layouts/competitive-landscape.html +0 -1
- package/dist/spec/previews/layouts/customer-journey.html +0 -1
- package/dist/spec/previews/layouts/customer-logos.html +0 -1
- package/dist/spec/previews/layouts/dashboard.html +0 -1
- package/dist/spec/previews/layouts/data-visualization.html +0 -1
- package/dist/spec/previews/layouts/decision-tree.html +0 -1
- package/dist/spec/previews/layouts/detailed-data-table.html +0 -1
- package/dist/spec/previews/layouts/ecosystem-map.html +0 -1
- package/dist/spec/previews/layouts/executive-decision.html +0 -1
- package/dist/spec/previews/layouts/executive-summary.html +0 -1
- package/dist/spec/previews/layouts/faq.html +0 -1
- package/dist/spec/previews/layouts/feature-comparison-matrix.html +0 -1
- package/dist/spec/previews/layouts/forecast-scenario.html +0 -1
- package/dist/spec/previews/layouts/funnel-pyramid.html +0 -1
- package/dist/spec/previews/layouts/gantt-project-plan.html +0 -1
- package/dist/spec/previews/layouts/geographic-map.html +0 -1
- package/dist/spec/previews/layouts/heatmap-cohort.html +0 -1
- package/dist/spec/previews/layouts/hub-and-spoke.html +0 -1
- package/dist/spec/previews/layouts/icon-grid.html +0 -1
- package/dist/spec/previews/layouts/image-focus.html +0 -1
- package/dist/spec/previews/layouts/index.json +0 -357
- package/dist/spec/previews/layouts/key-takeaway.html +0 -1
- package/dist/spec/previews/layouts/kpi-scorecard.html +0 -1
- package/dist/spec/previews/layouts/logic-tree.html +0 -1
- package/dist/spec/previews/layouts/market-size.html +0 -1
- package/dist/spec/previews/layouts/matrix-quadrant.html +0 -1
- package/dist/spec/previews/layouts/network-dependency-map.html +0 -1
- package/dist/spec/previews/layouts/one-column-explainer.html +0 -1
- package/dist/spec/previews/layouts/org-chart.html +0 -1
- package/dist/spec/previews/layouts/persona-grid.html +0 -1
- package/dist/spec/previews/layouts/photo-grid.html +0 -1
- package/dist/spec/previews/layouts/pricing-table.html +0 -1
- package/dist/spec/previews/layouts/process-flow.html +0 -1
- package/dist/spec/previews/layouts/product-feature.html +0 -1
- package/dist/spec/previews/layouts/pros-cons.html +0 -1
- package/dist/spec/previews/layouts/qa-discussion.html +0 -1
- package/dist/spec/previews/layouts/quote-highlight.html +0 -1
- package/dist/spec/previews/layouts/raci-matrix.html +0 -1
- package/dist/spec/previews/layouts/risk-heatmap.html +0 -1
- package/dist/spec/previews/layouts/roadmap.html +0 -1
- package/dist/spec/previews/layouts/screenshot-walkthrough.html +0 -1
- package/dist/spec/previews/layouts/section-divider.html +0 -1
- package/dist/spec/previews/layouts/single-message-statement.html +0 -1
- package/dist/spec/previews/layouts/stats-metrics.html +0 -1
- package/dist/spec/previews/layouts/status-rag.html +0 -1
- package/dist/spec/previews/layouts/swimlane-process.html +0 -1
- package/dist/spec/previews/layouts/swot-analysis.html +0 -1
- package/dist/spec/previews/layouts/team-bio.html +0 -1
- package/dist/spec/previews/layouts/testimonial-grid.html +0 -1
- package/dist/spec/previews/layouts/thank-you-cta.html +0 -1
- package/dist/spec/previews/layouts/three-column.html +0 -1
- package/dist/spec/previews/layouts/timeline.html +0 -1
- package/dist/spec/previews/layouts/title-slide.html +0 -1
- package/dist/spec/previews/layouts/two-column.html +0 -1
- package/dist/spec/previews/layouts/venn-overlap.html +0 -1
- package/dist/spec/previews/layouts/waterfall-bridge.html +0 -1
- package/dist/spec/previews/layouts/wheel-radial.html +0 -1
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { checkCatalogsOption, resolveReference, unresolvedReference, provenanceOf } from './chunk-SPFV27O5.js';
|
|
2
|
-
|
|
3
1
|
// src/table.ts
|
|
4
2
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
5
3
|
function tableGrid(value, path = "table") {
|
|
@@ -1187,10 +1185,10 @@ function slideSectionDiagnostics(presentation, uses) {
|
|
|
1187
1185
|
const out = [];
|
|
1188
1186
|
presentation.slides.forEach((slide, index) => {
|
|
1189
1187
|
if (!isRecord(slide) || typeof slide.section === "string" && slide.section !== "") return;
|
|
1190
|
-
const
|
|
1188
|
+
const own3 = `/slides/${index}/`;
|
|
1191
1189
|
const design = isRecord(slide.design) ? slide.design : {};
|
|
1192
1190
|
const inherited = ["header", "footer"].filter((kind2) => design[kind2] === void 0).map((kind2) => `/design/${kind2}/`);
|
|
1193
|
-
const where = paths.find((path) => path.startsWith(
|
|
1191
|
+
const where = paths.find((path) => path.startsWith(own3) || inherited.some((prefix) => path.startsWith(prefix)));
|
|
1194
1192
|
if (where === void 0) return;
|
|
1195
1193
|
out.push({ code: "variable-builtin-missing", severity: "warning", path: `/slides/${index}`, id: "slide.section", message: `Slide ${index + 1} has no section, so '{{slide.section}}' (used at ${where}) resolves to nothing on it; give the slide a section or remove the token.` });
|
|
1196
1194
|
});
|
|
@@ -1989,7 +1987,8 @@ function intrinsicImageAspect(value, assets) {
|
|
|
1989
1987
|
}
|
|
1990
1988
|
|
|
1991
1989
|
// src/design-hints.ts
|
|
1992
|
-
var DESIGN_HINT_KEYS = ["titleAlignment", "contentAlignment", "contentBox", "contentDirection", "chartPrimary", "imageFit", "listBullet"];
|
|
1990
|
+
var DESIGN_HINT_KEYS = ["titleAlignment", "contentAlignment", "contentBox", "contentDirection", "chartPrimary", "imageFit", "listBullet", "mirror"];
|
|
1991
|
+
var THEME_DESIGN_KEYS = ["titleAlignment", "contentAlignment", "contentBox", "contentDirection", "imageFit", "listBullet"];
|
|
1993
1992
|
var ALIGNMENTS = ["left", "center", "right"];
|
|
1994
1993
|
var VALUES = {
|
|
1995
1994
|
titleAlignment: ALIGNMENTS,
|
|
@@ -1998,12 +1997,14 @@ var VALUES = {
|
|
|
1998
1997
|
contentDirection: ["horizontal", "vertical"],
|
|
1999
1998
|
chartPrimary: ["none", "top", "bottom", "left", "right"],
|
|
2000
1999
|
imageFit: ["cover", "contain", "stretch"],
|
|
2001
|
-
listBullet: ["character", "image"]
|
|
2000
|
+
listBullet: ["character", "image"],
|
|
2001
|
+
mirror: "boolean"
|
|
2002
2002
|
};
|
|
2003
|
+
var themeKeys = new Set(THEME_DESIGN_KEYS);
|
|
2003
2004
|
var accepts = (key, value) => VALUES[key] === "boolean" ? typeof value === "boolean" : VALUES[key].includes(value);
|
|
2004
2005
|
var object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2005
2006
|
function resolveDesignHints(options = {}) {
|
|
2006
|
-
const slide = object(object(options.slide).design), host = object(options.deck), deck = object(object(options.presentation).design), layout = object(object(options.layout).design);
|
|
2007
|
+
const slide = object(object(options.slide).design), host = object(options.deck), deck = object(object(options.presentation).design), theme = object(object(options.theme).design), layout = object(object(options.layout).design);
|
|
2007
2008
|
const index = options.slideIndex ?? 0;
|
|
2008
2009
|
const result = { sources: {}, paths: {} };
|
|
2009
2010
|
const set2 = (key, value, source, path) => {
|
|
@@ -2015,6 +2016,7 @@ function resolveDesignHints(options = {}) {
|
|
|
2015
2016
|
if (accepts(key, slide[key])) set2(key, slide[key], "slide", `slides.${index}.design.${key}`);
|
|
2016
2017
|
else if (accepts(key, host[key])) set2(key, host[key], "deck", `design.${key}`);
|
|
2017
2018
|
else if (accepts(key, deck[key])) set2(key, deck[key], "deck", `design.${key}`);
|
|
2019
|
+
else if (themeKeys.has(key) && accepts(key, theme[key])) set2(key, theme[key], "theme", slide.theme !== void 0 ? `slides.${index}.design.theme` : "design.theme");
|
|
2018
2020
|
else if (accepts(key, layout[key])) set2(key, layout[key], "layout", `slides.${index}.layout`);
|
|
2019
2021
|
}
|
|
2020
2022
|
return result;
|
|
@@ -2043,73 +2045,441 @@ function readingRows(items) {
|
|
|
2043
2045
|
return rows3.map((row) => row.items.sort((a, b) => index.get(a) - index.get(b)));
|
|
2044
2046
|
}
|
|
2045
2047
|
|
|
2046
|
-
// src/layout-
|
|
2047
|
-
var
|
|
2048
|
-
var
|
|
2049
|
-
var
|
|
2048
|
+
// src/layout-template.ts
|
|
2049
|
+
var REGION_KINDS = ["text", "list", "image", "video", "chart", "table", "code", "metric", "quote", "timeline", "group"];
|
|
2050
|
+
var REGION_ROLES = ["primary", "secondary", "media", "supporting"];
|
|
2051
|
+
var REGION_FLOWS = ["none", "grid", "column", "auto"];
|
|
2052
|
+
var REGION_ANCHORS = ["top", "middle", "bottom"];
|
|
2053
|
+
var HEADING_AREAS = ["title", "subtitle"];
|
|
2054
|
+
var RESERVED_REGION_NAMES = ["title", "subtitle", "tag", "auto", "left", "center", "right", "top", "middle", "bottom"];
|
|
2055
|
+
var MAX_TEMPLATE_TRACKS = 12;
|
|
2056
|
+
var MAX_REGION_BLOCKS = 12;
|
|
2057
|
+
var AUTO_LAYOUT = "auto";
|
|
2058
|
+
var OPFLayoutTemplateError = class extends RangeError {
|
|
2059
|
+
constructor(issues) {
|
|
2060
|
+
super(`The layout template is invalid: ${issues.map((issue) => `${issue.path || "/"}: ${issue.message}`).join("; ")}`);
|
|
2061
|
+
this.issues = issues;
|
|
2062
|
+
this.name = "OPFLayoutTemplateError";
|
|
2063
|
+
}
|
|
2064
|
+
issues;
|
|
2065
|
+
code = "layout-template";
|
|
2066
|
+
};
|
|
2067
|
+
var NAME = /^[a-z][a-z0-9-]*$/;
|
|
2050
2068
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2069
|
+
var pointerSegment = (segment2) => segment2.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
2070
|
+
var reserved = new Set(RESERVED_REGION_NAMES);
|
|
2071
|
+
var headingNames = new Set(HEADING_AREAS);
|
|
2072
|
+
var positive = (value) => typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
2073
|
+
function isLayoutTemplate(layout) {
|
|
2074
|
+
return Object.hasOwn(record4(layout), "areas");
|
|
2075
|
+
}
|
|
2076
|
+
function layoutRegion(name, value) {
|
|
2077
|
+
const entry = record4(value);
|
|
2078
|
+
const accepts2 = Array.isArray(entry.accepts) ? [...new Set(entry.accepts.filter((kind2) => REGION_KINDS.includes(kind2)))] : [];
|
|
2079
|
+
const flow = REGION_FLOWS.includes(entry.flow) ? entry.flow : "auto";
|
|
2080
|
+
const max = Number.isInteger(entry.max) && entry.max >= 1 && entry.max <= MAX_REGION_BLOCKS ? entry.max : flow === "none" ? 1 : 6;
|
|
2081
|
+
return {
|
|
2082
|
+
name,
|
|
2083
|
+
accepts: accepts2,
|
|
2084
|
+
role: REGION_ROLES.includes(entry.role) ? entry.role : "primary",
|
|
2085
|
+
flow,
|
|
2086
|
+
max,
|
|
2087
|
+
bleed: entry.bleed === true,
|
|
2088
|
+
listColumns: entry.listColumns === "auto" ? "auto" : 1,
|
|
2089
|
+
anchor: REGION_ANCHORS.includes(entry.anchor) ? entry.anchor : "top",
|
|
2090
|
+
empty: entry.empty === "keep" ? "keep" : "collapse"
|
|
2091
|
+
};
|
|
2067
2092
|
}
|
|
2068
|
-
function
|
|
2069
|
-
const
|
|
2070
|
-
const
|
|
2071
|
-
|
|
2093
|
+
function parse(layout) {
|
|
2094
|
+
const value = record4(layout);
|
|
2095
|
+
const issues = [];
|
|
2096
|
+
const grid = (code, path, message) => issues.push({ code, path, message });
|
|
2097
|
+
const areas = value.areas;
|
|
2098
|
+
if (!Array.isArray(areas) || !areas.length) {
|
|
2099
|
+
grid("layout-template", "/areas", "a template needs 1 to 12 rows of area names");
|
|
2100
|
+
return { issues };
|
|
2101
|
+
}
|
|
2102
|
+
if (areas.length > MAX_TEMPLATE_TRACKS) grid("layout-template", "/areas", `a template has at most ${MAX_TEMPLATE_TRACKS} rows; this one has ${areas.length}`);
|
|
2103
|
+
const cells = areas.map((row, index) => {
|
|
2104
|
+
if (typeof row !== "string") {
|
|
2105
|
+
grid("layout-template", `/areas/${index}`, "each row is a string of area names");
|
|
2106
|
+
return [];
|
|
2107
|
+
}
|
|
2108
|
+
const words = row.trim().split(/\s+/).filter(Boolean);
|
|
2109
|
+
if (!words.length) grid("layout-template", `/areas/${index}`, 'a row needs at least one area name or "."');
|
|
2110
|
+
for (const word of words) if (word !== "." && !NAME.test(word)) grid("layout-template", `/areas/${index}`, `'${word}' is not an area name (lowercase letters, digits and hyphens, starting with a letter) or "."`);
|
|
2111
|
+
return words;
|
|
2112
|
+
});
|
|
2113
|
+
const width = cells[0]?.length ?? 0;
|
|
2114
|
+
cells.forEach((row, index) => {
|
|
2115
|
+
if (index > 0 && row.length !== width && row.length) grid("layout-template", `/areas/${index}`, `every row has the same number of cells; row ${index + 1} has ${row.length}, row 1 has ${width}`);
|
|
2116
|
+
});
|
|
2117
|
+
if (width > MAX_TEMPLATE_TRACKS) grid("layout-template", "/areas", `a template has at most ${MAX_TEMPLATE_TRACKS} columns; this one has ${width}`);
|
|
2118
|
+
const columns2 = value.columns === void 0 ? Array.from({ length: width }, () => 1) : value.columns;
|
|
2119
|
+
const rows3 = value.rows === void 0 ? Array.from({ length: cells.length }, () => 1) : value.rows;
|
|
2120
|
+
if (!Array.isArray(columns2) || columns2.length !== width || !columns2.every(positive)) grid("layout-template", "/columns", `columns needs one positive number per cell of a row (${width})`);
|
|
2121
|
+
if (!Array.isArray(rows3) || rows3.length !== cells.length || !rows3.every((size) => size === "auto" || positive(size))) grid("layout-template", "/rows", `rows needs one positive number or "auto" per row (${cells.length})`);
|
|
2122
|
+
if (issues.length) return { issues };
|
|
2123
|
+
const bounds = /* @__PURE__ */ new Map();
|
|
2124
|
+
cells.forEach((row, r) => {
|
|
2125
|
+
row.forEach((name, c) => {
|
|
2126
|
+
if (name === ".") return;
|
|
2127
|
+
const found = bounds.get(name);
|
|
2128
|
+
if (!found) bounds.set(name, { top: r, left: c, bottom: r, right: c, count: 1 });
|
|
2129
|
+
else {
|
|
2130
|
+
found.top = Math.min(found.top, r);
|
|
2131
|
+
found.left = Math.min(found.left, c);
|
|
2132
|
+
found.bottom = Math.max(found.bottom, r);
|
|
2133
|
+
found.right = Math.max(found.right, c);
|
|
2134
|
+
found.count++;
|
|
2135
|
+
}
|
|
2136
|
+
});
|
|
2137
|
+
});
|
|
2138
|
+
const list = [];
|
|
2139
|
+
for (const [name, box] of bounds) {
|
|
2140
|
+
const filled = (box.bottom - box.top + 1) * (box.right - box.left + 1);
|
|
2141
|
+
let rectangle = filled === box.count;
|
|
2142
|
+
for (let r = box.top; rectangle && r <= box.bottom; r++) for (let c = box.left; c <= box.right; c++) if (cells[r][c] !== name) {
|
|
2143
|
+
rectangle = false;
|
|
2144
|
+
break;
|
|
2145
|
+
}
|
|
2146
|
+
if (!rectangle) {
|
|
2147
|
+
grid("layout-template", "/areas", `the cells of '${name}' do not form one filled rectangle`);
|
|
2148
|
+
continue;
|
|
2149
|
+
}
|
|
2150
|
+
list.push({ name, row: box.top, column: box.left, rowSpan: box.bottom - box.top + 1, columnSpan: box.right - box.left + 1, heading: headingNames.has(name) });
|
|
2151
|
+
}
|
|
2152
|
+
if (issues.length) return { issues };
|
|
2153
|
+
list.sort((a, b) => a.row - b.row || a.column - b.column);
|
|
2154
|
+
const entries = record4(value.regions);
|
|
2155
|
+
const region = (path, message) => grid("layout-region", path, message);
|
|
2156
|
+
if (value.regions !== void 0 && (value.regions === null || typeof value.regions !== "object" || Array.isArray(value.regions))) region("/regions", "regions is an object keyed by region name");
|
|
2157
|
+
for (const name of Object.keys(entries)) {
|
|
2158
|
+
if (reserved.has(name)) region(`/regions/${pointerSegment(name)}`, `'${name}' is reserved and cannot name a region (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
|
|
2159
|
+
else if (!bounds.has(name)) region(`/regions/${pointerSegment(name)}`, `region '${name}' has no area in areas`);
|
|
2160
|
+
}
|
|
2161
|
+
for (const area of list) {
|
|
2162
|
+
if (area.heading) continue;
|
|
2163
|
+
if (reserved.has(area.name)) {
|
|
2164
|
+
if (!Object.hasOwn(entries, area.name)) region("/areas", `'${area.name}' is reserved and cannot name a body area (reserved: ${RESERVED_REGION_NAMES.join(", ")})`);
|
|
2165
|
+
continue;
|
|
2166
|
+
}
|
|
2167
|
+
if (!Object.hasOwn(entries, area.name)) region("/regions", `body area '${area.name}' has no entry in regions`);
|
|
2168
|
+
}
|
|
2169
|
+
if (bounds.has("subtitle") && !bounds.has("title")) region("/areas", "a 'subtitle' area needs a 'title' area");
|
|
2170
|
+
for (const [name, entry] of Object.entries(entries)) {
|
|
2171
|
+
const raw = record4(entry);
|
|
2172
|
+
if (raw.flow === "none" && raw.max !== void 0 && raw.max !== 1) region(`/regions/${pointerSegment(name)}/max`, `a region with flow "none" holds one block; max must be 1, not ${JSON.stringify(raw.max)}`);
|
|
2173
|
+
}
|
|
2174
|
+
const regions = list.filter((area) => !area.heading && !reserved.has(area.name) && Object.hasOwn(entries, area.name)).map((area) => layoutRegion(area.name, entries[area.name]));
|
|
2175
|
+
for (const entry of regions) if (!entry.accepts.length) region(`/regions/${pointerSegment(entry.name)}/accepts`, `region '${entry.name}' accepts no content kind`);
|
|
2176
|
+
if (value.overflowRegion !== void 0 && !regions.some((entry) => entry.name === value.overflowRegion)) region("/overflowRegion", `overflowRegion ${JSON.stringify(value.overflowRegion)} is not a region of this layout`);
|
|
2177
|
+
if (issues.length) return { issues };
|
|
2178
|
+
const overflowRegion = typeof value.overflowRegion === "string" ? value.overflowRegion : regions.find((entry) => entry.role === "primary" && entry.flow !== "none")?.name;
|
|
2179
|
+
return {
|
|
2180
|
+
issues,
|
|
2181
|
+
template: {
|
|
2182
|
+
rows: rows3.slice(),
|
|
2183
|
+
columns: columns2.slice(),
|
|
2184
|
+
grid: cells,
|
|
2185
|
+
areas: list,
|
|
2186
|
+
regions,
|
|
2187
|
+
...overflowRegion !== void 0 ? { overflowRegion } : {},
|
|
2188
|
+
title: bounds.has("title"),
|
|
2189
|
+
subtitle: bounds.has("subtitle")
|
|
2190
|
+
}
|
|
2072
2191
|
};
|
|
2073
|
-
visit(layoutSlots(layout));
|
|
2074
|
-
return leaves;
|
|
2075
2192
|
}
|
|
2076
|
-
function
|
|
2077
|
-
|
|
2078
|
-
if (!slot.children) return slot.type;
|
|
2079
|
-
const mode = record4(slot.placeholder.composition).mode;
|
|
2080
|
-
return `${typeof mode === "string" && mode !== "auto" ? mode : "group"} (${describe(slot.children)})`;
|
|
2081
|
-
}).join(", ");
|
|
2082
|
-
return describe(layoutSlots(layout));
|
|
2193
|
+
function layoutTemplateIssues(layout) {
|
|
2194
|
+
return isLayoutTemplate(layout) ? parse(layout).issues : [];
|
|
2083
2195
|
}
|
|
2084
|
-
function
|
|
2085
|
-
|
|
2196
|
+
function layoutTemplate(layout) {
|
|
2197
|
+
const parsed = parse(layout);
|
|
2198
|
+
if (!parsed.template) throw new OPFLayoutTemplateError(parsed.issues);
|
|
2199
|
+
return parsed.template;
|
|
2086
2200
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2201
|
+
|
|
2202
|
+
// src/bind-regions.ts
|
|
2203
|
+
var FIELDS = ["text", "items", "bullets", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
|
|
2204
|
+
var FIELD_KINDS = { text: "text", bullets: "text", items: "list", image: "image", video: "video", chart: "chart", table: "table", code: "code", metric: "metric", quote: "quote", timeline: "timeline" };
|
|
2205
|
+
var IMAGE_EDGES = ["left", "right", "top", "bottom"];
|
|
2206
|
+
var PROMOTED_REGION_KEY = /^(top|middle|bottom)(\+(top|middle|bottom))*(:(left|center|right)(\+(left|center|right))*)?$|^(left|center|right)(\+(left|center|right))*$/;
|
|
2207
|
+
var record5 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2208
|
+
var empty = (value) => value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
|
|
2209
|
+
function blockKind(block) {
|
|
2210
|
+
const value = record5(block);
|
|
2211
|
+
if (Array.isArray(value.blocks)) return "group";
|
|
2212
|
+
if (typeof value.type === "string" && value.type !== "group" && Object.values(FIELD_KINDS).includes(value.type)) return value.type;
|
|
2213
|
+
const field = FIELDS.find((name) => value[name] !== void 0);
|
|
2214
|
+
return field ? FIELD_KINDS[field] : "text";
|
|
2215
|
+
}
|
|
2216
|
+
function leafKinds(block, into = /* @__PURE__ */ new Set(), depth = 0) {
|
|
2217
|
+
if (depth > 32) return into;
|
|
2218
|
+
for (const child of Array.isArray(block.blocks) ? block.blocks : []) {
|
|
2219
|
+
const value = record5(child);
|
|
2220
|
+
if (Array.isArray(value.blocks)) leafKinds(value, into, depth + 1);
|
|
2221
|
+
else into.add(blockKind(value));
|
|
2222
|
+
}
|
|
2223
|
+
return into;
|
|
2224
|
+
}
|
|
2225
|
+
function regionAccepts(region, block) {
|
|
2226
|
+
const kind2 = blockKind(block);
|
|
2227
|
+
if (region.accepts.includes(kind2)) return true;
|
|
2228
|
+
if (kind2 !== "group") return false;
|
|
2229
|
+
const kinds = leafKinds(record5(block));
|
|
2230
|
+
return kinds.size > 0 && [...kinds].every((leaf) => region.accepts.includes(leaf));
|
|
2231
|
+
}
|
|
2232
|
+
function placedImageBlocks(slide) {
|
|
2233
|
+
const value = record5(slide);
|
|
2234
|
+
const placed = /* @__PURE__ */ new Set();
|
|
2235
|
+
if (!Array.isArray(value.blocks) || Object.keys(value).some((key) => PROMOTED_REGION_KEY.test(key))) return placed;
|
|
2236
|
+
const used = /* @__PURE__ */ new Set();
|
|
2237
|
+
value.blocks.forEach((block, index) => {
|
|
2238
|
+
const host = record5(block);
|
|
2239
|
+
if (Array.isArray(host.blocks) || host.image === void 0 || host.placement === void 0) return;
|
|
2240
|
+
const edge = record5(host.placement).edge;
|
|
2241
|
+
if (!IMAGE_EDGES.includes(edge) || used.has(edge)) return;
|
|
2242
|
+
used.add(edge);
|
|
2243
|
+
placed.add(index);
|
|
2244
|
+
});
|
|
2245
|
+
return placed;
|
|
2246
|
+
}
|
|
2247
|
+
function rootNodes(slide, slideIndex = 0) {
|
|
2248
|
+
const value = record5(slide), base = `slides.${slideIndex}`;
|
|
2249
|
+
if (Array.isArray(value.blocks)) {
|
|
2250
|
+
const placed = placedImageBlocks(value);
|
|
2251
|
+
return value.blocks.flatMap((block, index) => {
|
|
2252
|
+
const host = record5(block);
|
|
2253
|
+
if (placed.has(index)) return [];
|
|
2254
|
+
if (!Array.isArray(host.blocks) && FIELDS.every((field) => empty(host[field]))) return [];
|
|
2255
|
+
if (Array.isArray(host.blocks) && !host.blocks.length) return [];
|
|
2256
|
+
return [{ path: `${base}.blocks.${index}`, kind: blockKind(host), block: index, value: host }];
|
|
2257
|
+
});
|
|
2258
|
+
}
|
|
2259
|
+
const nodes = [];
|
|
2260
|
+
for (const field of FIELDS) {
|
|
2261
|
+
if (empty(value[field]) || field === "bullets" && !empty(value.text)) continue;
|
|
2262
|
+
const fields2 = field === "text" && !empty(value.bullets) ? ["text", "bullets"] : [field];
|
|
2263
|
+
nodes.push({ path: `${base}.${field}`, kind: FIELD_KINDS[field], fields: fields2, value: Object.fromEntries(fields2.map((name) => [name, value[name]])) });
|
|
2264
|
+
}
|
|
2265
|
+
return nodes;
|
|
2266
|
+
}
|
|
2267
|
+
function regionRoleRank(role, kind2) {
|
|
2268
|
+
const media = kind2 === "image" || kind2 === "video";
|
|
2269
|
+
return media ? { media: 0, primary: 1, secondary: 2, supporting: 3 }[role] : { primary: 0, secondary: 1, supporting: 2, media: 3 }[role];
|
|
2270
|
+
}
|
|
2271
|
+
function bindRegions(slide, layout, options = {}) {
|
|
2272
|
+
const template = layoutTemplate(layout);
|
|
2273
|
+
const value = record5(slide), index = options.slideIndex ?? 0;
|
|
2274
|
+
const regions = template.regions.map((region) => ({ name: region.name, blocks: [], overflow: [] }));
|
|
2275
|
+
const result = { regions, below: [], diagnostics: [] };
|
|
2276
|
+
if (Object.keys(value).some((key) => PROMOTED_REGION_KEY.test(key))) return result;
|
|
2277
|
+
const byName = new Map(template.regions.map((region, order2) => [region.name, { region, binding: regions[order2], order: order2 }]));
|
|
2278
|
+
const room = (name) => {
|
|
2279
|
+
const entry = byName.get(name);
|
|
2280
|
+
return entry.binding.blocks.length < entry.region.max;
|
|
2281
|
+
};
|
|
2282
|
+
const nodes = rootNodes(value, index);
|
|
2283
|
+
const rest = [];
|
|
2284
|
+
for (const node of nodes) {
|
|
2285
|
+
const pin = node.block !== void 0 ? node.value.region : void 0;
|
|
2286
|
+
if (typeof pin !== "string") {
|
|
2287
|
+
rest.push(node);
|
|
2288
|
+
continue;
|
|
2289
|
+
}
|
|
2290
|
+
const target = byName.get(pin), pinPath = `${node.path}.region`;
|
|
2291
|
+
if (!target) result.diagnostics.push({ code: "region-unknown", path: pinPath, region: pin, message: `The layout has no region '${pin}'; the block is placed by its kind instead.` });
|
|
2292
|
+
else if (!regionAccepts(target.region, node.value)) result.diagnostics.push({ code: "region-kind", path: pinPath, region: pin, message: `Region '${pin}' does not accept ${node.kind} content (it accepts ${target.region.accepts.join(", ")}); the block is placed by its kind instead.` });
|
|
2293
|
+
else if (!room(pin)) result.diagnostics.push({ code: "region-full", path: pinPath, region: pin, message: `Region '${pin}' already holds its ${target.region.max} block${target.region.max === 1 ? "" : "s"}; the block is placed by its kind instead.` });
|
|
2294
|
+
else {
|
|
2295
|
+
target.binding.blocks.push({ path: node.path, kind: node.kind, block: node.block, pinned: true });
|
|
2296
|
+
continue;
|
|
2297
|
+
}
|
|
2298
|
+
rest.push(node);
|
|
2299
|
+
}
|
|
2300
|
+
const overflowName = template.overflowRegion;
|
|
2301
|
+
for (const node of rest) {
|
|
2302
|
+
const bound = { path: node.path, kind: node.kind, ...node.block !== void 0 ? { block: node.block } : {}, ...node.fields ? { fields: node.fields } : {} };
|
|
2303
|
+
let best;
|
|
2304
|
+
for (const [name, entry] of byName) {
|
|
2305
|
+
if (!regionAccepts(entry.region, node.value) || !room(name)) continue;
|
|
2306
|
+
const rank = regionRoleRank(entry.region.role, node.kind);
|
|
2307
|
+
if (!best || rank < best.rank || rank === best.rank && entry.order < best.order) best = { rank, order: entry.order, name };
|
|
2308
|
+
}
|
|
2309
|
+
if (best) {
|
|
2310
|
+
byName.get(best.name).binding.blocks.push(bound);
|
|
2311
|
+
continue;
|
|
2312
|
+
}
|
|
2313
|
+
if (overflowName === void 0) {
|
|
2314
|
+
result.below.push(bound);
|
|
2315
|
+
result.diagnostics.push({ code: "layout-unplaced", path: node.path, message: "No region of the layout takes this block; it is drawn below the layout's grid. Choose another layout, pin it to a region, or paginate." });
|
|
2316
|
+
continue;
|
|
2317
|
+
}
|
|
2318
|
+
const overflow = byName.get(overflowName);
|
|
2319
|
+
if (room(overflowName)) {
|
|
2320
|
+
overflow.binding.blocks.push(bound);
|
|
2321
|
+
continue;
|
|
2104
2322
|
}
|
|
2323
|
+
overflow.binding.overflow.push(bound);
|
|
2324
|
+
result.diagnostics.push({ code: "layout-unplaced", path: node.path, region: overflowName, message: `No region of the layout has room for this block; it is drawn in '${overflowName}' beyond its ${overflow.region.max} block${overflow.region.max === 1 ? "" : "s"}. Paginate to move it to a continuation slide, choose another layout, or remove a block.` });
|
|
2325
|
+
}
|
|
2326
|
+
const order = new Map(nodes.map((node, position) => [node.path, position]));
|
|
2327
|
+
for (const binding of regions) binding.blocks.sort((a, b) => order.get(a.path) - order.get(b.path));
|
|
2328
|
+
return result;
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
// src/template-geometry.ts
|
|
2332
|
+
function gridFlowShape(count, landscape) {
|
|
2333
|
+
if (!Number.isInteger(count) || count < 1) return { columns: 1, rows: 0, perRow: [] };
|
|
2334
|
+
let columns2;
|
|
2335
|
+
if (landscape) columns2 = count <= 3 ? count : count === 4 ? 2 : count <= 6 ? 3 : 4;
|
|
2336
|
+
else columns2 = count <= 3 ? 1 : count <= 6 ? 2 : Math.ceil(count / 3);
|
|
2337
|
+
const rows3 = Math.ceil(count / columns2);
|
|
2338
|
+
const perRow = Array.from({ length: rows3 }, (_, row) => Math.min(columns2, count - row * columns2));
|
|
2339
|
+
return { columns: columns2, rows: rows3, perRow };
|
|
2340
|
+
}
|
|
2341
|
+
function flowShape(arrangement, count, landscape) {
|
|
2342
|
+
if (count < 1) return { columns: 1, rows: 0, perRow: [] };
|
|
2343
|
+
if (arrangement === "row") return { columns: count, rows: 1, perRow: [count] };
|
|
2344
|
+
if (arrangement === "column") return { columns: 1, rows: count, perRow: Array.from({ length: count }, () => 1) };
|
|
2345
|
+
return gridFlowShape(count, landscape);
|
|
2346
|
+
}
|
|
2347
|
+
function flowCells(shape, box, requestedGap) {
|
|
2348
|
+
if (!shape.rows) return { cells: [], gap: requestedGap };
|
|
2349
|
+
const gap = Math.max(0, Math.min(requestedGap, box.width / (shape.columns * 2), box.height / (shape.rows * 2)));
|
|
2350
|
+
const width = (box.width - gap * (shape.columns - 1)) / shape.columns;
|
|
2351
|
+
const height = (box.height - gap * (shape.rows - 1)) / shape.rows;
|
|
2352
|
+
const cells = [];
|
|
2353
|
+
shape.perRow.forEach((count, row) => {
|
|
2354
|
+
const used = count * width + (count - 1) * gap, start = box.x + (box.width - used) / 2;
|
|
2355
|
+
for (let column = 0; column < count; column++) cells.push({ x: count === shape.columns ? box.x + column * (width + gap) : start + column * (width + gap), y: box.y + row * (height + gap), width, height });
|
|
2356
|
+
});
|
|
2357
|
+
return { cells, gap };
|
|
2358
|
+
}
|
|
2359
|
+
function columnWidths(sizes, total, gap) {
|
|
2360
|
+
const sum = sizes.reduce((a, b) => a + b, 0);
|
|
2361
|
+
const rest = Math.max(0, total - Math.max(0, sizes.length - 1) * gap);
|
|
2362
|
+
return sizes.map((size) => sum > 0 ? rest * size / sum : 0);
|
|
2363
|
+
}
|
|
2364
|
+
function collapseAreas(grid, empty2, heading, absorbs = () => true) {
|
|
2365
|
+
const owner = grid.map((row) => [...row]);
|
|
2366
|
+
const joined = /* @__PURE__ */ new Map();
|
|
2367
|
+
const rect = (name) => {
|
|
2368
|
+
let top = Infinity, left = Infinity, bottom = -1, right = -1;
|
|
2369
|
+
owner.forEach((row, r) => {
|
|
2370
|
+
row.forEach((cell, c) => {
|
|
2371
|
+
if (cell === name) {
|
|
2372
|
+
top = Math.min(top, r);
|
|
2373
|
+
left = Math.min(left, c);
|
|
2374
|
+
bottom = Math.max(bottom, r);
|
|
2375
|
+
right = Math.max(right, c);
|
|
2376
|
+
}
|
|
2377
|
+
});
|
|
2378
|
+
});
|
|
2379
|
+
return bottom < 0 ? void 0 : { row: top, column: left, rowSpan: bottom - top + 1, columnSpan: right - left + 1 };
|
|
2105
2380
|
};
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2381
|
+
const order = [];
|
|
2382
|
+
for (const row of owner) for (const cell of row) if (cell !== "." && !order.includes(cell)) order.push(cell);
|
|
2383
|
+
const pending = order.filter((name) => empty2.has(name));
|
|
2384
|
+
let changed = true;
|
|
2385
|
+
while (changed) {
|
|
2386
|
+
changed = false;
|
|
2387
|
+
for (const name of pending) {
|
|
2388
|
+
if (joined.has(name)) continue;
|
|
2389
|
+
const own3 = rect(name);
|
|
2390
|
+
if (!own3) continue;
|
|
2391
|
+
const neighbour = (side) => {
|
|
2392
|
+
const cells = [];
|
|
2393
|
+
if (side === "start" || side === "end") {
|
|
2394
|
+
const column = side === "start" ? own3.column - 1 : own3.column + own3.columnSpan;
|
|
2395
|
+
if (column < 0 || column >= (owner[0]?.length ?? 0)) return void 0;
|
|
2396
|
+
for (let r = own3.row; r < own3.row + own3.rowSpan; r++) cells.push(owner[r][column]);
|
|
2397
|
+
} else {
|
|
2398
|
+
const row = side === "above" ? own3.row - 1 : own3.row + own3.rowSpan;
|
|
2399
|
+
if (row < 0 || row >= owner.length) return void 0;
|
|
2400
|
+
for (let c = own3.column; c < own3.column + own3.columnSpan; c++) cells.push(owner[row][c]);
|
|
2401
|
+
}
|
|
2402
|
+
const candidate = cells[0];
|
|
2403
|
+
if (candidate === void 0 || candidate === "." || candidate === name || cells.some((cell) => cell !== candidate)) return void 0;
|
|
2404
|
+
if (empty2.has(candidate) || !absorbs(candidate)) return void 0;
|
|
2405
|
+
const other = rect(candidate);
|
|
2406
|
+
const fits = side === "start" || side === "end" ? other.row === own3.row && other.rowSpan === own3.rowSpan : other.column === own3.column && other.columnSpan === own3.columnSpan;
|
|
2407
|
+
return fits ? candidate : void 0;
|
|
2408
|
+
};
|
|
2409
|
+
const sides = ["start", "end", "below", "above"];
|
|
2410
|
+
let target;
|
|
2411
|
+
for (const body of [true, false]) {
|
|
2412
|
+
for (const side of sides) {
|
|
2413
|
+
const candidate = neighbour(side);
|
|
2414
|
+
if (candidate !== void 0 && heading(candidate) !== body) {
|
|
2415
|
+
target = candidate;
|
|
2416
|
+
break;
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
if (target !== void 0) break;
|
|
2420
|
+
}
|
|
2421
|
+
if (target === void 0) continue;
|
|
2422
|
+
for (const row of owner) row.forEach((cell, c) => {
|
|
2423
|
+
if (cell === name) row[c] = target;
|
|
2424
|
+
});
|
|
2425
|
+
joined.set(name, target);
|
|
2426
|
+
changed = true;
|
|
2427
|
+
}
|
|
2111
2428
|
}
|
|
2112
|
-
return {
|
|
2429
|
+
return { grid: owner, joined };
|
|
2430
|
+
}
|
|
2431
|
+
function areaRects(grid) {
|
|
2432
|
+
const rects = /* @__PURE__ */ new Map();
|
|
2433
|
+
grid.forEach((row, r) => {
|
|
2434
|
+
row.forEach((name, c) => {
|
|
2435
|
+
if (name === ".") return;
|
|
2436
|
+
const found = rects.get(name);
|
|
2437
|
+
if (!found) rects.set(name, { row: r, column: c, rowSpan: 1, columnSpan: 1 });
|
|
2438
|
+
else {
|
|
2439
|
+
found.rowSpan = Math.max(found.rowSpan, r - found.row + 1);
|
|
2440
|
+
found.columnSpan = Math.max(found.columnSpan, c - found.column + 1);
|
|
2441
|
+
}
|
|
2442
|
+
});
|
|
2443
|
+
});
|
|
2444
|
+
return rects;
|
|
2445
|
+
}
|
|
2446
|
+
function listColumnBreaks(heights, levels, count) {
|
|
2447
|
+
const n = heights.length;
|
|
2448
|
+
if (count <= 1 || n < 2) return [];
|
|
2449
|
+
const allowed = Array.from({ length: n }, (_, index) => index > 0 && (levels[index] ?? 0) === 0);
|
|
2450
|
+
const prefix = [0];
|
|
2451
|
+
for (const height of heights) prefix.push(prefix.at(-1) + height);
|
|
2452
|
+
const span = (from, to) => prefix[to] - prefix[from];
|
|
2453
|
+
const memo = /* @__PURE__ */ new Map();
|
|
2454
|
+
const solve = (start, columns2) => {
|
|
2455
|
+
const key = `${start}:${columns2}`;
|
|
2456
|
+
const found = memo.get(key);
|
|
2457
|
+
if (found) return found;
|
|
2458
|
+
let best = { cost: span(start, n), breaks: [] };
|
|
2459
|
+
if (columns2 > 1) for (let next = start + 1; next < n; next++) {
|
|
2460
|
+
if (!allowed[next]) continue;
|
|
2461
|
+
const rest = solve(next, columns2 - 1);
|
|
2462
|
+
const cost = Math.max(span(start, next), rest.cost);
|
|
2463
|
+
if (cost < best.cost - 1e-9) best = { cost, breaks: [next, ...rest.breaks] };
|
|
2464
|
+
}
|
|
2465
|
+
memo.set(key, best);
|
|
2466
|
+
return best;
|
|
2467
|
+
};
|
|
2468
|
+
return solve(0, count).breaks;
|
|
2469
|
+
}
|
|
2470
|
+
function allocateRows(rows3, total, gap) {
|
|
2471
|
+
const auto = rows3.map((row) => row.size === "auto" ? Math.max(0, Math.min(row.need, row.kind === "below" ? total : total / 2)) : 0);
|
|
2472
|
+
const visible = rows3.filter((row, index) => row.size !== "auto" || auto[index] > 0).length;
|
|
2473
|
+
const headings2 = rows3.reduce((sum, row, index) => sum + (row.kind === "heading" ? auto[index] : 0), 0);
|
|
2474
|
+
const space = Math.max(0, total - headings2 - Math.max(0, visible - 1) * gap);
|
|
2475
|
+
const numeric = rows3.reduce((sum, row) => sum + (row.size === "auto" ? 0 : row.size), 0);
|
|
2476
|
+
const numericNeed = rows3.reduce((sum, row) => sum + (row.size === "auto" ? 0 : Math.max(0, row.need)), 0);
|
|
2477
|
+
const reserve = numeric > 0 ? Math.min(numericNeed, space / 2) : 0;
|
|
2478
|
+
const body = rows3.reduce((sum, row, index) => sum + (row.size === "auto" && row.kind !== "heading" ? auto[index] : 0), 0);
|
|
2479
|
+
const factor = body > space - reserve && body > 0 ? Math.max(0, space - reserve) / body : 1;
|
|
2480
|
+
const heights = rows3.map((row, index) => row.size === "auto" ? row.kind === "heading" ? auto[index] : auto[index] * factor : 0);
|
|
2481
|
+
const rest = Math.max(0, space - heights.reduce((sum, height, index) => sum + (rows3[index].kind === "heading" ? 0 : height), 0));
|
|
2482
|
+
return rows3.map((row, index) => row.size === "auto" ? heights[index] : numeric > 0 ? rest * row.size / numeric : 0);
|
|
2113
2483
|
}
|
|
2114
2484
|
|
|
2115
2485
|
// src/direction.ts
|
|
@@ -2152,6 +2522,215 @@ function paragraphDirectionAt(text2, deckDirection) {
|
|
|
2152
2522
|
};
|
|
2153
2523
|
}
|
|
2154
2524
|
|
|
2525
|
+
// src/catalog-refs.ts
|
|
2526
|
+
var catalogKinds = ["layouts", "themes", "colorSchemes", "fontSchemes", "narratives", "audiences", "purposes", "tones"];
|
|
2527
|
+
var CATALOG_REFERENCE_PATTERN = /^(?:([a-z][a-z0-9-]*):)?([a-z][a-z0-9-]*)$/;
|
|
2528
|
+
var CATALOG_GROUP_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
2529
|
+
function provenanceOf(found) {
|
|
2530
|
+
const { record: _record, ...provenance } = found;
|
|
2531
|
+
return provenance;
|
|
2532
|
+
}
|
|
2533
|
+
var OPFCatalogsOptionError = class extends TypeError {
|
|
2534
|
+
code = "invalid-catalogs";
|
|
2535
|
+
constructor(entry, detail) {
|
|
2536
|
+
super(`${entry}: the catalogs option must be an array of registered catalogs ({ source, <kind>: { <id>: record } } with known catalog kinds); ${detail}.`);
|
|
2537
|
+
this.name = "OPFCatalogsOptionError";
|
|
2538
|
+
}
|
|
2539
|
+
};
|
|
2540
|
+
function checkCatalogsOption(catalogs, entry) {
|
|
2541
|
+
if (catalogs === void 0) return [];
|
|
2542
|
+
if (!Array.isArray(catalogs)) throw new OPFCatalogsOptionError(entry, `got ${catalogs === null ? "null" : typeof catalogs}`);
|
|
2543
|
+
catalogs.forEach((catalog, index) => {
|
|
2544
|
+
if (!isRec(catalog) || typeof catalog.source !== "string") throw new OPFCatalogsOptionError(entry, `catalogs[${index}] is not an object with a string source`);
|
|
2545
|
+
for (const [kind2, records] of Object.entries(catalog)) {
|
|
2546
|
+
if (kind2 === "source") continue;
|
|
2547
|
+
if (!catalogKinds.includes(kind2)) throw new OPFCatalogsOptionError(entry, `catalogs[${index}].${kind2} is not a catalog kind`);
|
|
2548
|
+
if (!isRec(records)) throw new OPFCatalogsOptionError(entry, `catalogs[${index}].${kind2} is not an object of records keyed by id`);
|
|
2549
|
+
}
|
|
2550
|
+
});
|
|
2551
|
+
return catalogs;
|
|
2552
|
+
}
|
|
2553
|
+
var OPFUnresolvedReferenceError = class extends Error {
|
|
2554
|
+
diagnostics;
|
|
2555
|
+
constructor(diagnostics) {
|
|
2556
|
+
super(diagnostics.map((diagnostic) => diagnostic.message).join(" "));
|
|
2557
|
+
this.name = "OPFUnresolvedReferenceError";
|
|
2558
|
+
this.diagnostics = diagnostics;
|
|
2559
|
+
}
|
|
2560
|
+
};
|
|
2561
|
+
var isRec = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2562
|
+
var rec = (value) => isRec(value) ? value : {};
|
|
2563
|
+
var own2 = (value, key) => Object.hasOwn(value, key);
|
|
2564
|
+
function parseReference(reference) {
|
|
2565
|
+
if (typeof reference !== "string") return void 0;
|
|
2566
|
+
const match = CATALOG_REFERENCE_PATTERN.exec(reference);
|
|
2567
|
+
if (!match) return void 0;
|
|
2568
|
+
const [, group, id] = match;
|
|
2569
|
+
return group === void 0 ? { id } : { group, id };
|
|
2570
|
+
}
|
|
2571
|
+
function groupsOf(document) {
|
|
2572
|
+
return rec(rec(document).catalogs);
|
|
2573
|
+
}
|
|
2574
|
+
function catalogGroupDeclared(document, name) {
|
|
2575
|
+
const groups = groupsOf(document);
|
|
2576
|
+
return own2(groups, name) && (isRec(groups[name]) || name === "default" && groups[name] === false);
|
|
2577
|
+
}
|
|
2578
|
+
function catalogGroupSource(document, name, options = {}) {
|
|
2579
|
+
if (name === "custom") return void 0;
|
|
2580
|
+
const group = groupsOf(document)[name];
|
|
2581
|
+
if (name === "default") {
|
|
2582
|
+
if (group === false) return void 0;
|
|
2583
|
+
const source2 = rec(group).source;
|
|
2584
|
+
return typeof source2 === "string" ? source2 : options.catalogs?.[0]?.source;
|
|
2585
|
+
}
|
|
2586
|
+
const source = rec(group).source;
|
|
2587
|
+
return typeof source === "string" ? source : void 0;
|
|
2588
|
+
}
|
|
2589
|
+
function registeredCatalog(source, options = {}) {
|
|
2590
|
+
if (source === void 0) return void 0;
|
|
2591
|
+
return options.catalogs?.find((catalog) => catalog?.source === source);
|
|
2592
|
+
}
|
|
2593
|
+
function lookupInGroup(document, kind2, group, id, reference, options = {}) {
|
|
2594
|
+
const groups = groupsOf(document);
|
|
2595
|
+
if (group === "default" && groups.default === false) return void 0;
|
|
2596
|
+
if (group !== "default" && group !== "custom" && !isRec(groups[group])) return void 0;
|
|
2597
|
+
const source = catalogGroupSource(document, group, options);
|
|
2598
|
+
const embedded = rec(rec(groups[group])[kind2]);
|
|
2599
|
+
if (own2(embedded, id) && isRec(embedded[id])) {
|
|
2600
|
+
return { kind: kind2, reference, id, group, ...source !== void 0 ? { source } : {}, origin: "document", record: embedded[id] };
|
|
2601
|
+
}
|
|
2602
|
+
if (group === "custom") return void 0;
|
|
2603
|
+
const hosted = registeredCatalog(source, options)?.[kind2];
|
|
2604
|
+
if (hosted && own2(hosted, id) && isRec(hosted[id])) {
|
|
2605
|
+
return { kind: kind2, reference, id, group, ...source !== void 0 ? { source } : {}, origin: "host", record: hosted[id] };
|
|
2606
|
+
}
|
|
2607
|
+
return void 0;
|
|
2608
|
+
}
|
|
2609
|
+
function resolveReference(document, kind2, reference, options = {}) {
|
|
2610
|
+
checkCatalogsOption(options.catalogs, "resolveReference");
|
|
2611
|
+
const parsed = parseReference(reference);
|
|
2612
|
+
if (!parsed) return void 0;
|
|
2613
|
+
const written = reference;
|
|
2614
|
+
if (parsed.group !== void 0) return lookupInGroup(document, kind2, parsed.group, parsed.id, written, options);
|
|
2615
|
+
const order = [...new Set([options.group, "custom", "default"].filter((group) => typeof group === "string"))];
|
|
2616
|
+
for (const group of order) {
|
|
2617
|
+
const found = lookupInGroup(document, kind2, group, parsed.id, written, options);
|
|
2618
|
+
if (found) return found;
|
|
2619
|
+
}
|
|
2620
|
+
return void 0;
|
|
2621
|
+
}
|
|
2622
|
+
var KIND_NOUNS = {
|
|
2623
|
+
layouts: "Layout",
|
|
2624
|
+
themes: "Theme",
|
|
2625
|
+
colorSchemes: "Colour scheme",
|
|
2626
|
+
fontSchemes: "Font scheme",
|
|
2627
|
+
narratives: "Narrative",
|
|
2628
|
+
audiences: "Audience",
|
|
2629
|
+
purposes: "Purpose",
|
|
2630
|
+
tones: "Tone"
|
|
2631
|
+
};
|
|
2632
|
+
function unresolvedReference(document, kind2, reference, path, options = {}) {
|
|
2633
|
+
const parsed = parseReference(reference);
|
|
2634
|
+
const group = parsed?.group ?? "default";
|
|
2635
|
+
const source = catalogGroupSource(document, group, options);
|
|
2636
|
+
const noun = KIND_NOUNS[kind2];
|
|
2637
|
+
const where = parsed?.group !== void 0 && !catalogGroupDeclared(document, parsed.group) ? `the document declares no catalogs.${parsed.group} group` : group === "custom" ? "it is not in catalogs.custom" : group === "default" && groupsOf(document).default === false ? "it is not in catalogs.custom and catalogs.default is false" : source === void 0 ? `it is not embedded in catalogs.${group === "default" ? "custom or catalogs.default" : group} and no catalog is registered for it` : `it is not embedded in catalogs.${group === "default" ? "custom or catalogs.default" : group} and the catalog registered for ${source} ${registeredCatalog(source, options) ? "has no such record" : "is not registered"}`;
|
|
2638
|
+
const fallback = kind2 === "layouts" ? "automatic" : "engine-default";
|
|
2639
|
+
return {
|
|
2640
|
+
code: "unresolved-reference",
|
|
2641
|
+
kind: kind2,
|
|
2642
|
+
reference,
|
|
2643
|
+
path,
|
|
2644
|
+
group,
|
|
2645
|
+
...source !== void 0 ? { source } : {},
|
|
2646
|
+
fallback,
|
|
2647
|
+
message: `${noun} '${reference}' resolves nowhere: ${where}; ${fallback === "automatic" ? "the slide composes automatically" : "the engine default is used"}.`
|
|
2648
|
+
};
|
|
2649
|
+
}
|
|
2650
|
+
var pushReference = (sites, kind2, value, path, group) => {
|
|
2651
|
+
if (typeof value === "string" && parseReference(value)) sites.push({ kind: kind2, reference: value, path, ...group !== void 0 ? { group } : {} });
|
|
2652
|
+
};
|
|
2653
|
+
var pushObjectReference = (sites, kind2, value, path, group) => {
|
|
2654
|
+
if (typeof value === "string") pushReference(sites, kind2, value, path, group);
|
|
2655
|
+
else if (isRec(value)) pushReference(sites, kind2, value.id, [...path, "id"], group);
|
|
2656
|
+
};
|
|
2657
|
+
function designSites(sites, design, path) {
|
|
2658
|
+
if (!isRec(design)) return;
|
|
2659
|
+
pushReference(sites, "themes", design.theme, [...path, "theme"]);
|
|
2660
|
+
pushObjectReference(sites, "colorSchemes", design.colorScheme, [...path, "colorScheme"]);
|
|
2661
|
+
pushObjectReference(sites, "fontSchemes", design.fontScheme, [...path, "fontScheme"]);
|
|
2662
|
+
}
|
|
2663
|
+
function recordReferenceSites(kind2, record9, path, group) {
|
|
2664
|
+
const sites = [];
|
|
2665
|
+
if (kind2 === "themes" && isRec(record9)) {
|
|
2666
|
+
pushObjectReference(sites, "colorSchemes", record9.colorScheme, [...path, "colorScheme"], group);
|
|
2667
|
+
pushObjectReference(sites, "fontSchemes", record9.fontScheme, [...path, "fontScheme"], group);
|
|
2668
|
+
}
|
|
2669
|
+
return sites;
|
|
2670
|
+
}
|
|
2671
|
+
function catalogReferenceSites(document, options = {}) {
|
|
2672
|
+
const deck = rec(document);
|
|
2673
|
+
const sites = [];
|
|
2674
|
+
pushReference(sites, "narratives", deck.narrative, ["narrative"]);
|
|
2675
|
+
if (Array.isArray(deck.audience)) deck.audience.forEach((entry, index) => {
|
|
2676
|
+
pushObjectReference(sites, "audiences", entry, ["audience", index]);
|
|
2677
|
+
});
|
|
2678
|
+
else pushObjectReference(sites, "audiences", deck.audience, ["audience"]);
|
|
2679
|
+
pushObjectReference(sites, "purposes", deck.purpose, ["purpose"]);
|
|
2680
|
+
pushObjectReference(sites, "tones", deck.tone, ["tone"]);
|
|
2681
|
+
if (isRec(deck.language)) {
|
|
2682
|
+
pushReference(sites, "fontSchemes", deck.language.fontScheme, ["language", "fontScheme"]);
|
|
2683
|
+
pushReference(sites, "fontSchemes", deck.language.googleFontScheme, ["language", "googleFontScheme"]);
|
|
2684
|
+
}
|
|
2685
|
+
designSites(sites, deck.design, ["design"]);
|
|
2686
|
+
if (options.slides !== false && Array.isArray(deck.slides))
|
|
2687
|
+
deck.slides.forEach((slide, index) => {
|
|
2688
|
+
if (!isRec(slide)) return;
|
|
2689
|
+
if (slide.layout !== "auto") pushReference(sites, "layouts", slide.layout, ["slides", index, "layout"]);
|
|
2690
|
+
designSites(sites, slide.design, ["slides", index, "design"]);
|
|
2691
|
+
});
|
|
2692
|
+
if (options.records !== false)
|
|
2693
|
+
for (const [group, value] of Object.entries(groupsOf(document))) {
|
|
2694
|
+
if (!isRec(value)) continue;
|
|
2695
|
+
for (const kind2 of catalogKinds)
|
|
2696
|
+
for (const [id, record9] of Object.entries(rec(value[kind2]))) sites.push(...recordReferenceSites(kind2, record9, ["catalogs", group, kind2, id], group));
|
|
2697
|
+
}
|
|
2698
|
+
return sites;
|
|
2699
|
+
}
|
|
2700
|
+
var dottedPath = (path) => path.join(".");
|
|
2701
|
+
var pointerPath = (path) => path.length ? `/${path.map((part) => String(part).replaceAll("~", "~0").replaceAll("/", "~1")).join("/")}` : "";
|
|
2702
|
+
function catalogRecords(document, kind2, options = {}) {
|
|
2703
|
+
checkCatalogsOption(options.catalogs, "catalogRecords");
|
|
2704
|
+
const result = [];
|
|
2705
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2706
|
+
const add = (entry) => {
|
|
2707
|
+
if (seen.has(entry.reference)) return;
|
|
2708
|
+
seen.add(entry.reference);
|
|
2709
|
+
result.push(entry);
|
|
2710
|
+
};
|
|
2711
|
+
const groups = groupsOf(document);
|
|
2712
|
+
const names = [.../* @__PURE__ */ new Set(["custom", "default", ...Object.keys(groups)])];
|
|
2713
|
+
for (const group of names) {
|
|
2714
|
+
if (group === "default" && groups.default === false) continue;
|
|
2715
|
+
if (group !== "custom" && group !== "default" && !isRec(groups[group])) continue;
|
|
2716
|
+
const prefix = group === "custom" || group === "default" ? "" : `${group}:`;
|
|
2717
|
+
for (const id of Object.keys(rec(rec(groups[group])[kind2]))) {
|
|
2718
|
+
const found = lookupInGroup(document, kind2, group, id, `${prefix}${id}`, options);
|
|
2719
|
+
if (found) add(found);
|
|
2720
|
+
}
|
|
2721
|
+
if (group === "custom") continue;
|
|
2722
|
+
const hosted = registeredCatalog(catalogGroupSource(document, group, options), options)?.[kind2];
|
|
2723
|
+
for (const id of Object.keys(hosted ?? {})) {
|
|
2724
|
+
const found = lookupInGroup(document, kind2, group, id, `${prefix}${id}`, options);
|
|
2725
|
+
if (found) add(found);
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
return result;
|
|
2729
|
+
}
|
|
2730
|
+
function embeddedCopy(record9) {
|
|
2731
|
+
return Object.fromEntries(Object.entries(rec(record9)).filter(([key]) => key !== "$schema" && key !== "id" && !key.startsWith("x-")).map(([key, value]) => [key, structuredClone(value)]));
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2155
2734
|
// src/generated/engine-data.ts
|
|
2156
2735
|
var engineDefaultsSource = {
|
|
2157
2736
|
"theme": {
|
|
@@ -2198,10 +2777,10 @@ var SOCIAL_PLATFORMS = engineVocabulariesSource.socialPlatforms;
|
|
|
2198
2777
|
var LANGUAGES = engineVocabulariesSource.languages;
|
|
2199
2778
|
|
|
2200
2779
|
// src/design-records.ts
|
|
2201
|
-
var
|
|
2202
|
-
var
|
|
2780
|
+
var isRec2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2781
|
+
var rec2 = (value) => isRec2(value) ? value : {};
|
|
2203
2782
|
function resolveRecordReference(document, kind2, reference, path, fallback, options, diagnostics) {
|
|
2204
|
-
const object2 =
|
|
2783
|
+
const object2 = isRec2(reference) ? reference : void 0;
|
|
2205
2784
|
const id = typeof reference === "string" ? reference : typeof object2?.id === "string" ? object2.id : void 0;
|
|
2206
2785
|
if (id === void 0) return { record: { ...fallback, ...object2 } };
|
|
2207
2786
|
const found = resolveReference(document, kind2, id, options);
|
|
@@ -2210,27 +2789,27 @@ function resolveRecordReference(document, kind2, reference, path, fallback, opti
|
|
|
2210
2789
|
}
|
|
2211
2790
|
function resolveDesignRecords(document, slideIndex, options = {}) {
|
|
2212
2791
|
checkCatalogsOption(options.catalogs, "resolveDesignRecords");
|
|
2213
|
-
const deck =
|
|
2792
|
+
const deck = rec2(document);
|
|
2214
2793
|
const slides = Array.isArray(deck.slides) ? deck.slides : [];
|
|
2215
|
-
const
|
|
2216
|
-
const shared =
|
|
2217
|
-
const design = { ...shared, ...
|
|
2794
|
+
const own3 = slideIndex === void 0 ? {} : rec2(rec2(slides[slideIndex]).design);
|
|
2795
|
+
const shared = rec2(deck.design);
|
|
2796
|
+
const design = { ...shared, ...own3 };
|
|
2218
2797
|
const slidePath = `slides.${slideIndex}.design`;
|
|
2219
2798
|
const diagnostics = [];
|
|
2220
|
-
const themePath =
|
|
2799
|
+
const themePath = own3.theme !== void 0 ? `${slidePath}.theme` : "design.theme";
|
|
2221
2800
|
const themeFound = typeof design.theme === "string" ? resolveReference(document, "themes", design.theme, options) : void 0;
|
|
2222
2801
|
if (typeof design.theme === "string" && !themeFound) diagnostics.push(unresolvedReference(document, "themes", design.theme, themePath, options));
|
|
2223
2802
|
const theme = themeFound ? { ...themeFound.record } : { ...ENGINE_DEFAULT_THEME };
|
|
2224
2803
|
const inTheme = { ...options, ...themeFound ? { group: themeFound.group } : {} };
|
|
2225
2804
|
const inThemePath = (key) => themeFound?.origin === "document" ? `catalogs.${themeFound.group}.themes.${themeFound.id}.${key}` : themePath;
|
|
2226
2805
|
const colorFromDesign = design.colorScheme !== void 0;
|
|
2227
|
-
const colorSchemePath =
|
|
2806
|
+
const colorSchemePath = own3.colorScheme !== void 0 ? `${slidePath}.colorScheme` : shared.colorScheme !== void 0 ? "design.colorScheme" : inThemePath("colorScheme");
|
|
2228
2807
|
const color = resolveRecordReference(document, "colorSchemes", colorFromDesign ? design.colorScheme : theme.colorScheme, colorFromDesign ? colorSchemePath : inThemePath("colorScheme"), ENGINE_DEFAULT_COLOR_SCHEME, colorFromDesign ? options : inTheme, diagnostics);
|
|
2229
2808
|
const fontFromDesign = design.fontScheme !== void 0;
|
|
2230
|
-
const fontSchemePath =
|
|
2809
|
+
const fontSchemePath = own3.fontScheme !== void 0 ? `${slidePath}.fontScheme` : shared.fontScheme !== void 0 ? "design.fontScheme" : inThemePath("fontScheme");
|
|
2231
2810
|
const font = resolveRecordReference(document, "fontSchemes", fontFromDesign ? design.fontScheme : theme.fontScheme, fontSchemePath, ENGINE_DEFAULT_FONT_SCHEME, fontFromDesign ? options : inTheme, diagnostics);
|
|
2232
2811
|
const fontReference = fontFromDesign ? design.fontScheme : theme.fontScheme;
|
|
2233
|
-
const fontSchemeReference = typeof fontReference === "string" ? fontReference :
|
|
2812
|
+
const fontSchemeReference = typeof fontReference === "string" ? fontReference : isRec2(fontReference) && typeof fontReference.id === "string" ? fontReference.id : void 0;
|
|
2234
2813
|
const provenance = {
|
|
2235
2814
|
...themeFound ? { theme: provenanceOf(themeFound) } : {},
|
|
2236
2815
|
...color.provenance ? { colorScheme: color.provenance } : {},
|
|
@@ -2551,11 +3130,11 @@ function listNumbers(items, numbering) {
|
|
|
2551
3130
|
const object2 = isObject(item) ? item : void 0;
|
|
2552
3131
|
const level = object2?.level === void 0 ? 0 : object2.level;
|
|
2553
3132
|
if (typeof level !== "number" || !Number.isInteger(level) || level < 0) throw new RangeError("List levels must be nonnegative integers.");
|
|
2554
|
-
const
|
|
2555
|
-
if (
|
|
3133
|
+
const own3 = object2?.start;
|
|
3134
|
+
if (own3 !== void 0 && (typeof own3 !== "number" || !Number.isInteger(own3) || own3 < 1 || own3 > MAX_NUMBERING_VALUE)) throw new RangeError(`A list item start must be an integer from 1 to ${MAX_NUMBERING_VALUE}.`);
|
|
2556
3135
|
const { style: authored, start, suffix } = numberingAtLevel(levels, level);
|
|
2557
3136
|
const previous = counters[level];
|
|
2558
|
-
const value =
|
|
3137
|
+
const value = own3 ?? (previous === void 0 ? start : previous + 1);
|
|
2559
3138
|
counters[level] = value;
|
|
2560
3139
|
counters.length = level + 1;
|
|
2561
3140
|
const adapted = !numberingStyleDraws(authored, value);
|
|
@@ -3624,8 +4203,8 @@ function codeSyntaxPalette(theme = {}, options = {}) {
|
|
|
3624
4203
|
return palette;
|
|
3625
4204
|
}
|
|
3626
4205
|
function codeSyntaxPaletteForScheme(scheme, options = {}) {
|
|
3627
|
-
const
|
|
3628
|
-
const pick = (role, slot, fallback) => normalize(
|
|
4206
|
+
const record9 = scheme && typeof scheme === "object" ? scheme : {};
|
|
4207
|
+
const pick = (role, slot, fallback) => normalize(record9[role]) ?? normalize(record9[slot]) ?? fallback;
|
|
3629
4208
|
return codeSyntaxPalette({ primary: pick("primary", "accent1", "#2563EB"), secondary: pick("secondary", "accent2", "#0F766E"), accent: pick("accent", "accent3", "#F59E0B") }, options);
|
|
3630
4209
|
}
|
|
3631
4210
|
|
|
@@ -3777,8 +4356,8 @@ var blend = (from, to, amount) => {
|
|
|
3777
4356
|
return toHex(a.map((value, index) => value + (b[index] - value) * amount));
|
|
3778
4357
|
};
|
|
3779
4358
|
function codeHighlightColors(scheme, palette = codeSyntaxPaletteForScheme(scheme)) {
|
|
3780
|
-
const
|
|
3781
|
-
const primary = normalize(
|
|
4359
|
+
const record9 = scheme && typeof scheme === "object" ? scheme : {};
|
|
4360
|
+
const primary = normalize(record9.primary) ?? normalize(record9.accent1) ?? "#2563EB";
|
|
3782
4361
|
const [hue, saturation] = toHsl(primary);
|
|
3783
4362
|
const tint = fromHsl(hue, Math.min(saturation, 0.7), 0.45);
|
|
3784
4363
|
const band = blend(CODE_PANEL_BACKGROUND, tint, CODE_HIGHLIGHT_BAND_TINT);
|
|
@@ -3975,7 +4554,7 @@ var CAPTION_FONT_RATIO = 0.6;
|
|
|
3975
4554
|
var CAPTION_MAX_RATIO = 0.35;
|
|
3976
4555
|
var FOOTNOTE_MAX_RATIO = 0.35;
|
|
3977
4556
|
var CAPTIONABLE_FIELDS = Object.freeze(["image", "chart", "table", "video"]);
|
|
3978
|
-
var
|
|
4557
|
+
var record6 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
3979
4558
|
var isRecord3 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
3980
4559
|
var round = (value) => Math.round(value * 1e6) / 1e6 || value;
|
|
3981
4560
|
var regionKey = /^(top|middle|bottom|left|center|right)([+:]|$)/;
|
|
@@ -3983,7 +4562,7 @@ var TEXT_FIELDS = ["text", "items", "bullets"];
|
|
|
3983
4562
|
var HEADING_FIELDS = ["tag", "title", "subtitle"];
|
|
3984
4563
|
function annotationText(value) {
|
|
3985
4564
|
if (typeof value === "string") return value;
|
|
3986
|
-
if (Array.isArray(value)) return value.map((run) => typeof run === "string" ? run :
|
|
4565
|
+
if (Array.isArray(value)) return value.map((run) => typeof run === "string" ? run : record6(run).text ?? "").join("");
|
|
3987
4566
|
if (isRecord3(value) && value.text !== void 0) return annotationText(value.text);
|
|
3988
4567
|
return value === void 0 || value === null ? "" : String(value);
|
|
3989
4568
|
}
|
|
@@ -4015,7 +4594,7 @@ function walkCitationRuns(slide, basePath, visit) {
|
|
|
4015
4594
|
});
|
|
4016
4595
|
};
|
|
4017
4596
|
const host = (node, path, depth) => {
|
|
4018
|
-
const payload =
|
|
4597
|
+
const payload = record6(node);
|
|
4019
4598
|
if (Array.isArray(payload.blocks)) {
|
|
4020
4599
|
if (depth > 32) return;
|
|
4021
4600
|
payload.blocks.forEach((block, index) => {
|
|
@@ -4030,7 +4609,7 @@ function walkCitationRuns(slide, basePath, visit) {
|
|
|
4030
4609
|
}
|
|
4031
4610
|
if (isRecord3(payload.quote)) runs(payload.quote.text, `${path}.quote.text`);
|
|
4032
4611
|
};
|
|
4033
|
-
const value =
|
|
4612
|
+
const value = record6(slide);
|
|
4034
4613
|
for (const field of HEADING_FIELDS) runs(value[field], `${basePath}.${field}`);
|
|
4035
4614
|
const regions = Object.keys(value).filter((key) => regionKey.test(key)).sort();
|
|
4036
4615
|
if (regions.length) {
|
|
@@ -4047,7 +4626,7 @@ function walkCitationRuns(slide, basePath, visit) {
|
|
|
4047
4626
|
}
|
|
4048
4627
|
var citationMarkerText = (numbers) => numbers.join(",");
|
|
4049
4628
|
function referenceList(presentation) {
|
|
4050
|
-
const list =
|
|
4629
|
+
const list = record6(presentation).references;
|
|
4051
4630
|
return Array.isArray(list) ? list.filter((item) => isRecord3(item) && typeof item.id === "string") : [];
|
|
4052
4631
|
}
|
|
4053
4632
|
function numberSlide(slide, slideIndex, references, numbering) {
|
|
@@ -4080,7 +4659,7 @@ function numberSlide(slide, slideIndex, references, numbering) {
|
|
|
4080
4659
|
}
|
|
4081
4660
|
function collectCitations(presentation) {
|
|
4082
4661
|
const references = referenceList(presentation), numbering = { notes: [], byId: /* @__PURE__ */ new Map() }, slides = /* @__PURE__ */ new Map();
|
|
4083
|
-
const list =
|
|
4662
|
+
const list = record6(presentation).slides;
|
|
4084
4663
|
if (Array.isArray(list)) list.forEach((slide, index) => {
|
|
4085
4664
|
const result = numberSlide(slide, index, references, numbering);
|
|
4086
4665
|
if (result) slides.set(index, result);
|
|
@@ -4090,7 +4669,7 @@ function collectCitations(presentation) {
|
|
|
4090
4669
|
}
|
|
4091
4670
|
function slideCitations(slide, slideIndex, presentation) {
|
|
4092
4671
|
const references = referenceList(presentation), numbering = { notes: [], byId: /* @__PURE__ */ new Map() };
|
|
4093
|
-
const list =
|
|
4672
|
+
const list = record6(presentation).slides;
|
|
4094
4673
|
if (Array.isArray(list)) for (let index = 0; index < Math.min(slideIndex, list.length); index += 1) numberSlide(list[index], index, references, numbering);
|
|
4095
4674
|
return numberSlide(slide, slideIndex, references, numbering);
|
|
4096
4675
|
}
|
|
@@ -4153,12 +4732,39 @@ function referencesSlide(presentation, options = {}) {
|
|
|
4153
4732
|
return { title, items };
|
|
4154
4733
|
}
|
|
4155
4734
|
|
|
4735
|
+
// src/layout-content.ts
|
|
4736
|
+
var LAYOUT_BODY_KINDS = ["text", "list", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
|
|
4737
|
+
var record7 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
4738
|
+
function layoutStructure(layout) {
|
|
4739
|
+
if (!isLayoutTemplate(layout)) return "";
|
|
4740
|
+
return templateAreas(layout).map((entry) => entry.region ? `${entry.name} (${entry.region.flow}: ${entry.region.accepts.join(", ")})` : entry.name).join(", ");
|
|
4741
|
+
}
|
|
4742
|
+
function layoutContent(layout) {
|
|
4743
|
+
const areas = isLayoutTemplate(layout) ? templateAreas(layout) : [];
|
|
4744
|
+
const regions = areas.flatMap((entry) => entry.region ? [entry.region] : []);
|
|
4745
|
+
const lead = regions.find((region) => region.role === "primary") ?? regions[0];
|
|
4746
|
+
const leadKind = lead?.accepts.find((kind2) => kind2 !== "group");
|
|
4747
|
+
const title = areas.some((entry) => entry.name === "title");
|
|
4748
|
+
return { kind: leadKind ?? "title", count: regions.length, heading: { title, subtitle: title || areas.some((entry) => entry.name === "subtitle"), tag: title } };
|
|
4749
|
+
}
|
|
4750
|
+
function templateAreas(layout) {
|
|
4751
|
+
const value = record7(layout), regions = record7(value.regions);
|
|
4752
|
+
const rows3 = Array.isArray(value.areas) ? value.areas.filter((row) => typeof row === "string") : [];
|
|
4753
|
+
const seen = /* @__PURE__ */ new Set(), out = [];
|
|
4754
|
+
for (const row of rows3) for (const name of row.trim().split(/\s+/)) {
|
|
4755
|
+
if (!name || name === "." || seen.has(name)) continue;
|
|
4756
|
+
seen.add(name);
|
|
4757
|
+
out.push(name === "title" || name === "subtitle" || !Object.hasOwn(regions, name) ? { name } : { name, region: layoutRegion(name, regions[name]) });
|
|
4758
|
+
}
|
|
4759
|
+
return out;
|
|
4760
|
+
}
|
|
4761
|
+
|
|
4156
4762
|
// src/composition.ts
|
|
4157
4763
|
var MAX_COMPOSITION_DEPTH = 32;
|
|
4158
4764
|
var FALLBACK_CODE_FAMILY = "Roboto Mono";
|
|
4159
4765
|
var DEFAULT_FONT_FAMILIES = { heading: String(ENGINE_DEFAULT_FONT_SCHEME.major), body: String(ENGINE_DEFAULT_FONT_SCHEME.minor) };
|
|
4160
4766
|
function resolveFontFamilies(input) {
|
|
4161
|
-
const scheme =
|
|
4767
|
+
const scheme = record8(input);
|
|
4162
4768
|
const family = (value) => typeof value === "string" && value ? value : void 0;
|
|
4163
4769
|
const accent = family(scheme.accent);
|
|
4164
4770
|
return {
|
|
@@ -4229,12 +4835,6 @@ function translateTextFit(fit, dy) {
|
|
|
4229
4835
|
}
|
|
4230
4836
|
};
|
|
4231
4837
|
}
|
|
4232
|
-
var FIELD_KINDS = { text: "text", bullets: "text", items: "list", image: "image", video: "video", chart: "chart", table: "table", code: "code", metric: "metric", quote: "quote", timeline: "timeline" };
|
|
4233
|
-
function chartPrimaryLayout(side, kinds) {
|
|
4234
|
-
const first = side === "left" || side === "top";
|
|
4235
|
-
const group = { type: "group", composition: {}, placeholders: kinds.map((type) => ({ type })) };
|
|
4236
|
-
return { composition: { mode: side === "left" || side === "right" ? "row" : "column", weights: first ? [3, 2] : [2, 3] }, placeholders: first ? [{ type: "chart" }, group] : [group, { type: "chart" }] };
|
|
4237
|
-
}
|
|
4238
4838
|
var OPFCompositionError = class extends Error {
|
|
4239
4839
|
constructor(diagnostics, explanation) {
|
|
4240
4840
|
super("Slide content does not fit its composition.");
|
|
@@ -4250,11 +4850,11 @@ var fields = ["text", "items", "bullets", "image", "video", "chart", "table", "c
|
|
|
4250
4850
|
var headings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
|
|
4251
4851
|
var rows2 = ["top", "middle", "bottom"];
|
|
4252
4852
|
var columns = ["left", "center", "right"];
|
|
4253
|
-
var
|
|
4853
|
+
var record8 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
4254
4854
|
var kind = (field) => field === "items" ? "list" : field === "bullets" ? "text" : field;
|
|
4255
4855
|
var round2 = (value) => Math.round(value * 1e6) / 1e6 || value;
|
|
4256
4856
|
var PLACEMENT_BAND = 0.5;
|
|
4257
|
-
var
|
|
4857
|
+
var IMAGE_EDGES2 = ["left", "right", "top", "bottom"];
|
|
4258
4858
|
var IMAGE_FITS = ["cover", "contain", "stretch"];
|
|
4259
4859
|
var BACKGROUND_FITS = ["cover", "contain", "stretch", "tile"];
|
|
4260
4860
|
var IMAGE_SOURCE = /^(asset:|https:\/\/|data:|\.\/|\.\.\/)/;
|
|
@@ -4269,7 +4869,7 @@ var pathNumber = (value) => String(round2(value));
|
|
|
4269
4869
|
var IMAGE_SHAPES = { rectangle: "rect", rounded: "roundRect", circle: "ellipse", hexagon: "hexagon" };
|
|
4270
4870
|
var roundBox = (box) => ({ x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) });
|
|
4271
4871
|
var imageFocus = (value) => {
|
|
4272
|
-
const focus =
|
|
4872
|
+
const focus = record8(value), x = finite(focus.x, 0, 1), y = finite(focus.y, 0, 1);
|
|
4273
4873
|
return x !== void 0 && y !== void 0 ? { x, y } : { x: 0.5, y: 0.5 };
|
|
4274
4874
|
};
|
|
4275
4875
|
function imageShape(kind2, box, cornerRadius = 1 / 6) {
|
|
@@ -4310,7 +4910,7 @@ function fitImage(frame, fit, aspect, focus = { x: 0.5, y: 0.5 }) {
|
|
|
4310
4910
|
}
|
|
4311
4911
|
function imageBackground(value) {
|
|
4312
4912
|
if (typeof value === "string") return IMAGE_SOURCE.test(value) ? { src: value, fit: "cover", focus: { x: 0.5, y: 0.5 } } : void 0;
|
|
4313
|
-
const background =
|
|
4913
|
+
const background = record8(value);
|
|
4314
4914
|
if (background.type !== "image" || typeof background.src !== "string" || !background.src) return void 0;
|
|
4315
4915
|
const opacity = finite(background.opacity, 0, 1);
|
|
4316
4916
|
return {
|
|
@@ -4325,13 +4925,13 @@ function imageBackground(value) {
|
|
|
4325
4925
|
}
|
|
4326
4926
|
function composeRecolor(value) {
|
|
4327
4927
|
if (value === "grayscale") return { type: "grayscale" };
|
|
4328
|
-
const duotone =
|
|
4928
|
+
const duotone = record8(value);
|
|
4329
4929
|
return duotone.dark !== void 0 && duotone.light !== void 0 ? { type: "duotone", dark: duotone.dark, light: duotone.light } : void 0;
|
|
4330
4930
|
}
|
|
4331
4931
|
function composeOverlay(value, frame, shape, path, mirrorSide, diagnostics) {
|
|
4332
|
-
const overlay =
|
|
4932
|
+
const overlay = record8(value), opacity = finite(overlay.opacity, 0, 1);
|
|
4333
4933
|
if (overlay.color === void 0 || opacity === void 0) return void 0;
|
|
4334
|
-
const edge =
|
|
4934
|
+
const edge = IMAGE_EDGES2.includes(overlay.edge) ? mirrorSide(overlay.edge) : void 0;
|
|
4335
4935
|
if (edge && shape.kind !== "rectangle") {
|
|
4336
4936
|
diagnostics.push({ code: "unsupported-image-treatment", path: `${path}.edge`, message: "An edge overlay needs a rectangle frame; a band cannot follow a rounded, circular or hexagonal mask as one native shape. Remove edge or use shape rectangle." });
|
|
4337
4937
|
return void 0;
|
|
@@ -4354,7 +4954,7 @@ function composeImage(host, hostPath, region, frameArea, context) {
|
|
|
4354
4954
|
const focus = imageFocus(host.focus);
|
|
4355
4955
|
const shape = imageShape(kindName, box, finite(host.cornerRadius, 0, 0.5));
|
|
4356
4956
|
const result = { region: roundBox(region), box, fit, focus, shape };
|
|
4357
|
-
const border =
|
|
4957
|
+
const border = record8(host.border), borderWidth = finite(border.width, 0, 64);
|
|
4358
4958
|
if (border.color !== void 0 && borderWidth) result.border = { color: border.color, width: round2(borderWidth * scale) };
|
|
4359
4959
|
const opacity = finite(host.opacity, 0, 1);
|
|
4360
4960
|
if (opacity !== void 0 && opacity < 1) result.opacity = opacity;
|
|
@@ -4368,8 +4968,8 @@ function composeImage(host, hostPath, region, frameArea, context) {
|
|
|
4368
4968
|
return result;
|
|
4369
4969
|
}
|
|
4370
4970
|
function resolveBackgroundImage(slide, presentation, themeBackground, width, height, path, mirrorSide, diagnostics) {
|
|
4371
|
-
const
|
|
4372
|
-
const [value, at3] =
|
|
4971
|
+
const own3 = record8(slide.design), deck = record8(record8(presentation).design);
|
|
4972
|
+
const [value, at3] = own3.background !== void 0 ? [own3.background, `${path}.design.background`] : deck.background !== void 0 ? [deck.background, "design.background"] : [themeBackground, "theme"];
|
|
4373
4973
|
const background = imageBackground(value);
|
|
4374
4974
|
if (!background) return void 0;
|
|
4375
4975
|
const box = { x: 0, y: 0, width, height };
|
|
@@ -4379,7 +4979,7 @@ function resolveBackgroundImage(slide, presentation, themeBackground, width, hei
|
|
|
4379
4979
|
if (recolor) result.recolor = recolor;
|
|
4380
4980
|
const overlay = composeOverlay(background.overlay, box, imageShape("rectangle", box), `${at3}.overlay`, mirrorSide, diagnostics);
|
|
4381
4981
|
if (overlay) result.overlay = overlay;
|
|
4382
|
-
const aspect = background.fit === "tile" ? void 0 : intrinsicImageAspect(background.src,
|
|
4982
|
+
const aspect = background.fit === "tile" ? void 0 : intrinsicImageAspect(background.src, record8(presentation).assets);
|
|
4383
4983
|
if (aspect) result.picture = fitImage(box, background.fit, aspect, background.focus);
|
|
4384
4984
|
return result;
|
|
4385
4985
|
}
|
|
@@ -4410,8 +5010,8 @@ function breaksInsideWord(text2, fit) {
|
|
|
4410
5010
|
});
|
|
4411
5011
|
}
|
|
4412
5012
|
function layoutFurniture(input, options = {}) {
|
|
4413
|
-
const slide =
|
|
4414
|
-
const settings = { ...
|
|
5013
|
+
const slide = record8(input), width = options.width ?? 1280, height = options.height ?? 720, scale = Math.min(width, height) / 720;
|
|
5014
|
+
const settings = { ...record8(record8(options.layout).composition), ...record8(slide.composition) };
|
|
4415
5015
|
assertComposition(settings);
|
|
4416
5016
|
const furnitureRtl = (options.direction ?? resolveSlideDirection(options.presentation, options.slideIndex)) === "rtl";
|
|
4417
5017
|
const minimum = snapFontSizeUp((settings.minFontSize ?? 16) * scale), size = gridFontSize(13 * scale, minimum), padding = (options.textRasterPadding ?? 2) * scale;
|
|
@@ -4423,13 +5023,13 @@ function layoutFurniture(input, options = {}) {
|
|
|
4423
5023
|
if (options.date !== void 0 && (typeof options.date !== "string" || !parseIsoDate(options.date))) throw new RangeError("The furniture date option must be an ISO YYYY-MM-DD calendar date.");
|
|
4424
5024
|
const outlines = options.textMeasurement?.outlineBounds !== void 0, parts = [], diagnostics = [];
|
|
4425
5025
|
const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
|
|
4426
|
-
const primaryIndex = organizations.findIndex((item) =>
|
|
4427
|
-
const organization =
|
|
5026
|
+
const primaryIndex = organizations.findIndex((item) => record8(item).role === "primary"), organizationIndex2 = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
|
|
5027
|
+
const organization = record8(organizations[organizationIndex2]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex2}` : "organization";
|
|
4428
5028
|
const fontFamily = options.fontFamilies?.body ?? "sans-serif";
|
|
4429
5029
|
let headerBottom = 0, footerTop = height, configured = false;
|
|
4430
5030
|
const error = (path, message, code = "text-overflow") => diagnostics.push({ code, path, message });
|
|
4431
5031
|
for (const kind2 of ["header", "footer"]) {
|
|
4432
|
-
const local =
|
|
5032
|
+
const local = record8(slide.design)[kind2] !== void 0, value = local ? record8(slide.design)[kind2] : options.presentation?.design?.[kind2];
|
|
4433
5033
|
if (value === void 0 || value === false) continue;
|
|
4434
5034
|
const root = local ? `${sourceRoot}.design.${kind2}` : `design.${kind2}`;
|
|
4435
5035
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("Header/footer content must be an object or false.");
|
|
@@ -4437,7 +5037,7 @@ function layoutFurniture(input, options = {}) {
|
|
|
4437
5037
|
const zones = [];
|
|
4438
5038
|
for (const [index, zone] of ["left", "center", "right"].entries()) {
|
|
4439
5039
|
const side = furnitureRtl && zone !== "center" ? zone === "left" ? "right" : "left" : zone;
|
|
4440
|
-
const content =
|
|
5040
|
+
const content = record8(record8(value)[zone]), path = `${root}.${zone}`, x = width * (0.07 + (furnitureRtl ? 2 - index : index) * 0.3), zoneWidth = width * 0.26;
|
|
4441
5041
|
const pending = [];
|
|
4442
5042
|
const add = (field, text2, generated = false, sourcePath, extras = {}) => {
|
|
4443
5043
|
if (text2 === void 0) return;
|
|
@@ -4446,7 +5046,7 @@ function layoutFurniture(input, options = {}) {
|
|
|
4446
5046
|
pending.push({ type: "text", field, text: text2, generated, sourcePath: sourcePath ?? (!generated ? partPath : void 0), extras, partPath, style: resolveTextStyle({ fontFamily, fontWeight: 400, italic: false, path: partPath }, options.textMeasurement) });
|
|
4447
5047
|
};
|
|
4448
5048
|
const addImage = (source, sourcePath, reference) => {
|
|
4449
|
-
const imageHeight = Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source,
|
|
5049
|
+
const imageHeight = Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source, record8(options.presentation).assets) ?? 1));
|
|
4450
5050
|
pending.push({ type: "image", sourcePath, image: source, ...reference !== void 0 ? { reference } : {}, width: imageWidth, height: imageHeight });
|
|
4451
5051
|
};
|
|
4452
5052
|
if (content.image !== void 0) {
|
|
@@ -4465,7 +5065,7 @@ function layoutFurniture(input, options = {}) {
|
|
|
4465
5065
|
add("text", resolved.text, false, void 0, { fields: resolved.fields });
|
|
4466
5066
|
} else add("text", content.text);
|
|
4467
5067
|
if (content.socials === true) {
|
|
4468
|
-
const links = Object.entries(
|
|
5068
|
+
const links = Object.entries(record8(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2, "organization") }));
|
|
4469
5069
|
if (links.length) add("socials", links.map((link) => link.text).join("\n"), true, `${organizationRoot}.socials`, { links });
|
|
4470
5070
|
else error(`${path}.socials`, "Generated social profiles need a primary organization with socials.", "unresolved-content");
|
|
4471
5071
|
}
|
|
@@ -4572,11 +5172,22 @@ function layoutFurniture(input, options = {}) {
|
|
|
4572
5172
|
var textSegments = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
4573
5173
|
var WRAP_TOLERANCE = 0.01;
|
|
4574
5174
|
var HANGING_SPACE = /[^\S\r\n\u00a0\u202f\ufeff]/u;
|
|
5175
|
+
var SCRIPT_WIDTH_FACTORS = [
|
|
5176
|
+
[/\p{Script=Tamil}/u, 1.53],
|
|
5177
|
+
[/\p{Script=Malayalam}/u, 1.76],
|
|
5178
|
+
[/\p{Script=Sinhala}/u, 1.44],
|
|
5179
|
+
[/\p{Script=Myanmar}/u, 1.18],
|
|
5180
|
+
[/\p{Script=Ethiopic}/u, 1.13],
|
|
5181
|
+
[/\p{Script=Georgian}/u, 1.28]
|
|
5182
|
+
];
|
|
4575
5183
|
function measureText(text2, fontSize) {
|
|
4576
5184
|
let units = 0;
|
|
4577
5185
|
for (const character of text2) {
|
|
4578
|
-
if (/\p{
|
|
4579
|
-
|
|
5186
|
+
if (/\p{Mn}|\p{Me}|\u200d|\ufe0f/u.test(character)) continue;
|
|
5187
|
+
if (/\p{Mc}/u.test(character) && /\p{Script=Latin}|\p{Script=Han}|\p{Script=Hangul}|\p{Script=Hiragana}|\p{Script=Katakana}/u.test(character)) continue;
|
|
5188
|
+
const base = character === " " ? 0.32 : /[A-Z0-9]/.test(character) ? 0.62 : character.codePointAt(0) > 11904 ? 1 : 0.54;
|
|
5189
|
+
const factor = SCRIPT_WIDTH_FACTORS.find(([script]) => script.test(character))?.[1] ?? 1;
|
|
5190
|
+
units += base * factor;
|
|
4580
5191
|
}
|
|
4581
5192
|
return units * fontSize;
|
|
4582
5193
|
}
|
|
@@ -5067,19 +5678,19 @@ function fitSourceText(text2, box, size, minimum, step, measure, prose = false,
|
|
|
5067
5678
|
const layout = (fontSize) => {
|
|
5068
5679
|
const tabWidth = measure(" ", fontSize) * 4;
|
|
5069
5680
|
if (!Number.isFinite(tabWidth) || text2.includes(" ") && tabWidth <= 0) throw new RangeError("Text tabs require a positive finite measured space advance.");
|
|
5070
|
-
const measureLine = (start2, end2,
|
|
5681
|
+
const measureLine = (start2, end2, record9 = false) => {
|
|
5071
5682
|
let x = 0, offset = start2;
|
|
5072
5683
|
const segments = [];
|
|
5073
5684
|
for (const [index, segment2] of text2.slice(start2, end2).split(" ").entries()) {
|
|
5074
5685
|
if (index) {
|
|
5075
5686
|
const next = (Math.floor(x / tabWidth + 1e-9) + 1) * tabWidth;
|
|
5076
|
-
if (
|
|
5687
|
+
if (record9) segments.push({ kind: "tab", start: offset, end: offset + 1, x, width: next - x });
|
|
5077
5688
|
x = next;
|
|
5078
5689
|
offset++;
|
|
5079
5690
|
}
|
|
5080
5691
|
if (segment2) {
|
|
5081
5692
|
const advance = measure(segment2, fontSize);
|
|
5082
|
-
if (
|
|
5693
|
+
if (record9) segments.push({ kind: "text", start: offset, end: offset + segment2.length, x, width: advance });
|
|
5083
5694
|
x += advance;
|
|
5084
5695
|
offset += segment2.length;
|
|
5085
5696
|
}
|
|
@@ -5436,12 +6047,12 @@ function fitList(input, box, requestedSize = 25, minFontSize = 16, options = { s
|
|
|
5436
6047
|
function contentText(field, value) {
|
|
5437
6048
|
if (field === "text" || headings.has(field)) return flatten(value);
|
|
5438
6049
|
if (field === "items" || field === "bullets") return (Array.isArray(value) ? value : [value]).map((item) => {
|
|
5439
|
-
const entry =
|
|
6050
|
+
const entry = record8(item);
|
|
5440
6051
|
return `\u2022 ${flatten(item)}${entry.description ? `
|
|
5441
6052
|
${flatten(entry.description)}` : ""}`;
|
|
5442
6053
|
}).join("\n");
|
|
5443
|
-
if (field === "code") return flatten(
|
|
5444
|
-
if (field === "quote") return flatten(
|
|
6054
|
+
if (field === "code") return flatten(record8(value).source ?? value);
|
|
6055
|
+
if (field === "quote") return flatten(record8(value).text ?? value);
|
|
5445
6056
|
return void 0;
|
|
5446
6057
|
}
|
|
5447
6058
|
function layoutTable(value, box, options = {}) {
|
|
@@ -5512,7 +6123,7 @@ function flatten(value) {
|
|
|
5512
6123
|
if (value == null) return "";
|
|
5513
6124
|
if (typeof value !== "object") return String(value);
|
|
5514
6125
|
if (Array.isArray(value)) return value.map(flatten).join("");
|
|
5515
|
-
const item =
|
|
6126
|
+
const item = record8(value);
|
|
5516
6127
|
return flatten(item.text ?? item.value ?? item.source ?? JSON.stringify(value));
|
|
5517
6128
|
}
|
|
5518
6129
|
function regionParts(key) {
|
|
@@ -5567,16 +6178,43 @@ function assertComposition(value) {
|
|
|
5567
6178
|
if (value.weights !== void 0 && (!Array.isArray(value.weights) || !value.weights.length || value.weights.length > 12 || value.weights.some((weight) => !Number.isFinite(weight) || weight <= 0 || weight > 100))) throw new RangeError("Invalid composition.weights.");
|
|
5568
6179
|
if (value.overflow !== void 0 && !["warn", "error"].includes(value.overflow)) throw new RangeError("Invalid composition.overflow.");
|
|
5569
6180
|
}
|
|
6181
|
+
var LAYOUT_MASTER = /* @__PURE__ */ Symbol("opf.layoutMaster");
|
|
6182
|
+
function mergeListColumns(columns2) {
|
|
6183
|
+
const fits = columns2.map((column) => column.text), first = fits[0];
|
|
6184
|
+
const directions = fits.flatMap((fit) => fit.directions ?? []);
|
|
6185
|
+
return { ...first, listEntries: fits.flatMap((fit) => fit.listEntries), lines: fits.flatMap((fit) => fit.lines), height: Math.max(...fits.map((fit) => fit.height)), overflow: fits.some((fit) => fit.overflow), ...first.directions ? { directions } : {} };
|
|
6186
|
+
}
|
|
6187
|
+
function composeLayoutAreas(layout, options = {}) {
|
|
6188
|
+
const template = layoutTemplate(layout), source = record8(layout);
|
|
6189
|
+
const kept = { ...source, regions: Object.fromEntries(Object.entries(record8(source.regions)).map(([name, value]) => [name, { ...record8(value), empty: "keep" }])) };
|
|
6190
|
+
const { mirror, bleed = true, placements = [], ...compose } = options;
|
|
6191
|
+
const slide = {
|
|
6192
|
+
...template.title ? { title: "Title", subtitle: "Subtitle" } : {},
|
|
6193
|
+
...placements.length ? { blocks: placements.map((placement) => ({ image: "https://example.invalid/placeholder.png", placement: { ...placement } })) } : {},
|
|
6194
|
+
...mirror !== void 0 ? { design: { mirror } } : {}
|
|
6195
|
+
};
|
|
6196
|
+
const result = composeSlide(slide, { ...compose, layout: kept, [LAYOUT_MASTER]: true });
|
|
6197
|
+
const areas = template.areas.map((area) => {
|
|
6198
|
+
if (area.heading) {
|
|
6199
|
+
const found = result.headingAreas?.find((entry) => entry.name === area.name);
|
|
6200
|
+
return { name: area.name, heading: true, box: found ? { ...found.box } : { x: 0, y: 0, width: 0, height: 0 }, ...found?.parts ? { parts: found.parts } : {} };
|
|
6201
|
+
}
|
|
6202
|
+
const region = result.regions.find((entry) => entry.name === area.name);
|
|
6203
|
+
return { name: area.name, heading: false, box: { ...!bleed && region.areaBox ? region.areaBox : region.box } };
|
|
6204
|
+
});
|
|
6205
|
+
return { contentBox: { ...result.contentBox }, areas };
|
|
6206
|
+
}
|
|
5570
6207
|
function composeSlide(input, options = {}) {
|
|
5571
|
-
const slide =
|
|
6208
|
+
const slide = record8(input), layout = record8(options.layout);
|
|
5572
6209
|
const width = options.width ?? 1280, height = options.height ?? 720;
|
|
5573
6210
|
if (![width, height].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Canvas dimensions must be finite and positive.");
|
|
5574
6211
|
const scale = Math.min(width, height) / 720;
|
|
5575
6212
|
const deckDirection = options.direction ?? resolveSlideDirection(options.presentation, options.slideIndex);
|
|
5576
6213
|
const rtl = deckDirection === "rtl", textDirection = rtl ? "rtl" : void 0;
|
|
5577
|
-
const
|
|
6214
|
+
const template = isLayoutTemplate(layout) ? layoutTemplate(layout) : void 0;
|
|
6215
|
+
const hints = resolveDesignHints({ slide, layout, theme: { design: options.themeDesign }, presentation: options.presentation, slideIndex: options.slideIndex, deck: { titleAlignment: options.titleAlignment, contentAlignment: options.contentAlignment, contentBox: options.contentBox } });
|
|
5578
6216
|
const hasCards = hints.contentBox ?? false;
|
|
5579
|
-
const composition = { ...
|
|
6217
|
+
const composition = { ...record8(layout.composition), ...record8(slide.composition) };
|
|
5580
6218
|
assertComposition(composition);
|
|
5581
6219
|
const padding = (composition.padding ?? 0.08) * Math.min(width, height);
|
|
5582
6220
|
const gap = (composition.gap ?? 1 / 30) * Math.min(width, height);
|
|
@@ -5657,17 +6295,15 @@ function composeSlide(input, options = {}) {
|
|
|
5657
6295
|
const mirrorSide = (side) => !rtl ? side : side === "left" ? "right" : side === "right" ? "left" : side;
|
|
5658
6296
|
const backgroundImage = resolveBackgroundImage(slide, options.presentation, options.themeBackground, width, height, path, mirrorSide, imageDiagnostics);
|
|
5659
6297
|
const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
|
|
5660
|
-
const assets =
|
|
6298
|
+
const assets = record8(options.presentation).assets;
|
|
5661
6299
|
const imageContext = (placement) => ({ fit: hints.imageFit, scale, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
|
|
5662
6300
|
const area = { left: 0, top: 0, right: width, bottom: height };
|
|
5663
|
-
const
|
|
5664
|
-
const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record6(block).blocks) && record6(block).image !== void 0 ? [{ host: record6(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
|
|
6301
|
+
const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record8(block).blocks) && record8(block).image !== void 0 ? [{ host: record8(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
|
|
5665
6302
|
const placed = [], usedEdges = /* @__PURE__ */ new Set();
|
|
5666
|
-
topImages.forEach((node
|
|
5667
|
-
const
|
|
5668
|
-
const
|
|
5669
|
-
|
|
5670
|
-
if (!value || !IMAGE_EDGES.includes(value.edge)) return;
|
|
6303
|
+
topImages.forEach((node) => {
|
|
6304
|
+
const own3 = node.block !== void 0 && node.host.placement !== void 0 ? record8(node.host.placement) : void 0;
|
|
6305
|
+
const value = own3;
|
|
6306
|
+
if (!value || !IMAGE_EDGES2.includes(value.edge)) return;
|
|
5671
6307
|
const edge = mirrorSide(value.edge);
|
|
5672
6308
|
if (usedEdges.has(edge)) return;
|
|
5673
6309
|
usedEdges.add(edge);
|
|
@@ -5679,8 +6315,8 @@ function composeSlide(input, options = {}) {
|
|
|
5679
6315
|
else if (edge === "right") area.right = region.x;
|
|
5680
6316
|
else if (edge === "top") area.top += band;
|
|
5681
6317
|
else area.bottom = region.y;
|
|
5682
|
-
const placement = { edge, size, inset: value.inset === true, path:
|
|
5683
|
-
placed.push({ ...node, placement, region
|
|
6318
|
+
const placement = { edge, size, inset: value.inset === true, path: `${node.hostPath}.placement` };
|
|
6319
|
+
placed.push({ ...node, placement, region });
|
|
5684
6320
|
});
|
|
5685
6321
|
const placedBlocks = new Set(placed.flatMap((entry) => entry.block !== void 0 ? [entry.block] : []));
|
|
5686
6322
|
const placedRoot = placed.some((entry) => entry.block === void 0);
|
|
@@ -5696,17 +6332,16 @@ function composeSlide(input, options = {}) {
|
|
|
5696
6332
|
diagnostics.push(...footnotes.diagnostics);
|
|
5697
6333
|
bodyBottom = footnotes.box.y - gap * 0.5;
|
|
5698
6334
|
}
|
|
5699
|
-
const layoutPlaceholders = Array.isArray(layout.placeholders) ? layout.placeholders : [];
|
|
5700
6335
|
const hasLayoutRecord = options.layout !== void 0 && options.layout !== null && typeof options.layout === "object";
|
|
5701
|
-
const headingOnlyLayout = layoutPlaceholders.length > 0 && layoutPlaceholders.every((placeholder) => headings.has(placeholder.type ?? "") || placeholder.type === "image" && typeof placeholder.placement === "object" && placeholder.placement !== null);
|
|
5702
6336
|
const emptyPayload = (value) => value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
|
|
5703
6337
|
const emptyHost = (host) => emptyPayload(host.blocks) && fields.every((field) => emptyPayload(host[field]));
|
|
5704
6338
|
const flowBlocks = Array.isArray(slide.blocks) ? slide.blocks.filter((_, index) => !placedBlocks.has(index)) : slide.blocks;
|
|
5705
|
-
const hasBodyPayload = regions.some((key) => !emptyHost(
|
|
5706
|
-
const
|
|
6339
|
+
const hasBodyPayload = regions.some((key) => !emptyHost(record8(slide[key]))) || !emptyPayload(flowBlocks) || fields.some((field) => !(placedRoot && field === "image") && !emptyPayload(slide[field]));
|
|
6340
|
+
const useTemplate = template !== void 0 && !regions.length;
|
|
6341
|
+
const isCover = !hasBodyPayload && (useTemplate || !hasLayoutRecord);
|
|
5707
6342
|
coverGroup = isCover;
|
|
5708
6343
|
let logo;
|
|
5709
|
-
if (isCover) {
|
|
6344
|
+
if (isCover && options[LAYOUT_MASTER] !== true) {
|
|
5710
6345
|
const resolved = resolveLogo(options.presentation, slide, { shape: "full", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
5711
6346
|
if (resolved) {
|
|
5712
6347
|
const logoHeight = 56 * scale;
|
|
@@ -5717,7 +6352,7 @@ function composeSlide(input, options = {}) {
|
|
|
5717
6352
|
}
|
|
5718
6353
|
let y = logo ? logo.box.y + logo.box.height + gap : headingTop;
|
|
5719
6354
|
const headingItems = [];
|
|
5720
|
-
for (const field of ["tag", "title", "subtitle"]) {
|
|
6355
|
+
for (const field of useTemplate ? [] : ["tag", "title", "subtitle"]) {
|
|
5721
6356
|
if (!slide[field] || Array.isArray(slide[field]) && !annotationText(slide[field])) continue;
|
|
5722
6357
|
const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
|
|
5723
6358
|
const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
|
|
@@ -5769,7 +6404,7 @@ function composeSlide(input, options = {}) {
|
|
|
5769
6404
|
const collect = (host, basePath, depth = 0, ancestors = []) => {
|
|
5770
6405
|
if (Array.isArray(host.blocks)) {
|
|
5771
6406
|
if (depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(host)) throw new RangeError(`Content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels.`);
|
|
5772
|
-
const settings =
|
|
6407
|
+
const settings = record8(host.composition);
|
|
5773
6408
|
assertComposition(settings);
|
|
5774
6409
|
return [{
|
|
5775
6410
|
field: "blocks",
|
|
@@ -5778,7 +6413,7 @@ function composeSlide(input, options = {}) {
|
|
|
5778
6413
|
path: basePath,
|
|
5779
6414
|
payload: host,
|
|
5780
6415
|
composition: settings,
|
|
5781
|
-
children: host.blocks.flatMap((block, index) => collect(
|
|
6416
|
+
children: host.blocks.flatMap((block, index) => collect(record8(block), `${basePath}.blocks.${index}`, depth + 1, [...ancestors, host]))
|
|
5782
6417
|
}];
|
|
5783
6418
|
}
|
|
5784
6419
|
const captioned = host.caption !== void 0 ? fields.filter((field) => host[field] !== void 0 && CAPTIONABLE_FIELDS.includes(field)) : [];
|
|
@@ -5788,27 +6423,27 @@ function composeSlide(input, options = {}) {
|
|
|
5788
6423
|
type: host.type ?? kind(field),
|
|
5789
6424
|
value: fieldValue(field),
|
|
5790
6425
|
path: `${basePath}.${field}`,
|
|
5791
|
-
payload: field === "image" ? imagePayload(host) : { type: host.type ?? kind(field), [field]: fieldValue(field), ...host.numbering !== void 0 && (field === "items" || field === "bullets") ? { numbering: host.numbering } : {} },
|
|
6426
|
+
payload: field === "image" ? imagePayload(host) : { type: host.type ?? kind(field), [field]: fieldValue(field), ...host.numbering !== void 0 && (field === "items" || field === "bullets") ? { numbering: host.numbering } : {}, ...host.columns !== void 0 && (field === "items" || field === "bullets") ? { columns: host.columns } : {} },
|
|
5792
6427
|
...field === "image" ? { host, hostPath: basePath } : {},
|
|
5793
6428
|
...captioned.length === 1 && captioned[0] === field ? { caption: host.caption, captionPath: `${basePath}.caption` } : {}
|
|
5794
6429
|
}));
|
|
5795
6430
|
};
|
|
5796
6431
|
const regionsInReadingOrder = visualReadingOrder(regions.map((key) => ({ key, box: regionBox(regionParts(key), contentBox, gap) }))).map((entry) => entry.key);
|
|
5797
|
-
const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(
|
|
6432
|
+
const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(record8(slide[key]), `${path}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => placedBlocks.has(index) ? [] : collect(record8(block), `${path}.blocks.${index}`)) : collect(placedRoot ? { ...slide, image: void 0 } : slide, path);
|
|
5798
6433
|
const groups = [], flows = [];
|
|
5799
6434
|
const decisions = options.explain ? [] : void 0;
|
|
5800
|
-
const inheritedSettings = (parent,
|
|
6435
|
+
const inheritedSettings = (parent, own3 = {}) => ({
|
|
5801
6436
|
minFontSize: parent.minFontSize,
|
|
5802
|
-
...
|
|
5803
|
-
overflow: parent.overflow === "error" ? "error" :
|
|
6437
|
+
...own3,
|
|
6438
|
+
overflow: parent.overflow === "error" ? "error" : own3.overflow ?? parent.overflow
|
|
5804
6439
|
});
|
|
5805
6440
|
const inset = (box, settings) => {
|
|
5806
6441
|
const amount = (settings.padding ?? 0) * Math.min(box.width, box.height);
|
|
5807
6442
|
return { x: box.x + amount, y: box.y + amount, width: box.width - amount * 2, height: box.height - amount * 2 };
|
|
5808
6443
|
};
|
|
5809
6444
|
const acceptedBox = (box) => ({ x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) });
|
|
5810
|
-
const payloadBox = (box) => {
|
|
5811
|
-
if (!
|
|
6445
|
+
const payloadBox = (box, cards = hasCards) => {
|
|
6446
|
+
if (!cards) return box;
|
|
5812
6447
|
const frame = acceptedBox(box), padding2 = Math.min(12 * scale, frame.width / 4, frame.height / 4);
|
|
5813
6448
|
return acceptedBox({ x: frame.x + padding2, y: frame.y + padding2, width: frame.width - 2 * padding2, height: frame.height - 2 * padding2 });
|
|
5814
6449
|
};
|
|
@@ -5892,24 +6527,13 @@ function composeSlide(input, options = {}) {
|
|
|
5892
6527
|
};
|
|
5893
6528
|
const scoreNode = (node, box, settings, penalties) => {
|
|
5894
6529
|
if (!node.children) return leafScore(node, box, settings, penalties);
|
|
5895
|
-
const
|
|
5896
|
-
const cols = defaultColumns(slotCount, area2,
|
|
5897
|
-
const boxes = gridBoxes(slotCount, area2, cols, (
|
|
5898
|
-
return node.children.reduce((score, child, index) => score + scoreNode(child, boxes[index],
|
|
6530
|
+
const own3 = inheritedSettings(settings, node.composition), area2 = inset(box, own3), slotCount = Math.max(node.children.length, 0);
|
|
6531
|
+
const cols = defaultColumns(slotCount, area2, own3);
|
|
6532
|
+
const boxes = gridBoxes(slotCount, area2, cols, (own3.gap ?? 1 / 30) * Math.min(box.width, box.height), own3.weights ?? [], modeFor(own3) === "column");
|
|
6533
|
+
return node.children.reduce((score, child, index) => score + scoreNode(child, boxes[index], own3, penalties), 0);
|
|
5899
6534
|
};
|
|
5900
|
-
const
|
|
5901
|
-
|
|
5902
|
-
const box = boxes[index];
|
|
5903
|
-
if (!box) return;
|
|
5904
|
-
slots.push({ path: entry.path, type: entry.type, depth: entry.depth, box: acceptedBox(box) });
|
|
5905
|
-
if (!entry.children) return;
|
|
5906
|
-
const own2 = inheritedSettings(settings, record6(entry.placeholder.composition)), inner = inset(box, own2);
|
|
5907
|
-
const cols = defaultColumns(entry.children.length, inner, own2);
|
|
5908
|
-
const mirror = (cell) => rtl ? { ...cell, x: inner.x + inner.width - (cell.x - inner.x) - cell.width } : cell;
|
|
5909
|
-
emptySlots(entry.children, gridBoxes(entry.children.length, inner, cols, (own2.gap ?? 1 / 30) * Math.min(box.width, box.height), own2.weights ?? [], modeFor(own2) === "column").map(mirror), own2);
|
|
5910
|
-
});
|
|
5911
|
-
const arrange = (nodes, area2, settings, reserved = 0, gapOverride, containerPath = path, recorded = true, template) => {
|
|
5912
|
-
const count = Math.max(nodes.length, reserved);
|
|
6535
|
+
const arrange = (nodes, area2, settings, reserved2 = 0, gapOverride, containerPath = path, recorded = true) => {
|
|
6536
|
+
const count = Math.max(nodes.length, reserved2);
|
|
5913
6537
|
if (!count) return;
|
|
5914
6538
|
const mode = modeFor(settings), localGap = (settings.gap ?? 1 / 30) * Math.min(area2.width, area2.height);
|
|
5915
6539
|
const actualGap = gapOverride ?? (settings === rootSettings ? gap : localGap);
|
|
@@ -5920,9 +6544,9 @@ function composeSlide(input, options = {}) {
|
|
|
5920
6544
|
let best = Infinity;
|
|
5921
6545
|
for (let candidate = 1; candidate <= Math.min(count, settings.columns ?? 6); candidate++) {
|
|
5922
6546
|
const boxes2 = gridBoxes(count, area2, candidate, actualGap, settings.weights ?? [], false);
|
|
5923
|
-
const
|
|
5924
|
-
const penalties = candidates ? { cellProportions: 0, fontReduction: 0, textOverflow: 0, tableOverflow: 0, smallCells: 0, emptySlots
|
|
5925
|
-
const score = nodes.reduce((sum, node, i) => sum + scoreNode(node, boxes2[i], settings, penalties), 0) +
|
|
6547
|
+
const emptySlots = (Math.ceil(count / candidate) * candidate - count) * 2;
|
|
6548
|
+
const penalties = candidates ? { cellProportions: 0, fontReduction: 0, textOverflow: 0, tableOverflow: 0, smallCells: 0, emptySlots } : void 0;
|
|
6549
|
+
const score = nodes.reduce((sum, node, i) => sum + scoreNode(node, boxes2[i], settings, penalties), 0) + emptySlots;
|
|
5926
6550
|
if (penalties && candidates) candidates.push({ columns: candidate, rows: Math.ceil(count / candidate), score, penalties });
|
|
5927
6551
|
if (score < best) {
|
|
5928
6552
|
best = score;
|
|
@@ -5940,114 +6564,370 @@ function composeSlide(input, options = {}) {
|
|
|
5940
6564
|
const grid = gridGeometry(count, area2, cols, actualGap, settings.weights ?? [], mode === "column");
|
|
5941
6565
|
const mirrored = (box) => rtl ? { ...box, x: area2.x + area2.width - (box.x - area2.x) - box.width } : box;
|
|
5942
6566
|
const boxes = grid.boxes.map(mirrored);
|
|
5943
|
-
if (template) emptySlots(template.slice(nodes.length), boxes.slice(nodes.length), settings);
|
|
5944
6567
|
if (recorded && !hasRegions) flows.push({ path: containerPath, box: { ...area2 }, composition: { ...settings }, columns: rtl ? grid.columns.map((track) => ({ offset: area2.width - track.offset - track.size, size: track.size })) : grid.columns, rows: grid.rows, gap: grid.gap, itemCount: nodes.length, slotCount: count });
|
|
5945
6568
|
nodes.forEach((node, index) => {
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
6569
|
+
const box = node.region ? mirrored(regionBox(node.region, area2, actualGap)) : boxes[index];
|
|
6570
|
+
placeNode(node, box, settings);
|
|
6571
|
+
});
|
|
6572
|
+
};
|
|
6573
|
+
let regionTag, templateCell = false;
|
|
6574
|
+
const placeNode = (node, box, settings, cards = hasCards, listColumns) => {
|
|
6575
|
+
if (node.children) {
|
|
6576
|
+
const own3 = inheritedSettings(settings, node.composition), inner = inset(box, own3);
|
|
6577
|
+
if (!node.synthetic) groups.push({ path: node.path, box, contentBox: inner, composition: own3 });
|
|
6578
|
+
arrange(node.children, inner, own3, 0, (own3.gap ?? 1 / 30) * Math.min(box.width, box.height), node.path, !node.synthetic);
|
|
6579
|
+
return;
|
|
6580
|
+
}
|
|
6581
|
+
const frameBox = cards ? acceptedBox(box) : void 0;
|
|
6582
|
+
box = payloadBox(box, cards);
|
|
6583
|
+
const caption = captionOf(node, box);
|
|
6584
|
+
if (caption) {
|
|
6585
|
+
box = caption.mediaBox;
|
|
6586
|
+
diagnostics.push(...caption.diagnostics);
|
|
6587
|
+
}
|
|
6588
|
+
const textValue = contentText(node.field, node.value);
|
|
6589
|
+
const quoteLayout = node.field === "quote" ? measureQuote(node, box, settings) : void 0;
|
|
6590
|
+
const codeLayout = node.field === "code" ? measureCode(node, box, settings) : void 0;
|
|
6591
|
+
const metricLayout = node.field === "metric" ? measureMetric(node, box, settings) : void 0;
|
|
6592
|
+
const timelineLayout = node.field === "timeline" ? measureTimeline(node, box, settings) : void 0;
|
|
6593
|
+
const internal = quoteLayout ?? codeLayout ?? metricLayout ?? timelineLayout, body = internal?.parts.find((part) => part.role === "body" || part.role === "value");
|
|
6594
|
+
const columns2 = textValue !== void 0 && !internal ? listColumnsFor(node, box, settings, listColumns) : void 0;
|
|
6595
|
+
const text2 = internal ? body?.fit : columns2 ? columns2.length > 1 ? mergeListColumns(columns2) : columns2[0].text : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, 25 * scale, snapFontSizeUp((settings.minFontSize ?? 16) * scale), node.path, node.payload.numbering) : void 0;
|
|
6596
|
+
const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext()) : void 0;
|
|
6597
|
+
items.push({
|
|
6598
|
+
path: node.path,
|
|
6599
|
+
field: node.field,
|
|
6600
|
+
type: node.type,
|
|
6601
|
+
value: node.value,
|
|
6602
|
+
payload: node.payload,
|
|
6603
|
+
box: internal ? acceptedBox(box) : box,
|
|
6604
|
+
...image ? { image } : {},
|
|
6605
|
+
...frameBox ? { frameBox } : {},
|
|
6606
|
+
text: text2,
|
|
6607
|
+
textStyle: body?.style ?? styleFor(node.field, node.path),
|
|
6608
|
+
composition: settings,
|
|
6609
|
+
alignment: alignmentFor(node.field),
|
|
6610
|
+
...quoteLayout ? { quoteLayout } : {},
|
|
6611
|
+
...codeLayout ? { codeLayout } : {},
|
|
6612
|
+
...metricLayout ? { metricLayout } : {},
|
|
6613
|
+
...timelineLayout ? { timelineLayout } : {},
|
|
6614
|
+
...bulletImage && node.payload.numbering === void 0 && (node.field === "items" || node.field === "bullets") ? { bulletImage } : {},
|
|
6615
|
+
...caption ? { caption } : {},
|
|
6616
|
+
...regionTag !== void 0 ? { region: regionTag } : {},
|
|
6617
|
+
...columns2 && columns2.length > 1 ? { listColumns: columns2 } : {}
|
|
6618
|
+
});
|
|
6619
|
+
if (box.width < 100 * scale || !templateCell && box.height < 60 * scale) diagnostics.push({ code: "small-cell", path: node.path, message: "Content cell is too small for comfortable reading; use fewer blocks or a different composition." });
|
|
6620
|
+
};
|
|
6621
|
+
const listColumnsFor = (node, box, settings, regionMode) => {
|
|
6622
|
+
if (node.field !== "items" && node.field !== "bullets") return void 0;
|
|
6623
|
+
const values = node.value;
|
|
6624
|
+
if (!Array.isArray(values) || values.length < 2) return void 0;
|
|
6625
|
+
const own3 = node.payload.columns;
|
|
6626
|
+
const mode = own3 === "auto" || own3 === 1 || own3 === 2 || own3 === 3 ? own3 : regionMode;
|
|
6627
|
+
if (mode === void 0 || mode === 1) return void 0;
|
|
6628
|
+
const start = 25 * scale, floor = snapFontSizeUp((settings.minFontSize ?? 16) * scale);
|
|
6629
|
+
const numbering = node.payload.numbering;
|
|
6630
|
+
const listOptions = { ...richOptions(styleFor(node.field, node.path)), ...numbering !== void 0 ? { numbering } : bulletImage ? { bulletImage } : {} };
|
|
6631
|
+
const columnGap = (count2) => Math.min(gap, box.width / (count2 * 2));
|
|
6632
|
+
const columnBoxes = (count2) => {
|
|
6633
|
+
const between = columnGap(count2), columnWidth = (box.width - between * (count2 - 1)) / count2;
|
|
6634
|
+
const ordered = Array.from({ length: count2 }, (_, index) => ({ x: box.x + index * (columnWidth + between), y: box.y, width: columnWidth, height: box.height }));
|
|
6635
|
+
return rtl ? ordered.map((cell) => ({ ...cell, x: box.x + box.width - (cell.x - box.x) - cell.width })) : ordered;
|
|
6636
|
+
};
|
|
6637
|
+
const chunk = (from, to) => numbering !== void 0 ? sliceNumberedItems(values, numbering, from, to) : values.slice(from, to);
|
|
6638
|
+
const sourcePaths = (index) => {
|
|
6639
|
+
const source = values[index], object2 = source !== null && typeof source === "object" && !Array.isArray(source);
|
|
6640
|
+
return { textPath: `${node.path}.${index}${object2 ? ".text" : ""}`, descriptionPath: `${node.path}.${index}.description` };
|
|
6641
|
+
};
|
|
6642
|
+
const renumber = (fit, from) => ({ ...fit, listEntries: fit.listEntries.map((entry) => ({ ...entry, index: entry.index + from, ...sourcePaths(entry.index + from) })) });
|
|
6643
|
+
const split = (count2, size2, minimum) => {
|
|
6644
|
+
const boxes = columnBoxes(count2);
|
|
6645
|
+
const whole = fitList(values, { ...boxes[0], height: 1e6 }, start, start, listOptions);
|
|
6646
|
+
const first = whole.listEntries[0].textBox.y;
|
|
6647
|
+
const heights = whole.listEntries.map((entry, index) => (whole.listEntries[index + 1]?.textBox.y ?? first + whole.height) - entry.textBox.y);
|
|
6648
|
+
const breaks = [0, ...listColumnBreaks(heights, whole.listEntries.map((entry) => entry.level), count2), values.length];
|
|
6649
|
+
return boxes.slice(0, breaks.length - 1).map((cell, index) => ({ box: cell, start: breaks[index], end: breaks[index + 1], text: renumber(fitList(chunk(breaks[index], breaks[index + 1]), cell, size2, minimum, listOptions), breaks[index]) }));
|
|
6650
|
+
};
|
|
6651
|
+
const quarter = width / 4;
|
|
6652
|
+
const counts = typeof mode === "number" ? [mode] : [2, 3].filter((count2) => (box.width - columnGap(count2) * (count2 - 1)) / count2 >= quarter);
|
|
6653
|
+
if (mode === "auto") {
|
|
6654
|
+
if (!fitList(values, box, start, start, listOptions).overflow) return void 0;
|
|
6655
|
+
for (const count2 of counts) {
|
|
6656
|
+
const columns2 = split(count2, start, start);
|
|
6657
|
+
if (columns2.every((column) => !column.text.overflow)) return columns2;
|
|
6658
|
+
}
|
|
6659
|
+
}
|
|
6660
|
+
const count = counts.at(-1);
|
|
6661
|
+
if (count === void 0) return void 0;
|
|
6662
|
+
const shrunk = split(count, start, floor);
|
|
6663
|
+
const size = Math.min(...shrunk.map((column) => column.text.fontSize));
|
|
6664
|
+
return shrunk.map((column) => ({ ...column, text: renumber(fitList(chunk(column.start, column.end), column.box, size, size, listOptions), column.start) }));
|
|
6665
|
+
};
|
|
6666
|
+
const LONG_LINES = 6, LONG_CODE_LINES = 12, startSize = 25 * scale;
|
|
6667
|
+
const estimatedLines = (value, cellWidth, size) => flatten(value).split("\n").reduce((sum, paragraph) => sum + Math.max(1, wrapText(paragraph, Math.max(1, cellWidth), size).length), 0);
|
|
6668
|
+
const isLong = (node, cellWidth) => {
|
|
6669
|
+
if (node.children) return node.children.some((child) => isLong(child, cellWidth));
|
|
6670
|
+
if (node.field === "text") return estimatedLines(node.value, cellWidth, startSize) > LONG_LINES;
|
|
6671
|
+
if (node.field === "items" || node.field === "bullets") {
|
|
6672
|
+
let lines = 0;
|
|
6673
|
+
for (const entry of Array.isArray(node.value) ? node.value : []) {
|
|
6674
|
+
const object2 = entry !== null && typeof entry === "object" && !Array.isArray(entry) ? entry : void 0;
|
|
6675
|
+
const indent = startSize * 1.1 * (1 + (typeof object2?.level === "number" ? object2.level : 0));
|
|
6676
|
+
lines += estimatedLines(object2 ? object2.text : entry, cellWidth - indent, startSize);
|
|
6677
|
+
if (object2?.description !== void 0) lines += estimatedLines(object2.description, cellWidth - indent, startSize * 0.82);
|
|
6678
|
+
}
|
|
6679
|
+
return lines > LONG_LINES;
|
|
6680
|
+
}
|
|
6681
|
+
if (node.field === "quote") return estimatedLines(typeof node.value === "string" ? node.value : record8(node.value).text, cellWidth, startSize) > LONG_LINES;
|
|
6682
|
+
if (node.field === "table") {
|
|
6683
|
+
const value = record8(node.value);
|
|
6684
|
+
return (Array.isArray(value.rows) ? value.rows.length + (Array.isArray(value.columns) ? 1 : 0) : 0) > LONG_LINES;
|
|
6685
|
+
}
|
|
6686
|
+
if (node.field === "code") return String(typeof node.value === "string" ? node.value : record8(node.value).source ?? "").split("\n").length > LONG_CODE_LINES;
|
|
6687
|
+
return false;
|
|
6688
|
+
};
|
|
6689
|
+
const naturalHeight = (node, cellWidth, cards) => {
|
|
6690
|
+
const pad = cards ? 2 * Math.min(12 * scale, cellWidth / 4) : 0, inner = Math.max(scale, cellWidth - pad);
|
|
6691
|
+
if (node.children) return node.children.reduce((sum, child) => sum + naturalHeight(child, cellWidth, false), 0) + gap * Math.max(0, node.children.length - 1) + pad;
|
|
6692
|
+
let content;
|
|
6693
|
+
if (node.field === "text" || node.field === "items" || node.field === "bullets") {
|
|
6694
|
+
const fit = fitContent(node.field, node.value, contentText(node.field, node.value) ?? "", { x: 0, y: 0, width: inner, height: 1e6 }, startSize, startSize, node.path, node.payload.numbering);
|
|
6695
|
+
content = "height" in fit && typeof fit.height === "number" ? fit.height : fit.lines.length * fit.lineHeight;
|
|
6696
|
+
} else if (node.field === "quote") content = estimatedLines(typeof node.value === "string" ? node.value : record8(node.value).text, inner, 32 * scale) * 32 * 1.22 * scale + 2 * 20 * 1.22 * scale;
|
|
6697
|
+
else if (node.field === "code") content = String(typeof node.value === "string" ? node.value : record8(node.value).source ?? "").split("\n").length * 18 * 1.4 * scale + 24 * scale;
|
|
6698
|
+
else if (node.field === "metric") content = 150 * scale;
|
|
6699
|
+
else if (node.field === "timeline") content = 170 * scale;
|
|
6700
|
+
else if (node.field === "table") {
|
|
6701
|
+
const value = record8(node.value);
|
|
6702
|
+
content = ((Array.isArray(value.rows) ? value.rows.length : 4) + 1) * 36 * scale;
|
|
6703
|
+
} else content = inner / 1.6;
|
|
6704
|
+
return content + (node.caption !== void 0 ? 32 * scale : 0) + pad;
|
|
6705
|
+
};
|
|
6706
|
+
const templateRegions = [], headingAreas = [];
|
|
6707
|
+
const requestedTemplateGap = gap;
|
|
6708
|
+
const composeTemplate = () => {
|
|
6709
|
+
const plan2 = template, frame = contentBox;
|
|
6710
|
+
const binding = bindRegions(slide, layout, { slideIndex: options.slideIndex ?? 0 });
|
|
6711
|
+
for (const entry of binding.diagnostics) diagnostics.push({ code: entry.code, path: entry.path, message: entry.message, ...entry.region !== void 0 ? { region: entry.region } : {} });
|
|
6712
|
+
const unitOf = (bound) => {
|
|
6713
|
+
const host = bound.block !== void 0 ? record8(slide.blocks[bound.block]) : { ...Object.fromEntries((bound.fields ?? []).map((field) => [field, slide[field]])), ...Object.fromEntries(["type", "caption", "numbering"].filter((key) => slide[key] !== void 0).map((key) => [key, slide[key]])) };
|
|
6714
|
+
const parts = collect(host, bound.block !== void 0 ? `${path}.blocks.${bound.block}` : path);
|
|
6715
|
+
return parts.length === 1 ? parts[0] : { field: "blocks", type: "group", value: parts.map((part) => part.payload), path: bound.path, payload: {}, children: parts, composition: { mode: "column" }, synthetic: true };
|
|
6716
|
+
};
|
|
6717
|
+
const contents = new Map(binding.regions.map((entry) => [entry.name, [...entry.blocks, ...entry.overflow].map(unitOf)]));
|
|
6718
|
+
const BELOW = "(below)";
|
|
6719
|
+
const belowUnits = binding.below.map(unitOf);
|
|
6720
|
+
const belowRegion = { name: BELOW, accepts: [], role: "supporting", flow: "auto", max: belowUnits.length, bleed: false, listColumns: 1, anchor: "top", empty: "collapse" };
|
|
6721
|
+
const unitsOf = (name) => name === BELOW ? belowUnits : contents.get(name) ?? [];
|
|
6722
|
+
const shown = (field) => !!slide[field] && !(Array.isArray(slide[field]) && !annotationText(slide[field]));
|
|
6723
|
+
const titleFields = ["tag", "title", ...plan2.subtitle ? [] : ["subtitle"]].filter(shown);
|
|
6724
|
+
const subtitleFields = plan2.subtitle && shown("subtitle") ? ["subtitle"] : [];
|
|
6725
|
+
const columnCount = plan2.columns.length;
|
|
6726
|
+
const cells = plan2.grid.map((row) => [...row]);
|
|
6727
|
+
const rowSizes = [...plan2.rows];
|
|
6728
|
+
const implicitTitle = !plan2.title && titleFields.length > 0;
|
|
6729
|
+
if (implicitTitle) {
|
|
6730
|
+
cells.unshift(Array.from({ length: columnCount }, () => "title"));
|
|
6731
|
+
rowSizes.unshift("auto");
|
|
6732
|
+
}
|
|
6733
|
+
if (belowUnits.length) {
|
|
6734
|
+
cells.push(Array.from({ length: columnCount }, () => BELOW));
|
|
6735
|
+
rowSizes.push("auto");
|
|
6736
|
+
}
|
|
6737
|
+
const gap2 = Math.max(0, Math.min(requestedTemplateGap, frame.width / (columnCount * 2), frame.height / (rowSizes.length * 2)));
|
|
6738
|
+
const regionOf = new Map(plan2.regions.map((region) => [region.name, region]));
|
|
6739
|
+
const empty2 = /* @__PURE__ */ new Set();
|
|
6740
|
+
for (const region of plan2.regions) if (!unitsOf(region.name).length && region.empty !== "keep") empty2.add(region.name);
|
|
6741
|
+
if (plan2.title && !titleFields.length) empty2.add("title");
|
|
6742
|
+
if (plan2.subtitle && !subtitleFields.length) empty2.add("subtitle");
|
|
6743
|
+
const collapsed = collapseAreas(cells, empty2, (name) => name === "title" || name === "subtitle", (name) => name !== BELOW);
|
|
6744
|
+
const rects = areaRects(collapsed.grid), ownRects = areaRects(cells);
|
|
6745
|
+
const widths = columnWidths(plan2.columns, frame.width, gap2);
|
|
6746
|
+
const columnX = [];
|
|
6747
|
+
widths.reduce((x, size) => {
|
|
6748
|
+
columnX.push(x);
|
|
6749
|
+
return x + size + gap2;
|
|
6750
|
+
}, 0);
|
|
6751
|
+
const spanWidth = (rect) => widths.slice(rect.column, rect.column + rect.columnSpan).reduce((a, b) => a + b, 0) + gap2 * (rect.columnSpan - 1);
|
|
6752
|
+
const headingItemsAt = (fields2, x, y2, areaWidth) => {
|
|
6753
|
+
const list = [];
|
|
6754
|
+
let top = y2;
|
|
6755
|
+
for (const field of fields2) {
|
|
6756
|
+
const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
|
|
6757
|
+
const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
|
|
6758
|
+
const box = { x, y: top, width: areaWidth, height: maxHeight };
|
|
6759
|
+
const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
|
|
6760
|
+
box.height = Math.min(maxHeight, Math.max("richLines" in text2 ? text2.height : text2.lines.length * text2.lineHeight, text2.placement?.height ?? 0));
|
|
6761
|
+
list.push({ path: `${path}.${field}`, field, type: "text", value: slide[field], payload: { text: slide[field] }, box, text: text2, textStyle: styleFor(field, `${path}.${field}`), composition, alignment: alignmentFor(field) });
|
|
6762
|
+
top += box.height + gap2 * 0.5;
|
|
6763
|
+
}
|
|
6764
|
+
return list;
|
|
6765
|
+
};
|
|
6766
|
+
const groupHeight = (list) => list.length ? list.at(-1).box.y + list.at(-1).box.height - list[0].box.y : 0;
|
|
6767
|
+
const arrangementOf = (region, units, cell) => {
|
|
6768
|
+
if (direction !== void 0 && region.flow !== "none") return direction === "horizontal" ? "row" : "column";
|
|
6769
|
+
const flow = region.flow === "none" && units.length > 1 ? "auto" : region.flow;
|
|
6770
|
+
if (flow === "none" || flow === "column") return "column";
|
|
6771
|
+
if (flow === "grid") return "grid";
|
|
6772
|
+
const shape = gridFlowShape(units.length, cell.width >= cell.height);
|
|
6773
|
+
const cards = hasCards && !region.bleed;
|
|
6774
|
+
const cellWidth = (cell.width - gap2 * (shape.columns - 1)) / shape.columns - (cards ? 2 * Math.min(12 * scale, cell.width / 4) : 0);
|
|
6775
|
+
return units.some((unit) => isLong(unit, cellWidth)) ? "column" : "grid";
|
|
6776
|
+
};
|
|
6777
|
+
const regionNeed = (name, areaWidth) => {
|
|
6778
|
+
const units = unitsOf(name), region = name === BELOW ? belowRegion : regionOf.get(name);
|
|
6779
|
+
if (!units.length) return region.empty === "keep" ? 2 * startSize * 1.22 + (hasCards && !region.bleed ? 2 * Math.min(12 * scale, areaWidth / 4) : 0) : 0;
|
|
6780
|
+
const shape = flowShape(arrangementOf(region, units, { width: areaWidth, height: areaWidth / 4 }), units.length, true);
|
|
6781
|
+
const cellWidth = (areaWidth - gap2 * (shape.columns - 1)) / shape.columns, cards = hasCards && !region.bleed;
|
|
6782
|
+
let total = 0, index = 0;
|
|
6783
|
+
for (const count of shape.perRow) {
|
|
6784
|
+
let row = 0;
|
|
6785
|
+
for (let k = 0; k < count; k++) row = Math.max(row, naturalHeight(units[index++], cellWidth, cards));
|
|
6786
|
+
total += row;
|
|
6787
|
+
}
|
|
6788
|
+
return total + gap2 * Math.max(0, shape.rows - 1);
|
|
6789
|
+
};
|
|
6790
|
+
const areaNeed = (name, rect) => name === "title" ? groupHeight(headingItemsAt(titleFields, 0, 0, spanWidth(rect))) : name === "subtitle" ? groupHeight(headingItemsAt(subtitleFields, 0, 0, spanWidth(rect))) : regionNeed(name, spanWidth(rect));
|
|
6791
|
+
const demands = rowSizes.map((size, row) => {
|
|
6792
|
+
let need = 0, heading = false, below = false;
|
|
6793
|
+
for (const [name, rect] of rects) {
|
|
6794
|
+
if (size === "auto" ? rect.row !== row || rect.rowSpan !== 1 : row < rect.row || row >= rect.row + rect.rowSpan) continue;
|
|
6795
|
+
if (size !== "auto" && rect.rowSpan > 1 && rowSizes.slice(rect.row, rect.row + rect.rowSpan).some((entry) => entry === "auto")) continue;
|
|
6796
|
+
const value = areaNeed(name, rect) / rect.rowSpan;
|
|
6797
|
+
if (value > need) {
|
|
6798
|
+
need = value;
|
|
6799
|
+
heading = name === "title" || name === "subtitle";
|
|
6800
|
+
below = name === BELOW;
|
|
5959
6801
|
}
|
|
5960
|
-
const textValue = contentText(node.field, node.value);
|
|
5961
|
-
const quoteLayout = node.field === "quote" ? measureQuote(node, box, settings) : void 0;
|
|
5962
|
-
const codeLayout = node.field === "code" ? measureCode(node, box, settings) : void 0;
|
|
5963
|
-
const metricLayout = node.field === "metric" ? measureMetric(node, box, settings) : void 0;
|
|
5964
|
-
const timelineLayout = node.field === "timeline" ? measureTimeline(node, box, settings) : void 0;
|
|
5965
|
-
const internal = quoteLayout ?? codeLayout ?? metricLayout ?? timelineLayout, body = internal?.parts.find((part) => part.role === "body" || part.role === "value");
|
|
5966
|
-
const text2 = internal ? body?.fit : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, 25 * scale, snapFontSizeUp((settings.minFontSize ?? 16) * scale), node.path, node.payload.numbering) : void 0;
|
|
5967
|
-
const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext()) : void 0;
|
|
5968
|
-
items.push({
|
|
5969
|
-
path: node.path,
|
|
5970
|
-
field: node.field,
|
|
5971
|
-
type: node.type,
|
|
5972
|
-
value: node.value,
|
|
5973
|
-
payload: node.payload,
|
|
5974
|
-
box: internal ? acceptedBox(box) : box,
|
|
5975
|
-
...image ? { image } : {},
|
|
5976
|
-
...frameBox ? { frameBox } : {},
|
|
5977
|
-
text: text2,
|
|
5978
|
-
textStyle: body?.style ?? styleFor(node.field, node.path),
|
|
5979
|
-
composition: settings,
|
|
5980
|
-
alignment: alignmentFor(node.field),
|
|
5981
|
-
...quoteLayout ? { quoteLayout } : {},
|
|
5982
|
-
...codeLayout ? { codeLayout } : {},
|
|
5983
|
-
...metricLayout ? { metricLayout } : {},
|
|
5984
|
-
...timelineLayout ? { timelineLayout } : {},
|
|
5985
|
-
...bulletImage && node.payload.numbering === void 0 && (node.field === "items" || node.field === "bullets") ? { bulletImage } : {},
|
|
5986
|
-
...caption ? { caption } : {}
|
|
5987
|
-
});
|
|
5988
|
-
if (box.width < 100 * scale || box.height < 60 * scale) diagnostics.push({ code: "small-cell", path: node.path, message: "Content cell is too small for comfortable reading; use fewer blocks or a different composition." });
|
|
5989
6802
|
}
|
|
6803
|
+
return { size, need, kind: heading ? "heading" : below ? "below" : "body" };
|
|
5990
6804
|
});
|
|
6805
|
+
const heights = allocateRows(demands, frame.height, gap2);
|
|
6806
|
+
const rowY = [];
|
|
6807
|
+
heights.reduce((y2, size, row) => {
|
|
6808
|
+
rowY.push(size > 0 || !heights.slice(0, row).some((above) => above > 0) ? y2 : y2 - gap2);
|
|
6809
|
+
return size > 0 ? y2 + size + gap2 : y2;
|
|
6810
|
+
}, 0);
|
|
6811
|
+
const logical = (rect) => {
|
|
6812
|
+
const last = rect.row + rect.rowSpan - 1, y2 = frame.y + rowY[rect.row];
|
|
6813
|
+
return { x: frame.x + columnX[rect.column], y: y2, width: spanWidth(rect), height: Math.max(0, frame.y + rowY[last] + heights[last] - y2) };
|
|
6814
|
+
};
|
|
6815
|
+
const flip = hints.mirror === true !== rtl;
|
|
6816
|
+
const physical = (cell) => flip ? { ...cell, x: frame.x + frame.width - (cell.x - frame.x) - cell.width } : cell;
|
|
6817
|
+
const bleed = (cell) => {
|
|
6818
|
+
const near = (a, b) => Math.abs(a - b) < 0.01;
|
|
6819
|
+
const left = near(cell.x, frame.x) ? area.left : cell.x, top = near(cell.y, frame.y) ? area.top : cell.y;
|
|
6820
|
+
const right = near(cell.x + cell.width, frame.x + frame.width) ? area.right : cell.x + cell.width;
|
|
6821
|
+
const bottom = near(cell.y + cell.height, frame.y + frame.height) ? area.bottom : cell.y + cell.height;
|
|
6822
|
+
return { x: left, y: top, width: right - left, height: bottom - top };
|
|
6823
|
+
};
|
|
6824
|
+
const placeHeadings = (name, fields2) => {
|
|
6825
|
+
const rect = rects.get(name), original = ownRects.get(name);
|
|
6826
|
+
if (!rect) {
|
|
6827
|
+
if (original) headingAreas.push({ name, box: roundBox(physical(logical(original))), collapsed: true });
|
|
6828
|
+
return;
|
|
6829
|
+
}
|
|
6830
|
+
const cell = physical(logical(rect));
|
|
6831
|
+
const list = headingItemsAt(fields2, cell.x, cell.y, cell.width);
|
|
6832
|
+
const centred = !rowSizes.slice(rect.row, rect.row + rect.rowSpan).every((size) => size === "auto");
|
|
6833
|
+
const shift = centred ? Math.max(0, (cell.height - groupHeight(list)) / 2) : 0;
|
|
6834
|
+
for (const item of list) {
|
|
6835
|
+
if (shift) {
|
|
6836
|
+
item.box.y += shift;
|
|
6837
|
+
if (item.text) item.text = translateTextFit(item.text, shift);
|
|
6838
|
+
}
|
|
6839
|
+
if (furniture && item.box.y + item.box.height > bodyBottom + 0.01) diagnostics.push({ code: "text-overflow", path: item.path, message: "Repeated furniture leaves too little room for this heading. Change the header/footer or slide design." });
|
|
6840
|
+
items.push(item);
|
|
6841
|
+
}
|
|
6842
|
+
let parts;
|
|
6843
|
+
const upper = list.filter((item) => item.field !== "subtitle"), lower = list.find((item) => item.field === "subtitle");
|
|
6844
|
+
if (name === "title" && !plan2.subtitle && list.length) {
|
|
6845
|
+
const bottom = cell.y + cell.height, last = upper.at(-1);
|
|
6846
|
+
const split = Math.min(bottom, lower ? lower.box.y : last.box.y + last.box.height + gap2 * 0.5);
|
|
6847
|
+
const titleBottom = Math.max(cell.y, last ? last.box.y + last.box.height : split - gap2 * 0.5);
|
|
6848
|
+
parts = { title: roundBox({ x: cell.x, y: cell.y, width: cell.width, height: titleBottom - cell.y }), subtitle: roundBox({ x: cell.x, y: split, width: cell.width, height: Math.max(0, bottom - split) }) };
|
|
6849
|
+
}
|
|
6850
|
+
headingAreas.push({ name, box: roundBox(cell), ...name === "title" && implicitTitle ? { implicit: true } : {}, ...parts ? { parts } : {} });
|
|
6851
|
+
};
|
|
6852
|
+
placeHeadings("title", titleFields);
|
|
6853
|
+
if (plan2.subtitle) placeHeadings("subtitle", subtitleFields);
|
|
6854
|
+
const slideComposition = record8(slide.composition);
|
|
6855
|
+
const overridden = ["mode", "columns", "weights"].some((key) => slideComposition[key] !== void 0) ? plan2.regions.find((region) => region.role === "primary" && region.flow !== "none")?.name : void 0;
|
|
6856
|
+
const settings = { ...composition };
|
|
6857
|
+
const placeRegion = (region, units, area2) => {
|
|
6858
|
+
regionTag = region.name === BELOW ? void 0 : region.name;
|
|
6859
|
+
const cell = { ...area2, width: Math.max(scale, area2.width), height: Math.max(scale, area2.height) };
|
|
6860
|
+
templateCell = true;
|
|
6861
|
+
try {
|
|
6862
|
+
const cards = hasCards && !region.bleed;
|
|
6863
|
+
if (region.name === overridden) {
|
|
6864
|
+
arrange(units, cell, { ...settings, mode: slideComposition.mode ?? "auto" }, 0, gap2, path, true);
|
|
6865
|
+
return "composition";
|
|
6866
|
+
}
|
|
6867
|
+
const arrangement = arrangementOf(region, units, cell);
|
|
6868
|
+
let boxes = flowCells(flowShape(arrangement, units.length, cell.width >= cell.height), cell, gap2).cells;
|
|
6869
|
+
if (arrangement === "column" && region.anchor !== "top" && units.every((unit) => !unit.children && (unit.field === "text" || unit.field === "items" || unit.field === "bullets"))) {
|
|
6870
|
+
const naturals = units.map((unit) => naturalHeight(unit, cell.width, cards) + 2 * rasterPadding + scale);
|
|
6871
|
+
const used = naturals.reduce((a, b) => a + b, 0) + gap2 * (units.length - 1);
|
|
6872
|
+
if (used < cell.height) {
|
|
6873
|
+
let y2 = cell.y + (region.anchor === "middle" ? (cell.height - used) / 2 : cell.height - used);
|
|
6874
|
+
boxes = naturals.map((size) => {
|
|
6875
|
+
const next = { x: cell.x, y: y2, width: cell.width, height: size };
|
|
6876
|
+
y2 += size + gap2;
|
|
6877
|
+
return next;
|
|
6878
|
+
});
|
|
6879
|
+
}
|
|
6880
|
+
}
|
|
6881
|
+
if (rtl) boxes = boxes.map((box) => ({ ...box, x: cell.x + cell.width - (box.x - cell.x) - box.width }));
|
|
6882
|
+
units.forEach((unit, index) => {
|
|
6883
|
+
placeNode(unit, boxes[index], settings, cards, region.listColumns);
|
|
6884
|
+
});
|
|
6885
|
+
return arrangement;
|
|
6886
|
+
} finally {
|
|
6887
|
+
regionTag = void 0;
|
|
6888
|
+
templateCell = false;
|
|
6889
|
+
}
|
|
6890
|
+
};
|
|
6891
|
+
for (const region of plan2.regions) {
|
|
6892
|
+
const units = unitsOf(region.name), bound = binding.regions.find((entry) => entry.name === region.name);
|
|
6893
|
+
const rect = rects.get(region.name);
|
|
6894
|
+
let cell = physical(logical(rect ?? ownRects.get(region.name)));
|
|
6895
|
+
const areaBox = region.bleed && rect ? roundBox(cell) : void 0;
|
|
6896
|
+
if (region.bleed && rect) cell = bleed(cell);
|
|
6897
|
+
const arrangement = units.length && rect ? placeRegion(region, units, cell) : void 0;
|
|
6898
|
+
templateRegions.push({
|
|
6899
|
+
name: region.name,
|
|
6900
|
+
box: roundBox(cell),
|
|
6901
|
+
accepts: [...region.accepts],
|
|
6902
|
+
role: region.role,
|
|
6903
|
+
flow: region.flow,
|
|
6904
|
+
max: region.max,
|
|
6905
|
+
anchor: region.anchor,
|
|
6906
|
+
...arrangement ? { arrangement } : {},
|
|
6907
|
+
content: bound.blocks.map((block) => block.path),
|
|
6908
|
+
...bound.overflow.length ? { overflow: bound.overflow.map((block) => block.path) } : {},
|
|
6909
|
+
...collapsed.joined.has(region.name) ? { collapsed: true } : {},
|
|
6910
|
+
...region.bleed ? { bleed: true } : {},
|
|
6911
|
+
...areaBox ? { areaBox } : {}
|
|
6912
|
+
});
|
|
6913
|
+
}
|
|
6914
|
+
if (belowUnits.length) placeRegion(belowRegion, belowUnits, physical(logical(rects.get(BELOW))));
|
|
5991
6915
|
};
|
|
5992
|
-
const
|
|
5993
|
-
const placedSlots = new Set(placed.flatMap((entry) => imagePlaceholders[entry.slot] ? [imagePlaceholders[entry.slot].placeholder] : []));
|
|
5994
|
-
if (placedSlots.size) {
|
|
5995
|
-
for (let index = placeholders.length - 1; index >= 0; index--) if (placedSlots.has(placeholders[index])) placeholders.splice(index, 1);
|
|
5996
|
-
}
|
|
5997
|
-
const ownMode = record6(slide.composition).mode;
|
|
6916
|
+
const ownMode = record8(slide.composition).mode;
|
|
5998
6917
|
const direction = hints.contentDirection;
|
|
5999
6918
|
const directionMode = direction === "vertical" ? "column" : direction === "horizontal" ? "row" : "auto";
|
|
6000
6919
|
const chartHint = hints.chartPrimary;
|
|
6001
6920
|
const chartSide = chartHint === "left" || chartHint === "right" || chartHint === "top" || chartHint === "bottom" ? chartHint : void 0;
|
|
6002
6921
|
const chartIndex = pending.findIndex((node) => !node.children && node.field === "chart");
|
|
6003
|
-
const chartPrimary = chartSide !== void 0 && !ownMode && !regions.length && chartIndex >= 0 && pending.some((node) => node.children || node.field !== "chart") ? chartSide : void 0;
|
|
6004
|
-
const
|
|
6005
|
-
const
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
const templated = !sugar && !regions.length && recordSlots.some((slot) => slot.children) && pending.every((node) => !node.children);
|
|
6009
|
-
const fillSlots = (entries, queue, cursor, recordSlot) => {
|
|
6010
|
-
const nodes = [];
|
|
6011
|
-
for (const entry of entries) {
|
|
6012
|
-
if (cursor.next >= queue.length) break;
|
|
6013
|
-
if (!entry.children) {
|
|
6014
|
-
nodes.push({ ...queue[cursor.next++], ...recordSlot ? { slot: entry } : {} });
|
|
6015
|
-
continue;
|
|
6016
|
-
}
|
|
6017
|
-
const own2 = record6(entry.placeholder.composition);
|
|
6018
|
-
assertComposition(own2);
|
|
6019
|
-
const children = fillSlots(entry.children, queue, cursor, recordSlot);
|
|
6020
|
-
nodes.push({
|
|
6021
|
-
field: "blocks",
|
|
6022
|
-
type: "group",
|
|
6023
|
-
value: children.map((child) => child.payload),
|
|
6024
|
-
path,
|
|
6025
|
-
payload: {},
|
|
6026
|
-
children,
|
|
6027
|
-
composition: own2,
|
|
6028
|
-
synthetic: true,
|
|
6029
|
-
reserved: own2.mode ? 0 : entry.children.length,
|
|
6030
|
-
...recordSlot ? { slot: entry, slots: entry.children } : {}
|
|
6031
|
-
});
|
|
6032
|
-
}
|
|
6033
|
-
return nodes;
|
|
6034
|
-
};
|
|
6035
|
-
if (sugar) {
|
|
6922
|
+
const chartPrimary = chartSide !== void 0 && !useTemplate && !ownMode && !regions.length && chartIndex >= 0 && pending.some((node) => node.children || node.field !== "chart") ? chartSide : void 0;
|
|
6923
|
+
const firstChart = chartPrimary === "left" || chartPrimary === "top";
|
|
6924
|
+
const rootSettings = chartPrimary ? { ...composition, mode: chartPrimary === "left" || chartPrimary === "right" ? "row" : "column", weights: firstChart ? [3, 2] : [2, 3], columns: void 0 } : { ...composition, mode: composition.mode ?? directionMode };
|
|
6925
|
+
if (useTemplate) composeTemplate();
|
|
6926
|
+
else if (chartPrimary) {
|
|
6036
6927
|
const primary = pending[chartIndex], rest = pending.filter((_, index) => index !== chartIndex);
|
|
6037
|
-
const
|
|
6038
|
-
arrange(
|
|
6039
|
-
} else
|
|
6040
|
-
const cursor = { next: 0 };
|
|
6041
|
-
const nodes = fillSlots(recordSlots, pending, cursor, true);
|
|
6042
|
-
arrange([...nodes, ...pending.slice(cursor.next)], contentBox, rootSettings, composition.mode ? 0 : placeholders.length, void 0, path, true, recordSlots);
|
|
6043
|
-
const order = /* @__PURE__ */ new Map();
|
|
6044
|
-
const number = (entries) => entries.forEach((entry) => {
|
|
6045
|
-
order.set(entry.path, order.size);
|
|
6046
|
-
if (entry.children) number(entry.children);
|
|
6047
|
-
});
|
|
6048
|
-
number(recordSlots);
|
|
6049
|
-
slots.sort((a, b) => order.get(a.path) - order.get(b.path));
|
|
6050
|
-
} else arrange(pending, contentBox, rootSettings, composition.mode ? 0 : placeholders.length);
|
|
6928
|
+
const support = { field: "blocks", type: "group", value: rest.map((node) => node.payload), path, payload: {}, children: rest, composition: {}, synthetic: true };
|
|
6929
|
+
arrange(firstChart ? [primary, support] : [support, primary], contentBox, rootSettings, 0);
|
|
6930
|
+
} else arrange(pending, contentBox, rootSettings, 0);
|
|
6051
6931
|
if (listBullet?.value === "image" && !bulletImage && items.some((item) => (item.field === "items" || item.field === "bullets") && item.payload.numbering === void 0)) {
|
|
6052
6932
|
diagnostics.push({ code: "unresolved-content", path: listBullet.path, message: "Picture bullets (listBullet: image) need an organization logo (the primary organization, or the one design.logo names); the marker glyph is drawn instead." });
|
|
6053
6933
|
}
|
|
@@ -6087,8 +6967,7 @@ function composeSlide(input, options = {}) {
|
|
|
6087
6967
|
} : void 0;
|
|
6088
6968
|
if (failures.length) throw new OPFCompositionError(failures, explanation);
|
|
6089
6969
|
diagnostics.push(...imageDiagnostics, ...numberingDiagnostics);
|
|
6090
|
-
|
|
6091
|
-
return { width, height, contentBox, items, groups, flows, ...slots.length ? { slots } : {}, diagnostics, composition, design: hints, ...furniture ? { furniture } : {}, ...backgroundImage ? { backgroundImage } : {}, ...logo ? { logo } : {}, ...rtl ? { direction: "rtl" } : {}, ...footnotes ? { footnotes } : {}, ...explanation ? { explanation } : {} };
|
|
6970
|
+
return { width, height, contentBox, items, groups, flows, ...useTemplate ? { regions: templateRegions, headingAreas } : {}, diagnostics, composition, design: hints, ...furniture ? { furniture } : {}, ...backgroundImage ? { backgroundImage } : {}, ...logo ? { logo } : {}, ...rtl ? { direction: "rtl" } : {}, ...footnotes ? { footnotes } : {}, ...explanation ? { explanation } : {} };
|
|
6092
6971
|
}
|
|
6093
6972
|
function resolveCanvasDimensions(input) {
|
|
6094
6973
|
const presets = {
|
|
@@ -6103,7 +6982,7 @@ function resolveCanvasDimensions(input) {
|
|
|
6103
6982
|
letter: [11, 8.5],
|
|
6104
6983
|
a4: [11.69, 8.27]
|
|
6105
6984
|
};
|
|
6106
|
-
const value =
|
|
6985
|
+
const value = record8(input);
|
|
6107
6986
|
const preset = presets[typeof input === "string" ? input : value.preset] ?? presets.widescreen;
|
|
6108
6987
|
const width = (value.widthInches ?? preset[0]) * 96;
|
|
6109
6988
|
const height = (value.heightInches ?? preset[1]) * 96;
|
|
@@ -6111,4 +6990,4 @@ function resolveCanvasDimensions(input) {
|
|
|
6111
6990
|
return { width, height };
|
|
6112
6991
|
}
|
|
6113
6992
|
|
|
6114
|
-
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE,
|
|
6993
|
+
export { AUTO_LAYOUT, CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CATALOG_GROUP_PATTERN, CATALOG_REFERENCE_PATTERN, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, HEADING_AREAS, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_REGION_BLOCKS, MAX_ROMAN_VALUE, MAX_TEMPLATE_TRACKS, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCatalogsOptionError, OPFCompositionError, OPFLayoutTemplateError, OPFUnresolvedReferenceError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, PROMOTED_REGION_KEY, REGION_ANCHORS, REGION_FLOWS, REGION_KINDS, REGION_ROLES, RESERVED_REGION_NAMES, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, THEME_DESIGN_KEYS, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, allocateRows, annotationText, bindRegions, blockKind, captionSettings, catalogGroupDeclared, catalogGroupSource, catalogKinds, catalogRecords, catalogReferenceSites, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, checkCatalogsOption, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeLayoutAreas, composeSlide, datasetDiagnostics, defaultSlideBackground, dottedPath, embeddedCopy, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, gridFlowShape, hasContentVariables, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isLayoutTemplate, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutRegion, layoutStructure, layoutTable, layoutTemplate, layoutTemplateIssues, layoutTimeline, layoutWatermark, listBuiltinVariables, listColumnBreaks, listNumbers, listVariables, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, parseReference, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, placedImageBlocks, pointerPath, promotedRegionKeys, provenanceOf, readingRows, recordReferenceSites, referencesSlide, regionAccepts, regionRoleRank, registeredCatalog, resolveCanvasDimensions, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveReference, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, rootNodes, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unresolvedReference, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
|