@openpresentation/opf 0.13.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -49
- package/dist/catalog-refs-BSfGELpt.d.ts +128 -0
- package/dist/catalog-schemas-CinPh5WA.d.ts +12 -0
- package/dist/catalog.d.ts +91 -0
- package/dist/{chunk-E34DJ5LL.js → catalog.js} +16949 -17628
- package/dist/{chart-data-Cdr6rRVV.d.ts → chart-data-BnNqgnC-.d.ts} +17 -6
- package/dist/{chunk-7QBCWNWL.js → chunk-2CJPC4HI.js} +1807 -1904
- package/dist/{chunk-II5EYKZU.js → chunk-374R35TJ.js} +2 -92
- package/dist/chunk-3JG4YXWF.js +1842 -0
- package/dist/chunk-3RKB4RDJ.js +192 -0
- package/dist/{chunk-IS2CPNVJ.js → chunk-5FTUIDUH.js} +26 -26
- package/dist/{chunk-GJKJL4YY.js → chunk-HXHOZ7AH.js} +1379 -504
- package/dist/{chunk-MPM7NRG7.js → chunk-O744SXXA.js} +2014 -885
- package/dist/chunk-QDI75P2M.js +3515 -0
- package/dist/chunk-SPFV27O5.js +210 -0
- package/dist/chunk-TRDXRRQK.js +17 -0
- package/dist/chunk-TWQJLI6E.js +601 -0
- package/dist/{chunk-ATGDDJPX.js → chunk-U4J75TRG.js} +3 -3
- package/dist/{chunk-RAYB46AB.js → chunk-UBFJ2QHH.js} +34 -30
- package/dist/chunk-VGAOJEY7.js +94 -0
- package/dist/chunk-ZPU46TFA.js +83 -0
- package/dist/{composition-D7we69Tr.d.ts → composition-D2tghM82.d.ts} +947 -111
- package/dist/composition.d.ts +3 -2
- package/dist/composition.js +2 -2
- package/dist/convert.d.ts +18 -19
- package/dist/convert.js +61 -50
- package/dist/data.d.ts +4 -4
- package/dist/data.js +3 -3
- package/dist/diff.d.ts +4 -4
- package/dist/diff.js +7 -605
- package/dist/docs.js +56 -44
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +49451 -6259
- package/dist/finding-CT_f_vbD.d.ts +212 -0
- package/dist/format.d.ts +4 -4
- package/dist/format.js +2 -83
- package/dist/index.d.ts +492 -309
- package/dist/index.js +767 -1097
- package/dist/json-BFSdESOE.d.ts +19 -0
- package/dist/markdown.d.ts +40 -27
- package/dist/markdown.js +9 -1941
- package/dist/pagination-wedbe7eq.d.ts +119 -0
- package/dist/pagination.d.ts +4 -61
- package/dist/pagination.js +6 -6
- package/dist/patch.d.ts +12 -23
- package/dist/patch.js +6 -6
- package/dist/{presentation-mG-IYErQ.d.ts → presentation-CDKQVkyI.d.ts} +702 -1026
- package/dist/repo-readme.js +1 -1
- package/dist/schemas.d.ts +284 -1
- package/dist/schemas.js +1 -1
- package/dist/spec/README.md +11 -6
- package/dist/spec/catalogs/audiences/index.json +2 -50
- package/dist/spec/catalogs/chart-types/100pct-stacked-area.json +21 -0
- package/dist/spec/catalogs/chart-types/100pct-stacked-bar.json +22 -0
- package/dist/spec/catalogs/chart-types/100pct-stacked-column.json +22 -0
- package/dist/spec/catalogs/chart-types/area.json +2 -60
- package/dist/spec/catalogs/chart-types/bar.json +2 -48
- package/dist/spec/catalogs/chart-types/box-and-whisker.json +2 -132
- package/dist/spec/catalogs/chart-types/column.json +2 -52
- package/dist/spec/catalogs/chart-types/combo.json +37 -0
- package/dist/spec/catalogs/chart-types/doughnut.json +2 -40
- package/dist/spec/catalogs/chart-types/filled-radar.json +2 -52
- package/dist/spec/catalogs/chart-types/funnel.json +2 -46
- package/dist/spec/catalogs/chart-types/histogram.json +2 -149
- package/dist/spec/catalogs/chart-types/index.json +50 -520
- package/dist/spec/catalogs/chart-types/line-with-markers.json +2 -60
- package/dist/spec/catalogs/chart-types/line.json +2 -60
- package/dist/spec/catalogs/chart-types/pareto.json +2 -50
- package/dist/spec/catalogs/chart-types/pie.json +2 -40
- package/dist/spec/catalogs/chart-types/radar-with-markers.json +2 -52
- package/dist/spec/catalogs/chart-types/radar.json +2 -52
- package/dist/spec/catalogs/chart-types/scatter.json +2 -73
- package/dist/spec/catalogs/chart-types/stacked-area.json +21 -0
- package/dist/spec/catalogs/chart-types/stacked-bar.json +22 -0
- package/dist/spec/catalogs/chart-types/stacked-column.json +22 -0
- package/dist/spec/catalogs/chart-types/stacked-line-with-markers.json +22 -0
- package/dist/spec/catalogs/chart-types/stacked-line.json +21 -0
- package/dist/spec/catalogs/chart-types/treemap.json +2 -48
- package/dist/spec/catalogs/chart-types/waterfall.json +2 -52
- package/dist/spec/catalogs/chart-types/world.json +2 -64
- package/dist/spec/catalogs/font-schemes/angsana-new.json +2 -2
- package/dist/spec/catalogs/font-schemes/aparajita.json +3 -3
- package/dist/spec/catalogs/font-schemes/aptos.json +1 -1
- package/dist/spec/catalogs/font-schemes/arabic-typesetting.json +2 -2
- package/dist/spec/catalogs/font-schemes/arial.json +1 -1
- package/dist/spec/catalogs/font-schemes/batang.json +2 -2
- package/dist/spec/catalogs/font-schemes/bookman.json +1 -1
- package/dist/spec/catalogs/font-schemes/calibri.json +1 -1
- package/dist/spec/catalogs/font-schemes/century-schoolbook.json +1 -1
- package/dist/spec/catalogs/font-schemes/consolas.json +2 -4
- package/dist/spec/catalogs/font-schemes/constantia.json +1 -1
- package/dist/spec/catalogs/font-schemes/courier-new.json +2 -4
- package/dist/spec/catalogs/font-schemes/daunpenh.json +2 -2
- package/dist/spec/catalogs/font-schemes/david.json +2 -2
- package/dist/spec/catalogs/font-schemes/dilleniaupc.json +2 -2
- package/dist/spec/catalogs/font-schemes/fangsong.json +2 -2
- package/dist/spec/catalogs/font-schemes/garamond.json +1 -1
- package/dist/spec/catalogs/font-schemes/gautami.json +2 -2
- package/dist/spec/catalogs/font-schemes/georgia.json +1 -1
- package/dist/spec/catalogs/font-schemes/gisha.json +3 -3
- package/dist/spec/catalogs/font-schemes/grandview.json +1 -1
- package/dist/spec/catalogs/font-schemes/gungsuh.json +2 -2
- package/dist/spec/catalogs/font-schemes/impact.json +1 -1
- package/dist/spec/catalogs/font-schemes/index.json +1 -1
- package/dist/spec/catalogs/font-schemes/kalinga.json +2 -2
- package/dist/spec/catalogs/font-schemes/kartika.json +2 -2
- package/dist/spec/catalogs/font-schemes/khmer-ui.json +2 -2
- package/dist/spec/catalogs/font-schemes/latha.json +2 -2
- package/dist/spec/catalogs/font-schemes/lucida-sans.json +1 -1
- package/dist/spec/catalogs/font-schemes/malgun-gothic.json +2 -2
- package/dist/spec/catalogs/font-schemes/mangal.json +4 -5
- package/dist/spec/catalogs/font-schemes/meiryo.json +2 -2
- package/dist/spec/catalogs/font-schemes/microsoft-jhenghei.json +2 -2
- package/dist/spec/catalogs/font-schemes/microsoft-yahei.json +5 -5
- package/dist/spec/catalogs/font-schemes/mingliu.json +2 -2
- package/dist/spec/catalogs/font-schemes/miriam.json +2 -2
- package/dist/spec/catalogs/font-schemes/montserrat.json +1 -1
- package/dist/spec/catalogs/font-schemes/ms-mincho.json +2 -2
- package/dist/spec/catalogs/font-schemes/nirmala-ui.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-naksh-arabic.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-nastaliq-urdu.json +3 -3
- package/dist/spec/catalogs/font-schemes/noto-sans-arabic.json +4 -4
- package/dist/spec/catalogs/font-schemes/noto-sans-armenian.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-bengali.json +3 -3
- package/dist/spec/catalogs/font-schemes/noto-sans-devangari.json +3 -3
- package/dist/spec/catalogs/font-schemes/noto-sans-ethiopic.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-georgian.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-gujarati.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-gurmukhi.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-hebrew.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-jp.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-kannada.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-khmer.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-kr.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-malayalam.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-mongolian.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-oriya.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-sc.json +5 -5
- package/dist/spec/catalogs/font-schemes/noto-sans-tamil.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-tc.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-telugu.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans-thai.json +2 -2
- package/dist/spec/catalogs/font-schemes/noto-sans.json +5 -5
- package/dist/spec/catalogs/font-schemes/nyala.json +2 -2
- package/dist/spec/catalogs/font-schemes/open-sans.json +1 -1
- package/dist/spec/catalogs/font-schemes/pmingliu.json +2 -2
- package/dist/spec/catalogs/font-schemes/poppins.json +1 -1
- package/dist/spec/catalogs/font-schemes/pt-serif.json +1 -1
- package/dist/spec/catalogs/font-schemes/raavi.json +2 -2
- package/dist/spec/catalogs/font-schemes/raleway.json +1 -1
- package/dist/spec/catalogs/font-schemes/roboto.json +1 -1
- package/dist/spec/catalogs/font-schemes/rockwell.json +1 -1
- package/dist/spec/catalogs/font-schemes/sakkal-majalla.json +4 -4
- package/dist/spec/catalogs/font-schemes/seaford.json +1 -1
- package/dist/spec/catalogs/font-schemes/segoe-ui-light.json +1 -1
- package/dist/spec/catalogs/font-schemes/segoe-ui.json +1 -1
- package/dist/spec/catalogs/font-schemes/shonar-bangla.json +3 -3
- package/dist/spec/catalogs/font-schemes/shruti.json +2 -2
- package/dist/spec/catalogs/font-schemes/simsun.json +2 -2
- package/dist/spec/catalogs/font-schemes/skeena.json +1 -1
- package/dist/spec/catalogs/font-schemes/sylfaen.json +3 -3
- package/dist/spec/catalogs/font-schemes/tahoma.json +1 -1
- package/dist/spec/catalogs/font-schemes/tenorite.json +1 -1
- package/dist/spec/catalogs/font-schemes/times-new-roman.json +1 -1
- package/dist/spec/catalogs/font-schemes/traditional-arabic.json +4 -4
- package/dist/spec/catalogs/font-schemes/trebuchet-ms.json +1 -1
- package/dist/spec/catalogs/font-schemes/tunga.json +2 -2
- package/dist/spec/catalogs/font-schemes/verdana.json +1 -1
- package/dist/spec/catalogs/font-schemes/vrinda.json +2 -2
- package/dist/spec/catalogs/font-schemes/yu-gothic.json +2 -2
- package/dist/spec/catalogs/layouts/action-plan.json +9 -15
- package/dist/spec/catalogs/layouts/agenda.json +8 -15
- package/dist/spec/catalogs/layouts/appendix-index.json +7 -15
- package/dist/spec/catalogs/layouts/architecture-stack.json +9 -15
- package/dist/spec/catalogs/layouts/assumptions-dependencies.json +9 -15
- package/dist/spec/catalogs/layouts/before-after.json +9 -15
- package/dist/spec/catalogs/layouts/benchmark-target-table.json +9 -15
- package/dist/spec/catalogs/layouts/blank.json +11 -1
- package/dist/spec/catalogs/layouts/bullet-list.json +9 -15
- package/dist/spec/catalogs/layouts/business-model-canvas.json +9 -15
- package/dist/spec/catalogs/layouts/capability-map.json +11 -16
- package/dist/spec/catalogs/layouts/case-study.json +9 -15
- package/dist/spec/catalogs/layouts/chapter-recap.json +8 -15
- package/dist/spec/catalogs/layouts/chart-1x-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/chart-1x.json +15 -0
- package/dist/spec/catalogs/layouts/chart-2x-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/chart-2x-vertical-title-left.json +37 -0
- package/dist/spec/catalogs/layouts/chart-2x.json +15 -0
- package/dist/spec/catalogs/layouts/chart-3x-bottom-vertical-title-left.json +46 -0
- package/dist/spec/catalogs/layouts/chart-3x-left-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/chart-3x-left.json +40 -0
- package/dist/spec/catalogs/layouts/chart-3x-right-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/chart-3x-right.json +40 -0
- package/dist/spec/catalogs/layouts/chart-3x-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/chart-3x-top-vertical-title-left.json +46 -0
- package/dist/spec/catalogs/layouts/chart-3x.json +15 -0
- package/dist/spec/catalogs/layouts/circular-lifecycle.json +9 -15
- package/dist/spec/catalogs/layouts/code-1x.json +10 -0
- package/dist/spec/catalogs/layouts/comparison.json +9 -15
- package/dist/spec/catalogs/layouts/competitive-landscape.json +11 -16
- package/dist/spec/catalogs/layouts/customer-journey.json +11 -16
- package/dist/spec/catalogs/layouts/customer-logos.json +9 -15
- package/dist/spec/catalogs/layouts/dashboard.json +9 -15
- package/dist/spec/catalogs/layouts/data-visualization.json +9 -15
- package/dist/spec/catalogs/layouts/decision-tree.json +11 -16
- package/dist/spec/catalogs/layouts/detailed-data-table.json +9 -15
- package/dist/spec/catalogs/layouts/ecosystem-map.json +11 -16
- package/dist/spec/catalogs/layouts/executive-decision.json +9 -15
- package/dist/spec/catalogs/layouts/executive-summary.json +9 -15
- package/dist/spec/catalogs/layouts/extract/canonical.json +7 -16
- package/dist/spec/catalogs/layouts/faq.json +9 -15
- package/dist/spec/catalogs/layouts/feature-comparison-matrix.json +9 -15
- package/dist/spec/catalogs/layouts/forecast-scenario.json +9 -15
- package/dist/spec/catalogs/layouts/funnel-pyramid.json +9 -15
- package/dist/spec/catalogs/layouts/gantt-project-plan.json +9 -15
- package/dist/spec/catalogs/layouts/geographic-map.json +10 -15
- package/dist/spec/catalogs/layouts/heatmap-cohort.json +9 -15
- package/dist/spec/catalogs/layouts/hub-and-spoke.json +9 -15
- package/dist/spec/catalogs/layouts/icon-grid.json +11 -16
- package/dist/spec/catalogs/layouts/image-1x-crop-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/image-1x-crop-title-left.json +32 -0
- package/dist/spec/catalogs/layouts/image-1x-crop.json +27 -0
- package/dist/spec/catalogs/layouts/image-1x-fit-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/image-1x.json +14 -1
- package/dist/spec/catalogs/layouts/image-2x-crop-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/image-2x-crop-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/image-2x-crop-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/image-2x-crop.json +33 -0
- package/dist/spec/catalogs/layouts/image-2x-fit-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/image-2x-fit-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/image-2x-fit-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/image-2x.json +15 -2
- package/dist/spec/catalogs/layouts/image-3x-crop-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/image-3x-crop-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/image-3x-crop-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/image-3x-crop.json +36 -0
- package/dist/spec/catalogs/layouts/image-3x-fit-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/image-3x-fit-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/image-3x-fit-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/image-3x-fit.json +36 -0
- package/dist/spec/catalogs/layouts/image-3x.json +16 -3
- package/dist/spec/catalogs/layouts/image-focus.json +13 -18
- package/dist/spec/catalogs/layouts/image-only-1x-crop-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/image-only-1x-fit-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/image-only-2x-crop-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical-title-left.json +38 -0
- package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical.json +33 -0
- package/dist/spec/catalogs/layouts/image-only-2x-fit-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical-title-left.json +38 -0
- package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical.json +33 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical.json +36 -0
- package/dist/spec/catalogs/layouts/image-only-3x-crop.json +35 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical.json +36 -0
- package/dist/spec/catalogs/layouts/image-only-3x-fit.json +35 -0
- package/dist/spec/catalogs/layouts/index.json +1041 -151
- package/dist/spec/catalogs/layouts/key-takeaway.json +8 -15
- package/dist/spec/catalogs/layouts/kpi-scorecard.json +9 -15
- package/dist/spec/catalogs/layouts/list-1x-box-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-center.json +33 -0
- package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-left.json +33 -0
- package/dist/spec/catalogs/layouts/list-1x-box-vertical.json +28 -0
- package/dist/spec/catalogs/layouts/list-1x-box.json +27 -0
- package/dist/spec/catalogs/layouts/list-1x-itemimage-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/list-1x-itemimage-vertical-title-center.json +33 -0
- package/dist/spec/catalogs/layouts/list-1x-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/list-1x-vertical-title-center.json +32 -0
- package/dist/spec/catalogs/layouts/list-1x.json +17 -1
- package/dist/spec/catalogs/layouts/list-2x-box-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-box-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/list-2x-box.json +33 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-left.json +39 -0
- package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical.json +34 -0
- package/dist/spec/catalogs/layouts/list-2x-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/list-2x-vertical-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-vertical-title-left.json +38 -0
- package/dist/spec/catalogs/layouts/list-2x-vertical.json +33 -0
- package/dist/spec/catalogs/layouts/list-2x.json +16 -0
- package/dist/spec/catalogs/layouts/list-3x-box-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-center.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-box-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/list-3x-box.json +36 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-center.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-left.json +42 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical.json +37 -0
- package/dist/spec/catalogs/layouts/list-3x-itemimage.json +36 -0
- package/dist/spec/catalogs/layouts/list-3x-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/list-3x-vertical-title-center.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/list-3x-vertical.json +36 -0
- package/dist/spec/catalogs/layouts/list-3x.json +16 -0
- package/dist/spec/catalogs/layouts/list-4x-box-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-left.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-box-vertical.json +40 -0
- package/dist/spec/catalogs/layouts/list-4x-box.json +40 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-left.json +45 -0
- package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical.json +40 -0
- package/dist/spec/catalogs/layouts/list-4x-title-center.json +44 -0
- package/dist/spec/catalogs/layouts/list-4x-vertical-title-center.json +44 -0
- package/dist/spec/catalogs/layouts/list-4x-vertical-title-left.json +44 -0
- package/dist/spec/catalogs/layouts/list-4x-vertical.json +39 -0
- package/dist/spec/catalogs/layouts/list-4x.json +16 -0
- package/dist/spec/catalogs/layouts/list-5x-box-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-center.json +50 -0
- package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-left.json +50 -0
- package/dist/spec/catalogs/layouts/list-5x-box-vertical.json +45 -0
- package/dist/spec/catalogs/layouts/list-5x-box.json +43 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-left.json +48 -0
- package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical.json +43 -0
- package/dist/spec/catalogs/layouts/list-5x-title-center.json +47 -0
- package/dist/spec/catalogs/layouts/list-5x-vertical-title-center.json +47 -0
- package/dist/spec/catalogs/layouts/list-5x-vertical-title-left.json +47 -0
- package/dist/spec/catalogs/layouts/list-5x-vertical.json +42 -0
- package/dist/spec/catalogs/layouts/list-5x.json +16 -0
- package/dist/spec/catalogs/layouts/list-6x-box-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-center.json +53 -0
- package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-left.json +53 -0
- package/dist/spec/catalogs/layouts/list-6x-box-vertical.json +48 -0
- package/dist/spec/catalogs/layouts/list-6x-box.json +46 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-center.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-left.json +51 -0
- package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical.json +46 -0
- package/dist/spec/catalogs/layouts/list-6x-title-center.json +50 -0
- package/dist/spec/catalogs/layouts/list-6x-vertical-title-center.json +50 -0
- package/dist/spec/catalogs/layouts/list-6x-vertical-title-left.json +50 -0
- package/dist/spec/catalogs/layouts/list-6x-vertical.json +45 -0
- package/dist/spec/catalogs/layouts/list-6x.json +16 -0
- package/dist/spec/catalogs/layouts/logic-tree.json +9 -15
- package/dist/spec/catalogs/layouts/market-size.json +9 -15
- package/dist/spec/catalogs/layouts/matrix-quadrant.json +9 -15
- package/dist/spec/catalogs/layouts/media-1x.json +11 -1
- package/dist/spec/catalogs/layouts/network-dependency-map.json +10 -15
- package/dist/spec/catalogs/layouts/number-1x-box-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/number-1x-box.json +25 -0
- package/dist/spec/catalogs/layouts/number-1x-title-center.json +29 -0
- package/dist/spec/catalogs/layouts/number-1x.json +16 -1
- package/dist/spec/catalogs/layouts/number-2x-box-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/number-2x-box.json +31 -0
- package/dist/spec/catalogs/layouts/number-2x-title-center.json +35 -0
- package/dist/spec/catalogs/layouts/number-2x.json +15 -0
- package/dist/spec/catalogs/layouts/number-3x-box-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/number-3x-box.json +34 -0
- package/dist/spec/catalogs/layouts/number-3x-title-center.json +38 -0
- package/dist/spec/catalogs/layouts/number-3x.json +15 -0
- package/dist/spec/catalogs/layouts/number-4x-box-title-center.json +43 -0
- package/dist/spec/catalogs/layouts/number-4x-box.json +38 -0
- package/dist/spec/catalogs/layouts/number-4x-title-center.json +42 -0
- package/dist/spec/catalogs/layouts/number-4x.json +15 -0
- package/dist/spec/catalogs/layouts/number-5x-box-title-center.json +46 -0
- package/dist/spec/catalogs/layouts/number-5x-box.json +41 -0
- package/dist/spec/catalogs/layouts/number-5x-title-center.json +45 -0
- package/dist/spec/catalogs/layouts/number-5x.json +15 -0
- package/dist/spec/catalogs/layouts/number-6x-box-title-center.json +49 -0
- package/dist/spec/catalogs/layouts/number-6x-box.json +44 -0
- package/dist/spec/catalogs/layouts/number-6x-title-center.json +48 -0
- package/dist/spec/catalogs/layouts/number-6x.json +15 -0
- package/dist/spec/catalogs/layouts/one-column-explainer.json +9 -15
- package/dist/spec/catalogs/layouts/org-chart.json +9 -15
- package/dist/spec/catalogs/layouts/persona-grid.json +11 -16
- package/dist/spec/catalogs/layouts/photo-grid.json +14 -19
- package/dist/spec/catalogs/layouts/pricing-table.json +9 -15
- package/dist/spec/catalogs/layouts/process-flow.json +9 -15
- package/dist/spec/catalogs/layouts/product-feature.json +11 -16
- package/dist/spec/catalogs/layouts/pros-cons.json +9 -15
- package/dist/spec/catalogs/layouts/qa-discussion.json +7 -15
- package/dist/spec/catalogs/layouts/quote-1x.json +11 -1
- package/dist/spec/catalogs/layouts/quote-highlight.json +9 -15
- package/dist/spec/catalogs/layouts/raci-matrix.json +9 -15
- package/dist/spec/catalogs/layouts/risk-heatmap.json +9 -15
- package/dist/spec/catalogs/layouts/roadmap.json +9 -15
- package/dist/spec/catalogs/layouts/screenshot-walkthrough.json +11 -16
- package/dist/spec/catalogs/layouts/section-divider.json +8 -15
- package/dist/spec/catalogs/layouts/single-message-statement.json +8 -15
- package/dist/spec/catalogs/layouts/stats-metrics.json +9 -15
- package/dist/spec/catalogs/layouts/status-rag.json +9 -15
- package/dist/spec/catalogs/layouts/swimlane-process.json +11 -16
- package/dist/spec/catalogs/layouts/swot-analysis.json +9 -15
- package/dist/spec/catalogs/layouts/table-1x.json +10 -0
- package/dist/spec/catalogs/layouts/team-bio.json +11 -16
- package/dist/spec/catalogs/layouts/testimonial-grid.json +9 -15
- package/dist/spec/catalogs/layouts/text-1x-box-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-box-title-left.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-center-box-title-center.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-center-box-title-left.json +31 -0
- package/dist/spec/catalogs/layouts/text-1x-center-box.json +26 -0
- package/dist/spec/catalogs/layouts/text-1x-center-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/text-1x-center-title-left.json +30 -0
- package/dist/spec/catalogs/layouts/text-1x-center.json +25 -0
- package/dist/spec/catalogs/layouts/text-1x-left-box.json +26 -0
- package/dist/spec/catalogs/layouts/text-1x-title-center.json +30 -0
- package/dist/spec/catalogs/layouts/text-1x.json +11 -1
- package/dist/spec/catalogs/layouts/text-2x-box-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-box-vertical-title-left.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-center-box-title-center.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-center-box-vertical-title-left.json +37 -0
- package/dist/spec/catalogs/layouts/text-2x-center-box.json +32 -0
- package/dist/spec/catalogs/layouts/text-2x-center-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x-center-vertical-title-left.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x-center.json +31 -0
- package/dist/spec/catalogs/layouts/text-2x-left-box.json +32 -0
- package/dist/spec/catalogs/layouts/text-2x-title-center.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x-vertical-title-left.json +36 -0
- package/dist/spec/catalogs/layouts/text-2x.json +10 -0
- package/dist/spec/catalogs/layouts/text-3x-box-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x-box-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/text-3x-center-box-title-center.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x-center-box-vertical-title-left.json +41 -0
- package/dist/spec/catalogs/layouts/text-3x-center-box.json +35 -0
- package/dist/spec/catalogs/layouts/text-3x-center-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/text-3x-center-vertical-title-left.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x-center.json +34 -0
- package/dist/spec/catalogs/layouts/text-3x-left-box.json +35 -0
- package/dist/spec/catalogs/layouts/text-3x-left.json +34 -0
- package/dist/spec/catalogs/layouts/text-3x-title-center.json +39 -0
- package/dist/spec/catalogs/layouts/text-3x-vertical-title-left.json +40 -0
- package/dist/spec/catalogs/layouts/text-3x.json +10 -0
- package/dist/spec/catalogs/layouts/thank-you-cta.json +8 -15
- package/dist/spec/catalogs/layouts/three-column.json +9 -15
- package/dist/spec/catalogs/layouts/timeline-1x.json +11 -1
- package/dist/spec/catalogs/layouts/timeline.json +9 -15
- package/dist/spec/catalogs/layouts/title-center-box.json +27 -0
- package/dist/spec/catalogs/layouts/title-center-image-bottom.json +34 -0
- package/dist/spec/catalogs/layouts/title-center-image-top.json +34 -0
- package/dist/spec/catalogs/layouts/title-center.json +26 -0
- package/dist/spec/catalogs/layouts/title-left-image-bottom.json +34 -0
- package/dist/spec/catalogs/layouts/title-left-image-left.json +34 -0
- package/dist/spec/catalogs/layouts/title-left-image-right.json +34 -0
- package/dist/spec/catalogs/layouts/title-left-image-top.json +34 -0
- package/dist/spec/catalogs/layouts/title-slide.json +8 -15
- package/dist/spec/catalogs/layouts/title-subtitle.json +11 -1
- package/dist/spec/catalogs/layouts/title.json +11 -1
- package/dist/spec/catalogs/layouts/two-column.json +9 -15
- package/dist/spec/catalogs/layouts/venn-overlap.json +9 -15
- package/dist/spec/catalogs/layouts/waterfall-bridge.json +9 -15
- package/dist/spec/catalogs/layouts/wheel-radial.json +9 -15
- package/dist/spec/catalogs/manifest.json +22 -22
- package/dist/spec/catalogs/narratives/board-meeting.json +45 -45
- package/dist/spec/catalogs/narratives/business-narrative.json +19 -19
- package/dist/spec/catalogs/narratives/business-review.json +27 -27
- package/dist/spec/catalogs/narratives/capacity-planning.json +19 -19
- package/dist/spec/catalogs/narratives/challenge-resolution.json +17 -17
- package/dist/spec/catalogs/narratives/change-story.json +13 -13
- package/dist/spec/catalogs/narratives/classic-story.json +17 -17
- package/dist/spec/catalogs/narratives/company-intro.json +21 -21
- package/dist/spec/catalogs/narratives/conference-talk.json +4 -4
- package/dist/spec/catalogs/narratives/data-story.json +13 -14
- package/dist/spec/catalogs/narratives/early-startup-pitch.json +27 -27
- package/dist/spec/catalogs/narratives/educate.json +21 -21
- package/dist/spec/catalogs/narratives/employee-review.json +19 -19
- package/dist/spec/catalogs/narratives/failure-analysis.json +23 -23
- package/dist/spec/catalogs/narratives/focus.json +27 -27
- package/dist/spec/catalogs/narratives/golden-circle.json +4 -4
- package/dist/spec/catalogs/narratives/heros-journey.json +13 -13
- package/dist/spec/catalogs/narratives/index.json +145 -145
- package/dist/spec/catalogs/narratives/innovation.json +21 -21
- package/dist/spec/catalogs/narratives/justice.json +25 -25
- package/dist/spec/catalogs/narratives/marketing-strategy.json +25 -25
- package/dist/spec/catalogs/narratives/performance-improvement-plan.json +19 -19
- package/dist/spec/catalogs/narratives/performance-review.json +25 -25
- package/dist/spec/catalogs/narratives/persuade.json +17 -17
- package/dist/spec/catalogs/narratives/persuasive-sales.json +19 -19
- package/dist/spec/catalogs/narratives/pitch-deck.json +6 -6
- package/dist/spec/catalogs/narratives/problem-solution.json +5 -5
- package/dist/spec/catalogs/narratives/product-launch.json +23 -23
- package/dist/spec/catalogs/narratives/project-proposal.json +23 -23
- package/dist/spec/catalogs/narratives/pyramid-principle.json +9 -9
- package/dist/spec/catalogs/narratives/qbr.json +8 -8
- package/dist/spec/catalogs/narratives/rags-to-riches.json +17 -17
- package/dist/spec/catalogs/narratives/reveal.json +19 -19
- package/dist/spec/catalogs/narratives/scqa.json +4 -4
- package/dist/spec/catalogs/narratives/situation-complication-resolution.json +11 -11
- package/dist/spec/catalogs/narratives/sparkline.json +11 -11
- package/dist/spec/catalogs/narratives/star-method.json +11 -11
- package/dist/spec/catalogs/narratives/status-update.json +15 -15
- package/dist/spec/catalogs/narratives/strategic-advisory.json +17 -17
- package/dist/spec/catalogs/narratives/strategic-narrative.json +4 -4
- package/dist/spec/catalogs/narratives/survey-analysis.json +23 -23
- package/dist/spec/catalogs/narratives/survival-story.json +23 -23
- package/dist/spec/catalogs/narratives/transformation-arc.json +4 -4
- package/dist/spec/catalogs/narratives/trend-analysis.json +17 -17
- package/dist/spec/catalogs/narratives/underdog-victory.json +19 -19
- package/dist/spec/catalogs/narratives/venture-pitch.json +27 -27
- package/dist/spec/catalogs/narratives/vision-roadmap.json +13 -13
- package/dist/spec/catalogs/narratives/weekly-progress.json +23 -23
- package/dist/spec/catalogs/narratives/what-so-what-now-what.json +9 -9
- package/dist/spec/openapi.yaml +4 -7
- package/dist/spec/reference/engine-defaults.json +22 -30
- package/dist/spec/reference/engine-vocabularies.json +1577 -0
- package/dist/spec/schemas/audience.schema.json +6 -27
- package/dist/spec/schemas/catalog-index.schema.json +2 -2
- package/dist/spec/schemas/catalog-manifest.schema.json +3 -3
- package/dist/spec/schemas/chart-type.schema.json +17 -321
- package/dist/spec/schemas/color-scheme.schema.json +23 -36
- package/dist/spec/schemas/finding.schema.json +191 -0
- package/dist/spec/schemas/font-scheme.schema.json +17 -75
- package/dist/spec/schemas/language.schema.json +7 -28
- package/dist/spec/schemas/layout.schema.json +130 -184
- package/dist/spec/schemas/narrative.schema.json +20 -48
- package/dist/spec/schemas/opf.schema.json +678 -701
- package/dist/spec/schemas/purpose.schema.json +5 -26
- package/dist/spec/schemas/social-platform.schema.json +2 -48
- package/dist/spec/schemas/theme.schema.json +13 -38
- package/dist/spec/schemas/tone.schema.json +4 -25
- package/dist/spec-files.d.ts +1 -1
- package/dist/spec-files.js +1 -1
- package/dist/symbol-font-encodings.js +18448 -1
- package/dist/types.d.ts +1125 -4
- package/dist/validation-types-BOcY9GTs.d.ts +276 -0
- package/dist/validator.d.ts +63 -4
- package/dist/validator.js +5 -5
- package/dist/yaml.d.ts +102 -0
- package/dist/yaml.js +322 -0
- package/package.json +9 -17
- package/dist/audit.d.ts +0 -35
- package/dist/audit.js +0 -7
- package/dist/catalogs-ywCamd8C.d.ts +0 -1465
- package/dist/catalogs.d.ts +0 -2
- package/dist/catalogs.js +0 -2
- package/dist/chunk-7N4VMAT4.js +0 -1694
- package/dist/chunk-FYLJVF7X.js +0 -18448
- package/dist/chunk-INU7ZNSB.js +0 -670
- package/dist/chunk-IYCJUKWD.js +0 -951
- package/dist/chunk-PIQXLBBJ.js +0 -445
- package/dist/chunk-S5W34SIJ.js +0 -1
- package/dist/lint-B7azdiuE.d.ts +0 -197
- package/dist/lint.d.ts +0 -7
- package/dist/lint.js +0 -6
- package/dist/previews.d.ts +0 -40
- package/dist/previews.js +0 -1
- package/dist/schemas-BbPonsTz.d.ts +0 -270
- package/dist/spec/catalogs/audiences/customers.json +0 -27
- package/dist/spec/catalogs/audiences/executives.json +0 -27
- package/dist/spec/catalogs/audiences/investors.json +0 -27
- package/dist/spec/catalogs/audiences/marketing-team.json +0 -27
- package/dist/spec/catalogs/audiences/regulators.json +0 -27
- package/dist/spec/catalogs/audiences/sales-team.json +0 -27
- package/dist/spec/catalogs/chart-types/100pct-bullet-bar-2x.json +0 -91
- package/dist/spec/catalogs/chart-types/100pct-bullet-bar-3x.json +0 -103
- package/dist/spec/catalogs/chart-types/100pct-bullet-bar.json +0 -79
- package/dist/spec/catalogs/chart-types/100pct-bullet-column-2x.json +0 -91
- package/dist/spec/catalogs/chart-types/100pct-bullet-column-3x.json +0 -103
- package/dist/spec/catalogs/chart-types/100pct-bullet-column.json +0 -79
- package/dist/spec/catalogs/chart-types/100pct-progress-bar.json +0 -105
- package/dist/spec/catalogs/chart-types/100pct-stacked-area-2x.json +0 -106
- package/dist/spec/catalogs/chart-types/100pct-stacked-area-3x.json +0 -123
- package/dist/spec/catalogs/chart-types/100pct-stacked-bar-2x.json +0 -89
- package/dist/spec/catalogs/chart-types/100pct-stacked-bar-3x.json +0 -100
- package/dist/spec/catalogs/chart-types/100pct-stacked-column-2x.json +0 -95
- package/dist/spec/catalogs/chart-types/100pct-stacked-column-3x.json +0 -108
- package/dist/spec/catalogs/chart-types/australia.json +0 -76
- package/dist/spec/catalogs/chart-types/box-and-whisker-2x.json +0 -136
- package/dist/spec/catalogs/chart-types/box-and-whisker-3x.json +0 -168
- package/dist/spec/catalogs/chart-types/bullet-bar-2x.json +0 -89
- package/dist/spec/catalogs/chart-types/bullet-bar-3x.json +0 -101
- package/dist/spec/catalogs/chart-types/bullet-bar.json +0 -77
- package/dist/spec/catalogs/chart-types/bullet-column-2x.json +0 -89
- package/dist/spec/catalogs/chart-types/bullet-column-3x.json +0 -101
- package/dist/spec/catalogs/chart-types/bullet-column.json +0 -77
- package/dist/spec/catalogs/chart-types/canada.json +0 -86
- package/dist/spec/catalogs/chart-types/clustered-bar-2x.json +0 -89
- package/dist/spec/catalogs/chart-types/clustered-column.json +0 -95
- package/dist/spec/catalogs/chart-types/dot-plot-2x.json +0 -99
- package/dist/spec/catalogs/chart-types/dot-plot-3x.json +0 -124
- package/dist/spec/catalogs/chart-types/dot-plot-4x.json +0 -149
- package/dist/spec/catalogs/chart-types/dot-plot-5x.json +0 -174
- package/dist/spec/catalogs/chart-types/dot-plot-6x.json +0 -199
- package/dist/spec/catalogs/chart-types/dot-plot.json +0 -74
- package/dist/spec/catalogs/chart-types/dumbbell.json +0 -120
- package/dist/spec/catalogs/chart-types/line-2x.json +0 -105
- package/dist/spec/catalogs/chart-types/line-3x.json +0 -127
- package/dist/spec/catalogs/chart-types/line-with-high-low-and-markers.json +0 -144
- package/dist/spec/catalogs/chart-types/line-with-high-low.json +0 -144
- package/dist/spec/catalogs/chart-types/line-with-markers-2x.json +0 -106
- package/dist/spec/catalogs/chart-types/line-with-markers-3x.json +0 -128
- package/dist/spec/catalogs/chart-types/sparkline-2x.json +0 -138
- package/dist/spec/catalogs/chart-types/sparkline-3x.json +0 -174
- package/dist/spec/catalogs/chart-types/sparkline-4x.json +0 -210
- package/dist/spec/catalogs/chart-types/sparkline-5x.json +0 -246
- package/dist/spec/catalogs/chart-types/sparkline-6x.json +0 -282
- package/dist/spec/catalogs/chart-types/sparkline.json +0 -102
- package/dist/spec/catalogs/chart-types/stacked-area-2x.json +0 -106
- package/dist/spec/catalogs/chart-types/stacked-area-3x.json +0 -123
- package/dist/spec/catalogs/chart-types/stacked-bar-2x.json +0 -89
- package/dist/spec/catalogs/chart-types/stacked-bar-3x.json +0 -100
- package/dist/spec/catalogs/chart-types/stacked-column-2x.json +0 -95
- package/dist/spec/catalogs/chart-types/stacked-column-3x.json +0 -108
- package/dist/spec/catalogs/chart-types/stacked-line-2x.json +0 -106
- package/dist/spec/catalogs/chart-types/stacked-line-3x.json +0 -123
- package/dist/spec/catalogs/chart-types/stacked-line-with-markers-2x.json +0 -107
- package/dist/spec/catalogs/chart-types/stacked-line-with-markers-3x.json +0 -124
- package/dist/spec/catalogs/chart-types/treemap-2x.json +0 -101
- package/dist/spec/catalogs/chart-types/treemap-3x.json +0 -122
- package/dist/spec/catalogs/chart-types/united-kingdom.json +0 -68
- package/dist/spec/catalogs/chart-types/united-states.json +0 -82
- package/dist/spec/catalogs/layouts/image-bleed.json +0 -10
- package/dist/validator-CIylxoIm.d.ts +0 -172
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { checkCatalogsOption, resolveReference, unresolvedReference, provenanceOf } from './chunk-SPFV27O5.js';
|
|
2
2
|
|
|
3
3
|
// src/table.ts
|
|
4
4
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
@@ -7,7 +7,7 @@ function tableGrid(value, path = "table") {
|
|
|
7
7
|
const values = [...hasHeaders ? [table.columns] : [], ...Array.isArray(table.rows) ? table.rows : []];
|
|
8
8
|
const columnCount = values.reduce((count, row) => Math.max(count, Array.isArray(row) ? row.length : 0), 1), rowCount = values.length;
|
|
9
9
|
const owners = Array.from({ length: rowCount }, () => Array(columnCount));
|
|
10
|
-
const
|
|
10
|
+
const rows3 = Array.from({ length: rowCount }, () => []), issues = [];
|
|
11
11
|
const location = (r, c) => `${path}.${hasHeaders && r === 0 ? "columns" : `rows.${r - Number(hasHeaders)}`}.${c}`;
|
|
12
12
|
for (let r = 0; r < rowCount; r++) for (let c = 0; c < columnCount; c++) {
|
|
13
13
|
const input = values[r]?.[c], cellPath = location(r, c), existing = owners[r][c];
|
|
@@ -15,21 +15,21 @@ function tableGrid(value, path = "table") {
|
|
|
15
15
|
if (input !== null) issues.push({ path: cellPath, message: "A position covered by a spanning cell must explicitly contain null; content cannot be hidden." });
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
|
-
const
|
|
19
|
-
const column = !styled && hasHeaders && r === 0 && typeof
|
|
20
|
-
const rowSpan = styled ?
|
|
18
|
+
const object2 = record(input), styled = Object.hasOwn(object2, "value");
|
|
19
|
+
const column = !styled && hasHeaders && r === 0 && typeof object2.name === "string";
|
|
20
|
+
const rowSpan = styled ? object2.rowSpan ?? 1 : 1, colSpan = styled ? object2.colSpan ?? 1 : 1;
|
|
21
21
|
if (!Number.isSafeInteger(rowSpan) || !Number.isSafeInteger(colSpan) || rowSpan < 1 || colSpan < 1 || r + rowSpan > rowCount || c + colSpan > columnCount || hasHeaders && r === 0 && rowSpan > 1) {
|
|
22
22
|
issues.push({ path: cellPath, message: "Cell spans must be positive integers within the table grid and cannot cross from headers into body rows." });
|
|
23
23
|
continue;
|
|
24
24
|
}
|
|
25
|
-
const cell = { input, value: styled ?
|
|
26
|
-
|
|
25
|
+
const cell = { input, value: styled ? object2.value : column ? object2.name : input, style: styled ? record(object2.style) : {}, row: r, column: c, rowSpan, colSpan, header: hasHeaders && r === 0, path: cellPath, valuePath: styled ? cellPath + ".value" : column ? cellPath + ".name" : cellPath };
|
|
26
|
+
rows3[r].push(cell);
|
|
27
27
|
for (let y = r; y < r + rowSpan; y++) for (let x = c; x < c + colSpan; x++) {
|
|
28
28
|
if (owners[y][x]) issues.push({ path: cellPath, message: "Cell spans cannot overlap another spanning cell." });
|
|
29
29
|
else owners[y][x] = cell;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
return { rows:
|
|
32
|
+
return { rows: rows3, columnCount, rowCount, hasHeaders, owners, issues };
|
|
33
33
|
}
|
|
34
34
|
function tableRowBoundaries(value) {
|
|
35
35
|
const grid = tableGrid(value), offset = Number(grid.hasHeaders), count = grid.rowCount - offset;
|
|
@@ -38,562 +38,6 @@ function tableRowBoundaries(value) {
|
|
|
38
38
|
return [...allowed];
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// src/generated/catalog-ids.ts
|
|
42
|
-
var catalogIds = {
|
|
43
|
-
audiences: [
|
|
44
|
-
"executives",
|
|
45
|
-
"board",
|
|
46
|
-
"engineering-team",
|
|
47
|
-
"investors",
|
|
48
|
-
"customers",
|
|
49
|
-
"sales-team",
|
|
50
|
-
"marketing-team",
|
|
51
|
-
"all-hands",
|
|
52
|
-
"candidates",
|
|
53
|
-
"regulators",
|
|
54
|
-
"executive",
|
|
55
|
-
"investor",
|
|
56
|
-
"technical",
|
|
57
|
-
"sales",
|
|
58
|
-
"marketing",
|
|
59
|
-
"academic",
|
|
60
|
-
"internal-team",
|
|
61
|
-
"customer",
|
|
62
|
-
"general-public",
|
|
63
|
-
"media",
|
|
64
|
-
"partner",
|
|
65
|
-
"regulatory"
|
|
66
|
-
],
|
|
67
|
-
purposes: [
|
|
68
|
-
"inform",
|
|
69
|
-
"decide",
|
|
70
|
-
"align",
|
|
71
|
-
"persuade",
|
|
72
|
-
"educate",
|
|
73
|
-
"report",
|
|
74
|
-
"pitch",
|
|
75
|
-
"sell",
|
|
76
|
-
"plan"
|
|
77
|
-
],
|
|
78
|
-
tones: [
|
|
79
|
-
"formal",
|
|
80
|
-
"casual",
|
|
81
|
-
"inspirational",
|
|
82
|
-
"technical",
|
|
83
|
-
"persuasive",
|
|
84
|
-
"authoritative",
|
|
85
|
-
"conversational"
|
|
86
|
-
],
|
|
87
|
-
themes: [
|
|
88
|
-
"minimal",
|
|
89
|
-
"classic",
|
|
90
|
-
"dark",
|
|
91
|
-
"bold"
|
|
92
|
-
],
|
|
93
|
-
layouts: [
|
|
94
|
-
"blank",
|
|
95
|
-
"chart-1x",
|
|
96
|
-
"chart-2x",
|
|
97
|
-
"chart-3x",
|
|
98
|
-
"code-1x",
|
|
99
|
-
"image-1x",
|
|
100
|
-
"image-2x",
|
|
101
|
-
"image-3x",
|
|
102
|
-
"image-bleed",
|
|
103
|
-
"list-1x",
|
|
104
|
-
"list-2x",
|
|
105
|
-
"list-3x",
|
|
106
|
-
"list-4x",
|
|
107
|
-
"list-5x",
|
|
108
|
-
"list-6x",
|
|
109
|
-
"media-1x",
|
|
110
|
-
"number-1x",
|
|
111
|
-
"number-2x",
|
|
112
|
-
"number-3x",
|
|
113
|
-
"number-4x",
|
|
114
|
-
"number-5x",
|
|
115
|
-
"number-6x",
|
|
116
|
-
"quote-1x",
|
|
117
|
-
"table-1x",
|
|
118
|
-
"text-1x",
|
|
119
|
-
"text-2x",
|
|
120
|
-
"text-3x",
|
|
121
|
-
"timeline-1x",
|
|
122
|
-
"title",
|
|
123
|
-
"title-subtitle",
|
|
124
|
-
"title-slide",
|
|
125
|
-
"two-column",
|
|
126
|
-
"image-focus",
|
|
127
|
-
"data-visualization",
|
|
128
|
-
"quote-highlight",
|
|
129
|
-
"section-divider",
|
|
130
|
-
"agenda",
|
|
131
|
-
"thank-you-cta",
|
|
132
|
-
"bullet-list",
|
|
133
|
-
"three-column",
|
|
134
|
-
"icon-grid",
|
|
135
|
-
"faq",
|
|
136
|
-
"stats-metrics",
|
|
137
|
-
"comparison",
|
|
138
|
-
"swot-analysis",
|
|
139
|
-
"matrix-quadrant",
|
|
140
|
-
"funnel-pyramid",
|
|
141
|
-
"timeline",
|
|
142
|
-
"process-flow",
|
|
143
|
-
"photo-grid",
|
|
144
|
-
"before-after",
|
|
145
|
-
"testimonial-grid",
|
|
146
|
-
"team-bio",
|
|
147
|
-
"pricing-table",
|
|
148
|
-
"roadmap",
|
|
149
|
-
"product-feature",
|
|
150
|
-
"executive-summary",
|
|
151
|
-
"key-takeaway",
|
|
152
|
-
"chapter-recap",
|
|
153
|
-
"qa-discussion",
|
|
154
|
-
"single-message-statement",
|
|
155
|
-
"one-column-explainer",
|
|
156
|
-
"case-study",
|
|
157
|
-
"pros-cons",
|
|
158
|
-
"feature-comparison-matrix",
|
|
159
|
-
"venn-overlap",
|
|
160
|
-
"decision-tree",
|
|
161
|
-
"kpi-scorecard",
|
|
162
|
-
"dashboard",
|
|
163
|
-
"waterfall-bridge",
|
|
164
|
-
"benchmark-target-table",
|
|
165
|
-
"heatmap-cohort",
|
|
166
|
-
"risk-heatmap",
|
|
167
|
-
"forecast-scenario",
|
|
168
|
-
"swimlane-process",
|
|
169
|
-
"gantt-project-plan",
|
|
170
|
-
"circular-lifecycle",
|
|
171
|
-
"customer-journey",
|
|
172
|
-
"org-chart",
|
|
173
|
-
"capability-map",
|
|
174
|
-
"logic-tree",
|
|
175
|
-
"hub-and-spoke",
|
|
176
|
-
"architecture-stack",
|
|
177
|
-
"ecosystem-map",
|
|
178
|
-
"network-dependency-map",
|
|
179
|
-
"wheel-radial",
|
|
180
|
-
"geographic-map",
|
|
181
|
-
"screenshot-walkthrough",
|
|
182
|
-
"market-size",
|
|
183
|
-
"persona-grid",
|
|
184
|
-
"competitive-landscape",
|
|
185
|
-
"business-model-canvas",
|
|
186
|
-
"customer-logos",
|
|
187
|
-
"executive-decision",
|
|
188
|
-
"status-rag",
|
|
189
|
-
"raci-matrix",
|
|
190
|
-
"action-plan",
|
|
191
|
-
"assumptions-dependencies",
|
|
192
|
-
"appendix-index",
|
|
193
|
-
"detailed-data-table"
|
|
194
|
-
],
|
|
195
|
-
chartTypes: [
|
|
196
|
-
"100pct-stacked-area-3x",
|
|
197
|
-
"100pct-stacked-bar-3x",
|
|
198
|
-
"100pct-stacked-column-3x",
|
|
199
|
-
"area",
|
|
200
|
-
"bar",
|
|
201
|
-
"box-and-whisker",
|
|
202
|
-
"column",
|
|
203
|
-
"doughnut",
|
|
204
|
-
"filled-radar",
|
|
205
|
-
"funnel",
|
|
206
|
-
"histogram",
|
|
207
|
-
"line",
|
|
208
|
-
"line-with-markers",
|
|
209
|
-
"pareto",
|
|
210
|
-
"pie",
|
|
211
|
-
"radar",
|
|
212
|
-
"radar-with-markers",
|
|
213
|
-
"scatter",
|
|
214
|
-
"stacked-area-3x",
|
|
215
|
-
"stacked-bar-3x",
|
|
216
|
-
"stacked-column-3x",
|
|
217
|
-
"stacked-line-3x",
|
|
218
|
-
"stacked-line-with-markers-3x",
|
|
219
|
-
"treemap",
|
|
220
|
-
"waterfall",
|
|
221
|
-
"world",
|
|
222
|
-
"100pct-bullet-bar",
|
|
223
|
-
"100pct-bullet-bar-2x",
|
|
224
|
-
"100pct-bullet-bar-3x",
|
|
225
|
-
"100pct-bullet-column",
|
|
226
|
-
"100pct-bullet-column-2x",
|
|
227
|
-
"100pct-bullet-column-3x",
|
|
228
|
-
"100pct-progress-bar",
|
|
229
|
-
"100pct-stacked-area-2x",
|
|
230
|
-
"100pct-stacked-bar-2x",
|
|
231
|
-
"100pct-stacked-column-2x",
|
|
232
|
-
"australia",
|
|
233
|
-
"box-and-whisker-2x",
|
|
234
|
-
"box-and-whisker-3x",
|
|
235
|
-
"bullet-bar",
|
|
236
|
-
"bullet-bar-2x",
|
|
237
|
-
"bullet-bar-3x",
|
|
238
|
-
"bullet-column",
|
|
239
|
-
"bullet-column-2x",
|
|
240
|
-
"bullet-column-3x",
|
|
241
|
-
"canada",
|
|
242
|
-
"clustered-bar-2x",
|
|
243
|
-
"clustered-column",
|
|
244
|
-
"dot-plot",
|
|
245
|
-
"dot-plot-2x",
|
|
246
|
-
"dot-plot-3x",
|
|
247
|
-
"dot-plot-4x",
|
|
248
|
-
"dot-plot-5x",
|
|
249
|
-
"dot-plot-6x",
|
|
250
|
-
"dumbbell",
|
|
251
|
-
"line-2x",
|
|
252
|
-
"line-3x",
|
|
253
|
-
"line-with-high-low",
|
|
254
|
-
"line-with-high-low-and-markers",
|
|
255
|
-
"line-with-markers-2x",
|
|
256
|
-
"line-with-markers-3x",
|
|
257
|
-
"sparkline",
|
|
258
|
-
"sparkline-2x",
|
|
259
|
-
"sparkline-3x",
|
|
260
|
-
"sparkline-4x",
|
|
261
|
-
"sparkline-5x",
|
|
262
|
-
"sparkline-6x",
|
|
263
|
-
"stacked-area-2x",
|
|
264
|
-
"stacked-bar-2x",
|
|
265
|
-
"stacked-column-2x",
|
|
266
|
-
"stacked-line-2x",
|
|
267
|
-
"stacked-line-with-markers-2x",
|
|
268
|
-
"treemap-2x",
|
|
269
|
-
"treemap-3x",
|
|
270
|
-
"united-kingdom",
|
|
271
|
-
"united-states"
|
|
272
|
-
],
|
|
273
|
-
narratives: [
|
|
274
|
-
"problem-solution",
|
|
275
|
-
"scqa",
|
|
276
|
-
"pyramid-principle",
|
|
277
|
-
"situation-complication-resolution",
|
|
278
|
-
"what-so-what-now-what",
|
|
279
|
-
"strategic-narrative",
|
|
280
|
-
"golden-circle",
|
|
281
|
-
"conference-talk",
|
|
282
|
-
"transformation-arc",
|
|
283
|
-
"pitch-deck",
|
|
284
|
-
"early-startup-pitch",
|
|
285
|
-
"venture-pitch",
|
|
286
|
-
"persuasive-sales",
|
|
287
|
-
"sparkline",
|
|
288
|
-
"company-intro",
|
|
289
|
-
"marketing-strategy",
|
|
290
|
-
"product-launch",
|
|
291
|
-
"strategic-advisory",
|
|
292
|
-
"challenge-resolution",
|
|
293
|
-
"project-proposal",
|
|
294
|
-
"vision-roadmap",
|
|
295
|
-
"failure-analysis",
|
|
296
|
-
"star-method",
|
|
297
|
-
"classic-story",
|
|
298
|
-
"heros-journey",
|
|
299
|
-
"business-narrative",
|
|
300
|
-
"change-story",
|
|
301
|
-
"rags-to-riches",
|
|
302
|
-
"underdog-victory",
|
|
303
|
-
"survival-story",
|
|
304
|
-
"educate",
|
|
305
|
-
"persuade",
|
|
306
|
-
"reveal",
|
|
307
|
-
"justice",
|
|
308
|
-
"innovation",
|
|
309
|
-
"focus",
|
|
310
|
-
"qbr",
|
|
311
|
-
"business-review",
|
|
312
|
-
"board-meeting",
|
|
313
|
-
"weekly-progress",
|
|
314
|
-
"status-update",
|
|
315
|
-
"performance-review",
|
|
316
|
-
"survey-analysis",
|
|
317
|
-
"trend-analysis",
|
|
318
|
-
"data-story",
|
|
319
|
-
"employee-review",
|
|
320
|
-
"performance-improvement-plan",
|
|
321
|
-
"capacity-planning"
|
|
322
|
-
],
|
|
323
|
-
socialPlatforms: [
|
|
324
|
-
"linkedin",
|
|
325
|
-
"x",
|
|
326
|
-
"github",
|
|
327
|
-
"youtube",
|
|
328
|
-
"instagram",
|
|
329
|
-
"facebook",
|
|
330
|
-
"tiktok",
|
|
331
|
-
"threads",
|
|
332
|
-
"mastodon",
|
|
333
|
-
"bluesky"
|
|
334
|
-
],
|
|
335
|
-
languages: [
|
|
336
|
-
"afrikaans",
|
|
337
|
-
"albanian",
|
|
338
|
-
"amharic",
|
|
339
|
-
"arabic",
|
|
340
|
-
"armenian",
|
|
341
|
-
"aymara",
|
|
342
|
-
"azerbaijani",
|
|
343
|
-
"bengali",
|
|
344
|
-
"berber-latin",
|
|
345
|
-
"bosnian-latin",
|
|
346
|
-
"bulgarian",
|
|
347
|
-
"catalan",
|
|
348
|
-
"cebuano",
|
|
349
|
-
"chinese-simplified",
|
|
350
|
-
"chinese-traditional",
|
|
351
|
-
"chittagonian",
|
|
352
|
-
"croatian",
|
|
353
|
-
"czech",
|
|
354
|
-
"danish",
|
|
355
|
-
"dutch",
|
|
356
|
-
"english",
|
|
357
|
-
"english-au",
|
|
358
|
-
"english-ca",
|
|
359
|
-
"english-gb",
|
|
360
|
-
"english-in",
|
|
361
|
-
"english-us",
|
|
362
|
-
"estonian",
|
|
363
|
-
"filipino",
|
|
364
|
-
"finnish",
|
|
365
|
-
"french",
|
|
366
|
-
"fulfulde",
|
|
367
|
-
"galician",
|
|
368
|
-
"georgian",
|
|
369
|
-
"german",
|
|
370
|
-
"greek",
|
|
371
|
-
"gujarati",
|
|
372
|
-
"hausa",
|
|
373
|
-
"hebrew",
|
|
374
|
-
"hindi",
|
|
375
|
-
"hungarian",
|
|
376
|
-
"igbo",
|
|
377
|
-
"indonesian",
|
|
378
|
-
"italian",
|
|
379
|
-
"japanese",
|
|
380
|
-
"kannada",
|
|
381
|
-
"kazakh",
|
|
382
|
-
"khmer",
|
|
383
|
-
"kinyarwanda",
|
|
384
|
-
"korean",
|
|
385
|
-
"kurmanji",
|
|
386
|
-
"latvian",
|
|
387
|
-
"lithuanian",
|
|
388
|
-
"macedonian",
|
|
389
|
-
"malagasy",
|
|
390
|
-
"malay",
|
|
391
|
-
"malayalam",
|
|
392
|
-
"maori",
|
|
393
|
-
"marathi",
|
|
394
|
-
"mongolian",
|
|
395
|
-
"nepali",
|
|
396
|
-
"norwegian",
|
|
397
|
-
"odia",
|
|
398
|
-
"oromo",
|
|
399
|
-
"pashto",
|
|
400
|
-
"persian",
|
|
401
|
-
"polish",
|
|
402
|
-
"portuguese",
|
|
403
|
-
"punjabi-gurmukhi",
|
|
404
|
-
"punjabi-shahmukhi",
|
|
405
|
-
"romanian",
|
|
406
|
-
"russian",
|
|
407
|
-
"serbian-cyrillic",
|
|
408
|
-
"serbian-latin",
|
|
409
|
-
"shona",
|
|
410
|
-
"slovak",
|
|
411
|
-
"slovenian",
|
|
412
|
-
"somali",
|
|
413
|
-
"spanish",
|
|
414
|
-
"swahili",
|
|
415
|
-
"swedish",
|
|
416
|
-
"tagalog",
|
|
417
|
-
"tajik",
|
|
418
|
-
"tamil",
|
|
419
|
-
"telugu",
|
|
420
|
-
"thai",
|
|
421
|
-
"turkish",
|
|
422
|
-
"ukrainian",
|
|
423
|
-
"urdu",
|
|
424
|
-
"uzbek-latin",
|
|
425
|
-
"vietnamese-quoc-ngu",
|
|
426
|
-
"xhosa",
|
|
427
|
-
"yoruba",
|
|
428
|
-
"zulu"
|
|
429
|
-
],
|
|
430
|
-
colorSchemes: [
|
|
431
|
-
"black-and-white",
|
|
432
|
-
"bold-red",
|
|
433
|
-
"boost",
|
|
434
|
-
"burnt-orange",
|
|
435
|
-
"cool-horizon",
|
|
436
|
-
"corporate-blue",
|
|
437
|
-
"deep-purple",
|
|
438
|
-
"forest-green",
|
|
439
|
-
"golden-yellow",
|
|
440
|
-
"luxury",
|
|
441
|
-
"pastel-red",
|
|
442
|
-
"slate-gray",
|
|
443
|
-
"steel-blue",
|
|
444
|
-
"vibes"
|
|
445
|
-
],
|
|
446
|
-
fontSchemes: [
|
|
447
|
-
"consolas",
|
|
448
|
-
"courier-new",
|
|
449
|
-
"arial",
|
|
450
|
-
"calibri",
|
|
451
|
-
"impact",
|
|
452
|
-
"lucida-sans",
|
|
453
|
-
"segoe-ui",
|
|
454
|
-
"segoe-ui-light",
|
|
455
|
-
"tahoma",
|
|
456
|
-
"trebuchet-ms",
|
|
457
|
-
"verdana",
|
|
458
|
-
"bookman",
|
|
459
|
-
"century-schoolbook",
|
|
460
|
-
"constantia",
|
|
461
|
-
"garamond",
|
|
462
|
-
"rockwell",
|
|
463
|
-
"times-new-roman",
|
|
464
|
-
"aptos",
|
|
465
|
-
"grandview",
|
|
466
|
-
"seaford",
|
|
467
|
-
"skeena",
|
|
468
|
-
"tenorite",
|
|
469
|
-
"georgia",
|
|
470
|
-
"microsoft-yahei",
|
|
471
|
-
"simsun",
|
|
472
|
-
"fangsong",
|
|
473
|
-
"yu-gothic",
|
|
474
|
-
"pmingliu",
|
|
475
|
-
"mingliu",
|
|
476
|
-
"ms-mincho",
|
|
477
|
-
"malgun-gothic",
|
|
478
|
-
"batang",
|
|
479
|
-
"gungsuh",
|
|
480
|
-
"mangal",
|
|
481
|
-
"nirmala-ui",
|
|
482
|
-
"latha",
|
|
483
|
-
"david",
|
|
484
|
-
"miriam",
|
|
485
|
-
"gisha",
|
|
486
|
-
"vrinda",
|
|
487
|
-
"shruti",
|
|
488
|
-
"tunga",
|
|
489
|
-
"kartika",
|
|
490
|
-
"kalinga",
|
|
491
|
-
"raavi",
|
|
492
|
-
"gautami",
|
|
493
|
-
"arabic-typesetting",
|
|
494
|
-
"microsoft-jhenghei",
|
|
495
|
-
"meiryo",
|
|
496
|
-
"angsana-new",
|
|
497
|
-
"aparajita",
|
|
498
|
-
"dilleniaupc",
|
|
499
|
-
"sakkal-majalla",
|
|
500
|
-
"shonar-bangla",
|
|
501
|
-
"sylfaen",
|
|
502
|
-
"traditional-arabic",
|
|
503
|
-
"montserrat",
|
|
504
|
-
"open-sans",
|
|
505
|
-
"poppins",
|
|
506
|
-
"pt-serif",
|
|
507
|
-
"raleway",
|
|
508
|
-
"roboto",
|
|
509
|
-
"noto-sans-arabic",
|
|
510
|
-
"noto-sans-armenian",
|
|
511
|
-
"noto-sans-bengali",
|
|
512
|
-
"noto-sans-devangari",
|
|
513
|
-
"noto-sans-georgian",
|
|
514
|
-
"noto-sans-gujarati",
|
|
515
|
-
"noto-sans-gurmukhi",
|
|
516
|
-
"noto-sans-hebrew",
|
|
517
|
-
"noto-sans-jp",
|
|
518
|
-
"noto-sans-kannada",
|
|
519
|
-
"noto-sans-kr",
|
|
520
|
-
"noto-sans-malayalam",
|
|
521
|
-
"noto-sans-mongolian",
|
|
522
|
-
"noto-sans-oriya",
|
|
523
|
-
"noto-sans-sc",
|
|
524
|
-
"noto-sans-tamil",
|
|
525
|
-
"noto-sans-tc",
|
|
526
|
-
"noto-sans-telugu",
|
|
527
|
-
"noto-sans",
|
|
528
|
-
"noto-sans-thai",
|
|
529
|
-
"noto-nastaliq-urdu",
|
|
530
|
-
"noto-naksh-arabic",
|
|
531
|
-
"noto-sans-ethiopic",
|
|
532
|
-
"noto-sans-khmer",
|
|
533
|
-
"nyala",
|
|
534
|
-
"daunpenh",
|
|
535
|
-
"khmer-ui"
|
|
536
|
-
]
|
|
537
|
-
};
|
|
538
|
-
var deprecatedCatalogIds = {
|
|
539
|
-
"audiences/executives": "executive",
|
|
540
|
-
"audiences/investors": "investor",
|
|
541
|
-
"audiences/customers": "customer",
|
|
542
|
-
"audiences/sales-team": "sales",
|
|
543
|
-
"audiences/marketing-team": "marketing",
|
|
544
|
-
"audiences/regulators": "regulatory",
|
|
545
|
-
"chartTypes/100pct-bullet-bar": "100pct-stacked-bar-3x",
|
|
546
|
-
"chartTypes/100pct-bullet-bar-2x": "100pct-stacked-bar-3x",
|
|
547
|
-
"chartTypes/100pct-bullet-bar-3x": "100pct-stacked-bar-3x",
|
|
548
|
-
"chartTypes/100pct-bullet-column": "100pct-stacked-column-3x",
|
|
549
|
-
"chartTypes/100pct-bullet-column-2x": "100pct-stacked-column-3x",
|
|
550
|
-
"chartTypes/100pct-bullet-column-3x": "100pct-stacked-column-3x",
|
|
551
|
-
"chartTypes/100pct-progress-bar": "100pct-stacked-bar-3x",
|
|
552
|
-
"chartTypes/100pct-stacked-area-2x": "100pct-stacked-area-3x",
|
|
553
|
-
"chartTypes/100pct-stacked-bar-2x": "100pct-stacked-bar-3x",
|
|
554
|
-
"chartTypes/100pct-stacked-column-2x": "100pct-stacked-column-3x",
|
|
555
|
-
"chartTypes/australia": "world",
|
|
556
|
-
"chartTypes/box-and-whisker-2x": "box-and-whisker",
|
|
557
|
-
"chartTypes/box-and-whisker-3x": "box-and-whisker",
|
|
558
|
-
"chartTypes/bullet-bar": "bar",
|
|
559
|
-
"chartTypes/bullet-bar-2x": "bar",
|
|
560
|
-
"chartTypes/bullet-bar-3x": "bar",
|
|
561
|
-
"chartTypes/bullet-column": "column",
|
|
562
|
-
"chartTypes/bullet-column-2x": "column",
|
|
563
|
-
"chartTypes/bullet-column-3x": "column",
|
|
564
|
-
"chartTypes/canada": "world",
|
|
565
|
-
"chartTypes/clustered-bar-2x": "bar",
|
|
566
|
-
"chartTypes/clustered-column": "column",
|
|
567
|
-
"chartTypes/dot-plot": "scatter",
|
|
568
|
-
"chartTypes/dot-plot-2x": "scatter",
|
|
569
|
-
"chartTypes/dot-plot-3x": "scatter",
|
|
570
|
-
"chartTypes/dot-plot-4x": "scatter",
|
|
571
|
-
"chartTypes/dot-plot-5x": "scatter",
|
|
572
|
-
"chartTypes/dot-plot-6x": "scatter",
|
|
573
|
-
"chartTypes/dumbbell": "scatter",
|
|
574
|
-
"chartTypes/line-2x": "line",
|
|
575
|
-
"chartTypes/line-3x": "line",
|
|
576
|
-
"chartTypes/line-with-high-low": "line",
|
|
577
|
-
"chartTypes/line-with-high-low-and-markers": "line-with-markers",
|
|
578
|
-
"chartTypes/line-with-markers-2x": "line-with-markers",
|
|
579
|
-
"chartTypes/line-with-markers-3x": "line-with-markers",
|
|
580
|
-
"chartTypes/sparkline": "line",
|
|
581
|
-
"chartTypes/sparkline-2x": "line",
|
|
582
|
-
"chartTypes/sparkline-3x": "line",
|
|
583
|
-
"chartTypes/sparkline-4x": "line",
|
|
584
|
-
"chartTypes/sparkline-5x": "line",
|
|
585
|
-
"chartTypes/sparkline-6x": "line",
|
|
586
|
-
"chartTypes/stacked-area-2x": "stacked-area-3x",
|
|
587
|
-
"chartTypes/stacked-bar-2x": "stacked-bar-3x",
|
|
588
|
-
"chartTypes/stacked-column-2x": "stacked-column-3x",
|
|
589
|
-
"chartTypes/stacked-line-2x": "stacked-line-3x",
|
|
590
|
-
"chartTypes/stacked-line-with-markers-2x": "stacked-line-with-markers-3x",
|
|
591
|
-
"chartTypes/treemap-2x": "treemap",
|
|
592
|
-
"chartTypes/treemap-3x": "treemap",
|
|
593
|
-
"chartTypes/united-kingdom": "world",
|
|
594
|
-
"chartTypes/united-states": "world"
|
|
595
|
-
};
|
|
596
|
-
|
|
597
41
|
// src/chart-options.ts
|
|
598
42
|
var END_POSITIONS = ["center", "inside-end", "inside-base", "outside-end"];
|
|
599
43
|
var STACKED_POSITIONS = ["center", "inside-end", "inside-base"];
|
|
@@ -602,9 +46,12 @@ var PIE_POSITIONS = ["center", "inside-end", "outside-end"];
|
|
|
602
46
|
var NONE = [];
|
|
603
47
|
var VALUE_CATEGORY = ["category", "value"];
|
|
604
48
|
var ALL_CONTENT = ["category", "value", "percent"];
|
|
605
|
-
var
|
|
606
|
-
var
|
|
607
|
-
var
|
|
49
|
+
var COMBO_POSITIONS = ["center", "inside-end", "inside-base", "outside-end", "above", "below", "left", "right"];
|
|
50
|
+
var categoryKinds = /* @__PURE__ */ new Set(["bar", "line", "area", "scatter", "histogram", "pareto", "box", "waterfall", "funnel", "combo"]);
|
|
51
|
+
var valueKinds = /* @__PURE__ */ new Set(["bar", "line", "area", "scatter", "histogram", "pareto", "box", "waterfall", "combo"]);
|
|
52
|
+
var legendKinds = /* @__PURE__ */ new Set(["bar", "line", "area", "pie", "doughnut", "scatter", "radar", "box", "combo"]);
|
|
53
|
+
var highlightSeriesKinds = /* @__PURE__ */ new Set(["bar", "line", "area", "scatter", "radar"]);
|
|
54
|
+
var highlightCategoryKinds = /* @__PURE__ */ new Set(["bar", "line", "pie", "doughnut"]);
|
|
608
55
|
function labelSupport(target) {
|
|
609
56
|
const none = { supported: true, content: VALUE_CATEGORY, positions: NONE, defaultPosition: null, defaultOn: false };
|
|
610
57
|
switch (target.kind) {
|
|
@@ -613,6 +60,9 @@ function labelSupport(target) {
|
|
|
613
60
|
case "line":
|
|
614
61
|
case "scatter":
|
|
615
62
|
return { ...none, positions: POINT_POSITIONS, defaultPosition: "above" };
|
|
63
|
+
// Columns take the clustered positions and lines the point positions ('center' fits both); each part falls back to its own default.
|
|
64
|
+
case "combo":
|
|
65
|
+
return { ...none, positions: COMBO_POSITIONS, defaultPosition: "outside-end" };
|
|
616
66
|
case "pie":
|
|
617
67
|
return { ...none, content: ALL_CONTENT, positions: PIE_POSITIONS, defaultPosition: "outside-end" };
|
|
618
68
|
case "doughnut":
|
|
@@ -634,25 +84,26 @@ function labelSupport(target) {
|
|
|
634
84
|
}
|
|
635
85
|
function chartOptionSupport(target) {
|
|
636
86
|
return {
|
|
637
|
-
axisTitles: { category: categoryKinds.has(target.kind), value: valueKinds.has(target.kind) },
|
|
87
|
+
axisTitles: { category: categoryKinds.has(target.kind), value: valueKinds.has(target.kind), secondary: target.kind === "combo" },
|
|
638
88
|
legend: legendKinds.has(target.kind),
|
|
89
|
+
highlight: { series: highlightSeriesKinds.has(target.kind), categories: highlightCategoryKinds.has(target.kind) },
|
|
639
90
|
dataLabels: labelSupport(target)
|
|
640
91
|
};
|
|
641
92
|
}
|
|
642
93
|
var KEPT = {
|
|
643
94
|
column: { kind: "bar" },
|
|
644
|
-
"stacked-column
|
|
645
|
-
"100pct-stacked-column
|
|
95
|
+
"stacked-column": { kind: "bar", stacked: true },
|
|
96
|
+
"100pct-stacked-column": { kind: "bar", stacked: true },
|
|
646
97
|
bar: { kind: "bar" },
|
|
647
|
-
"stacked-bar
|
|
648
|
-
"100pct-stacked-bar
|
|
98
|
+
"stacked-bar": { kind: "bar", stacked: true },
|
|
99
|
+
"100pct-stacked-bar": { kind: "bar", stacked: true },
|
|
649
100
|
line: { kind: "line" },
|
|
650
101
|
"line-with-markers": { kind: "line" },
|
|
651
|
-
"stacked-line
|
|
652
|
-
"stacked-line-with-markers
|
|
102
|
+
"stacked-line": { kind: "line", stacked: true },
|
|
103
|
+
"stacked-line-with-markers": { kind: "line", stacked: true },
|
|
653
104
|
area: { kind: "area" },
|
|
654
|
-
"stacked-area
|
|
655
|
-
"100pct-stacked-area
|
|
105
|
+
"stacked-area": { kind: "area", stacked: true },
|
|
106
|
+
"100pct-stacked-area": { kind: "area", stacked: true },
|
|
656
107
|
pie: { kind: "pie" },
|
|
657
108
|
doughnut: { kind: "doughnut" },
|
|
658
109
|
scatter: { kind: "scatter" },
|
|
@@ -665,14 +116,14 @@ var KEPT = {
|
|
|
665
116
|
"box-and-whisker": { kind: "box" },
|
|
666
117
|
waterfall: { kind: "waterfall" },
|
|
667
118
|
funnel: { kind: "funnel" },
|
|
668
|
-
world: { kind: "map" }
|
|
119
|
+
world: { kind: "map" },
|
|
120
|
+
combo: { kind: "combo" }
|
|
669
121
|
};
|
|
670
122
|
function chartOptionTarget(typeId) {
|
|
671
123
|
if (typeof typeId !== "string") return void 0;
|
|
672
124
|
const raw = typeId.trim().toLowerCase();
|
|
673
125
|
const id = raw === "donut" ? "doughnut" : raw;
|
|
674
|
-
const
|
|
675
|
-
const target = Object.hasOwn(KEPT, kept) ? KEPT[kept] : void 0;
|
|
126
|
+
const target = Object.hasOwn(KEPT, id) ? KEPT[id] : void 0;
|
|
676
127
|
return target ? { ...target } : void 0;
|
|
677
128
|
}
|
|
678
129
|
var record2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -686,11 +137,25 @@ function resolveChartOptions(chart, target) {
|
|
|
686
137
|
const support = target ? chartOptionSupport(target) : void 0;
|
|
687
138
|
const adapt = (option, reason, message) => result.diagnostics.push({ code: "chart-option-adapted", option, reason, message });
|
|
688
139
|
const kind2 = target?.kind ?? "unknown";
|
|
140
|
+
const combo = target?.kind === "combo";
|
|
141
|
+
if (!combo) {
|
|
142
|
+
for (const option of ["line", "secondaryAxis"]) {
|
|
143
|
+
if (chart[option] !== void 0) adapt(option, "unsupported-type", `Only a 'combo' chart draws line series${option === "secondaryAxis" ? " on a secondary axis" : ""}; ${option} is ignored on a '${kind2}' chart.`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
689
146
|
if (record2(chart.axisTitles)) {
|
|
690
|
-
for (const axis of ["category", "value"]) {
|
|
147
|
+
for (const axis of ["category", "value", "secondary"]) {
|
|
691
148
|
const raw = chart.axisTitles[axis];
|
|
692
149
|
if (typeof raw !== "string" || !raw.trim()) continue;
|
|
693
|
-
if (support && !support.axisTitles
|
|
150
|
+
if (axis === "secondary" && support && !support.axisTitles.secondary) {
|
|
151
|
+
adapt("axisTitles.secondary", "unsupported-type", `Only a 'combo' chart has a secondary value axis; the secondary axis title is not drawn or exported on a '${kind2}' chart.`);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (axis === "secondary" && combo && !(Array.isArray(chart.secondaryAxis) && chart.secondaryAxis.some((name) => typeof name === "string"))) {
|
|
155
|
+
adapt("axisTitles.secondary", "unsupported-type", "This combo chart plots no series on a secondary axis (secondaryAxis is absent); the secondary axis title is not drawn or exported.");
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (axis !== "secondary" && support && !support.axisTitles[axis]) {
|
|
694
159
|
adapt(`axisTitles.${axis}`, "unsupported-type", `A '${kind2}' chart has no ${axis} axis to title; the ${axis} axis title is not drawn or exported.`);
|
|
695
160
|
continue;
|
|
696
161
|
}
|
|
@@ -717,8 +182,18 @@ function resolveChartOptions(chart, target) {
|
|
|
717
182
|
if (!content.length) content.push("value");
|
|
718
183
|
const positions = support?.dataLabels.positions ?? NONE;
|
|
719
184
|
let position = support?.dataLabels.defaultPosition ?? null;
|
|
720
|
-
|
|
721
|
-
|
|
185
|
+
let linePosition;
|
|
186
|
+
const requestedPosition = typeof options.position === "string" && POSITIONS.has(options.position) && options.position !== "auto" ? options.position : void 0;
|
|
187
|
+
if (combo) {
|
|
188
|
+
linePosition = "above";
|
|
189
|
+
if (requestedPosition) {
|
|
190
|
+
if (END_POSITIONS.includes(requestedPosition)) position = requestedPosition;
|
|
191
|
+
else adapt("dataLabels.position", "unsupported-position", `The column series of a combo chart cannot place data labels '${requestedPosition}'; they use outside-end.`);
|
|
192
|
+
if (POINT_POSITIONS.includes(requestedPosition)) linePosition = requestedPosition;
|
|
193
|
+
else adapt("dataLabels.position", "unsupported-position", `The line series of a combo chart cannot place data labels '${requestedPosition}'; they use above.`);
|
|
194
|
+
}
|
|
195
|
+
} else if (requestedPosition) {
|
|
196
|
+
if (!support || positions.includes(requestedPosition)) position = requestedPosition;
|
|
722
197
|
else adapt("dataLabels.position", "unsupported-position", `A '${kind2}'${target?.stacked ? " stacked" : ""} chart cannot place data labels '${options.position}'; the type's default position is used.`);
|
|
723
198
|
}
|
|
724
199
|
let separator = typeof options.separator === "string" ? options.separator : DEFAULT_CHART_LABEL_SEPARATOR;
|
|
@@ -726,10 +201,23 @@ function resolveChartOptions(chart, target) {
|
|
|
726
201
|
separator = separator.replace(/[\r\n]+/g, " ");
|
|
727
202
|
adapt("dataLabels.separator", "unsupported-content", "A data label is one line; the line break in the separator is replaced with a space.");
|
|
728
203
|
}
|
|
729
|
-
result.dataLabels = { content, position, separator };
|
|
204
|
+
result.dataLabels = { content, position, separator, ...linePosition ? { linePosition } : {} };
|
|
730
205
|
}
|
|
731
206
|
}
|
|
732
|
-
|
|
207
|
+
if (record2(chart.highlight)) {
|
|
208
|
+
const names = (value) => Array.isArray(value) ? [...new Set(value.filter((entry) => typeof entry === "string"))] : [];
|
|
209
|
+
const kept = { series: [], categories: [] };
|
|
210
|
+
for (const part of ["series", "categories"]) {
|
|
211
|
+
const requested = names(chart.highlight[part]);
|
|
212
|
+
if (!requested.length) continue;
|
|
213
|
+
if (support && !support.highlight[part]) {
|
|
214
|
+
const alternative = part === "series" ? support.highlight.categories ? " (name categories instead)" : "" : support.highlight.series ? " (name series instead)" : "";
|
|
215
|
+
adapt(`highlight.${part}`, "unsupported-type", `A '${kind2}' chart cannot highlight ${part}${alternative}; the highlighted ${part} are ignored.`);
|
|
216
|
+
} else kept[part] = requested;
|
|
217
|
+
}
|
|
218
|
+
if (kept.series.length || kept.categories.length) result.highlight = kept;
|
|
219
|
+
}
|
|
220
|
+
result.active = result.legend !== void 0 || result.dataLabels !== void 0 || result.dataLabelsOff === true || result.axisTitles.category !== void 0 || result.axisTitles.value !== void 0 || result.axisTitles.secondary !== void 0;
|
|
733
221
|
return result;
|
|
734
222
|
}
|
|
735
223
|
function formatChartLabelNumber(value) {
|
|
@@ -741,6 +229,14 @@ function formatChartLabelPercent(share) {
|
|
|
741
229
|
function chartLabelText(parts, content, separator = DEFAULT_CHART_LABEL_SEPARATOR) {
|
|
742
230
|
return CONTENT_ORDER.filter((part) => content.includes(part) && parts[part] !== void 0).map((part) => parts[part]).join(separator);
|
|
743
231
|
}
|
|
232
|
+
function chartHighlightMarks(highlight, data) {
|
|
233
|
+
if (!highlight) return void 0;
|
|
234
|
+
const first = data.columns.length > 1 ? data.hasX ? 2 : 1 : 0;
|
|
235
|
+
const series = data.columns.slice(first).map((name) => highlight.series.includes(name));
|
|
236
|
+
const label = (cell) => cell === null || cell === void 0 ? "" : String(cell);
|
|
237
|
+
const categories = data.columns.length > 1 ? data.rows.map((row) => highlight.categories.includes(label(row[0]))) : data.rows.map(() => false);
|
|
238
|
+
return series.some(Boolean) || categories.some(Boolean) ? { series, categories } : void 0;
|
|
239
|
+
}
|
|
744
240
|
|
|
745
241
|
// src/content-walk.ts
|
|
746
242
|
function isRecord(value) {
|
|
@@ -749,7 +245,6 @@ function isRecord(value) {
|
|
|
749
245
|
function pathFor(parentPath, key) {
|
|
750
246
|
return parentPath === "/" ? `/${key}` : `${parentPath}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`;
|
|
751
247
|
}
|
|
752
|
-
var bareIdPattern = /^[a-z0-9][a-z0-9-]*$/;
|
|
753
248
|
var promotedRegionKeys = [
|
|
754
249
|
"left",
|
|
755
250
|
"center",
|
|
@@ -928,6 +423,24 @@ function formatSlideNumber(format, current, total) {
|
|
|
928
423
|
return { text: text2, fields: fields2 };
|
|
929
424
|
}
|
|
930
425
|
|
|
426
|
+
// src/deck-metadata.ts
|
|
427
|
+
function recordsOf(value) {
|
|
428
|
+
return (Array.isArray(value) ? value : value === void 0 || value === null ? [] : [value]).filter(isRecord);
|
|
429
|
+
}
|
|
430
|
+
function speakersOf(presentation) {
|
|
431
|
+
return isRecord(presentation) ? recordsOf(presentation.speaker) : [];
|
|
432
|
+
}
|
|
433
|
+
function organizationsOf(presentation) {
|
|
434
|
+
return isRecord(presentation) ? recordsOf(presentation.organization) : [];
|
|
435
|
+
}
|
|
436
|
+
function primarySpeaker(presentation) {
|
|
437
|
+
return speakersOf(presentation)[0];
|
|
438
|
+
}
|
|
439
|
+
function primaryOrganization(presentation) {
|
|
440
|
+
const organizations = organizationsOf(presentation);
|
|
441
|
+
return organizations.find((item) => item.role === "primary") ?? organizations[0];
|
|
442
|
+
}
|
|
443
|
+
|
|
931
444
|
// src/variables.ts
|
|
932
445
|
var VARIABLE_KINDS = ["color", "text", "number", "date", "image", "url", "list"];
|
|
933
446
|
var DEFAULT_VARIABLE_DATE_FORMAT = "MMMM d, yyyy";
|
|
@@ -941,12 +454,15 @@ var OPFVariableError = class extends Error {
|
|
|
941
454
|
}
|
|
942
455
|
};
|
|
943
456
|
var idPattern = /^[a-z][a-z0-9-]*$/;
|
|
944
|
-
var
|
|
457
|
+
var nameSource = String.raw`[a-z][a-z0-9-]*|(?:deck|speaker|organization)(?:\.[A-Za-z0-9_-]+){1,2}`;
|
|
458
|
+
var referencePattern = new RegExp(String.raw`^var:(${nameSource})$`);
|
|
459
|
+
var builtinNamePattern = /^(?:speakers|(?:deck|speaker|organization)(?:\.[A-Za-z0-9_-]+){1,2})$/;
|
|
460
|
+
var builtinUsePattern = /\{\{\s*(?:speakers\b|(?:deck|speaker|organization)\.)|^var:(?:speakers$|(?:deck|speaker|organization)\.)/;
|
|
945
461
|
var hexPattern = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
|
|
946
462
|
var urlPattern = /^(?:https?:\/\/|mailto:|tel:)\S+$/;
|
|
947
463
|
var datePrefixPattern = /^(\d{4}-\d{2}-\d{2})(?:[T ].*)?$/;
|
|
948
464
|
var decimalPattern = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
949
|
-
var tokenPattern =
|
|
465
|
+
var tokenPattern = new RegExp(String.raw`\\\{\{|\{\{\s*(${nameSource})\s*(?:\|([^{}]*))?\}\}`, "g");
|
|
950
466
|
var SAMPLES = {
|
|
951
467
|
color: "#000000",
|
|
952
468
|
text: "Sample text",
|
|
@@ -1039,8 +555,18 @@ function variableDeclarations(presentation) {
|
|
|
1039
555
|
}
|
|
1040
556
|
return out;
|
|
1041
557
|
}
|
|
558
|
+
function usesBuiltins(value, root = true) {
|
|
559
|
+
if (typeof value === "string") return value.length >= 6 && builtinUsePattern.test(value);
|
|
560
|
+
if (Array.isArray(value)) return value.some((entry) => usesBuiltins(entry, false));
|
|
561
|
+
if (!isRecord(value)) return false;
|
|
562
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
563
|
+
if (skippedKeys.has(key) || root && skippedRootKeys.has(key)) continue;
|
|
564
|
+
if (usesBuiltins(entry, false)) return true;
|
|
565
|
+
}
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
1042
568
|
function hasContentVariables(presentation) {
|
|
1043
|
-
return isTemplate(presentation) || variableDeclarations(presentation).some((declaration) => declaration.kind !== "color");
|
|
569
|
+
return isTemplate(presentation) || variableDeclarations(presentation).some((declaration) => declaration.kind !== "color") || usesBuiltins(presentation);
|
|
1044
570
|
}
|
|
1045
571
|
var POSITIVE_ZERO = "0";
|
|
1046
572
|
function formatVariableNumber(value, pattern) {
|
|
@@ -1127,6 +653,93 @@ function inlineText(effective, format, path, context) {
|
|
|
1127
653
|
return value.join(format ?? ", ");
|
|
1128
654
|
}
|
|
1129
655
|
}
|
|
656
|
+
var DECK_FIELDS = { name: "text", description: "text", author: "text" };
|
|
657
|
+
var SPEAKER_FIELDS = { name: "text", title: "text", email: "text", phone: "text", bio: "text", photo: "image" };
|
|
658
|
+
var ORGANIZATION_FIELDS = { name: "text", legalName: "text", tagline: "text", domain: "text", email: "text", phone: "text", logo: "image" };
|
|
659
|
+
function isBuiltinName(name) {
|
|
660
|
+
return builtinNamePattern.test(name);
|
|
661
|
+
}
|
|
662
|
+
function builtinFields(root) {
|
|
663
|
+
return root === "deck" ? DECK_FIELDS : root === "speaker" ? SPEAKER_FIELDS : ORGANIZATION_FIELDS;
|
|
664
|
+
}
|
|
665
|
+
function present(value) {
|
|
666
|
+
if (typeof value === "string") return value.trim() === "" ? void 0 : value;
|
|
667
|
+
if (isRecord(value)) return typeof value.src === "string" && value.src.trim() ? value : void 0;
|
|
668
|
+
return void 0;
|
|
669
|
+
}
|
|
670
|
+
function builtinSource(name, doc) {
|
|
671
|
+
if (name === "speakers") {
|
|
672
|
+
const names = speakersOf(doc).map((speaker) => present(speaker.name)).filter((entry) => typeof entry === "string");
|
|
673
|
+
return { ok: true, kind: "list", raw: names.length ? names : void 0 };
|
|
674
|
+
}
|
|
675
|
+
const parts = name.split(".");
|
|
676
|
+
const root = parts[0];
|
|
677
|
+
const fields2 = builtinFields(root);
|
|
678
|
+
const list = (names) => names.map((entry) => `'${entry}'`).join(", ");
|
|
679
|
+
if (root === "deck") {
|
|
680
|
+
const field2 = parts[1];
|
|
681
|
+
if (parts.length !== 2 || !Object.hasOwn(fields2, field2)) return { ok: false, message: `'${name}' is not a built-in variable; the deck built-ins are ${list(Object.keys(fields2).map((key) => `deck.${key}`))}.` };
|
|
682
|
+
const value = doc[field2];
|
|
683
|
+
return { ok: true, kind: "text", raw: field2 === "author" && Array.isArray(value) ? present(value.filter((entry) => typeof entry === "string").join(", ")) : present(value) };
|
|
684
|
+
}
|
|
685
|
+
const field = parts[parts.length - 1];
|
|
686
|
+
if (!Object.hasOwn(fields2, field)) {
|
|
687
|
+
return { ok: false, message: `'${name}' is not a built-in variable: '${field}' is not a ${root} field; the fields are ${list(Object.keys(fields2))}.` };
|
|
688
|
+
}
|
|
689
|
+
let entity;
|
|
690
|
+
if (parts.length === 2) entity = root === "speaker" ? primarySpeaker(doc) : primaryOrganization(doc);
|
|
691
|
+
else {
|
|
692
|
+
const id = parts[1];
|
|
693
|
+
const entries = root === "speaker" ? speakersOf(doc) : organizationsOf(doc);
|
|
694
|
+
entity = entries.find((entry) => entry.id === id);
|
|
695
|
+
if (!entity) return { ok: false, message: `'${name}' names no ${root} with id '${id}'.` };
|
|
696
|
+
}
|
|
697
|
+
return { ok: true, kind: fields2[field], raw: present(entity?.[field]) };
|
|
698
|
+
}
|
|
699
|
+
function builtinEffective(name, path, context) {
|
|
700
|
+
if (context.resolvingBuiltins.has(name)) return void 0;
|
|
701
|
+
const cached = context.builtins.get(name);
|
|
702
|
+
if (cached !== void 0) {
|
|
703
|
+
if (cached === null) diag(context, unknownBuiltin(name, path, context), `ubi:${name}:${path}`);
|
|
704
|
+
else if (cached.status === "unfilled") diag(context, missingBuiltin(name, path), `bim:${name}:${path}`);
|
|
705
|
+
return cached ?? void 0;
|
|
706
|
+
}
|
|
707
|
+
const source = builtinSource(name, context.doc);
|
|
708
|
+
if (!source.ok) {
|
|
709
|
+
context.builtins.set(name, null);
|
|
710
|
+
diag(context, unknownBuiltin(name, path, context), `ubi:${name}:${path}`);
|
|
711
|
+
return void 0;
|
|
712
|
+
}
|
|
713
|
+
const declaration = { id: name, kind: source.kind, path: "", required: context.keepMissingBuiltins };
|
|
714
|
+
let effective;
|
|
715
|
+
const coerced = source.raw === void 0 ? void 0 : coerceVariableValue(source.kind, source.raw);
|
|
716
|
+
if (coerced?.ok) {
|
|
717
|
+
let value = coerced.value;
|
|
718
|
+
if (typeof value === "string" && value.includes("{{")) {
|
|
719
|
+
context.resolvingBuiltins.add(name);
|
|
720
|
+
value = interpolate(value, path, context).value;
|
|
721
|
+
context.resolvingBuiltins.delete(name);
|
|
722
|
+
}
|
|
723
|
+
effective = { declaration: { ...declaration, value }, status: "filled", value, provided: false };
|
|
724
|
+
} else {
|
|
725
|
+
effective = { declaration, status: "unfilled", provided: false };
|
|
726
|
+
diag(context, missingBuiltin(name, path), `bim:${name}:${path}`);
|
|
727
|
+
}
|
|
728
|
+
context.builtins.set(name, effective);
|
|
729
|
+
return effective;
|
|
730
|
+
}
|
|
731
|
+
function unknownBuiltin(name, path, context) {
|
|
732
|
+
const source = builtinSource(name, context.doc);
|
|
733
|
+
return { code: "variable-unknown-builtin", severity: "error", path, id: name, message: source.ok ? `'${name}' is not a built-in variable.` : source.message };
|
|
734
|
+
}
|
|
735
|
+
function missingBuiltin(name, path) {
|
|
736
|
+
return { code: "variable-builtin-missing", severity: "warning", path, id: name, message: `Built-in '${name}' has no value in this document, so it resolves to nothing; add the field it reads (see docs/templates-and-variables.md).` };
|
|
737
|
+
}
|
|
738
|
+
function lookupVariable(id, path, context) {
|
|
739
|
+
const declared = context.effective.get(id);
|
|
740
|
+
if (declared || !isBuiltinName(id)) return declared;
|
|
741
|
+
return builtinEffective(id, path, context);
|
|
742
|
+
}
|
|
1130
743
|
function interpolate(text2, path, context) {
|
|
1131
744
|
let changed = false;
|
|
1132
745
|
const value = text2.replace(tokenPattern, (match, id, format) => {
|
|
@@ -1138,9 +751,9 @@ function interpolate(text2, path, context) {
|
|
|
1138
751
|
return match;
|
|
1139
752
|
}
|
|
1140
753
|
context.uses.push({ id, path, form: "token" });
|
|
1141
|
-
const effective =
|
|
754
|
+
const effective = lookupVariable(id, path, context);
|
|
1142
755
|
if (!effective) {
|
|
1143
|
-
diag(context, { code: "variable-unknown", severity: "warning", path, id, message: `'{{${id}}}' names no declared variable; declare '${id}' in the top-level variables map, or write '\\{{' for literal braces.` }, `unk:${id}:${path}`);
|
|
756
|
+
if (!isBuiltinName(id)) diag(context, { code: "variable-unknown", severity: "warning", path, id, message: `'{{${id}}}' names no declared variable; declare '${id}' in the top-level variables map, or write '\\{{' for literal braces.` }, `unk:${id}:${path}`);
|
|
1144
757
|
return match;
|
|
1145
758
|
}
|
|
1146
759
|
if (effective.status === "unfilled" && !context.shape) {
|
|
@@ -1168,7 +781,7 @@ function reduceString(text2, path, parentIsArray, context) {
|
|
|
1168
781
|
const reference = referencePattern.exec(text2);
|
|
1169
782
|
if (reference) {
|
|
1170
783
|
const id = reference[1];
|
|
1171
|
-
const effective =
|
|
784
|
+
const effective = lookupVariable(id, path, context);
|
|
1172
785
|
if (effective && effective.declaration.kind !== "color") {
|
|
1173
786
|
context.uses.push({ id, path, form: "reference" });
|
|
1174
787
|
if (effective.status === "unfilled" && !context.shape) {
|
|
@@ -1250,7 +863,11 @@ function plan(presentation, values, options) {
|
|
|
1250
863
|
unescape: false,
|
|
1251
864
|
shape: options.shape === true,
|
|
1252
865
|
content: hasContentVariables(presentation) || template,
|
|
1253
|
-
seen: /* @__PURE__ */ new Set()
|
|
866
|
+
seen: /* @__PURE__ */ new Set(),
|
|
867
|
+
doc: presentation,
|
|
868
|
+
keepMissingBuiltins: options.examples === true,
|
|
869
|
+
builtins: /* @__PURE__ */ new Map(),
|
|
870
|
+
resolvingBuiltins: /* @__PURE__ */ new Set()
|
|
1254
871
|
};
|
|
1255
872
|
const unfilled = [];
|
|
1256
873
|
const examplesUsed = [];
|
|
@@ -1374,6 +991,32 @@ function listVariables(presentation, values = {}) {
|
|
|
1374
991
|
};
|
|
1375
992
|
});
|
|
1376
993
|
}
|
|
994
|
+
var FIELD_LABELS = { name: "name", legalName: "legal name", tagline: "tagline", domain: "domain", email: "email", phone: "phone", logo: "logo", title: "title", bio: "bio", photo: "photo", description: "description", author: "author" };
|
|
995
|
+
function listBuiltinVariables(presentation) {
|
|
996
|
+
if (!isRecord(presentation)) return [];
|
|
997
|
+
const names = [];
|
|
998
|
+
for (const field of Object.keys(DECK_FIELDS)) names.push({ name: `deck.${field}`, label: `Deck ${FIELD_LABELS[field]}` });
|
|
999
|
+
for (const field of Object.keys(SPEAKER_FIELDS)) names.push({ name: `speaker.${field}`, label: `Speaker ${FIELD_LABELS[field]}` });
|
|
1000
|
+
names.push({ name: "speakers", label: "All speaker names" });
|
|
1001
|
+
for (const field of Object.keys(ORGANIZATION_FIELDS)) names.push({ name: `organization.${field}`, label: `Organization ${FIELD_LABELS[field]}` });
|
|
1002
|
+
for (const [root, entries] of [["speaker", speakersOf(presentation)], ["organization", organizationsOf(presentation)]]) {
|
|
1003
|
+
for (const entry of entries) {
|
|
1004
|
+
if (typeof entry.id !== "string" || entry.id === "") continue;
|
|
1005
|
+
for (const field of Object.keys(builtinFields(root))) names.push({ name: `${root}.${entry.id}.${field}`, label: `${root === "speaker" ? "Speaker" : "Organization"} ${entry.id} ${FIELD_LABELS[field]}` });
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
const built = plan(presentation, {}, { examples: false, partial: true, shape: true });
|
|
1009
|
+
built.context.content = true;
|
|
1010
|
+
walk(presentation, "", false, built.context);
|
|
1011
|
+
const out = [];
|
|
1012
|
+
for (const { name, label } of names) {
|
|
1013
|
+
const source = builtinSource(name, presentation);
|
|
1014
|
+
if (!source.ok) continue;
|
|
1015
|
+
const coerced = source.raw === void 0 ? void 0 : coerceVariableValue(source.kind, source.raw);
|
|
1016
|
+
out.push({ name, kind: source.kind, label, ...coerced?.ok ? { value: coerced.value } : {}, available: coerced?.ok === true, uses: built.context.uses.filter((use) => use.id === name) });
|
|
1017
|
+
}
|
|
1018
|
+
return out;
|
|
1019
|
+
}
|
|
1377
1020
|
|
|
1378
1021
|
// src/chart-data.ts
|
|
1379
1022
|
var record3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1451,7 +1094,7 @@ function excelInteger(integer) {
|
|
|
1451
1094
|
const placeholders = "#".repeat(width - zeros) + "0".repeat(zeros);
|
|
1452
1095
|
return placeholders.replace(/\B(?=(.{3})+$)/g, ",");
|
|
1453
1096
|
}
|
|
1454
|
-
function
|
|
1097
|
+
function toExcelNumberFormat(format) {
|
|
1455
1098
|
if (format === void 0 || format === "") return "General";
|
|
1456
1099
|
const parts = formatParts(format);
|
|
1457
1100
|
if (!parts) return "General";
|
|
@@ -1489,7 +1132,7 @@ function excelTokens(code) {
|
|
|
1489
1132
|
}
|
|
1490
1133
|
return tokens;
|
|
1491
1134
|
}
|
|
1492
|
-
function
|
|
1135
|
+
function fromExcelNumberFormat(code) {
|
|
1493
1136
|
if (typeof code !== "string") return void 0;
|
|
1494
1137
|
const trimmed = code.trim();
|
|
1495
1138
|
if (trimmed === "" || /^general$/i.test(trimmed)) return void 0;
|
|
@@ -1580,8 +1223,8 @@ function inlinedData(ref, datasets) {
|
|
|
1580
1223
|
const diagnostics = [];
|
|
1581
1224
|
const selection = selectFields(dataset.columns, ref.fields, "", "", diagnostics);
|
|
1582
1225
|
if (diagnostics.some((entry) => entry.code === "dataset-field-unknown")) return void 0;
|
|
1583
|
-
const
|
|
1584
|
-
return { columns: selection.columns.map(inlineColumn), rows:
|
|
1226
|
+
const rows3 = dataset.rows.map((row) => selection.indices.map((index) => Array.isArray(row) && index < row.length ? structuredClone(row[index]) : null));
|
|
1227
|
+
return { columns: selection.columns.map(inlineColumn), rows: rows3, ...record3(dataset.source) ? { source: structuredClone(dataset.source) } : {} };
|
|
1585
1228
|
}
|
|
1586
1229
|
function inlineDatasets(document) {
|
|
1587
1230
|
if (!record3(document)) return document;
|
|
@@ -1655,7 +1298,7 @@ function resolveChartData(chart, document, options = {}) {
|
|
|
1655
1298
|
const data = record3(chart) ? chart.data : void 0;
|
|
1656
1299
|
if (!record3(data)) return fail("no-columns", "The chart has no data.");
|
|
1657
1300
|
let columns2;
|
|
1658
|
-
let
|
|
1301
|
+
let rows3;
|
|
1659
1302
|
let columnsPath;
|
|
1660
1303
|
let rowsPath;
|
|
1661
1304
|
let source;
|
|
@@ -1675,15 +1318,12 @@ function resolveChartData(chart, document, options = {}) {
|
|
|
1675
1318
|
const selection = selectFields(dataset.columns, data.fields, at(base, "data", "fields"), columnsPath, diagnostics);
|
|
1676
1319
|
columns2 = selection.columns;
|
|
1677
1320
|
selected = selection.indices;
|
|
1678
|
-
|
|
1321
|
+
rows3 = dataset.rows;
|
|
1679
1322
|
if (record3(dataset.source)) source = dataset.source;
|
|
1680
|
-
} else if (typeof data.src === "string") {
|
|
1681
|
-
diagnostics.push({ code: "chart-data-source-unresolved", severity: "warning", path: at(base, "data", "src"), message: `chart data source '${data.src}' is not loaded by any engine; the preview and export draw a placeholder. Import the data inline (columns and rows, with a 'source' for provenance) or reference a dataset` });
|
|
1682
|
-
return fail("data-not-inline", "The chart reads an external data source, which no engine resolves.");
|
|
1683
1323
|
} else {
|
|
1684
1324
|
if (!Array.isArray(data.columns)) return fail("no-columns", "The chart data has no columns.");
|
|
1685
1325
|
columns2 = data.columns;
|
|
1686
|
-
|
|
1326
|
+
rows3 = Array.isArray(data.rows) ? data.rows : [];
|
|
1687
1327
|
columnsPath = at(base, "data", "columns");
|
|
1688
1328
|
rowsPath = at(base, "data", "rows");
|
|
1689
1329
|
formatDiagnostics(columns2, columnsPath, diagnostics);
|
|
@@ -1741,10 +1381,46 @@ function resolveChartData(chart, document, options = {}) {
|
|
|
1741
1381
|
series = [x];
|
|
1742
1382
|
x = void 0;
|
|
1743
1383
|
}
|
|
1384
|
+
let combo;
|
|
1385
|
+
if (record3(chart) && chartOptionTarget(chart.type)?.kind === "combo") {
|
|
1386
|
+
const listed = (option, problem) => {
|
|
1387
|
+
const found = /* @__PURE__ */ new Set();
|
|
1388
|
+
const value = chart[option];
|
|
1389
|
+
if (!Array.isArray(value)) return found;
|
|
1390
|
+
value.forEach((name, index) => {
|
|
1391
|
+
const path = at(base, option, index);
|
|
1392
|
+
const column = known(name, path);
|
|
1393
|
+
if (column === void 0) return;
|
|
1394
|
+
const reason = problem(column);
|
|
1395
|
+
if (reason) diagnostics.push({ code: "chart-mapping-adapted", severity: "warning", path, message: `${JSON.stringify(name)} ${reason}` });
|
|
1396
|
+
else found.add(column);
|
|
1397
|
+
});
|
|
1398
|
+
return found;
|
|
1399
|
+
};
|
|
1400
|
+
const notPlotted = "is not a plotted series of the chart";
|
|
1401
|
+
const lines = listed("line", (column) => series.includes(column) ? void 0 : `${notPlotted}; it is not drawn as a line`);
|
|
1402
|
+
if (chart.line === void 0 && series.length >= 2) lines.add(series[series.length - 1]);
|
|
1403
|
+
if (series.length && series.every((column) => lines.has(column))) {
|
|
1404
|
+
lines.delete(series[0]);
|
|
1405
|
+
diagnostics.push({ code: "chart-mapping-adapted", severity: "warning", path: at(base, chart.line === void 0 ? "type" : "line"), message: series.length === 1 ? `a combo chart needs at least two series, one drawn as columns and one as a line; its one series ${JSON.stringify(names[series[0]])} is drawn as columns` : `a combo chart keeps at least one column series; ${JSON.stringify(names[series[0]])} is drawn as columns, not as a line` });
|
|
1406
|
+
} else if (series.length === 1) {
|
|
1407
|
+
diagnostics.push({ code: "chart-mapping-adapted", severity: "warning", path: at(base, "type"), message: `a combo chart needs at least two series, one drawn as columns and one as a line; its one series ${JSON.stringify(names[series[0]])} is drawn as columns` });
|
|
1408
|
+
}
|
|
1409
|
+
const secondary = listed("secondaryAxis", (column) => !series.includes(column) ? `${notPlotted}; it has no axis to move to` : !lines.has(column) ? "is drawn as columns; only a line series can use the secondary axis, so it stays on the primary axis" : void 0);
|
|
1410
|
+
const bars = series.filter((column) => !lines.has(column));
|
|
1411
|
+
const primaryLines = series.filter((column) => lines.has(column) && !secondary.has(column));
|
|
1412
|
+
const secondaryLines = series.filter((column) => lines.has(column) && secondary.has(column));
|
|
1413
|
+
series = [...bars, ...primaryLines, ...secondaryLines];
|
|
1414
|
+
combo = [
|
|
1415
|
+
...bars.map(() => ({ role: "bar", axis: "primary" })),
|
|
1416
|
+
...primaryLines.map(() => ({ role: "line", axis: "primary" })),
|
|
1417
|
+
...secondaryLines.map(() => ({ role: "line", axis: "secondary" }))
|
|
1418
|
+
];
|
|
1419
|
+
}
|
|
1744
1420
|
const order = [category, ...x === void 0 ? [] : [x], ...series];
|
|
1745
|
-
if (!
|
|
1421
|
+
if (!rows3.length) return fail("no-rows", "The chart data has no rows.");
|
|
1746
1422
|
const lone = names.length === 1 && !diagnostics.some((entry) => entry.code === "dataset-field-unknown");
|
|
1747
|
-
const out =
|
|
1423
|
+
const out = rows3.map((row, rowIndex) => order.map((column, position) => {
|
|
1748
1424
|
const sourceIndex = selected ? selected[column] : column;
|
|
1749
1425
|
const cell = Array.isArray(row) && sourceIndex < row.length ? row[sourceIndex] : null;
|
|
1750
1426
|
if (position === 0 && !lone) return cell === void 0 ? null : cell;
|
|
@@ -1754,6 +1430,26 @@ function resolveChartData(chart, document, options = {}) {
|
|
|
1754
1430
|
}
|
|
1755
1431
|
return number;
|
|
1756
1432
|
}));
|
|
1433
|
+
const highlight = record3(chart) && record3(chart.highlight) ? chart.highlight : void 0;
|
|
1434
|
+
if (highlight) {
|
|
1435
|
+
const plotted = order.slice(order.length - series.length).map((index) => names[index]);
|
|
1436
|
+
const labels = lone ? void 0 : new Set(out.map((row) => row[0] === null || row[0] === void 0 ? "" : String(row[0])));
|
|
1437
|
+
const listed = (value) => Array.isArray(value) ? value : [];
|
|
1438
|
+
const highlightPath = at(base, "highlight");
|
|
1439
|
+
listed(highlight.series).forEach((name, index) => {
|
|
1440
|
+
const path = at(highlightPath, "series", index);
|
|
1441
|
+
if (typeof name !== "string" || !names.includes(name)) {
|
|
1442
|
+
diagnostics.push({ code: "chart-highlight-unknown-name", severity: "error", path, message: `highlight names series ${JSON.stringify(name)}, which the chart data does not have as a column; use one of ${names.map((entry) => JSON.stringify(entry)).join(", ")}` });
|
|
1443
|
+
} else if (!plotted.includes(name)) {
|
|
1444
|
+
diagnostics.push({ code: "chart-highlight-adapted", severity: "warning", path, message: `highlight names column ${JSON.stringify(name)}, which is not plotted as a series (it is the category or X column, or the mapping leaves it out); it highlights nothing` });
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
listed(highlight.categories).forEach((name, index) => {
|
|
1448
|
+
if (typeof name === "string" && labels?.has(name)) return;
|
|
1449
|
+
const shown = labels ? [...labels].slice(0, 12).map((entry) => JSON.stringify(entry)).join(", ") : "";
|
|
1450
|
+
diagnostics.push({ code: "chart-highlight-unknown-name", severity: "error", path: at(highlightPath, "categories", index), message: `highlight names category ${JSON.stringify(name)}, which no row of the chart data has as its label${shown ? `; the labels are ${shown}${labels.size > 12 ? ", ..." : ""}` : ""}` });
|
|
1451
|
+
});
|
|
1452
|
+
}
|
|
1757
1453
|
return {
|
|
1758
1454
|
ok: true,
|
|
1759
1455
|
columns: order.map((index) => names[index]),
|
|
@@ -1762,6 +1458,7 @@ function resolveChartData(chart, document, options = {}) {
|
|
|
1762
1458
|
rows: out,
|
|
1763
1459
|
...source ? { source } : {},
|
|
1764
1460
|
...datasetId !== void 0 ? { dataset: datasetId } : {},
|
|
1461
|
+
...combo ? { combo } : {},
|
|
1765
1462
|
diagnostics
|
|
1766
1463
|
};
|
|
1767
1464
|
}
|
|
@@ -1778,18 +1475,18 @@ function chartNumberFixes(chart, document, options) {
|
|
|
1778
1475
|
if (!candidates.size) return fixes;
|
|
1779
1476
|
const data = chart.data;
|
|
1780
1477
|
let columns2;
|
|
1781
|
-
let
|
|
1478
|
+
let rows3;
|
|
1782
1479
|
let columnsPath;
|
|
1783
1480
|
let rowsPath;
|
|
1784
1481
|
if (isDatasetRef(data)) {
|
|
1785
1482
|
const dataset = datasetsOf(document)[data.dataset];
|
|
1786
1483
|
columns2 = dataset.columns;
|
|
1787
|
-
|
|
1484
|
+
rows3 = dataset.rows;
|
|
1788
1485
|
columnsPath = at("/datasets", data.dataset, "columns");
|
|
1789
1486
|
rowsPath = at("/datasets", data.dataset, "rows");
|
|
1790
1487
|
} else {
|
|
1791
1488
|
columns2 = data.columns;
|
|
1792
|
-
|
|
1489
|
+
rows3 = data.rows;
|
|
1793
1490
|
columnsPath = at(options.path ?? "", "data", "columns");
|
|
1794
1491
|
rowsPath = at(options.path ?? "", "data", "rows");
|
|
1795
1492
|
}
|
|
@@ -1797,7 +1494,7 @@ function chartNumberFixes(chart, document, options) {
|
|
|
1797
1494
|
const header = columns2[column];
|
|
1798
1495
|
const name = columnName(header);
|
|
1799
1496
|
if (name === void 0 || columnFormat(header) !== void 0) continue;
|
|
1800
|
-
const fix = columnFix(
|
|
1497
|
+
const fix = columnFix(rows3, column, rowsPath);
|
|
1801
1498
|
if (!fix) continue;
|
|
1802
1499
|
fixes.set(column, {
|
|
1803
1500
|
patches: [...fix.patches, { op: "replace", path: at(columnsPath, column), value: record3(header) ? { ...header, format: fix.format } : { name, format: fix.format } }],
|
|
@@ -1808,14 +1505,14 @@ function chartNumberFixes(chart, document, options) {
|
|
|
1808
1505
|
}
|
|
1809
1506
|
return fixes;
|
|
1810
1507
|
}
|
|
1811
|
-
function columnFix(
|
|
1508
|
+
function columnFix(rows3, column, rowsPath) {
|
|
1812
1509
|
const cells = [];
|
|
1813
1510
|
let prefix;
|
|
1814
1511
|
let suffix;
|
|
1815
1512
|
let grouping = false;
|
|
1816
1513
|
let wide = false;
|
|
1817
1514
|
const decimals = [];
|
|
1818
|
-
for (const [index, row] of
|
|
1515
|
+
for (const [index, row] of rows3.entries()) {
|
|
1819
1516
|
const cell = Array.isArray(row) && column < row.length ? row[column] : null;
|
|
1820
1517
|
if (cell === null || cell === void 0 || cell === "") continue;
|
|
1821
1518
|
const patch = chartNumber(cell) === null;
|
|
@@ -1870,12 +1567,12 @@ function resolveTableData(table, document, options = {}) {
|
|
|
1870
1567
|
const columnsPath = at("/datasets", id, "columns");
|
|
1871
1568
|
formatDiagnostics(dataset.columns, columnsPath, diagnostics);
|
|
1872
1569
|
const selection = selectFields(dataset.columns, table.fields, at(base, "fields"), columnsPath, diagnostics);
|
|
1873
|
-
const
|
|
1874
|
-
return { columns: selection.columns, rows:
|
|
1570
|
+
const rows4 = dataset.rows.map((row) => selection.indices.map((index) => Array.isArray(row) && index < row.length ? row[index] : null));
|
|
1571
|
+
return { columns: selection.columns, rows: rows4, formats: selection.formats, dataset: id, diagnostics };
|
|
1875
1572
|
}
|
|
1876
1573
|
const columns2 = Array.isArray(table.columns) ? table.columns : void 0;
|
|
1877
|
-
const
|
|
1878
|
-
const width = Math.max(columns2?.length ?? 0, ...
|
|
1574
|
+
const rows3 = Array.isArray(table.rows) ? table.rows.filter(Array.isArray) : [];
|
|
1575
|
+
const width = Math.max(columns2?.length ?? 0, ...rows3.map((row) => row.length), 0);
|
|
1879
1576
|
const formats = Array.from({ length: width }, (_, index) => {
|
|
1880
1577
|
const header = columns2?.[index];
|
|
1881
1578
|
return columnFormat(header) ?? cellFormat(header);
|
|
@@ -1893,7 +1590,7 @@ function resolveTableData(table, document, options = {}) {
|
|
|
1893
1590
|
check(cell, at(base, "rows", rowIndex, index));
|
|
1894
1591
|
});
|
|
1895
1592
|
});
|
|
1896
|
-
return { ...columns2 ? { columns: columns2 } : {}, rows:
|
|
1593
|
+
return { ...columns2 ? { columns: columns2 } : {}, rows: rows3, formats, diagnostics };
|
|
1897
1594
|
}
|
|
1898
1595
|
function tableCellDisplayValue(cell, columnFormat2) {
|
|
1899
1596
|
if (record3(cell) && own(cell, "value")) {
|
|
@@ -2019,6 +1716,38 @@ function intrinsicImageAspect(value, assets) {
|
|
|
2019
1716
|
return size ? size.width / size.height : void 0;
|
|
2020
1717
|
}
|
|
2021
1718
|
|
|
1719
|
+
// src/design-hints.ts
|
|
1720
|
+
var DESIGN_HINT_KEYS = ["titleAlignment", "contentAlignment", "contentBox", "contentDirection", "chartPrimary", "imageFit", "listBullet"];
|
|
1721
|
+
var ALIGNMENTS = ["left", "center", "right"];
|
|
1722
|
+
var VALUES = {
|
|
1723
|
+
titleAlignment: ALIGNMENTS,
|
|
1724
|
+
contentAlignment: ALIGNMENTS,
|
|
1725
|
+
contentBox: "boolean",
|
|
1726
|
+
contentDirection: ["horizontal", "vertical"],
|
|
1727
|
+
chartPrimary: ["none", "top", "bottom", "left", "right"],
|
|
1728
|
+
imageFit: ["cover", "contain", "stretch"],
|
|
1729
|
+
listBullet: ["character", "image"]
|
|
1730
|
+
};
|
|
1731
|
+
var accepts = (key, value) => VALUES[key] === "boolean" ? typeof value === "boolean" : VALUES[key].includes(value);
|
|
1732
|
+
var object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1733
|
+
function resolveDesignHints(options = {}) {
|
|
1734
|
+
const slide = object(object(options.slide).design), host = object(options.deck), deck = object(object(options.presentation).design), layout = object(object(options.layout).design);
|
|
1735
|
+
const index = options.slideIndex ?? 0;
|
|
1736
|
+
const result = { sources: {}, paths: {} };
|
|
1737
|
+
const set2 = (key, value, source, path) => {
|
|
1738
|
+
result[key] = value;
|
|
1739
|
+
result.sources[key] = source;
|
|
1740
|
+
result.paths[key] = path;
|
|
1741
|
+
};
|
|
1742
|
+
for (const key of DESIGN_HINT_KEYS) {
|
|
1743
|
+
if (accepts(key, slide[key])) set2(key, slide[key], "slide", `slides.${index}.design.${key}`);
|
|
1744
|
+
else if (accepts(key, host[key])) set2(key, host[key], "deck", `design.${key}`);
|
|
1745
|
+
else if (accepts(key, deck[key])) set2(key, deck[key], "deck", `design.${key}`);
|
|
1746
|
+
else if (accepts(key, layout[key])) set2(key, layout[key], "layout", `slides.${index}.layout`);
|
|
1747
|
+
}
|
|
1748
|
+
return result;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
2022
1751
|
// src/reading-order.ts
|
|
2023
1752
|
function visualReadingOrder(items, direction = "ltr") {
|
|
2024
1753
|
const index = new Map(items.map((item, i) => [item, i]));
|
|
@@ -2028,18 +1757,18 @@ function visualReadingOrder(items, direction = "ltr") {
|
|
|
2028
1757
|
function readingRows(items) {
|
|
2029
1758
|
const index = new Map(items.map((item, i) => [item, i]));
|
|
2030
1759
|
const sorted = [...items].sort((a, b) => a.box.y - b.box.y || a.box.x - b.box.x || index.get(a) - index.get(b));
|
|
2031
|
-
const
|
|
1760
|
+
const rows3 = [];
|
|
2032
1761
|
for (const item of sorted) {
|
|
2033
1762
|
const centre = item.box.y + item.box.height / 2;
|
|
2034
|
-
const row =
|
|
1763
|
+
const row = rows3.find((candidate) => centre >= candidate.top && centre <= candidate.bottom);
|
|
2035
1764
|
if (row) {
|
|
2036
1765
|
row.items.push(item);
|
|
2037
1766
|
row.top = Math.min(row.top, item.box.y);
|
|
2038
1767
|
row.bottom = Math.max(row.bottom, item.box.y + item.box.height);
|
|
2039
|
-
} else
|
|
1768
|
+
} else rows3.push({ top: item.box.y, bottom: item.box.y + item.box.height, items: [item] });
|
|
2040
1769
|
}
|
|
2041
|
-
|
|
2042
|
-
return
|
|
1770
|
+
rows3.sort((a, b) => a.top - b.top);
|
|
1771
|
+
return rows3.map((row) => row.items.sort((a, b) => index.get(a) - index.get(b)));
|
|
2043
1772
|
}
|
|
2044
1773
|
|
|
2045
1774
|
// src/direction.ts
|
|
@@ -2082,7 +1811,106 @@ function paragraphDirectionAt(text2, deckDirection) {
|
|
|
2082
1811
|
};
|
|
2083
1812
|
}
|
|
2084
1813
|
|
|
1814
|
+
// src/generated/engine-data.ts
|
|
1815
|
+
var engineDefaultsSource = {
|
|
1816
|
+
"theme": {
|
|
1817
|
+
"background": {
|
|
1818
|
+
"type": "theme",
|
|
1819
|
+
"slot": "dark2"
|
|
1820
|
+
},
|
|
1821
|
+
"dimensions": "widescreen"
|
|
1822
|
+
},
|
|
1823
|
+
"colorScheme": {
|
|
1824
|
+
"accent1": "#2874A6",
|
|
1825
|
+
"accent2": "#1B4F72",
|
|
1826
|
+
"accent3": "#5499C7",
|
|
1827
|
+
"accent4": "#7BDBB2",
|
|
1828
|
+
"accent5": "#3AC67A",
|
|
1829
|
+
"accent6": "#24A89E",
|
|
1830
|
+
"dark1": "#000000",
|
|
1831
|
+
"dark2": "#011842",
|
|
1832
|
+
"light1": "#FFFFFF",
|
|
1833
|
+
"light2": "#F0F0F0",
|
|
1834
|
+
"hyperlink": "#0000EE",
|
|
1835
|
+
"followedHyperlink": "#551A8B"
|
|
1836
|
+
},
|
|
1837
|
+
"fontScheme": {
|
|
1838
|
+
"major": "Aptos Display",
|
|
1839
|
+
"minor": "Aptos",
|
|
1840
|
+
"languageFamily": "latin"
|
|
1841
|
+
},
|
|
1842
|
+
"chartTypes": [
|
|
1843
|
+
"stacked-column",
|
|
1844
|
+
"stacked-area",
|
|
1845
|
+
"line-with-markers"
|
|
1846
|
+
]
|
|
1847
|
+
};
|
|
1848
|
+
var engineVocabulariesSource = { "chartTypes": ["100pct-stacked-area", "100pct-stacked-bar", "100pct-stacked-column", "area", "bar", "box-and-whisker", "column", "combo", "doughnut", "filled-radar", "funnel", "histogram", "line", "line-with-markers", "pareto", "pie", "radar", "radar-with-markers", "scatter", "stacked-area", "stacked-bar", "stacked-column", "stacked-line", "stacked-line-with-markers", "treemap", "waterfall", "world"], "socialPlatforms": { "linkedin": { "baseUrl": "https://linkedin.com", "profileUrlPattern": "https://linkedin.com/in/{handle}", "companyUrlPattern": "https://linkedin.com/company/{handle}", "handlePrefix": "" }, "x": { "baseUrl": "https://x.com", "profileUrlPattern": "https://x.com/{handle}", "handlePrefix": "@" }, "github": { "baseUrl": "https://github.com", "profileUrlPattern": "https://github.com/{handle}", "companyUrlPattern": "https://github.com/{handle}", "handlePrefix": "" }, "youtube": { "baseUrl": "https://youtube.com", "profileUrlPattern": "https://youtube.com/@{handle}", "handlePrefix": "@" }, "instagram": { "baseUrl": "https://instagram.com", "profileUrlPattern": "https://instagram.com/{handle}", "handlePrefix": "@" }, "facebook": { "baseUrl": "https://facebook.com", "profileUrlPattern": "https://facebook.com/{handle}", "companyUrlPattern": "https://facebook.com/{handle}", "handlePrefix": "" }, "tiktok": { "baseUrl": "https://tiktok.com", "profileUrlPattern": "https://tiktok.com/@{handle}", "handlePrefix": "@" }, "threads": { "baseUrl": "https://threads.net", "profileUrlPattern": "https://threads.net/@{handle}", "handlePrefix": "@" }, "mastodon": { "baseUrl": "https://mastodon.social", "profileUrlPattern": "https://mastodon.social/@{handle}", "handlePrefix": "@" }, "bluesky": { "baseUrl": "https://bsky.app", "profileUrlPattern": "https://bsky.app/profile/{handle}", "handlePrefix": "" } }, "languages": [{ "tag": "af", "script": "Latn", "direction": "ltr", "ooxmlLang": "af-ZA", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "sq", "script": "Latn", "direction": "ltr", "ooxmlLang": "sq-AL", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "am", "script": "Ethi", "direction": "ltr", "ooxmlLang": "am-ET", "fonts": { "powerpoint": { "major": "Nyala", "minor": "Nyala" }, "google": { "major": "Noto Sans Ethiopic", "minor": "Noto Sans Ethiopic" } } }, { "tag": "ar", "script": "Arab", "direction": "rtl", "ooxmlLang": "ar-SA", "fonts": { "powerpoint": { "major": "Arabic Typesetting", "minor": "Arabic Typesetting" }, "google": { "major": "Noto Naskh Arabic", "minor": "Noto Naskh Arabic" } } }, { "tag": "hy", "script": "Armn", "direction": "ltr", "ooxmlLang": "hy-AM", "fonts": { "powerpoint": { "major": "Sylfaen", "minor": "Sylfaen" }, "google": { "major": "Noto Sans Armenian", "minor": "Noto Sans Armenian" } } }, { "tag": "ay", "script": "Latn", "direction": "ltr", "ooxmlLang": "ay-BO", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "az", "script": "Latn", "direction": "ltr", "ooxmlLang": "az-Latn-AZ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "bn", "script": "Beng", "direction": "ltr", "ooxmlLang": "bn-BD", "fonts": { "powerpoint": { "major": "Shonar Bangla", "minor": "Shonar Bangla" }, "google": { "major": "Noto Sans Bengali", "minor": "Noto Sans Bengali" } } }, { "tag": "ber-Latn", "script": "Latn", "direction": "ltr", "ooxmlLang": "tzm-Latn-DZ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "bs-Latn", "script": "Latn", "direction": "ltr", "ooxmlLang": "bs-Latn-BA", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "bg", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "bg-BG", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "ca", "script": "Latn", "direction": "ltr", "ooxmlLang": "ca-ES", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ceb", "script": "Latn", "direction": "ltr", "ooxmlLang": "ceb-PH", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "zh-Hans", "script": "Hans", "direction": "ltr", "ooxmlLang": "zh-CN", "fonts": { "powerpoint": { "major": "Microsoft YaHei", "minor": "Microsoft YaHei" }, "google": { "major": "Noto Sans SC", "minor": "Noto Sans SC" } } }, { "tag": "zh-Hant", "script": "Hant", "direction": "ltr", "ooxmlLang": "zh-TW", "fonts": { "powerpoint": { "major": "Microsoft JhengHei", "minor": "Microsoft JhengHei" }, "google": { "major": "Noto Sans TC", "minor": "Noto Sans TC" } } }, { "tag": "ctg", "script": "Beng", "direction": "ltr", "ooxmlLang": "bn-BD", "fonts": { "powerpoint": { "major": "Vrinda", "minor": "Vrinda" }, "google": { "major": "Noto Sans Bengali", "minor": "Noto Sans Bengali" } } }, { "tag": "hr", "script": "Latn", "direction": "ltr", "ooxmlLang": "hr-HR", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "cs", "script": "Latn", "direction": "ltr", "ooxmlLang": "cs-CZ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "da", "script": "Latn", "direction": "ltr", "ooxmlLang": "da-DK", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "nl", "script": "Latn", "direction": "ltr", "ooxmlLang": "nl-NL", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "en", "script": "Latn", "direction": "ltr", "ooxmlLang": "en-US", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "en-AU", "script": "Latn", "direction": "ltr", "ooxmlLang": "en-AU", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "en-CA", "script": "Latn", "direction": "ltr", "ooxmlLang": "en-CA", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "en-GB", "script": "Latn", "direction": "ltr", "ooxmlLang": "en-GB", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "en-IN", "script": "Latn", "direction": "ltr", "ooxmlLang": "en-IN", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "en-US", "script": "Latn", "direction": "ltr", "ooxmlLang": "en-US", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "et", "script": "Latn", "direction": "ltr", "ooxmlLang": "et-EE", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "fil", "script": "Latn", "direction": "ltr", "ooxmlLang": "fil-PH", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "fi", "script": "Latn", "direction": "ltr", "ooxmlLang": "fi-FI", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "fr", "script": "Latn", "direction": "ltr", "ooxmlLang": "fr-FR", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ff", "script": "Latn", "direction": "ltr", "ooxmlLang": "ff-Latn-SN", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "gl", "script": "Latn", "direction": "ltr", "ooxmlLang": "gl-ES", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ka", "script": "Geor", "direction": "ltr", "ooxmlLang": "ka-GE", "fonts": { "powerpoint": { "major": "Sylfaen", "minor": "Sylfaen" }, "google": { "major": "Noto Sans Georgian", "minor": "Noto Sans Georgian" } } }, { "tag": "de", "script": "Latn", "direction": "ltr", "ooxmlLang": "de-DE", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "el", "script": "Grek", "direction": "ltr", "ooxmlLang": "el-GR", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "gu", "script": "Gujr", "direction": "ltr", "ooxmlLang": "gu-IN", "fonts": { "powerpoint": { "major": "Shruti", "minor": "Shruti" }, "google": { "major": "Noto Sans Gujarati", "minor": "Noto Sans Gujarati" } } }, { "tag": "ha", "script": "Latn", "direction": "ltr", "ooxmlLang": "ha-Latn-NG", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "he", "script": "Hebr", "direction": "rtl", "ooxmlLang": "he-IL", "fonts": { "powerpoint": { "major": "David", "minor": "David" }, "google": { "major": "Noto Sans Hebrew", "minor": "Noto Sans Hebrew" } } }, { "tag": "hi", "script": "Deva", "direction": "ltr", "ooxmlLang": "hi-IN", "fonts": { "powerpoint": { "major": "Mangal", "minor": "Mangal" }, "google": { "major": "Noto Sans Devanagari", "minor": "Noto Sans Devanagari" } } }, { "tag": "hu", "script": "Latn", "direction": "ltr", "ooxmlLang": "hu-HU", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ig", "script": "Latn", "direction": "ltr", "ooxmlLang": "ig-NG", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "id", "script": "Latn", "direction": "ltr", "ooxmlLang": "id-ID", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "it", "script": "Latn", "direction": "ltr", "ooxmlLang": "it-IT", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ja", "script": "Jpan", "direction": "ltr", "ooxmlLang": "ja-JP", "fonts": { "powerpoint": { "major": "Meiryo", "minor": "Meiryo" }, "google": { "major": "Noto Sans JP", "minor": "Noto Sans JP" } } }, { "tag": "kn", "script": "Knda", "direction": "ltr", "ooxmlLang": "kn-IN", "fonts": { "powerpoint": { "major": "Tunga", "minor": "Tunga" }, "google": { "major": "Noto Sans Kannada", "minor": "Noto Sans Kannada" } } }, { "tag": "kk", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "kk-KZ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "km", "script": "Khmr", "direction": "ltr", "ooxmlLang": "km-KH", "fonts": { "powerpoint": { "major": "DaunPenh", "minor": "DaunPenh" }, "google": { "major": "Noto Sans Khmer", "minor": "Noto Sans Khmer" } } }, { "tag": "rw", "script": "Latn", "direction": "ltr", "ooxmlLang": "rw-RW", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ko", "script": "Kore", "direction": "ltr", "ooxmlLang": "ko-KR", "fonts": { "powerpoint": { "major": "Malgun Gothic", "minor": "Malgun Gothic" }, "google": { "major": "Noto Sans KR", "minor": "Noto Sans KR" } } }, { "tag": "kmr", "script": "Latn", "direction": "ltr", "ooxmlLang": "kmr-TR", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "lv", "script": "Latn", "direction": "ltr", "ooxmlLang": "lv-LV", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "lt", "script": "Latn", "direction": "ltr", "ooxmlLang": "lt-LT", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "mk", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "mk-MK", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "mg", "script": "Latn", "direction": "ltr", "ooxmlLang": "mg-MG", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "zsm", "script": "Latn", "direction": "ltr", "ooxmlLang": "ms-MY", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ml", "script": "Mlym", "direction": "ltr", "ooxmlLang": "ml-IN", "fonts": { "powerpoint": { "major": "Kartika", "minor": "Kartika" }, "google": { "major": "Noto Sans Malayalam", "minor": "Noto Sans Malayalam" } } }, { "tag": "mi", "script": "Latn", "direction": "ltr", "ooxmlLang": "mi-NZ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "mr", "script": "Deva", "direction": "ltr", "ooxmlLang": "mr-IN", "fonts": { "powerpoint": { "major": "Mangal", "minor": "Mangal" }, "google": { "major": "Noto Sans Devanagari", "minor": "Noto Sans Devanagari" } } }, { "tag": "mn", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "mn-MN", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans Mongolian", "minor": "Noto Sans Mongolian" } } }, { "tag": "ne", "script": "Deva", "direction": "ltr", "ooxmlLang": "ne-NP", "fonts": { "powerpoint": { "major": "Mangal", "minor": "Mangal" }, "google": { "major": "Noto Sans Devanagari", "minor": "Noto Sans Devanagari" } } }, { "tag": "no", "script": "Latn", "direction": "ltr", "ooxmlLang": "nb-NO", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "or", "script": "Orya", "direction": "ltr", "ooxmlLang": "or-IN", "fonts": { "powerpoint": { "major": "Kalinga", "minor": "Kalinga" }, "google": { "major": "Noto Sans Oriya", "minor": "Noto Sans Oriya" } } }, { "tag": "om", "script": "Latn", "direction": "ltr", "ooxmlLang": "om-ET", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ps", "script": "Arab", "direction": "rtl", "ooxmlLang": "ps-AF", "fonts": { "powerpoint": { "major": "Arial Black", "minor": "Arial" }, "google": { "major": "Noto Naskh Arabic", "minor": "Noto Naskh Arabic" } } }, { "tag": "fa", "script": "Arab", "direction": "rtl", "ooxmlLang": "fa-IR", "fonts": { "powerpoint": { "major": "Arabic Typesetting", "minor": "Arabic Typesetting" }, "google": { "major": "Noto Naskh Arabic", "minor": "Noto Naskh Arabic" } } }, { "tag": "pl", "script": "Latn", "direction": "ltr", "ooxmlLang": "pl-PL", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "pt", "script": "Latn", "direction": "ltr", "ooxmlLang": "pt-BR", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "pa-Guru", "script": "Guru", "direction": "ltr", "ooxmlLang": "pa-IN", "fonts": { "powerpoint": { "major": "Raavi", "minor": "Raavi" }, "google": { "major": "Noto Sans Gurmukhi", "minor": "Noto Sans Gurmukhi" } } }, { "tag": "pa-Arab", "script": "Arab", "direction": "rtl", "ooxmlLang": "pa-Arab-PK", "fonts": { "powerpoint": { "major": "Arial Black", "minor": "Arial" }, "google": { "major": "Noto Nastaliq Urdu", "minor": "Noto Nastaliq Urdu" } } }, { "tag": "ro", "script": "Latn", "direction": "ltr", "ooxmlLang": "ro-RO", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "ru", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "ru-RU", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "sr-Cyrl", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "sr-Cyrl-RS", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "sr-Latn", "script": "Latn", "direction": "ltr", "ooxmlLang": "sr-Latn-RS", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "sn", "script": "Latn", "direction": "ltr", "ooxmlLang": "sn-Latn-ZW", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "sk", "script": "Latn", "direction": "ltr", "ooxmlLang": "sk-SK", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "sl", "script": "Latn", "direction": "ltr", "ooxmlLang": "sl-SI", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "so", "script": "Latn", "direction": "ltr", "ooxmlLang": "so-SO", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "es", "script": "Latn", "direction": "ltr", "ooxmlLang": "es-ES", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "sw", "script": "Latn", "direction": "ltr", "ooxmlLang": "sw-KE", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "sv", "script": "Latn", "direction": "ltr", "ooxmlLang": "sv-SE", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "tl", "script": "Latn", "direction": "ltr", "ooxmlLang": "fil-PH", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "tg", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "tg-Cyrl-TJ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "ta", "script": "Taml", "direction": "ltr", "ooxmlLang": "ta-IN", "fonts": { "powerpoint": { "major": "Latha", "minor": "Latha" }, "google": { "major": "Noto Sans Tamil", "minor": "Noto Sans Tamil" } } }, { "tag": "te", "script": "Telu", "direction": "ltr", "ooxmlLang": "te-IN", "fonts": { "powerpoint": { "major": "Gautami", "minor": "Gautami" }, "google": { "major": "Noto Sans Telugu", "minor": "Noto Sans Telugu" } } }, { "tag": "th", "script": "Thai", "direction": "ltr", "ooxmlLang": "th-TH", "fonts": { "powerpoint": { "major": "Angsana New", "minor": "Angsana New" }, "google": { "major": "Noto Sans Thai", "minor": "Noto Sans Thai" } } }, { "tag": "tr", "script": "Latn", "direction": "ltr", "ooxmlLang": "tr-TR", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "uk", "script": "Cyrl", "direction": "ltr", "ooxmlLang": "uk-UA", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Noto Sans", "minor": "Noto Sans" } } }, { "tag": "ur", "script": "Arab", "direction": "rtl", "ooxmlLang": "ur-PK", "fonts": { "powerpoint": { "major": "Arabic Typesetting", "minor": "Arabic Typesetting" }, "google": { "major": "Noto Nastaliq Urdu", "minor": "Noto Nastaliq Urdu" } } }, { "tag": "uz-Latn", "script": "Latn", "direction": "ltr", "ooxmlLang": "uz-Latn-UZ", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "vi-Latn", "script": "Latn", "direction": "ltr", "ooxmlLang": "vi-VN", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "xh", "script": "Latn", "direction": "ltr", "ooxmlLang": "xh-ZA", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "yo", "script": "Latn", "direction": "ltr", "ooxmlLang": "yo-NG", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }, { "tag": "zu", "script": "Latn", "direction": "ltr", "ooxmlLang": "zu-ZA", "fonts": { "powerpoint": { "major": "Aptos Display", "minor": "Aptos" }, "google": { "major": "Roboto", "minor": "Roboto" } } }] };
|
|
1849
|
+
|
|
1850
|
+
// src/engine-vocabularies.ts
|
|
1851
|
+
var ENGINE_DEFAULT_THEME = engineDefaultsSource.theme;
|
|
1852
|
+
var ENGINE_DEFAULT_COLOR_SCHEME = engineDefaultsSource.colorScheme;
|
|
1853
|
+
var ENGINE_DEFAULT_FONT_SCHEME = engineDefaultsSource.fontScheme;
|
|
1854
|
+
var ENGINE_DEFAULT_CHART_TYPES = engineDefaultsSource.chartTypes;
|
|
1855
|
+
var CHART_TYPES = engineVocabulariesSource.chartTypes;
|
|
1856
|
+
var SOCIAL_PLATFORMS = engineVocabulariesSource.socialPlatforms;
|
|
1857
|
+
var LANGUAGES = engineVocabulariesSource.languages;
|
|
1858
|
+
|
|
1859
|
+
// src/design-records.ts
|
|
1860
|
+
var isRec = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1861
|
+
var rec = (value) => isRec(value) ? value : {};
|
|
1862
|
+
function resolveRecordReference(document, kind2, reference, path, fallback, options, diagnostics) {
|
|
1863
|
+
const object2 = isRec(reference) ? reference : void 0;
|
|
1864
|
+
const id = typeof reference === "string" ? reference : typeof object2?.id === "string" ? object2.id : void 0;
|
|
1865
|
+
if (id === void 0) return { record: { ...fallback, ...object2 } };
|
|
1866
|
+
const found = resolveReference(document, kind2, id, options);
|
|
1867
|
+
if (!found) diagnostics.push(unresolvedReference(document, kind2, id, object2 ? `${path}.id` : path, options));
|
|
1868
|
+
return { record: { ...found ? found.record : fallback, ...object2 }, ...found ? { provenance: provenanceOf(found) } : {} };
|
|
1869
|
+
}
|
|
1870
|
+
function resolveDesignRecords(document, slideIndex, options = {}) {
|
|
1871
|
+
checkCatalogsOption(options.catalogs, "resolveDesignRecords");
|
|
1872
|
+
const deck = rec(document);
|
|
1873
|
+
const slides = Array.isArray(deck.slides) ? deck.slides : [];
|
|
1874
|
+
const own2 = slideIndex === void 0 ? {} : rec(rec(slides[slideIndex]).design);
|
|
1875
|
+
const shared = rec(deck.design);
|
|
1876
|
+
const design = { ...shared, ...own2 };
|
|
1877
|
+
const slidePath = `slides.${slideIndex}.design`;
|
|
1878
|
+
const diagnostics = [];
|
|
1879
|
+
const themePath = own2.theme !== void 0 ? `${slidePath}.theme` : "design.theme";
|
|
1880
|
+
const themeFound = typeof design.theme === "string" ? resolveReference(document, "themes", design.theme, options) : void 0;
|
|
1881
|
+
if (typeof design.theme === "string" && !themeFound) diagnostics.push(unresolvedReference(document, "themes", design.theme, themePath, options));
|
|
1882
|
+
const theme = themeFound ? { ...themeFound.record } : { ...ENGINE_DEFAULT_THEME };
|
|
1883
|
+
const inTheme = { ...options, ...themeFound ? { group: themeFound.group } : {} };
|
|
1884
|
+
const inThemePath = (key) => themeFound?.origin === "document" ? `catalogs.${themeFound.group}.themes.${themeFound.id}.${key}` : themePath;
|
|
1885
|
+
const colorFromDesign = design.colorScheme !== void 0;
|
|
1886
|
+
const colorSchemePath = own2.colorScheme !== void 0 ? `${slidePath}.colorScheme` : shared.colorScheme !== void 0 ? "design.colorScheme" : inThemePath("colorScheme");
|
|
1887
|
+
const color = resolveRecordReference(document, "colorSchemes", colorFromDesign ? design.colorScheme : theme.colorScheme, colorFromDesign ? colorSchemePath : inThemePath("colorScheme"), ENGINE_DEFAULT_COLOR_SCHEME, colorFromDesign ? options : inTheme, diagnostics);
|
|
1888
|
+
const fontFromDesign = design.fontScheme !== void 0;
|
|
1889
|
+
const fontSchemePath = own2.fontScheme !== void 0 ? `${slidePath}.fontScheme` : shared.fontScheme !== void 0 ? "design.fontScheme" : inThemePath("fontScheme");
|
|
1890
|
+
const font = resolveRecordReference(document, "fontSchemes", fontFromDesign ? design.fontScheme : theme.fontScheme, fontSchemePath, ENGINE_DEFAULT_FONT_SCHEME, fontFromDesign ? options : inTheme, diagnostics);
|
|
1891
|
+
const fontReference = fontFromDesign ? design.fontScheme : theme.fontScheme;
|
|
1892
|
+
const fontSchemeReference = typeof fontReference === "string" ? fontReference : isRec(fontReference) && typeof fontReference.id === "string" ? fontReference.id : void 0;
|
|
1893
|
+
const provenance = {
|
|
1894
|
+
...themeFound ? { theme: provenanceOf(themeFound) } : {},
|
|
1895
|
+
...color.provenance ? { colorScheme: color.provenance } : {},
|
|
1896
|
+
...font.provenance ? { fontScheme: font.provenance } : {}
|
|
1897
|
+
};
|
|
1898
|
+
return { theme, colorScheme: color.record, fontScheme: font.record, themePath, colorSchemePath, fontSchemePath, ...fontSchemeReference !== void 0 ? { fontSchemeReference } : {}, provenance, diagnostics };
|
|
1899
|
+
}
|
|
1900
|
+
function resolveFontScheme(document, reference, path, options = {}) {
|
|
1901
|
+
checkCatalogsOption(options.catalogs, "resolveFontScheme");
|
|
1902
|
+
const diagnostics = [];
|
|
1903
|
+
const { record: scheme } = resolveRecordReference(document, "fontSchemes", reference, path, ENGINE_DEFAULT_FONT_SCHEME, options, diagnostics);
|
|
1904
|
+
return { scheme, diagnostics };
|
|
1905
|
+
}
|
|
1906
|
+
|
|
2085
1907
|
// src/script-fonts.ts
|
|
1908
|
+
function normalizeLanguageFamily(value) {
|
|
1909
|
+
if (value === "latin") return "latin";
|
|
1910
|
+
if (value === "ea" || value === "eastAsian") return "ea";
|
|
1911
|
+
if (value === "cs" || value === "complexScript") return "cs";
|
|
1912
|
+
return void 0;
|
|
1913
|
+
}
|
|
2086
1914
|
var eastAsianScripts = /* @__PURE__ */ new Set(["Hani", "Hans", "Hant", "Hanb", "Jpan", "Kore", "Hang", "Jamo", "Hira", "Kana", "Hrkt", "Bopo", "Yiii"]);
|
|
2087
1915
|
var complexScripts = /* @__PURE__ */ new Set([
|
|
2088
1916
|
"Arab",
|
|
@@ -2132,7 +1960,6 @@ var likelyScripts = {
|
|
|
2132
1960
|
mn: { script: "Cyrl", regions: { CN: "Mong" } },
|
|
2133
1961
|
ms: { script: "Latn" }
|
|
2134
1962
|
};
|
|
2135
|
-
var bareLanguageId = /^[a-z][a-z0-9-]*$/;
|
|
2136
1963
|
function scriptFontRole(script) {
|
|
2137
1964
|
const code = normalizeScript(script);
|
|
2138
1965
|
if (code && eastAsianScripts.has(code)) return "eastAsian";
|
|
@@ -2191,56 +2018,36 @@ function inferScript(tag) {
|
|
|
2191
2018
|
return void 0;
|
|
2192
2019
|
}
|
|
2193
2020
|
}
|
|
2194
|
-
function
|
|
2195
|
-
const kinds = isRecord(document.catalogs) ? document.catalogs : {};
|
|
2196
|
-
const entry = kinds[kind2];
|
|
2197
|
-
return isRecord(entry) && Array.isArray(entry.records) ? entry.records.filter(isRecord) : [];
|
|
2198
|
-
}
|
|
2199
|
-
function allRecords(document, kind2) {
|
|
2200
|
-
return [...inlineRecords(document, kind2), ...catalogs[kind2]];
|
|
2201
|
-
}
|
|
2202
|
-
function resolveReference(lookup, kind2, reference) {
|
|
2203
|
-
if (typeof reference === "string") return lookup(kind2, reference);
|
|
2204
|
-
if (!isRecord(reference)) return void 0;
|
|
2205
|
-
const base = typeof reference.id === "string" ? lookup(kind2, reference.id) : void 0;
|
|
2206
|
-
return { ...base, ...reference };
|
|
2207
|
-
}
|
|
2208
|
-
function matchLanguageTag(document, tag) {
|
|
2021
|
+
function matchLanguageTag(tag) {
|
|
2209
2022
|
const wanted = splitTag(tag);
|
|
2210
2023
|
if (!wanted) return void 0;
|
|
2211
|
-
const records = allRecords(document, "languages").filter((record6) => typeof record6.bcp47 === "string");
|
|
2212
2024
|
const key = canonicalTag(tag).toLowerCase();
|
|
2213
|
-
const exact =
|
|
2025
|
+
const exact = LANGUAGES.find((entry) => canonicalTag(entry.tag).toLowerCase() === key);
|
|
2214
2026
|
if (exact) return exact;
|
|
2215
2027
|
const language = matchingLanguages[wanted.language] ?? wanted.language;
|
|
2216
2028
|
const script = wanted.script ?? vendoredScript(language, wanted.region);
|
|
2217
|
-
const candidates =
|
|
2218
|
-
const parts = splitTag(
|
|
2029
|
+
const candidates = LANGUAGES.flatMap((entry) => {
|
|
2030
|
+
const parts = splitTag(entry.tag);
|
|
2219
2031
|
if (!parts || (matchingLanguages[parts.language] ?? parts.language) !== language) return [];
|
|
2220
|
-
const
|
|
2221
|
-
if (script &&
|
|
2222
|
-
return [{
|
|
2032
|
+
const entryScript = normalizeScript(entry.script) ?? parts.script ?? vendoredScript(language, parts.region);
|
|
2033
|
+
if (script && entryScript && script !== entryScript) return [];
|
|
2034
|
+
return [{ entry, region: parts.region }];
|
|
2223
2035
|
});
|
|
2224
|
-
return candidates.find((candidate) => wanted.region && candidate.region === wanted.region)?.
|
|
2036
|
+
return candidates.find((candidate) => wanted.region && candidate.region === wanted.region)?.entry ?? candidates.find((candidate) => !candidate.region)?.entry ?? candidates[0]?.entry;
|
|
2225
2037
|
}
|
|
2226
|
-
function resolveLanguage(
|
|
2038
|
+
function resolveLanguage(reference) {
|
|
2227
2039
|
if (typeof reference === "string") {
|
|
2228
2040
|
const value = reference.trim();
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
if (
|
|
2232
|
-
|
|
2233
|
-
if (matched) return { record: matched, authoredTag: value, languageId: text(matched.id) };
|
|
2234
|
-
return inferScript(value) ? { record: {}, authoredTag: value } : void 0;
|
|
2041
|
+
if (!splitTag(value)) return void 0;
|
|
2042
|
+
const known2 = matchLanguageTag(value);
|
|
2043
|
+
if (!known2 && !inferScript(value)) return void 0;
|
|
2044
|
+
return { tag: value, ...known2 ? { known: known2 } : {}, overrides: {} };
|
|
2235
2045
|
}
|
|
2236
2046
|
if (!isRecord(reference)) return void 0;
|
|
2237
|
-
const
|
|
2238
|
-
if (authoredTag !== void 0 && !splitTag(authoredTag)) return void 0;
|
|
2239
|
-
const base = typeof reference.id === "string" ? lookup("languages", reference.id) : authoredTag ? matchLanguageTag(document, authoredTag) : void 0;
|
|
2240
|
-
const record6 = { ...base, ...reference };
|
|
2241
|
-
const tag = text(record6.bcp47);
|
|
2047
|
+
const tag = text(reference.bcp47);
|
|
2242
2048
|
if (!tag || !splitTag(tag)) return void 0;
|
|
2243
|
-
|
|
2049
|
+
const known = matchLanguageTag(tag);
|
|
2050
|
+
return { tag, ...known ? { known } : {}, overrides: reference };
|
|
2244
2051
|
}
|
|
2245
2052
|
function pairFamilies(value) {
|
|
2246
2053
|
if (!isRecord(value)) return void 0;
|
|
@@ -2250,57 +2057,55 @@ function pairFamilies(value) {
|
|
|
2250
2057
|
const body = minor ?? major;
|
|
2251
2058
|
return heading && body ? { heading, body } : void 0;
|
|
2252
2059
|
}
|
|
2253
|
-
function schemeServesLanguage(scheme,
|
|
2060
|
+
function schemeServesLanguage(scheme, tag, script) {
|
|
2254
2061
|
const entries = Array.isArray(scheme.languages) ? scheme.languages.filter((entry) => typeof entry === "string") : [];
|
|
2255
2062
|
if (entries.length === 0) return true;
|
|
2256
|
-
const
|
|
2257
|
-
if (!
|
|
2258
|
-
const
|
|
2063
|
+
const wanted = splitTag(tag);
|
|
2064
|
+
if (!wanted) return false;
|
|
2065
|
+
const language = matchingLanguages[wanted.language] ?? wanted.language;
|
|
2259
2066
|
return entries.some((entry) => {
|
|
2260
|
-
const
|
|
2261
|
-
|
|
2067
|
+
const parts = splitTag(entry);
|
|
2068
|
+
if (!parts || (matchingLanguages[parts.language] ?? parts.language) !== language) return false;
|
|
2069
|
+
const entryScript = parts.script ?? vendoredScript(language, parts.region);
|
|
2070
|
+
return !entryScript || entryScript === script;
|
|
2262
2071
|
});
|
|
2263
2072
|
}
|
|
2264
2073
|
function resolveScriptFonts(input, options = {}) {
|
|
2265
2074
|
const document = isRecord(input) ? input : {};
|
|
2266
|
-
const lookup = (kind2, id) => inlineRecords(document, kind2).find((record7) => record7.id === id) ?? catalogs[kind2].find((record7) => record7.id === id);
|
|
2267
|
-
let design = isRecord(document.design) ? document.design : {};
|
|
2268
2075
|
if (options.slideIndex !== void 0) {
|
|
2269
2076
|
const slides = Array.isArray(document.slides) ? document.slides : [];
|
|
2270
2077
|
if (!Number.isInteger(options.slideIndex) || options.slideIndex < 0 || options.slideIndex >= slides.length) {
|
|
2271
2078
|
throw new RangeError(`slideIndex must be an integer between 0 and ${slides.length - 1}.`);
|
|
2272
2079
|
}
|
|
2273
|
-
const slide = slides[options.slideIndex];
|
|
2274
|
-
if (isRecord(slide) && isRecord(slide.design)) design = { ...design, ...slide.design };
|
|
2275
2080
|
}
|
|
2276
|
-
const
|
|
2277
|
-
const scheme =
|
|
2081
|
+
const catalogs = { catalogs: checkCatalogsOption(options.catalogs, "resolveScriptFonts") };
|
|
2082
|
+
const scheme = resolveDesignRecords(document, options.slideIndex, catalogs).fontScheme;
|
|
2278
2083
|
const latin = resolveFontFamilies(scheme);
|
|
2279
|
-
const fromOption = options.language !== void 0 ? resolveLanguage(
|
|
2280
|
-
const fromDocument = fromOption ? void 0 : resolveLanguage(document
|
|
2084
|
+
const fromOption = options.language !== void 0 ? resolveLanguage(options.language) : void 0;
|
|
2085
|
+
const fromDocument = fromOption ? void 0 : resolveLanguage(document.language);
|
|
2281
2086
|
const requestedDefault = text(options.defaultLanguage);
|
|
2282
2087
|
const fallbackTag = requestedDefault && splitTag(requestedDefault) ? requestedDefault : "en-US";
|
|
2283
|
-
const language = fromOption ?? fromDocument ?? resolveLanguage(
|
|
2088
|
+
const language = fromOption ?? fromDocument ?? resolveLanguage(fallbackTag) ?? { tag: fallbackTag, overrides: {} };
|
|
2284
2089
|
const languageSource = fromOption ? "option" : fromDocument ? "document" : "default";
|
|
2285
|
-
const
|
|
2286
|
-
const
|
|
2287
|
-
const
|
|
2288
|
-
const
|
|
2090
|
+
const overrides = language.overrides;
|
|
2091
|
+
const known = language.known;
|
|
2092
|
+
const bcp47 = canonicalTag(language.tag);
|
|
2093
|
+
const authoredOoxml = text(overrides.ooxmlLang);
|
|
2094
|
+
const lang = authoredOoxml ? canonicalTag(authoredOoxml) : splitTag(language.tag)?.region ? bcp47 : known ? canonicalTag(known.ooxmlLang) : bcp47;
|
|
2289
2095
|
const parts = splitTag(bcp47);
|
|
2290
|
-
const script = normalizeScript(
|
|
2096
|
+
const script = normalizeScript(overrides.script) ?? (known ? normalizeScript(known.script) ?? parts?.script ?? (parts ? vendoredScript(matchingLanguages[parts.language] ?? parts.language, parts.region) : void 0) : inferScript(bcp47)) ?? "Zzzz";
|
|
2291
2097
|
const scriptRole = scriptFontRole(script);
|
|
2292
|
-
const declaredDirection =
|
|
2098
|
+
const declaredDirection = overrides.direction ?? known?.direction;
|
|
2293
2099
|
const direction = declaredDirection === "rtl" || declaredDirection === "ltr" ? declaredDirection : rtlScripts.has(script) ? "rtl" : "ltr";
|
|
2294
|
-
const app = options.app ?? "
|
|
2295
|
-
const
|
|
2296
|
-
const
|
|
2297
|
-
const languageScheme = resolveReference(lookup, "fontSchemes", preferred) ?? resolveReference(lookup, "fontSchemes", alternate);
|
|
2100
|
+
const app = options.app ?? "powerpoint";
|
|
2101
|
+
const named = (key) => typeof overrides[key] === "string" ? resolveReference(document, "fontSchemes", overrides[key], catalogs)?.record : void 0;
|
|
2102
|
+
const languageScheme = app === "google-slides" ? named("googleFontScheme") ?? known?.fonts.google ?? named("fontScheme") : named("fontScheme") ?? known?.fonts.powerpoint ?? named("googleFontScheme");
|
|
2298
2103
|
const languageFamilies = pairFamilies(languageScheme);
|
|
2299
|
-
const schemeAdmitsLanguage = schemeServesLanguage(scheme,
|
|
2104
|
+
const schemeAdmitsLanguage = schemeServesLanguage(scheme, bcp47, script);
|
|
2300
2105
|
const slot = (role, family) => {
|
|
2301
2106
|
const explicit = pairFamilies(scheme[role]);
|
|
2302
2107
|
if (explicit) return { ...explicit, source: "fontScheme" };
|
|
2303
|
-
if (scheme.languageFamily === family && schemeAdmitsLanguage) return { ...latin, source: "schemeFamily" };
|
|
2108
|
+
if (normalizeLanguageFamily(scheme.languageFamily) === family && schemeAdmitsLanguage) return { ...latin, source: "schemeFamily" };
|
|
2304
2109
|
if (scriptRole === role && languageFamilies) return { ...languageFamilies, source: "language" };
|
|
2305
2110
|
return { heading: latin.heading, body: latin.body, source: "latin" };
|
|
2306
2111
|
};
|
|
@@ -2318,7 +2123,6 @@ function resolveScriptFonts(input, options = {}) {
|
|
|
2318
2123
|
...body,
|
|
2319
2124
|
lang,
|
|
2320
2125
|
bcp47,
|
|
2321
|
-
...language.languageId ? { languageId: language.languageId } : {},
|
|
2322
2126
|
languageSource,
|
|
2323
2127
|
script,
|
|
2324
2128
|
scriptRole,
|
|
@@ -2403,10 +2207,10 @@ function listNumbers(items, numbering) {
|
|
|
2403
2207
|
const levels = resolveNumbering(numbering);
|
|
2404
2208
|
const counters = [];
|
|
2405
2209
|
return items.map((item, index) => {
|
|
2406
|
-
const
|
|
2407
|
-
const level =
|
|
2210
|
+
const object2 = isObject(item) ? item : void 0;
|
|
2211
|
+
const level = object2?.level === void 0 ? 0 : object2.level;
|
|
2408
2212
|
if (typeof level !== "number" || !Number.isInteger(level) || level < 0) throw new RangeError("List levels must be nonnegative integers.");
|
|
2409
|
-
const own2 =
|
|
2213
|
+
const own2 = object2?.start;
|
|
2410
2214
|
if (own2 !== void 0 && (typeof own2 !== "number" || !Number.isInteger(own2) || own2 < 1 || own2 > MAX_NUMBERING_VALUE)) throw new RangeError(`A list item start must be an integer from 1 to ${MAX_NUMBERING_VALUE}.`);
|
|
2411
2215
|
const { style: authored, start, suffix } = numberingAtLevel(levels, level);
|
|
2412
2216
|
const previous = counters[level];
|
|
@@ -2425,8 +2229,8 @@ function sliceNumberedItems(items, numbering, from, to = items.length) {
|
|
|
2425
2229
|
const wanted = whole[from + index].value;
|
|
2426
2230
|
if (listNumbers(result.slice(0, index + 1), numbering)[index].value === wanted) continue;
|
|
2427
2231
|
const item = result[index];
|
|
2428
|
-
const
|
|
2429
|
-
result[index] = { ...
|
|
2232
|
+
const object2 = isObject(item) ? item : { text: item };
|
|
2233
|
+
result[index] = { ...object2, start: wanted };
|
|
2430
2234
|
}
|
|
2431
2235
|
return result;
|
|
2432
2236
|
}
|
|
@@ -2479,6 +2283,7 @@ var schemeColorRoles = /* @__PURE__ */ new Set([
|
|
|
2479
2283
|
"accent",
|
|
2480
2284
|
"background",
|
|
2481
2285
|
"surface",
|
|
2286
|
+
"surfaceAlt",
|
|
2482
2287
|
"text",
|
|
2483
2288
|
"textSecondary"
|
|
2484
2289
|
]);
|
|
@@ -2522,6 +2327,11 @@ function resolveColorRef(reference, options) {
|
|
|
2522
2327
|
const roleKey = reference;
|
|
2523
2328
|
const fromRoles = roles?.[roleKey];
|
|
2524
2329
|
if (fromRoles) return normalizeHexColor(fromRoles) ?? fallback;
|
|
2330
|
+
if (reference === "surfaceAlt") {
|
|
2331
|
+
const surface = resolveColorRef("surface", { colorScheme, roles, variables, fallback: "#FFFFFF" });
|
|
2332
|
+
const text2 = resolveColorRef("text", { colorScheme, roles, variables, fallback: textColorForFill(surface, "#000000") });
|
|
2333
|
+
return surfaceAltColor(surface, text2);
|
|
2334
|
+
}
|
|
2525
2335
|
const fromScheme = normalizeHexColor(colorScheme[reference]);
|
|
2526
2336
|
if (fromScheme) return fromScheme;
|
|
2527
2337
|
const slot = defaultRoleSlots[reference];
|
|
@@ -2530,6 +2340,52 @@ function resolveColorRef(reference, options) {
|
|
|
2530
2340
|
if (schemeColorSlots.has(reference)) return schemeSlot(colorScheme, reference, fallback);
|
|
2531
2341
|
return fallback;
|
|
2532
2342
|
}
|
|
2343
|
+
var DARK_BACKGROUND_LUMINANCE = 0.179;
|
|
2344
|
+
function isDarkColor(color) {
|
|
2345
|
+
const hex = normalizeHexColor(color);
|
|
2346
|
+
const value = hex ? luminance(hex) : void 0;
|
|
2347
|
+
return value !== void 0 && value < DARK_BACKGROUND_LUMINANCE;
|
|
2348
|
+
}
|
|
2349
|
+
function defaultSlideBackground(colorScheme) {
|
|
2350
|
+
return keepAlpha(colorScheme.background) ?? slotKeepingAlpha(colorScheme, "light1", "#FFFFFF");
|
|
2351
|
+
}
|
|
2352
|
+
function keepAlpha(value) {
|
|
2353
|
+
if (typeof value !== "string") return void 0;
|
|
2354
|
+
const hex = value.trim();
|
|
2355
|
+
if (/^#[0-9a-f]{8}$/i.test(hex)) return hex.toUpperCase();
|
|
2356
|
+
return normalizeHexColor(hex);
|
|
2357
|
+
}
|
|
2358
|
+
function slotKeepingAlpha(colorScheme, slot, fallback) {
|
|
2359
|
+
return keepAlpha(colorScheme[slot]) ?? fallback;
|
|
2360
|
+
}
|
|
2361
|
+
var DEFAULT_HYPERLINK = "#0563C1";
|
|
2362
|
+
var DEFAULT_FOLLOWED_HYPERLINK = "#954F72";
|
|
2363
|
+
var MIN_LINK_CONTRAST = 4.5;
|
|
2364
|
+
function readableLink(link, background, text2) {
|
|
2365
|
+
const linkHex = normalizeHexColor(link), backgroundHex = normalizeHexColor(background);
|
|
2366
|
+
const contrast2 = linkHex && backgroundHex ? colorContrast(linkHex, backgroundHex) : void 0;
|
|
2367
|
+
return contrast2 !== void 0 && contrast2 < MIN_LINK_CONTRAST ? text2 : link;
|
|
2368
|
+
}
|
|
2369
|
+
function resolveColorRoles(colorScheme, options = {}) {
|
|
2370
|
+
const slot = (name, fallback) => slotKeepingAlpha(colorScheme, name, fallback);
|
|
2371
|
+
const background = keepAlpha(options.background) ?? defaultSlideBackground(colorScheme);
|
|
2372
|
+
const dark = isDarkColor(background);
|
|
2373
|
+
const text2 = dark ? slot("light1", "#FFFFFF") : keepAlpha(colorScheme.text) ?? slot("dark1", "#111827");
|
|
2374
|
+
const surface = keepAlpha(colorScheme.surface) ?? (dark ? slot("dark2", "#1E293B") : slot("light2", "#F8FAFC"));
|
|
2375
|
+
return {
|
|
2376
|
+
primary: keepAlpha(colorScheme.primary) ?? slot("accent1", "#2563EB"),
|
|
2377
|
+
secondary: keepAlpha(colorScheme.secondary) ?? slot("accent2", "#0F766E"),
|
|
2378
|
+
accent: keepAlpha(colorScheme.accent) ?? slot("accent3", "#F59E0B"),
|
|
2379
|
+
background,
|
|
2380
|
+
surface,
|
|
2381
|
+
surfaceAlt: surfaceAltColor(surface, text2),
|
|
2382
|
+
text: text2,
|
|
2383
|
+
textSecondary: keepAlpha(colorScheme.textSecondary) ?? (dark ? slot("light2", "#E2E8F0") : slot("dark2", "#334155")),
|
|
2384
|
+
hyperlink: readableLink(slot("hyperlink", DEFAULT_HYPERLINK), background, text2),
|
|
2385
|
+
followedHyperlink: slot("followedHyperlink", DEFAULT_FOLLOWED_HYPERLINK),
|
|
2386
|
+
dark
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2533
2389
|
function luminance(value) {
|
|
2534
2390
|
if (typeof value !== "string") return void 0;
|
|
2535
2391
|
let hex = value.trim();
|
|
@@ -2547,19 +2403,19 @@ function colorContrast(foreground, background) {
|
|
|
2547
2403
|
return a === void 0 || b === void 0 ? void 0 : (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
|
|
2548
2404
|
}
|
|
2549
2405
|
function textColorForFill(fill, preferred) {
|
|
2550
|
-
const background = luminance(fill),
|
|
2551
|
-
if (background === void 0 ||
|
|
2406
|
+
const background = luminance(fill), contrast2 = colorContrast(preferred, fill);
|
|
2407
|
+
if (background === void 0 || contrast2 === void 0 || contrast2 >= 4.5) return preferred;
|
|
2552
2408
|
return (background + 0.05) / 0.05 >= 1.05 / (background + 0.05) ? "#000000" : "#FFFFFF";
|
|
2553
2409
|
}
|
|
2554
2410
|
function chartColorForFill(fill, preferred) {
|
|
2555
|
-
const
|
|
2556
|
-
if (
|
|
2411
|
+
const contrast2 = colorContrast(preferred, fill);
|
|
2412
|
+
if (contrast2 === void 0 || contrast2 >= 3) return preferred;
|
|
2557
2413
|
let hex = preferred.trim();
|
|
2558
2414
|
if (hex.length === 4) hex = `#${[...hex.slice(1)].map((c) => c + c).join("")}`;
|
|
2559
|
-
const
|
|
2415
|
+
const channels2 = [1, 3, 5].map((offset) => Number.parseInt(hex.slice(offset, offset + 2), 16));
|
|
2560
2416
|
for (let step = 1; step <= 255; step++) {
|
|
2561
2417
|
const candidates = [0, 255].map((target) => {
|
|
2562
|
-
const color = `#${
|
|
2418
|
+
const color = `#${channels2.map((channel) => Math.round(channel + (target - channel) * step / 255).toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
2563
2419
|
return { color, contrast: colorContrast(color, fill) ?? 0 };
|
|
2564
2420
|
}).sort((a, b) => b.contrast - a.contrast);
|
|
2565
2421
|
const best = candidates[0];
|
|
@@ -2581,8 +2437,8 @@ var toLinear = (channel) => {
|
|
|
2581
2437
|
return n <= 0.04045 ? n / 12.92 : ((n + 0.055) / 1.055) ** 2.4;
|
|
2582
2438
|
};
|
|
2583
2439
|
var fromLinear = (value) => 255 * (value <= 31308e-7 ? value * 12.92 : 1.055 * value ** (1 / 2.4) - 0.055);
|
|
2584
|
-
function labOf(
|
|
2585
|
-
const [r, g, b] =
|
|
2440
|
+
function labOf(channels2) {
|
|
2441
|
+
const [r, g, b] = channels2.map(toLinear);
|
|
2586
2442
|
const f = (t) => t > 216 / 24389 ? Math.cbrt(t) : (24389 / 27 * t + 16) / 116;
|
|
2587
2443
|
const fx = f((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / D65[0]), fy = f(0.2126729 * r + 0.7151522 * g + 0.072175 * b), fz = f((0.0193339 * r + 0.119192 * g + 0.9503041 * b) / D65[2]);
|
|
2588
2444
|
return [116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)];
|
|
@@ -2598,21 +2454,21 @@ function labToLinear([l, a, b]) {
|
|
|
2598
2454
|
];
|
|
2599
2455
|
return rgb.every((channel) => channel >= -5e-4 && channel <= 1.0005) ? rgb : void 0;
|
|
2600
2456
|
}
|
|
2601
|
-
var hexOfChannels = (
|
|
2457
|
+
var hexOfChannels = (channels2) => `#${channels2.map((channel) => Math.max(0, Math.min(255, Math.round(channel))).toString(16).padStart(2, "0")).join("").toUpperCase()}`;
|
|
2602
2458
|
function labWithLightness(l, a, b) {
|
|
2603
2459
|
const chroma = Math.hypot(a, b), hue = Math.atan2(b, a);
|
|
2604
2460
|
const at3 = (scale) => labToLinear([l, Math.cos(hue) * chroma * scale, Math.sin(hue) * chroma * scale]);
|
|
2605
|
-
let
|
|
2606
|
-
if (!
|
|
2461
|
+
let linear2 = at3(1);
|
|
2462
|
+
if (!linear2) {
|
|
2607
2463
|
let low = 0, high = 1;
|
|
2608
2464
|
for (let step = 0; step < 24; step++) {
|
|
2609
2465
|
const mid = (low + high) / 2;
|
|
2610
2466
|
if (at3(mid)) low = mid;
|
|
2611
2467
|
else high = mid;
|
|
2612
2468
|
}
|
|
2613
|
-
|
|
2469
|
+
linear2 = at3(low) ?? [0, 0, 0];
|
|
2614
2470
|
}
|
|
2615
|
-
return hexOfChannels(
|
|
2471
|
+
return hexOfChannels(linear2.map((channel) => fromLinear(Math.max(0, Math.min(1, channel)))));
|
|
2616
2472
|
}
|
|
2617
2473
|
function labDifference(a, b) {
|
|
2618
2474
|
return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
|
|
@@ -2621,15 +2477,15 @@ var CHART_SERIES_SHORTFALL_WEIGHT = 8;
|
|
|
2621
2477
|
function chartPaletteForFill(fill, palette) {
|
|
2622
2478
|
const opaqueFill = colorContrast(fill, fill) !== void 0;
|
|
2623
2479
|
const preferredLab = palette.map((color) => {
|
|
2624
|
-
const
|
|
2625
|
-
return
|
|
2480
|
+
const channels2 = opaqueChannels(color);
|
|
2481
|
+
return channels2 ? labOf(channels2) : void 0;
|
|
2626
2482
|
});
|
|
2627
2483
|
const adjusted = palette.map((color) => chartColorForFill(fill, color));
|
|
2628
2484
|
const kept = palette.map((color, index) => opaqueFill && preferredLab[index] !== void 0 && adjusted[index] === color);
|
|
2629
2485
|
const placed = palette.map((_, index) => kept[index] || !opaqueFill || !preferredLab[index] ? adjusted[index] : void 0);
|
|
2630
2486
|
const placedLab = placed.map((color) => {
|
|
2631
|
-
const
|
|
2632
|
-
return
|
|
2487
|
+
const channels2 = color === void 0 ? void 0 : opaqueChannels(color);
|
|
2488
|
+
return channels2 ? labOf(channels2) : void 0;
|
|
2633
2489
|
});
|
|
2634
2490
|
palette.forEach((_, index) => {
|
|
2635
2491
|
const wanted = preferredLab[index], base = adjusted[index];
|
|
@@ -2653,8 +2509,8 @@ function chartPaletteForFill(fill, palette) {
|
|
|
2653
2509
|
}
|
|
2654
2510
|
let best = { color: base, lab: baseLab, cost: cost({ moved: 0, ...start }), moved: 0 };
|
|
2655
2511
|
for (let step = 0; step <= 400; step++) {
|
|
2656
|
-
const color = labWithLightness(step / 4, wanted[1], wanted[2]),
|
|
2657
|
-
if (
|
|
2512
|
+
const color = labWithLightness(step / 4, wanted[1], wanted[2]), contrast2 = colorContrast(color, fill);
|
|
2513
|
+
if (contrast2 === void 0 || contrast2 < 3) continue;
|
|
2658
2514
|
const lab = labOf(opaqueChannels(color)), moved = Math.abs(lab[0] - baseLab[0]), total = cost({ moved, ...shortfall(lab) });
|
|
2659
2515
|
if (total < best.cost - 1e-9 || Math.abs(total - best.cost) <= 1e-9 && moved < best.moved) best = { color, lab, cost: total, moved };
|
|
2660
2516
|
}
|
|
@@ -2663,6 +2519,1113 @@ function chartPaletteForFill(fill, palette) {
|
|
|
2663
2519
|
});
|
|
2664
2520
|
return placed;
|
|
2665
2521
|
}
|
|
2522
|
+
var CHART_HIGHLIGHT_MUTED_MIX = 0.3;
|
|
2523
|
+
var CHART_HIGHLIGHT_MUTED_MIN_CONTRAST = 1.6;
|
|
2524
|
+
var mixChannels = (from, to, amount) => hexOfChannels(from.map((channel, index) => channel + (to[index] - channel) * amount));
|
|
2525
|
+
function chartHighlightColors(surface, primary, text2) {
|
|
2526
|
+
const fill = normalizeHexColor(surface) ?? "#FFFFFF";
|
|
2527
|
+
const accent = chartColorForFill(fill, normalizeHexColor(primary) ?? "#000000");
|
|
2528
|
+
const ink = normalizeHexColor(text2) ?? textColorForFill(fill, "#000000");
|
|
2529
|
+
const from = opaqueChannels(fill), to = opaqueChannels(ink);
|
|
2530
|
+
let muted = mixChannels(from, to, CHART_HIGHLIGHT_MUTED_MIX);
|
|
2531
|
+
for (let amount = CHART_HIGHLIGHT_MUTED_MIX; (colorContrast(muted, fill) ?? Infinity) < CHART_HIGHLIGHT_MUTED_MIN_CONTRAST && amount < 1; ) {
|
|
2532
|
+
amount = Math.min(1, amount + 0.02);
|
|
2533
|
+
muted = mixChannels(from, to, amount);
|
|
2534
|
+
}
|
|
2535
|
+
return { accent, muted };
|
|
2536
|
+
}
|
|
2537
|
+
var SURFACE_ALT_MIX = 0.1;
|
|
2538
|
+
var SURFACE_ALT_MIN_CONTRAST = 1.1;
|
|
2539
|
+
function surfaceAltColor(surface, text2) {
|
|
2540
|
+
const fill = normalizeHexColor(surface) ?? "#FFFFFF";
|
|
2541
|
+
const ink = normalizeHexColor(text2) ?? textColorForFill(fill, "#000000");
|
|
2542
|
+
const from = opaqueChannels(fill), toText = opaqueChannels(ink);
|
|
2543
|
+
const step = (color) => (colorContrast(color, fill) ?? 1) >= SURFACE_ALT_MIN_CONTRAST;
|
|
2544
|
+
const readable = (color) => (colorContrast(ink, color) ?? 0) >= 4.5 || (colorContrast(ink, color) ?? 0) >= (colorContrast(ink, fill) ?? 0);
|
|
2545
|
+
for (let amount = SURFACE_ALT_MIX; amount <= 0.5 + 1e-9; amount += 0.02) {
|
|
2546
|
+
const band = mixChannels(from, toText, amount);
|
|
2547
|
+
if (!readable(band)) break;
|
|
2548
|
+
if (step(band)) return band;
|
|
2549
|
+
}
|
|
2550
|
+
const away = (luminance(ink) ?? 0) > (luminance(fill) ?? 0) ? [0, 0, 0] : [255, 255, 255];
|
|
2551
|
+
for (let amount = SURFACE_ALT_MIX; amount <= 1 + 1e-9; amount += 0.02) {
|
|
2552
|
+
const band = mixChannels(from, away, Math.min(1, amount));
|
|
2553
|
+
if (step(band)) return band;
|
|
2554
|
+
}
|
|
2555
|
+
return mixChannels(from, toText, SURFACE_ALT_MIX);
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
// src/legible-color.ts
|
|
2559
|
+
var channels = (hex) => [1, 3, 5].map((offset) => Number.parseInt(hex.slice(offset, offset + 2), 16));
|
|
2560
|
+
var toHex = (values) => `#${values.map((value) => Math.max(0, Math.min(255, Math.round(value))).toString(16).padStart(2, "0")).join("").toUpperCase()}`;
|
|
2561
|
+
var linear = (value) => {
|
|
2562
|
+
const n = value / 255;
|
|
2563
|
+
return n <= 0.04045 ? n / 12.92 : ((n + 0.055) / 1.055) ** 2.4;
|
|
2564
|
+
};
|
|
2565
|
+
var luminance2 = (hex) => {
|
|
2566
|
+
const [r, g, b] = channels(hex);
|
|
2567
|
+
return 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b);
|
|
2568
|
+
};
|
|
2569
|
+
var contrast = (a, b) => {
|
|
2570
|
+
const x = luminance2(a), y = luminance2(b);
|
|
2571
|
+
return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
|
|
2572
|
+
};
|
|
2573
|
+
var normalize = (value) => {
|
|
2574
|
+
if (typeof value !== "string") return void 0;
|
|
2575
|
+
const text2 = value.trim();
|
|
2576
|
+
if (/^#[0-9a-f]{3}$/i.test(text2)) return `#${[...text2.slice(1)].map((c) => c + c).join("")}`.toUpperCase();
|
|
2577
|
+
return /^#[0-9a-f]{6}([0-9a-f]{2})?$/i.test(text2) ? text2.slice(0, 7).toUpperCase() : void 0;
|
|
2578
|
+
};
|
|
2579
|
+
function toHsl(hex) {
|
|
2580
|
+
const [r, g, b] = channels(hex).map((value) => value / 255);
|
|
2581
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b), l = (max + min) / 2, d = max - min;
|
|
2582
|
+
if (d === 0) return [0, 0, l];
|
|
2583
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
2584
|
+
const h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
|
|
2585
|
+
return [h * 60, s, l];
|
|
2586
|
+
}
|
|
2587
|
+
function fromHsl(h, s, l) {
|
|
2588
|
+
const hue = (h % 360 + 360) % 360, c = (1 - Math.abs(2 * l - 1)) * s, x = c * (1 - Math.abs(hue / 60 % 2 - 1)), m = l - c / 2;
|
|
2589
|
+
const [r, g, b] = hue < 60 ? [c, x, 0] : hue < 120 ? [x, c, 0] : hue < 180 ? [0, c, x] : hue < 240 ? [0, x, c] : hue < 300 ? [x, 0, c] : [c, 0, x];
|
|
2590
|
+
return toHex([(r + m) * 255, (g + m) * 255, (b + m) * 255]);
|
|
2591
|
+
}
|
|
2592
|
+
function legible(foreground, background, minimum) {
|
|
2593
|
+
if (contrast(foreground, background) >= minimum) return foreground;
|
|
2594
|
+
const [h, s, l] = toHsl(foreground), preferred = luminance2(background) < 0.5 ? 1 : -1;
|
|
2595
|
+
for (const direction of [preferred, -preferred]) {
|
|
2596
|
+
for (let step = 1; step <= 100; step++) {
|
|
2597
|
+
const lightness = l + direction * step / 100;
|
|
2598
|
+
if (lightness < 0 || lightness > 1) break;
|
|
2599
|
+
const candidate = fromHsl(h, s, lightness);
|
|
2600
|
+
if (contrast(candidate, background) >= minimum) return candidate;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
return contrast("#FFFFFF", background) >= contrast("#000000", background) ? "#FFFFFF" : "#000000";
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
// src/code-syntax.ts
|
|
2607
|
+
var CODE_HIGHLIGHT_MAX_LENGTH = 2e5;
|
|
2608
|
+
var CODE_SYNTAX_MIN_CONTRAST = 4.5;
|
|
2609
|
+
var CODE_PANEL_BACKGROUND = "#111827";
|
|
2610
|
+
var CODE_PANEL_FOREGROUND = "#E5E7EB";
|
|
2611
|
+
var set = (words) => new Set((words ?? "").split(/\s+/).filter(Boolean));
|
|
2612
|
+
var JS_KEYWORDS = "break case catch class const continue debugger default delete do else enum export extends finally for from function if import in instanceof let new of return static super switch this throw try typeof var void while with yield async await as get set declare namespace module abstract implements interface private protected public readonly override keyof satisfies type is infer";
|
|
2613
|
+
var JS = { line: ["//"], block: [["/*", "*/"]], strings: "'\"`", keywords: JS_KEYWORDS, literals: "true false null undefined NaN Infinity", types: "string number boolean object symbol bigint never unknown any void", defs: { function: "function", class: "type", interface: "type", enum: "type", type: "type" }, capsTypes: true, calls: true, decorators: true };
|
|
2614
|
+
var C_LIKE_KEYWORDS = "auto break case catch char class const constexpr continue default delete do double else enum explicit extern false final float for friend goto if inline int long mutable namespace new noexcept nullptr operator override private protected public register return short signed sizeof static struct switch template this throw true try typedef typename union unsigned using virtual void volatile while";
|
|
2615
|
+
var LANGUAGES2 = {
|
|
2616
|
+
javascript: JS,
|
|
2617
|
+
typescript: JS,
|
|
2618
|
+
python: { line: ["#"], strings: `'"`, triple: ['"""', "'''"], keywords: "and as assert async await break class continue def del elif else except finally for from global if import in is lambda nonlocal not or pass raise return try while with yield match case self cls", literals: "True False None", types: "int float str bool bytes list dict set tuple object type", defs: { def: "function", class: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
2619
|
+
rust: { line: ["//"], block: [["/*", "*/"]], strings: '"', rawStrings: "r", keywords: "as async await break const continue crate dyn else enum extern fn for if impl in let loop match mod move mut pub ref return self Self static struct super trait type unsafe use where while", literals: "true false", types: "i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 bool char str String Vec Option Result Box", defs: { fn: "function", struct: "type", enum: "type", trait: "type", type: "type", mod: "type" }, capsTypes: true, calls: true, macros: true },
|
|
2620
|
+
go: { line: ["//"], block: [["/*", "*/"]], strings: "\"'`", noEscapes: "`", keywords: "break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var", literals: "true false nil iota", types: "int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex64 complex128 string bool byte rune error any", defs: { func: "function", type: "type" }, capsTypes: true, calls: true },
|
|
2621
|
+
bash: { line: ["#"], strings: `'"`, noEscapes: "'", keywords: "if then else elif fi for while until do done case esac in function select time return exit break continue export local readonly declare unset set shift source alias trap eval exec", literals: "true false", variables: true, calls: false },
|
|
2622
|
+
json: { line: ["//"], block: [["/*", "*/"]], strings: '"', literals: "true false null", quotedKeys: true },
|
|
2623
|
+
yaml: { kind: "yaml" },
|
|
2624
|
+
toml: { kind: "ini", line: ["#"] },
|
|
2625
|
+
ini: { kind: "ini", line: ["#", ";"] },
|
|
2626
|
+
markup: { kind: "markup" },
|
|
2627
|
+
css: { kind: "css" },
|
|
2628
|
+
sql: { line: ["--"], block: [["/*", "*/"]], strings: `'"`, ci: true, keywords: "add all alter and any as asc between by case check column commit constraint create cross database default delete desc distinct drop else end exists foreign from full group having if in index inner insert into is join key left like limit not null offset on or order outer primary references replace right rollback select set table then top union unique update values view when where with", literals: "true false", types: "int integer bigint smallint decimal numeric float real double varchar char text date time timestamp boolean serial uuid json" },
|
|
2629
|
+
java: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, keywords: "abstract assert break case catch class const continue default do else enum extends final finally for goto if implements import instanceof interface native new package private protected public return static strictfp super switch synchronized this throw throws transient try var volatile while record sealed permits", literals: "true false null", types: "boolean byte char double float int long short void String Object", defs: { class: "type", interface: "type", enum: "type", record: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
2630
|
+
csharp: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, keywords: "abstract as async await base break case catch checked class const continue default delegate do else enum event explicit extern finally fixed for foreach goto if implicit in interface internal is lock namespace new operator out override params private protected public readonly ref return sealed sizeof stackalloc static struct switch this throw try typeof unchecked unsafe using var virtual volatile while record init required", literals: "true false null", types: "bool byte char decimal double float int long object sbyte short string uint ulong ushort void dynamic", defs: { class: "type", interface: "type", struct: "type", enum: "type", record: "type" }, capsTypes: true, calls: true, decorators: false },
|
|
2631
|
+
kotlin: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, triple: ['"""'], keywords: "abstract actual annotation as break by catch class companion const constructor continue crossinline data do else enum expect external final finally for fun get if import in infix init inline inner interface internal is it lateinit lazy noinline object open operator out override package private protected public reified return sealed set super suspend tailrec this throw try typealias val var vararg when where while", literals: "true false null", types: "Int Long Short Byte Float Double Boolean Char String Unit Any Nothing", defs: { fun: "function", class: "type", interface: "type", object: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
2632
|
+
swift: { line: ["//"], block: [["/*", "*/"]], strings: '"', triple: ['"""'], keywords: "actor as associatedtype async await break case catch class continue default defer deinit do else enum extension fallthrough fileprivate for func guard if import in init inout internal is let nonisolated open operator private protocol public repeat rethrows return self Self static struct subscript super switch throw throws try typealias var where while", literals: "true false nil", types: "Int Double Float Bool String Character Array Dictionary Set Optional Any", defs: { func: "function", class: "type", struct: "type", enum: "type", protocol: "type", extension: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
2633
|
+
ruby: { line: ["#"], strings: `'"`, keywords: "alias and begin break case class def defined do else elsif end ensure for if in module next not or redo rescue retry return self super then undef unless until when while yield require require_relative include extend attr_accessor attr_reader attr_writer private protected public", literals: "true false nil", defs: { def: "function", class: "type", module: "type" }, capsTypes: true, calls: true },
|
|
2634
|
+
php: { line: ["//", "#"], block: [["/*", "*/"]], strings: `'"`, keywords: "abstract and array as break callable case catch class clone const continue declare default do echo else elseif empty enddeclare endfor endforeach endif endswitch endwhile extends final finally fn for foreach function global goto if implements include include_once instanceof insteadof interface isset list match namespace new or print private protected public readonly require require_once return static switch throw trait try unset use var while xor yield", literals: "true false null TRUE FALSE NULL", defs: { function: "function", class: "type", interface: "type", trait: "type" }, capsTypes: true, calls: true, variables: true },
|
|
2635
|
+
c: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, keywords: C_LIKE_KEYWORDS, literals: "true false NULL nullptr", types: "size_t ssize_t int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t bool FILE", calls: true, capsTypes: false, directives: true, defs: { struct: "type", enum: "type", union: "type", class: "type" } },
|
|
2636
|
+
hcl: { line: ["#", "//"], block: [["/*", "*/"]], strings: '"', keywords: "resource data variable output locals module provider terraform for in if else dynamic content backend required_providers lifecycle", literals: "true false null", types: "string number bool list map set object tuple any", calls: true },
|
|
2637
|
+
dockerfile: { line: ["#"], strings: `'"`, keywords: "FROM RUN CMD LABEL MAINTAINER EXPOSE ENV ADD COPY ENTRYPOINT VOLUME USER WORKDIR ARG ONBUILD STOPSIGNAL HEALTHCHECK SHELL AS", variables: true }
|
|
2638
|
+
};
|
|
2639
|
+
var ALIASES = {
|
|
2640
|
+
js: "javascript",
|
|
2641
|
+
javascript: "javascript",
|
|
2642
|
+
mjs: "javascript",
|
|
2643
|
+
cjs: "javascript",
|
|
2644
|
+
jsx: "javascript",
|
|
2645
|
+
node: "javascript",
|
|
2646
|
+
nodejs: "javascript",
|
|
2647
|
+
ts: "typescript",
|
|
2648
|
+
typescript: "typescript",
|
|
2649
|
+
tsx: "typescript",
|
|
2650
|
+
mts: "typescript",
|
|
2651
|
+
cts: "typescript",
|
|
2652
|
+
python: "python",
|
|
2653
|
+
py: "python",
|
|
2654
|
+
python3: "python",
|
|
2655
|
+
py3: "python",
|
|
2656
|
+
rust: "rust",
|
|
2657
|
+
rs: "rust",
|
|
2658
|
+
go: "go",
|
|
2659
|
+
golang: "go",
|
|
2660
|
+
bash: "bash",
|
|
2661
|
+
sh: "bash",
|
|
2662
|
+
shell: "bash",
|
|
2663
|
+
zsh: "bash",
|
|
2664
|
+
console: "bash",
|
|
2665
|
+
shellscript: "bash",
|
|
2666
|
+
fish: "bash",
|
|
2667
|
+
json: "json",
|
|
2668
|
+
jsonc: "json",
|
|
2669
|
+
json5: "json",
|
|
2670
|
+
yaml: "yaml",
|
|
2671
|
+
yml: "yaml",
|
|
2672
|
+
toml: "toml",
|
|
2673
|
+
ini: "ini",
|
|
2674
|
+
conf: "ini",
|
|
2675
|
+
cfg: "ini",
|
|
2676
|
+
properties: "ini",
|
|
2677
|
+
env: "ini",
|
|
2678
|
+
markup: "markup",
|
|
2679
|
+
html: "markup",
|
|
2680
|
+
xml: "markup",
|
|
2681
|
+
svg: "markup",
|
|
2682
|
+
xhtml: "markup",
|
|
2683
|
+
vue: "markup",
|
|
2684
|
+
plist: "markup",
|
|
2685
|
+
css: "css",
|
|
2686
|
+
scss: "css",
|
|
2687
|
+
less: "css",
|
|
2688
|
+
sass: "css",
|
|
2689
|
+
sql: "sql",
|
|
2690
|
+
postgres: "sql",
|
|
2691
|
+
postgresql: "sql",
|
|
2692
|
+
mysql: "sql",
|
|
2693
|
+
sqlite: "sql",
|
|
2694
|
+
pgsql: "sql",
|
|
2695
|
+
java: "java",
|
|
2696
|
+
csharp: "csharp",
|
|
2697
|
+
cs: "csharp",
|
|
2698
|
+
"c#": "csharp",
|
|
2699
|
+
kotlin: "kotlin",
|
|
2700
|
+
kt: "kotlin",
|
|
2701
|
+
swift: "swift",
|
|
2702
|
+
ruby: "ruby",
|
|
2703
|
+
rb: "ruby",
|
|
2704
|
+
php: "php",
|
|
2705
|
+
c: "c",
|
|
2706
|
+
h: "c",
|
|
2707
|
+
cpp: "c",
|
|
2708
|
+
"c++": "c",
|
|
2709
|
+
cc: "c",
|
|
2710
|
+
cxx: "c",
|
|
2711
|
+
hpp: "c",
|
|
2712
|
+
hh: "c",
|
|
2713
|
+
objc: "c",
|
|
2714
|
+
hcl: "hcl",
|
|
2715
|
+
terraform: "hcl",
|
|
2716
|
+
tf: "hcl",
|
|
2717
|
+
tfvars: "hcl",
|
|
2718
|
+
dockerfile: "dockerfile",
|
|
2719
|
+
docker: "dockerfile"
|
|
2720
|
+
};
|
|
2721
|
+
var CODE_HIGHLIGHT_LANGUAGES = Object.freeze(Object.keys(LANGUAGES2));
|
|
2722
|
+
function resolveCodeLanguage(language) {
|
|
2723
|
+
if (typeof language !== "string") return void 0;
|
|
2724
|
+
const key = language.trim().toLowerCase().replace(/^(?:language|lang)[-:]/, "").replace(/^\./, "");
|
|
2725
|
+
return Object.hasOwn(ALIASES, key) ? ALIASES[key] : void 0;
|
|
2726
|
+
}
|
|
2727
|
+
var IDENT = /[\p{L}_$][\p{L}\p{N}_$]*/uy;
|
|
2728
|
+
var NUMBER = /(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d[\d_]*)?)[a-zA-Z]{0,4}/y;
|
|
2729
|
+
var isIdentChar = (character) => character !== void 0 && /[\p{L}\p{N}_$]/u.test(character);
|
|
2730
|
+
function endOfLine(source, from) {
|
|
2731
|
+
const index = source.slice(from).search(/\r\n|\r|\n/);
|
|
2732
|
+
return index < 0 ? source.length : from + index;
|
|
2733
|
+
}
|
|
2734
|
+
function pushToken(tokens, start, end, kind2) {
|
|
2735
|
+
if (end <= start) return;
|
|
2736
|
+
const last = tokens[tokens.length - 1];
|
|
2737
|
+
if (last && last.kind === kind2 && last.end === start && kind2 !== "function" && kind2 !== "property") last.end = end;
|
|
2738
|
+
else tokens.push({ start, end, kind: kind2 });
|
|
2739
|
+
}
|
|
2740
|
+
function scanQuoted(source, from, quote, escapes, multiline) {
|
|
2741
|
+
let index = from + 1;
|
|
2742
|
+
while (index < source.length) {
|
|
2743
|
+
const character = source[index];
|
|
2744
|
+
if (escapes && character === "\\") {
|
|
2745
|
+
index += 2;
|
|
2746
|
+
continue;
|
|
2747
|
+
}
|
|
2748
|
+
if (character === quote) return index + 1;
|
|
2749
|
+
if (!multiline && (character === "\n" || character === "\r")) return index;
|
|
2750
|
+
index++;
|
|
2751
|
+
}
|
|
2752
|
+
return source.length;
|
|
2753
|
+
}
|
|
2754
|
+
function scanGeneric(source, def) {
|
|
2755
|
+
const tokens = [];
|
|
2756
|
+
const keywords = set(def.keywords), literals = set(def.literals), types = set(def.types);
|
|
2757
|
+
const fold = (word) => def.ci ? word.toLowerCase() : word;
|
|
2758
|
+
if (def.ci) for (const list of [keywords, literals, types]) for (const word of [...list]) {
|
|
2759
|
+
list.delete(word);
|
|
2760
|
+
list.add(word.toLowerCase());
|
|
2761
|
+
}
|
|
2762
|
+
const strings = def.strings ?? "", lineComments = def.line ?? [], blocks = def.block ?? [], triples = def.triple ?? [];
|
|
2763
|
+
let index = 0, pendingDef;
|
|
2764
|
+
const atLineStart = (position) => {
|
|
2765
|
+
let at3 = position - 1;
|
|
2766
|
+
while (at3 >= 0 && (source[at3] === " " || source[at3] === " ")) at3--;
|
|
2767
|
+
return at3 < 0 || source[at3] === "\n" || source[at3] === "\r";
|
|
2768
|
+
};
|
|
2769
|
+
while (index < source.length) {
|
|
2770
|
+
const character = source[index];
|
|
2771
|
+
if (/\s/.test(character)) {
|
|
2772
|
+
index++;
|
|
2773
|
+
continue;
|
|
2774
|
+
}
|
|
2775
|
+
const lineComment = lineComments.find((opener) => source.startsWith(opener, index));
|
|
2776
|
+
if (lineComment && !(lineComment === "#" && def.directives) && !(lineComment === "#" && def.variables && source[index - 1] === "$") && !(def.variables && lineComment === "#" && index > 0 && !/[\s;&|(]/.test(source[index - 1]))) {
|
|
2777
|
+
const end = endOfLine(source, index);
|
|
2778
|
+
pushToken(tokens, index, end, "comment");
|
|
2779
|
+
index = end;
|
|
2780
|
+
continue;
|
|
2781
|
+
}
|
|
2782
|
+
const block = blocks.find(([opener]) => source.startsWith(opener, index));
|
|
2783
|
+
if (block) {
|
|
2784
|
+
const close = source.indexOf(block[1], index + block[0].length);
|
|
2785
|
+
const end = close < 0 ? source.length : close + block[1].length;
|
|
2786
|
+
pushToken(tokens, index, end, "comment");
|
|
2787
|
+
index = end;
|
|
2788
|
+
continue;
|
|
2789
|
+
}
|
|
2790
|
+
if (def.directives && character === "#" && atLineStart(index)) {
|
|
2791
|
+
const match = /#[ \t]*\w+/y;
|
|
2792
|
+
match.lastIndex = index;
|
|
2793
|
+
const found = match.exec(source);
|
|
2794
|
+
if (found) {
|
|
2795
|
+
pushToken(tokens, index, index + found[0].length, "keyword");
|
|
2796
|
+
index += found[0].length;
|
|
2797
|
+
if (/include/.test(found[0])) {
|
|
2798
|
+
const header = /[ \t]*(<[^>\n]*>)/y;
|
|
2799
|
+
header.lastIndex = index;
|
|
2800
|
+
const matched = header.exec(source);
|
|
2801
|
+
if (matched) {
|
|
2802
|
+
const start = index + matched[0].length - matched[1].length;
|
|
2803
|
+
pushToken(tokens, start, start + matched[1].length, "string");
|
|
2804
|
+
index += matched[0].length;
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
continue;
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
const triple = triples.find((opener) => source.startsWith(opener, index));
|
|
2811
|
+
if (triple) {
|
|
2812
|
+
const close = source.indexOf(triple, index + 3);
|
|
2813
|
+
const end = close < 0 ? source.length : close + 3;
|
|
2814
|
+
pushToken(tokens, index, end, "string");
|
|
2815
|
+
index = end;
|
|
2816
|
+
pendingDef = void 0;
|
|
2817
|
+
continue;
|
|
2818
|
+
}
|
|
2819
|
+
if (def.rawStrings && character === def.rawStrings && /^r#*"/.test(source.slice(index, index + 8)) && !isIdentChar(source[index - 1])) {
|
|
2820
|
+
const hashes = /^r(#*)"/.exec(source.slice(index, index + 8))[1];
|
|
2821
|
+
const close = source.indexOf(`"${hashes}`, index + 2 + hashes.length);
|
|
2822
|
+
const end = close < 0 ? source.length : close + 1 + hashes.length;
|
|
2823
|
+
pushToken(tokens, index, end, "string");
|
|
2824
|
+
index = end;
|
|
2825
|
+
continue;
|
|
2826
|
+
}
|
|
2827
|
+
if (strings.includes(character)) {
|
|
2828
|
+
if (def === LANGUAGES2.rust && character === "'" && !/^'(?:\\.[^']*|[^\\'])'/.test(source.slice(index, index + 12))) {
|
|
2829
|
+
const match = /'[\p{L}_][\p{L}\p{N}_]*/uy;
|
|
2830
|
+
match.lastIndex = index;
|
|
2831
|
+
const found = match.exec(source);
|
|
2832
|
+
const end2 = index + (found ? found[0].length : 1);
|
|
2833
|
+
if (found) pushToken(tokens, index, end2, "type");
|
|
2834
|
+
index = end2;
|
|
2835
|
+
continue;
|
|
2836
|
+
}
|
|
2837
|
+
const escapes = !(def.noEscapes ?? "").includes(character);
|
|
2838
|
+
const multiline = character === "`";
|
|
2839
|
+
const end = scanQuoted(source, index, character, escapes, multiline);
|
|
2840
|
+
let kind2 = "string";
|
|
2841
|
+
if (def.quotedKeys) {
|
|
2842
|
+
const after = /^[ \t]*:/.exec(source.slice(end, end + 40));
|
|
2843
|
+
if (after) kind2 = "property";
|
|
2844
|
+
}
|
|
2845
|
+
pushToken(tokens, index, end, kind2);
|
|
2846
|
+
index = end;
|
|
2847
|
+
pendingDef = void 0;
|
|
2848
|
+
continue;
|
|
2849
|
+
}
|
|
2850
|
+
if (def.variables && character === "$") {
|
|
2851
|
+
const match = /\$(?:\{[^}\n]*\}|[A-Za-z_]\w*|[0-9@#?!$*-])/y;
|
|
2852
|
+
match.lastIndex = index;
|
|
2853
|
+
const found = match.exec(source);
|
|
2854
|
+
if (found) {
|
|
2855
|
+
pushToken(tokens, index, index + found[0].length, "property");
|
|
2856
|
+
index += found[0].length;
|
|
2857
|
+
continue;
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
if (def.decorators && character === "@" && /[\p{L}_]/u.test(source[index + 1] ?? "")) {
|
|
2861
|
+
const match = /@[\p{L}_][\p{L}\p{N}_$.]*/uy;
|
|
2862
|
+
match.lastIndex = index;
|
|
2863
|
+
const found = match.exec(source);
|
|
2864
|
+
pushToken(tokens, index, index + found[0].length, "function");
|
|
2865
|
+
index += found[0].length;
|
|
2866
|
+
continue;
|
|
2867
|
+
}
|
|
2868
|
+
if (/\d/.test(character) && !isIdentChar(source[index - 1])) {
|
|
2869
|
+
NUMBER.lastIndex = index;
|
|
2870
|
+
const found = NUMBER.exec(source);
|
|
2871
|
+
if (found) {
|
|
2872
|
+
pushToken(tokens, index, index + found[0].length, "number");
|
|
2873
|
+
index += found[0].length;
|
|
2874
|
+
pendingDef = void 0;
|
|
2875
|
+
continue;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
if (def === LANGUAGES2.python && /[rRbBfFuU]/.test(character) && /^[rRbBfFuU]{1,2}['"]/.test(source.slice(index, index + 3)) && !isIdentChar(source[index - 1])) {
|
|
2879
|
+
const prefix = /^[rRbBfFuU]{1,2}/.exec(source.slice(index, index + 3))[0].length;
|
|
2880
|
+
const quote = source[index + prefix];
|
|
2881
|
+
const triple2 = source.startsWith(quote.repeat(3), index + prefix);
|
|
2882
|
+
let end;
|
|
2883
|
+
if (triple2) {
|
|
2884
|
+
const close = source.indexOf(quote.repeat(3), index + prefix + 3);
|
|
2885
|
+
end = close < 0 ? source.length : close + 3;
|
|
2886
|
+
} else end = scanQuoted(source, index + prefix, quote, !/[rR]/.test(source.slice(index, index + prefix)), false);
|
|
2887
|
+
pushToken(tokens, index, end, "string");
|
|
2888
|
+
index = end;
|
|
2889
|
+
pendingDef = void 0;
|
|
2890
|
+
continue;
|
|
2891
|
+
}
|
|
2892
|
+
IDENT.lastIndex = index;
|
|
2893
|
+
const identifier = IDENT.exec(source);
|
|
2894
|
+
if (identifier) {
|
|
2895
|
+
const word = identifier[0], end = index + word.length, folded = fold(word);
|
|
2896
|
+
let kind2;
|
|
2897
|
+
if (pendingDef && !keywords.has(folded)) kind2 = pendingDef;
|
|
2898
|
+
else if (keywords.has(folded)) {
|
|
2899
|
+
kind2 = "keyword";
|
|
2900
|
+
pendingDef = def.defs && Object.hasOwn(def.defs, folded) ? def.defs[folded] : void 0;
|
|
2901
|
+
pushToken(tokens, index, end, kind2);
|
|
2902
|
+
index = end;
|
|
2903
|
+
continue;
|
|
2904
|
+
} else if (literals.has(word) || literals.has(folded)) kind2 = "number";
|
|
2905
|
+
else if (types.has(folded)) kind2 = "type";
|
|
2906
|
+
else if (def.calls && source[end] === "(") kind2 = "function";
|
|
2907
|
+
else if (def.macros && source[end] === "!" && /[([{]/.test(source[end + 1] ?? "")) kind2 = "function";
|
|
2908
|
+
else if (def.capsTypes && /^[A-Z]/.test(word) && /[a-z]/.test(word)) kind2 = "type";
|
|
2909
|
+
pendingDef = void 0;
|
|
2910
|
+
if (kind2) pushToken(tokens, index, end, kind2);
|
|
2911
|
+
index = end;
|
|
2912
|
+
continue;
|
|
2913
|
+
}
|
|
2914
|
+
pendingDef = void 0;
|
|
2915
|
+
index++;
|
|
2916
|
+
}
|
|
2917
|
+
return tokens;
|
|
2918
|
+
}
|
|
2919
|
+
var YAML_LITERALS = /* @__PURE__ */ new Set(["true", "false", "null", "yes", "no", "on", "off", "~", "True", "False", "Null", "TRUE", "FALSE", "NULL"]);
|
|
2920
|
+
function scanYamlValue(source, start, end, tokens, comments) {
|
|
2921
|
+
let index = start;
|
|
2922
|
+
while (index < end) {
|
|
2923
|
+
const character = source[index];
|
|
2924
|
+
if (character === "#" && (index === start || /\s/.test(source[index - 1])) && comments.includes("#")) {
|
|
2925
|
+
pushToken(tokens, index, end, "comment");
|
|
2926
|
+
return;
|
|
2927
|
+
}
|
|
2928
|
+
if (character === ";" && comments.includes(";") && (index === start || /\s/.test(source[index - 1]))) {
|
|
2929
|
+
pushToken(tokens, index, end, "comment");
|
|
2930
|
+
return;
|
|
2931
|
+
}
|
|
2932
|
+
if (character === '"' || character === "'") {
|
|
2933
|
+
const close = scanQuoted(source, index, character, character === '"', false);
|
|
2934
|
+
pushToken(tokens, index, Math.min(close, end), "string");
|
|
2935
|
+
index = Math.min(close, end);
|
|
2936
|
+
continue;
|
|
2937
|
+
}
|
|
2938
|
+
if ((character === "&" || character === "*") && /[\w-]/.test(source[index + 1] ?? "")) {
|
|
2939
|
+
const match = /[&*][\w-]+/y;
|
|
2940
|
+
match.lastIndex = index;
|
|
2941
|
+
const found2 = match.exec(source);
|
|
2942
|
+
pushToken(tokens, index, index + found2[0].length, "type");
|
|
2943
|
+
index += found2[0].length;
|
|
2944
|
+
continue;
|
|
2945
|
+
}
|
|
2946
|
+
if (!isIdentChar(source[index - 1]) && /[\d-]/.test(character)) {
|
|
2947
|
+
const match = /-?\d[\d_]*(?:\.\d+)?(?:[eE][+-]?\d+)?(?=[\s,\]}]|$)/y;
|
|
2948
|
+
match.lastIndex = index;
|
|
2949
|
+
const found2 = match.exec(source);
|
|
2950
|
+
if (found2 && index + found2[0].length <= end) {
|
|
2951
|
+
pushToken(tokens, index, index + found2[0].length, "number");
|
|
2952
|
+
index += found2[0].length;
|
|
2953
|
+
continue;
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
const word = /[\w.~-]+/y;
|
|
2957
|
+
word.lastIndex = index;
|
|
2958
|
+
const found = word.exec(source);
|
|
2959
|
+
if (found) {
|
|
2960
|
+
if (YAML_LITERALS.has(found[0]) && !/[\w.-]/.test(source[index + found[0].length] ?? "")) pushToken(tokens, index, index + found[0].length, "number");
|
|
2961
|
+
index += found[0].length;
|
|
2962
|
+
continue;
|
|
2963
|
+
}
|
|
2964
|
+
index++;
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
function lineRanges(source) {
|
|
2968
|
+
const ranges = [];
|
|
2969
|
+
let cursor = 0;
|
|
2970
|
+
const pattern = /\r\n|\r|\n/g;
|
|
2971
|
+
for (let match = pattern.exec(source); match; match = pattern.exec(source)) {
|
|
2972
|
+
ranges.push({ start: cursor, end: match.index });
|
|
2973
|
+
cursor = match.index + match[0].length;
|
|
2974
|
+
}
|
|
2975
|
+
ranges.push({ start: cursor, end: source.length });
|
|
2976
|
+
return ranges;
|
|
2977
|
+
}
|
|
2978
|
+
function yamlKey(source, from, to) {
|
|
2979
|
+
const first = source[from];
|
|
2980
|
+
if (first === void 0 || from >= to) return void 0;
|
|
2981
|
+
let index = from;
|
|
2982
|
+
if (first === '"' || first === "'") {
|
|
2983
|
+
index = Math.min(scanQuoted(source, from, first, first === '"', false), to);
|
|
2984
|
+
let at3 = index;
|
|
2985
|
+
while (at3 < to && (source[at3] === " " || source[at3] === " ")) at3++;
|
|
2986
|
+
return source[index - 1] === first && source[at3] === ":" && (at3 + 1 >= to || /\s/.test(source[at3 + 1])) ? { nameEnd: index, colon: at3 } : void 0;
|
|
2987
|
+
}
|
|
2988
|
+
if (/[\s#:{}[\],&*!|>%@`]/.test(first) || first === "-" && /[\s#:]/.test(source[from + 1] ?? " ")) return void 0;
|
|
2989
|
+
for (; index < to; index++) {
|
|
2990
|
+
const character = source[index];
|
|
2991
|
+
if (character === "#" && /\s/.test(source[index - 1])) return void 0;
|
|
2992
|
+
if (character === ":" && (index + 1 >= to || /\s/.test(source[index + 1]))) {
|
|
2993
|
+
let nameEnd = index;
|
|
2994
|
+
while (nameEnd > from && /\s/.test(source[nameEnd - 1])) nameEnd--;
|
|
2995
|
+
return nameEnd > from ? { nameEnd, colon: index } : void 0;
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
return void 0;
|
|
2999
|
+
}
|
|
3000
|
+
function scanYaml(source) {
|
|
3001
|
+
const tokens = [];
|
|
3002
|
+
let blockIndent = -1;
|
|
3003
|
+
for (const { start, end } of lineRanges(source)) {
|
|
3004
|
+
const text2 = source.slice(start, end), indent = /^ */.exec(text2)[0].length;
|
|
3005
|
+
if (blockIndent >= 0) {
|
|
3006
|
+
if (text2.trim() === "" || indent > blockIndent) {
|
|
3007
|
+
if (text2.trim() !== "") pushToken(tokens, start + indent, end, "string");
|
|
3008
|
+
continue;
|
|
3009
|
+
}
|
|
3010
|
+
blockIndent = -1;
|
|
3011
|
+
}
|
|
3012
|
+
if (/^\s*#/.test(text2)) {
|
|
3013
|
+
pushToken(tokens, start + indent, end, "comment");
|
|
3014
|
+
continue;
|
|
3015
|
+
}
|
|
3016
|
+
if (/^(?:---|\.\.\.)(?:\s|$)/.test(text2)) {
|
|
3017
|
+
pushToken(tokens, start, start + 3, "keyword");
|
|
3018
|
+
scanYamlValue(source, start + 3, end, tokens, "#");
|
|
3019
|
+
continue;
|
|
3020
|
+
}
|
|
3021
|
+
let cursor = start + indent;
|
|
3022
|
+
const dash = /^(?:-\s+)+/.exec(text2.slice(indent));
|
|
3023
|
+
if (dash) cursor += dash[0].length;
|
|
3024
|
+
let valueStart = cursor;
|
|
3025
|
+
const key = yamlKey(source, cursor, end);
|
|
3026
|
+
if (key) {
|
|
3027
|
+
pushToken(tokens, cursor, key.nameEnd, "property");
|
|
3028
|
+
valueStart = key.colon + 1;
|
|
3029
|
+
}
|
|
3030
|
+
scanYamlValue(source, valueStart, end, tokens, "#");
|
|
3031
|
+
if (/(?:^|\s)[|>][+-]?\d?\s*(?:#.*)?$/.test(text2.slice(valueStart - start))) blockIndent = indent;
|
|
3032
|
+
}
|
|
3033
|
+
return tokens;
|
|
3034
|
+
}
|
|
3035
|
+
function scanIni(source, def) {
|
|
3036
|
+
const tokens = [], comments = (def.line ?? []).join("");
|
|
3037
|
+
for (const { start, end } of lineRanges(source)) {
|
|
3038
|
+
const text2 = source.slice(start, end), indent = /^\s*/.exec(text2)[0].length, first = text2[indent];
|
|
3039
|
+
if (first === void 0) continue;
|
|
3040
|
+
if (comments.includes(first)) {
|
|
3041
|
+
pushToken(tokens, start + indent, end, "comment");
|
|
3042
|
+
continue;
|
|
3043
|
+
}
|
|
3044
|
+
if (first === "[") {
|
|
3045
|
+
const close = text2.indexOf("]", indent);
|
|
3046
|
+
const stop = close < 0 ? end : start + close + 1;
|
|
3047
|
+
pushToken(tokens, start + indent, stop, "type");
|
|
3048
|
+
scanYamlValue(source, stop, end, tokens, comments);
|
|
3049
|
+
continue;
|
|
3050
|
+
}
|
|
3051
|
+
const key = /^("[^"\n]*"|'[^'\n]*'|[^\s=:#;"']+(?:\s+[^\s=:#;"']+)*)\s*[=:]/.exec(text2.slice(indent));
|
|
3052
|
+
let valueStart = start + indent;
|
|
3053
|
+
if (key) {
|
|
3054
|
+
pushToken(tokens, start + indent, start + indent + key[1].length, "property");
|
|
3055
|
+
valueStart = start + indent + key[0].length;
|
|
3056
|
+
}
|
|
3057
|
+
scanYamlValue(source, valueStart, end, tokens, comments);
|
|
3058
|
+
}
|
|
3059
|
+
return tokens;
|
|
3060
|
+
}
|
|
3061
|
+
function scanMarkup(source) {
|
|
3062
|
+
const tokens = [];
|
|
3063
|
+
let index = 0;
|
|
3064
|
+
while (index < source.length) {
|
|
3065
|
+
const open = source.indexOf("<", index);
|
|
3066
|
+
if (open < 0) break;
|
|
3067
|
+
if (source.startsWith("<!--", open)) {
|
|
3068
|
+
const close = source.indexOf("-->", open + 4);
|
|
3069
|
+
const end = close < 0 ? source.length : close + 3;
|
|
3070
|
+
pushToken(tokens, open, end, "comment");
|
|
3071
|
+
index = end;
|
|
3072
|
+
continue;
|
|
3073
|
+
}
|
|
3074
|
+
if (source.startsWith("<![CDATA[", open)) {
|
|
3075
|
+
const close = source.indexOf("]]>", open);
|
|
3076
|
+
const end = close < 0 ? source.length : close + 3;
|
|
3077
|
+
pushToken(tokens, open, end, "string");
|
|
3078
|
+
index = end;
|
|
3079
|
+
continue;
|
|
3080
|
+
}
|
|
3081
|
+
const name = /<([/?!]?)([A-Za-z][\w:.-]*|DOCTYPE)?/y;
|
|
3082
|
+
name.lastIndex = open;
|
|
3083
|
+
const found = name.exec(source);
|
|
3084
|
+
if (!found || !found[2]) {
|
|
3085
|
+
index = open + 1;
|
|
3086
|
+
continue;
|
|
3087
|
+
}
|
|
3088
|
+
pushToken(tokens, open + 1, open + found[0].length, "keyword");
|
|
3089
|
+
index = open + found[0].length;
|
|
3090
|
+
while (index < source.length && source[index] !== ">") {
|
|
3091
|
+
const character = source[index];
|
|
3092
|
+
if (character === '"' || character === "'") {
|
|
3093
|
+
const close = source.indexOf(character, index + 1);
|
|
3094
|
+
const end = close < 0 ? source.length : close + 1;
|
|
3095
|
+
pushToken(tokens, index, end, "string");
|
|
3096
|
+
index = end;
|
|
3097
|
+
continue;
|
|
3098
|
+
}
|
|
3099
|
+
const attribute = /[A-Za-z_:@#][\w:.@#-]*/y;
|
|
3100
|
+
attribute.lastIndex = index;
|
|
3101
|
+
const matched = attribute.exec(source);
|
|
3102
|
+
if (matched) {
|
|
3103
|
+
pushToken(tokens, index, index + matched[0].length, "property");
|
|
3104
|
+
index += matched[0].length;
|
|
3105
|
+
continue;
|
|
3106
|
+
}
|
|
3107
|
+
index++;
|
|
3108
|
+
}
|
|
3109
|
+
if (source[index] === ">") index++;
|
|
3110
|
+
}
|
|
3111
|
+
return tokens;
|
|
3112
|
+
}
|
|
3113
|
+
function scanCss(source) {
|
|
3114
|
+
const tokens = [];
|
|
3115
|
+
let index = 0, depth = 0;
|
|
3116
|
+
while (index < source.length) {
|
|
3117
|
+
const character = source[index];
|
|
3118
|
+
if (/\s/.test(character)) {
|
|
3119
|
+
index++;
|
|
3120
|
+
continue;
|
|
3121
|
+
}
|
|
3122
|
+
if (source.startsWith("/*", index)) {
|
|
3123
|
+
const close = source.indexOf("*/", index + 2);
|
|
3124
|
+
const end = close < 0 ? source.length : close + 2;
|
|
3125
|
+
pushToken(tokens, index, end, "comment");
|
|
3126
|
+
index = end;
|
|
3127
|
+
continue;
|
|
3128
|
+
}
|
|
3129
|
+
if (character === '"' || character === "'") {
|
|
3130
|
+
const end = scanQuoted(source, index, character, true, false);
|
|
3131
|
+
pushToken(tokens, index, end, "string");
|
|
3132
|
+
index = end;
|
|
3133
|
+
continue;
|
|
3134
|
+
}
|
|
3135
|
+
if (character === "{") {
|
|
3136
|
+
depth++;
|
|
3137
|
+
index++;
|
|
3138
|
+
continue;
|
|
3139
|
+
}
|
|
3140
|
+
if (character === "}") {
|
|
3141
|
+
depth = Math.max(0, depth - 1);
|
|
3142
|
+
index++;
|
|
3143
|
+
continue;
|
|
3144
|
+
}
|
|
3145
|
+
if (character === "@") {
|
|
3146
|
+
const match = /@[\w-]+/y;
|
|
3147
|
+
match.lastIndex = index;
|
|
3148
|
+
const found2 = match.exec(source);
|
|
3149
|
+
if (found2) {
|
|
3150
|
+
pushToken(tokens, index, index + found2[0].length, "keyword");
|
|
3151
|
+
index += found2[0].length;
|
|
3152
|
+
continue;
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
if (character === "!") {
|
|
3156
|
+
const match = /!\s*important/y;
|
|
3157
|
+
match.lastIndex = index;
|
|
3158
|
+
const found2 = match.exec(source);
|
|
3159
|
+
if (found2) {
|
|
3160
|
+
pushToken(tokens, index, index + found2[0].length, "keyword");
|
|
3161
|
+
index += found2[0].length;
|
|
3162
|
+
continue;
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
if (character === "#" && depth > 0) {
|
|
3166
|
+
const match = /#[\da-fA-F]{3,8}\b/y;
|
|
3167
|
+
match.lastIndex = index;
|
|
3168
|
+
const found2 = match.exec(source);
|
|
3169
|
+
if (found2) {
|
|
3170
|
+
pushToken(tokens, index, index + found2[0].length, "number");
|
|
3171
|
+
index += found2[0].length;
|
|
3172
|
+
continue;
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
if (depth > 0 && (/\d/.test(character) || (character === "-" || character === "." || character === "+") && /\d/.test(source[index + 1] ?? ""))) {
|
|
3176
|
+
const match = /[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?(?:%|[a-zA-Z]+)?/y;
|
|
3177
|
+
match.lastIndex = index;
|
|
3178
|
+
const found2 = match.exec(source);
|
|
3179
|
+
if (found2 && !isIdentChar(source[index - 1])) {
|
|
3180
|
+
pushToken(tokens, index, index + found2[0].length, "number");
|
|
3181
|
+
index += found2[0].length;
|
|
3182
|
+
continue;
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
const word = /-?[\p{L}_][\p{L}\p{N}_-]*/uy;
|
|
3186
|
+
word.lastIndex = index;
|
|
3187
|
+
const found = word.exec(source);
|
|
3188
|
+
if (found) {
|
|
3189
|
+
const end = index + found[0].length;
|
|
3190
|
+
let back = index - 1;
|
|
3191
|
+
while (back >= 0 && /\s/.test(source[back])) back--;
|
|
3192
|
+
const before = back >= 0 ? source[back] : "";
|
|
3193
|
+
if (depth > 0 && /^\s*:(?!:)/.test(source.slice(end, end + 8)) && (before === "{" || before === ";" || before === "")) pushToken(tokens, index, end, "property");
|
|
3194
|
+
else if (source[end] === "(") pushToken(tokens, index, end, "function");
|
|
3195
|
+
index = end;
|
|
3196
|
+
continue;
|
|
3197
|
+
}
|
|
3198
|
+
if (depth === 0 && (character === "." || character === "#")) {
|
|
3199
|
+
const match = /[.#][\p{L}_-][\p{L}\p{N}_-]*/uy;
|
|
3200
|
+
match.lastIndex = index;
|
|
3201
|
+
const matched = match.exec(source);
|
|
3202
|
+
if (matched) {
|
|
3203
|
+
pushToken(tokens, index, index + matched[0].length, "type");
|
|
3204
|
+
index += matched[0].length;
|
|
3205
|
+
continue;
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
index++;
|
|
3209
|
+
}
|
|
3210
|
+
return tokens;
|
|
3211
|
+
}
|
|
3212
|
+
function tokenizeCode(source, language) {
|
|
3213
|
+
const id = resolveCodeLanguage(language);
|
|
3214
|
+
if (id === void 0 || typeof source !== "string" || source.length === 0 || source.length > CODE_HIGHLIGHT_MAX_LENGTH) return [];
|
|
3215
|
+
const def = LANGUAGES2[id];
|
|
3216
|
+
let tokens;
|
|
3217
|
+
switch (def.kind) {
|
|
3218
|
+
case "yaml":
|
|
3219
|
+
tokens = scanYaml(source);
|
|
3220
|
+
break;
|
|
3221
|
+
case "ini":
|
|
3222
|
+
tokens = scanIni(source, def);
|
|
3223
|
+
break;
|
|
3224
|
+
case "markup":
|
|
3225
|
+
tokens = scanMarkup(source);
|
|
3226
|
+
break;
|
|
3227
|
+
case "css":
|
|
3228
|
+
tokens = scanCss(source);
|
|
3229
|
+
break;
|
|
3230
|
+
default:
|
|
3231
|
+
tokens = scanGeneric(source, def);
|
|
3232
|
+
}
|
|
3233
|
+
return tokens.filter((token) => token.end > token.start).sort((a, b) => a.start - b.start);
|
|
3234
|
+
}
|
|
3235
|
+
function codeLineRuns(tokens, start, end, source) {
|
|
3236
|
+
const runs = [];
|
|
3237
|
+
const push = (from, to, kind2) => {
|
|
3238
|
+
if (kind2 === void 0 || source === void 0 || !source.slice(from, to).includes(" ")) {
|
|
3239
|
+
runs.push(kind2 === void 0 ? { start: from, end: to } : { start: from, end: to, kind: kind2 });
|
|
3240
|
+
return;
|
|
3241
|
+
}
|
|
3242
|
+
let at3 = from;
|
|
3243
|
+
for (let index = from; index < to; index++) {
|
|
3244
|
+
if (source[index] !== " ") continue;
|
|
3245
|
+
if (index > at3) runs.push({ start: at3, end: index, kind: kind2 });
|
|
3246
|
+
runs.push({ start: index, end: index + 1 });
|
|
3247
|
+
at3 = index + 1;
|
|
3248
|
+
}
|
|
3249
|
+
if (at3 < to) runs.push({ start: at3, end: to, kind: kind2 });
|
|
3250
|
+
};
|
|
3251
|
+
let cursor = start;
|
|
3252
|
+
for (const token of tokens) {
|
|
3253
|
+
if (token.end <= start) continue;
|
|
3254
|
+
if (token.start >= end) break;
|
|
3255
|
+
const from = Math.max(token.start, start), to = Math.min(token.end, end);
|
|
3256
|
+
if (from > cursor) push(cursor, from);
|
|
3257
|
+
push(from, to, token.kind);
|
|
3258
|
+
cursor = to;
|
|
3259
|
+
}
|
|
3260
|
+
if (cursor < end) push(cursor, end);
|
|
3261
|
+
return runs;
|
|
3262
|
+
}
|
|
3263
|
+
var distance = (a, b) => Math.hypot(...channels(a).map((value, index) => value - channels(b)[index]));
|
|
3264
|
+
var FALLBACK = { keyword: "#C4B5FD", string: "#86EFAC", number: "#FCD34D", function: "#93C5FD", type: "#67E8F9", property: "#F9A8D4", comment: "#94A3B8" };
|
|
3265
|
+
function codeSyntaxPalette(theme = {}, options = {}) {
|
|
3266
|
+
const background = normalize(options.background) ?? CODE_PANEL_BACKGROUND, plain = normalize(options.foreground) ?? CODE_PANEL_FOREGROUND;
|
|
3267
|
+
const minimum = options.minimumContrast ?? CODE_SYNTAX_MIN_CONTRAST;
|
|
3268
|
+
const palette = { plain: legible(plain, background, minimum) };
|
|
3269
|
+
const taken = [palette.plain];
|
|
3270
|
+
const slots = [["keyword", theme.primary], ["string", theme.accent], ["number", theme.secondary], ["comment", theme.mutedText], ["function", void 0], ["type", void 0], ["property", void 0]];
|
|
3271
|
+
for (const [kind2, themed] of slots) {
|
|
3272
|
+
const candidates = [normalize(themed), FALLBACK[kind2]].filter((value) => value !== void 0).map((value) => legible(value, background, minimum));
|
|
3273
|
+
let [h, s, l] = toHsl(FALLBACK[kind2]);
|
|
3274
|
+
let pick = candidates.find((candidate) => taken.every((other) => distance(candidate, other) >= 48));
|
|
3275
|
+
for (let turn = 0; pick === void 0 && turn < 9; turn++) {
|
|
3276
|
+
h += 40;
|
|
3277
|
+
const candidate = legible(fromHsl(h, s, l), background, minimum);
|
|
3278
|
+
if (taken.every((other) => distance(candidate, other) >= 48)) pick = candidate;
|
|
3279
|
+
}
|
|
3280
|
+
palette[kind2] = pick ?? candidates[candidates.length - 1];
|
|
3281
|
+
taken.push(palette[kind2]);
|
|
3282
|
+
}
|
|
3283
|
+
return palette;
|
|
3284
|
+
}
|
|
3285
|
+
function codeSyntaxPaletteForScheme(scheme, options = {}) {
|
|
3286
|
+
const record6 = scheme && typeof scheme === "object" ? scheme : {};
|
|
3287
|
+
const pick = (role, slot, fallback) => normalize(record6[role]) ?? normalize(record6[slot]) ?? fallback;
|
|
3288
|
+
return codeSyntaxPalette({ primary: pick("primary", "accent1", "#2563EB"), secondary: pick("secondary", "accent2", "#0F766E"), accent: pick("accent", "accent3", "#F59E0B") }, options);
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
// src/metric-trend.ts
|
|
3292
|
+
var METRIC_DEFAULT_SENTIMENT = Object.freeze({ up: "positive", down: "negative", flat: "neutral" });
|
|
3293
|
+
function metricEffectiveSentiment(trend, sentiment) {
|
|
3294
|
+
return sentiment ?? METRIC_DEFAULT_SENTIMENT[trend];
|
|
3295
|
+
}
|
|
3296
|
+
var METRIC_TREND_SHAPES = Object.freeze({ up: "upArrow", down: "downArrow", flat: "rightArrow" });
|
|
3297
|
+
var METRIC_TREND_MIN_CONTRAST = 4.5;
|
|
3298
|
+
var SEMANTIC = {
|
|
3299
|
+
positive: { light: "#15803D", dark: "#4ADE80" },
|
|
3300
|
+
negative: { light: "#B91C1C", dark: "#F87171" }
|
|
3301
|
+
};
|
|
3302
|
+
function metricTrendColor(trend, options) {
|
|
3303
|
+
const background = normalize(options.background) ?? "#FFFFFF";
|
|
3304
|
+
const sentiment = metricEffectiveSentiment(trend, options.sentiment);
|
|
3305
|
+
if (sentiment === "neutral") return legible(normalize(options.neutral) ?? (luminance2(background) < 0.5 ? "#CBD5E1" : "#475569"), background, METRIC_TREND_MIN_CONTRAST);
|
|
3306
|
+
const pair = SEMANTIC[sentiment];
|
|
3307
|
+
return legible(luminance2(background) < 0.5 ? pair.dark : pair.light, background, METRIC_TREND_MIN_CONTRAST);
|
|
3308
|
+
}
|
|
3309
|
+
function metricTrendPoints(shape, box) {
|
|
3310
|
+
const { x: l, y: t, width: w, height: h } = box, r = l + w, b = t + h, hc = l + w / 2, vc = t + h / 2, ss = Math.min(w, h);
|
|
3311
|
+
if (shape === "rightArrow") {
|
|
3312
|
+
const x12 = r - ss * 0.5, y1 = vc - h * 0.25, y22 = vc + h * 0.25;
|
|
3313
|
+
return [[l, y1], [x12, y1], [x12, t], [r, vc], [x12, b], [x12, y22], [l, y22]];
|
|
3314
|
+
}
|
|
3315
|
+
const dy = ss * 0.5, x1 = hc - w * 0.25, x2 = hc + w * 0.25;
|
|
3316
|
+
if (shape === "upArrow") {
|
|
3317
|
+
const y22 = t + dy;
|
|
3318
|
+
return [[l, y22], [hc, t], [r, y22], [x2, y22], [x2, b], [x1, b], [x1, y22]];
|
|
3319
|
+
}
|
|
3320
|
+
const y2 = b - dy;
|
|
3321
|
+
return [[l, y2], [x1, y2], [x1, t], [x2, t], [x2, y2], [r, y2], [hc, b]];
|
|
3322
|
+
}
|
|
3323
|
+
function metricTrendMark(layout, options) {
|
|
3324
|
+
const part = layout.parts.find((candidate) => candidate.role === "trend");
|
|
3325
|
+
if (!part || !part.visible || !part.fit || part.fit.sourceLines.length === 0) return void 0;
|
|
3326
|
+
const trend = part.text.trim();
|
|
3327
|
+
if (!Object.hasOwn(METRIC_TREND_SHAPES, trend)) return void 0;
|
|
3328
|
+
const line = part.fit.sourceLines[0], origin = part.linePositions[0];
|
|
3329
|
+
if (!origin || line.width <= 0) return void 0;
|
|
3330
|
+
const size = part.fit.fontSize * 0.72, gap = part.fit.fontSize * 0.3, left = part.box.x, right = part.box.x + part.box.width;
|
|
3331
|
+
const after = origin.x + line.width + gap, before = origin.x - gap - size;
|
|
3332
|
+
const fitsAfter = after + size <= right + 0.01, fitsBefore = before >= left - 0.01;
|
|
3333
|
+
const x = layout.alignment === "left" ? fitsAfter ? after : fitsBefore ? before : void 0 : fitsBefore ? before : fitsAfter ? after : void 0;
|
|
3334
|
+
if (x === void 0) return void 0;
|
|
3335
|
+
const shape = METRIC_TREND_SHAPES[trend], box = { x, y: origin.baseline - size, width: size, height: size };
|
|
3336
|
+
const sentiment = metricEffectiveSentiment(trend, options.sentiment ?? layout.sentiment);
|
|
3337
|
+
return { trend, sentiment, shape, box, points: metricTrendPoints(shape, box), color: metricTrendColor(trend, { ...options, sentiment }), ariaLabel: `Trend: ${trend}`, path: part.path };
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
// src/timeline-status.ts
|
|
3341
|
+
var TIMELINE_STATUSES = Object.freeze(["done", "current", "planned"]);
|
|
3342
|
+
var TIMELINE_TEXT_MIN_CONTRAST = 4.5;
|
|
3343
|
+
var TIMELINE_OUTLINE_MIN_CONTRAST = 3;
|
|
3344
|
+
function timelineMarkerShapes(marker, colors) {
|
|
3345
|
+
const background = normalize(colors.background) ?? "#FFFFFF";
|
|
3346
|
+
const primary = normalize(colors.primary), outline = primary ? legible(primary, background, TIMELINE_OUTLINE_MIN_CONTRAST) : colors.primary;
|
|
3347
|
+
const shapes = [];
|
|
3348
|
+
const width = marker.strokeWidth ?? 0;
|
|
3349
|
+
if (marker.status === "current" && marker.ring) {
|
|
3350
|
+
shapes.push({ role: "ring", shape: "ellipse", cx: marker.x, cy: marker.y, radius: marker.ring.radius, fill: colors.background, stroke: { color: outline, width } });
|
|
3351
|
+
}
|
|
3352
|
+
if (marker.status === "planned") {
|
|
3353
|
+
shapes.push({ role: "marker", shape: "ellipse", cx: marker.x, cy: marker.y, radius: marker.radius, fill: colors.background, stroke: { color: outline, width } });
|
|
3354
|
+
} else {
|
|
3355
|
+
shapes.push({ role: "marker", shape: "ellipse", cx: marker.x, cy: marker.y, radius: marker.radius, fill: colors.primary });
|
|
3356
|
+
}
|
|
3357
|
+
return shapes;
|
|
3358
|
+
}
|
|
3359
|
+
function timelineTextColor(part, colors) {
|
|
3360
|
+
if (part.status !== "planned") return colors.text;
|
|
3361
|
+
const background = normalize(colors.background) ?? "#FFFFFF", muted = normalize(colors.mutedText);
|
|
3362
|
+
return muted ? legible(muted, background, TIMELINE_TEXT_MIN_CONTRAST) : colors.mutedText;
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
// src/code-highlight.ts
|
|
3366
|
+
function codeLineCount(source) {
|
|
3367
|
+
let count = 1;
|
|
3368
|
+
for (let index = 0; index < source.length; index++) {
|
|
3369
|
+
const char = source[index];
|
|
3370
|
+
if (char === "\r" && source[index + 1] === "\n") index++;
|
|
3371
|
+
if (char === "\r" || char === "\n") count++;
|
|
3372
|
+
}
|
|
3373
|
+
return count > 1 && /(?:\r\n|\r|\n)$/.test(source) ? count - 1 : count;
|
|
3374
|
+
}
|
|
3375
|
+
var isLine = (value) => typeof value === "number" && Number.isInteger(value) && value >= 1;
|
|
3376
|
+
function codeHighlightLines(highlight, source) {
|
|
3377
|
+
const lineCount = codeLineCount(source), marked = /* @__PURE__ */ new Set(), issues = [];
|
|
3378
|
+
if (!Array.isArray(highlight)) return { lineCount, lines: [], issues };
|
|
3379
|
+
highlight.forEach((entry, index) => {
|
|
3380
|
+
const range = Array.isArray(entry) ? entry : [entry, entry];
|
|
3381
|
+
if (range.length !== 2 || !isLine(range[0]) || !isLine(range[1])) {
|
|
3382
|
+
issues.push({ code: "code-highlight-invalid", index, message: "A code highlight entry is a line number or a [start, end] pair of line numbers from 1." });
|
|
3383
|
+
return;
|
|
3384
|
+
}
|
|
3385
|
+
const [start, end] = range;
|
|
3386
|
+
if (start > end) {
|
|
3387
|
+
issues.push({ code: "code-highlight-range-reversed", index, message: `The highlight range [${start}, ${end}] ends before it starts, so it marks no line; write [${end}, ${start}].` });
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
if (end > lineCount) issues.push({ code: "code-highlight-out-of-range", index, message: `The highlight ${start === end ? `line ${start}` : `range [${start}, ${end}]`} is past the last line (the code has ${lineCount} ${lineCount === 1 ? "line" : "lines"}); lines beyond it are ignored.` });
|
|
3391
|
+
for (let line = start; line <= Math.min(end, lineCount); line++) marked.add(line);
|
|
3392
|
+
});
|
|
3393
|
+
return { lineCount, lines: [...marked].sort((a, b) => a - b), issues };
|
|
3394
|
+
}
|
|
3395
|
+
function codeHighlightList(lines) {
|
|
3396
|
+
const sorted = [...new Set(lines)].sort((a, b) => a - b), out = [];
|
|
3397
|
+
for (let index = 0; index < sorted.length; ) {
|
|
3398
|
+
let end = index;
|
|
3399
|
+
while (sorted[end + 1] === sorted[end] + 1) end++;
|
|
3400
|
+
out.push(end === index ? sorted[index] : [sorted[index], sorted[end]]);
|
|
3401
|
+
index = end + 1;
|
|
3402
|
+
}
|
|
3403
|
+
return out;
|
|
3404
|
+
}
|
|
3405
|
+
function codeLineNumbers(sourceLines) {
|
|
3406
|
+
let line = 1;
|
|
3407
|
+
return sourceLines.map((entry) => {
|
|
3408
|
+
const number = line;
|
|
3409
|
+
if (entry.boundary === "hard") line++;
|
|
3410
|
+
return number;
|
|
3411
|
+
});
|
|
3412
|
+
}
|
|
3413
|
+
function codeHighlightBands(sourceLines, lines) {
|
|
3414
|
+
if (!lines.length) return [];
|
|
3415
|
+
const marked = new Set(lines), numbers = codeLineNumbers(sourceLines), bands = [];
|
|
3416
|
+
numbers.forEach((number, index) => {
|
|
3417
|
+
if (!marked.has(number)) return;
|
|
3418
|
+
const last = bands.at(-1);
|
|
3419
|
+
if (last && last.last === index - 1) last.last = index;
|
|
3420
|
+
else bands.push({ first: index, last: index });
|
|
3421
|
+
});
|
|
3422
|
+
return bands;
|
|
3423
|
+
}
|
|
3424
|
+
function codeHighlightSlice(highlight, source, start, end) {
|
|
3425
|
+
const { lines } = codeHighlightLines(highlight, source);
|
|
3426
|
+
if (!lines.length) return void 0;
|
|
3427
|
+
const breaks = (text2) => (text2.match(/\r\n|\r|\n/g) ?? []).length;
|
|
3428
|
+
const before = breaks(source.slice(0, start)), count = codeLineCount(source.slice(start, end));
|
|
3429
|
+
const kept = lines.filter((line) => line > before && line <= before + count).map((line) => line - before);
|
|
3430
|
+
return kept.length ? codeHighlightList(kept) : void 0;
|
|
3431
|
+
}
|
|
3432
|
+
var CODE_HIGHLIGHT_DIM = 0.35;
|
|
3433
|
+
var CODE_HIGHLIGHT_BAND_TINT = 0.3;
|
|
3434
|
+
var blend = (from, to, amount) => {
|
|
3435
|
+
const a = channels(from), b = channels(to);
|
|
3436
|
+
return toHex(a.map((value, index) => value + (b[index] - value) * amount));
|
|
3437
|
+
};
|
|
3438
|
+
function codeHighlightColors(scheme, palette = codeSyntaxPaletteForScheme(scheme)) {
|
|
3439
|
+
const record6 = scheme && typeof scheme === "object" ? scheme : {};
|
|
3440
|
+
const primary = normalize(record6.primary) ?? normalize(record6.accent1) ?? "#2563EB";
|
|
3441
|
+
const [hue, saturation] = toHsl(primary);
|
|
3442
|
+
const tint = fromHsl(hue, Math.min(saturation, 0.7), 0.45);
|
|
3443
|
+
const band = blend(CODE_PANEL_BACKGROUND, tint, CODE_HIGHLIGHT_BAND_TINT);
|
|
3444
|
+
const lit = {}, dim = {};
|
|
3445
|
+
for (const key of Object.keys(palette)) {
|
|
3446
|
+
lit[key] = legible(palette[key], band, CODE_SYNTAX_MIN_CONTRAST);
|
|
3447
|
+
dim[key] = legible(blend(palette[key], CODE_PANEL_BACKGROUND, CODE_HIGHLIGHT_DIM), CODE_PANEL_BACKGROUND, CODE_SYNTAX_MIN_CONTRAST);
|
|
3448
|
+
}
|
|
3449
|
+
return { band, lit, dim };
|
|
3450
|
+
}
|
|
3451
|
+
|
|
3452
|
+
// src/watermark.ts
|
|
3453
|
+
var WATERMARK_TEXT_ROTATION = -30;
|
|
3454
|
+
var WATERMARK_TEXT_MAX_WIDTH = 0.7;
|
|
3455
|
+
var WATERMARK_TEXT_MAX_HEIGHT = 0.3;
|
|
3456
|
+
function layoutWatermark(text2, size, options = {}) {
|
|
3457
|
+
const value = typeof text2 === "string" ? text2.replace(/\s*[\r\n]+\s*/g, " ").trim() : "";
|
|
3458
|
+
if (!value) return void 0;
|
|
3459
|
+
const { width, height } = size;
|
|
3460
|
+
if (![width, height].every((n) => Number.isFinite(n) && n > 0)) throw new RangeError("Watermark slide size must be finite and positive.");
|
|
3461
|
+
const fontFamily = options.fontFamily ?? "sans-serif", fontWeight = options.fontWeight ?? 700;
|
|
3462
|
+
const style = resolveTextStyle({ fontFamily, fontWeight, italic: false, path: "design.watermark" }, options.textMeasurement);
|
|
3463
|
+
const measure = textWidthMeasurer(style, options.textMeasurement);
|
|
3464
|
+
const reference = 100, unit = measure(value, reference);
|
|
3465
|
+
const wanted = unit > 0 ? WATERMARK_TEXT_MAX_WIDTH * width * reference / unit : WATERMARK_TEXT_MAX_HEIGHT * Math.min(width, height);
|
|
3466
|
+
const fontSize = Math.max(1, Math.min(wanted, WATERMARK_TEXT_MAX_HEIGHT * Math.min(width, height)));
|
|
3467
|
+
const textWidth = measure(value, fontSize);
|
|
3468
|
+
const boxWidth = textWidth + fontSize * 0.5, boxHeight = fontSize * 1.4;
|
|
3469
|
+
return {
|
|
3470
|
+
text: value,
|
|
3471
|
+
fontFamily: style.fontFamily,
|
|
3472
|
+
fontWeight,
|
|
3473
|
+
style,
|
|
3474
|
+
fontSize,
|
|
3475
|
+
textWidth,
|
|
3476
|
+
box: { x: (width - boxWidth) / 2, y: (height - boxHeight) / 2, width: boxWidth, height: boxHeight },
|
|
3477
|
+
rotation: WATERMARK_TEXT_ROTATION
|
|
3478
|
+
};
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
// src/pattern-fills.ts
|
|
3482
|
+
var PATTERN_PRESETS = Object.freeze([
|
|
3483
|
+
"pct5",
|
|
3484
|
+
"pct10",
|
|
3485
|
+
"pct20",
|
|
3486
|
+
"pct25",
|
|
3487
|
+
"pct30",
|
|
3488
|
+
"pct40",
|
|
3489
|
+
"pct50",
|
|
3490
|
+
"pct60",
|
|
3491
|
+
"pct70",
|
|
3492
|
+
"pct75",
|
|
3493
|
+
"pct80",
|
|
3494
|
+
"pct90",
|
|
3495
|
+
"horz",
|
|
3496
|
+
"vert",
|
|
3497
|
+
"ltHorz",
|
|
3498
|
+
"ltVert",
|
|
3499
|
+
"dkHorz",
|
|
3500
|
+
"dkVert",
|
|
3501
|
+
"narHorz",
|
|
3502
|
+
"narVert",
|
|
3503
|
+
"dashHorz",
|
|
3504
|
+
"dashVert",
|
|
3505
|
+
"cross",
|
|
3506
|
+
"dnDiag",
|
|
3507
|
+
"upDiag",
|
|
3508
|
+
"ltDnDiag",
|
|
3509
|
+
"ltUpDiag",
|
|
3510
|
+
"dkDnDiag",
|
|
3511
|
+
"dkUpDiag",
|
|
3512
|
+
"wdDnDiag",
|
|
3513
|
+
"wdUpDiag",
|
|
3514
|
+
"dashDnDiag",
|
|
3515
|
+
"dashUpDiag",
|
|
3516
|
+
"diagCross",
|
|
3517
|
+
"smCheck",
|
|
3518
|
+
"lgCheck",
|
|
3519
|
+
"smGrid",
|
|
3520
|
+
"lgGrid",
|
|
3521
|
+
"dotGrid",
|
|
3522
|
+
"smConfetti",
|
|
3523
|
+
"lgConfetti",
|
|
3524
|
+
"horzBrick",
|
|
3525
|
+
"diagBrick",
|
|
3526
|
+
"solidDmnd",
|
|
3527
|
+
"openDmnd",
|
|
3528
|
+
"dotDmnd",
|
|
3529
|
+
"plaid",
|
|
3530
|
+
"sphere",
|
|
3531
|
+
"weave",
|
|
3532
|
+
"divot",
|
|
3533
|
+
"shingle",
|
|
3534
|
+
"wave",
|
|
3535
|
+
"trellis",
|
|
3536
|
+
"zigZag"
|
|
3537
|
+
]);
|
|
3538
|
+
var PATTERN_PRESET_ALIASES = Object.freeze({ diagStripe: "wdUpDiag" });
|
|
3539
|
+
var PATTERN_TILE_SIZE = 8;
|
|
3540
|
+
var MEASURED = {
|
|
3541
|
+
pct5: "#......./......../......../......../....#.../......../......../........",
|
|
3542
|
+
pct10: "#......./......../....#.../......../#......./......../....#.../........",
|
|
3543
|
+
pct20: "#...#.../......../..#...#./......../#...#.../......../..#...#./........",
|
|
3544
|
+
pct25: "#...#.../..#...#./#...#.../..#...#./#...#.../..#...#./#...#.../..#...#.",
|
|
3545
|
+
pct30: "#.#.#.#./.#...#../#.#.#.#./...#...#/#.#.#.#./.#...#../#.#.#.#./...#...#",
|
|
3546
|
+
pct40: "#.#.#.#./.#.#.#.#/#.#.#.#./.#.#...#/#.#.#.#./.#.#.#.#/#.#.#.#./...#.#.#",
|
|
3547
|
+
pct50: "#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#",
|
|
3548
|
+
pct60: "###.###./.#.#.#.#/#.###.##/.#.#.#.#/###.###./.#.#.#.#/#.###.##/.#.#.#.#",
|
|
3549
|
+
pct70: ".###.###/##.###.#/.###.###/##.###.#/.###.###/##.###.#/.###.###/##.###.#",
|
|
3550
|
+
pct75: ".###.###/########/##.###.#/########/.###.###/########/##.###.#/########",
|
|
3551
|
+
pct80: "###.####/########/#######./########/###.####/########/#######./########",
|
|
3552
|
+
pct90: "########/########/########/####.###/########/########/########/.#######",
|
|
3553
|
+
horz: "########/......../......../......../......../......../......../........",
|
|
3554
|
+
vert: "#......./#......./#......./#......./#......./#......./#......./#.......",
|
|
3555
|
+
ltHorz: "########/......../......../......../########/......../......../........",
|
|
3556
|
+
ltVert: "#...#.../#...#.../#...#.../#...#.../#...#.../#...#.../#...#.../#...#...",
|
|
3557
|
+
dkHorz: "########/########/......../......../########/########/......../........",
|
|
3558
|
+
dkVert: "##..##../##..##../##..##../##..##../##..##../##..##../##..##../##..##..",
|
|
3559
|
+
narHorz: "########/......../########/......../########/......../########/........",
|
|
3560
|
+
narVert: ".#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#",
|
|
3561
|
+
dashHorz: "####..../......../......../......../....####/......../......../........",
|
|
3562
|
+
dashVert: "#......./#......./#......./#......./....#.../....#.../....#.../....#...",
|
|
3563
|
+
cross: "########/#......./#......./#......./#......./#......./#......./#.......",
|
|
3564
|
+
dnDiag: "#......./.#....../..#...../...#..../....#.../.....#../......#./.......#",
|
|
3565
|
+
upDiag: ".......#/......#./.....#../....#.../...#..../..#...../.#....../#.......",
|
|
3566
|
+
ltDnDiag: "#...#.../.#...#../..#...#./...#...#/#...#.../.#...#../..#...#./...#...#",
|
|
3567
|
+
ltUpDiag: "...#...#/..#...#./.#...#../#...#.../...#...#/..#...#./.#...#../#...#...",
|
|
3568
|
+
dkDnDiag: "##..##../.##..##./..##..##/#..##..#/##..##../.##..##./..##..##/#..##..#",
|
|
3569
|
+
dkUpDiag: "..##..##/.##..##./##..##../#..##..#/..##..##/.##..##./##..##../#..##..#",
|
|
3570
|
+
wdDnDiag: "##.....#/###...../.###..../..###.../...###../....###./.....###/#.....##",
|
|
3571
|
+
wdUpDiag: "#.....##/.....###/....###./...###../..###.../.###..../###...../##.....#",
|
|
3572
|
+
dashDnDiag: "......../......../#...#.../.#...#../..#...#./...#...#/......../........",
|
|
3573
|
+
dashUpDiag: "......../......../...#...#/..#...#./.#...#../#...#.../......../........",
|
|
3574
|
+
diagCross: "#......#/.#....#./..#..#../...##.../...##.../..#..#../.#....#./#......#",
|
|
3575
|
+
smCheck: "#..##..#/.##..##./.##..##./#..##..#/#..##..#/.##..##./.##..##./#..##..#",
|
|
3576
|
+
lgCheck: "####..../####..../####..../####..../....####/....####/....####/....####",
|
|
3577
|
+
smGrid: "########/#...#.../#...#.../#...#.../########/#...#.../#...#.../#...#...",
|
|
3578
|
+
lgGrid: "########/#......./#......./#......./#......./#......./#......./#.......",
|
|
3579
|
+
dotGrid: "#.#.#.#./......../#......./......../#......./......../#......./........",
|
|
3580
|
+
smConfetti: "#......./....#.../.#....../......#./...#..../.......#/..#...../.....#..",
|
|
3581
|
+
lgConfetti: "#.##...#/..##..../......##/...##.##/##.##.../##....../....##../#...##.#",
|
|
3582
|
+
horzBrick: "########/#......./#......./#......./########/....#.../....#.../....#...",
|
|
3583
|
+
diagBrick: ".......#/......#./.....#../....#.../...##.../..#..#../.#....#./#......#",
|
|
3584
|
+
solidDmnd: "...#..../..###.../.#####../#######./.#####../..###.../...#..../........",
|
|
3585
|
+
openDmnd: "#.....#./.#...#../..#.#.../...#..../..#.#.../.#...#../#.....#./.......#",
|
|
3586
|
+
dotDmnd: "#......./......../..#...#./......../....#.../......../..#...#./........",
|
|
3587
|
+
plaid: "#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#/####..../####..../####..../####....",
|
|
3588
|
+
sphere: ".###.###/#...#..#/#...####/#...####/.###.###/#..##.../#####.../#####...",
|
|
3589
|
+
weave: "#...#.../.#.#.#../..#...#./.#...#.#/#...#.../...#.#../..#...#./.#.#...#",
|
|
3590
|
+
divot: "......../...#..../....#.../...#..../......../#......./.......#/#.......",
|
|
3591
|
+
shingle: "......##/#....#../.#..#.../..##..../....##../......#./.......#/.......#",
|
|
3592
|
+
wave: "......../...##.../..#..#.#/##....../......../...##.../..#..#.#/##......",
|
|
3593
|
+
trellis: "########/.##..##./########/#..##..#/########/.##..##./########/#..##..#",
|
|
3594
|
+
zigZag: "#......#/.#....#./..#..#../...##.../#......#/.#....#./..#..#../...##..."
|
|
3595
|
+
};
|
|
3596
|
+
function rows(preset) {
|
|
3597
|
+
const art = MEASURED[preset];
|
|
3598
|
+
if (!art) return void 0;
|
|
3599
|
+
return art.split("/").map((row) => [...row].reduce((bits, cell, index) => cell === "#" ? bits | 128 >> index : bits, 0));
|
|
3600
|
+
}
|
|
3601
|
+
var BITMAPS = /* @__PURE__ */ new Map();
|
|
3602
|
+
for (const preset of PATTERN_PRESETS) {
|
|
3603
|
+
const bitmap = rows(preset);
|
|
3604
|
+
if (bitmap) BITMAPS.set(preset, Object.freeze(bitmap));
|
|
3605
|
+
}
|
|
3606
|
+
function resolvePatternPreset(preset) {
|
|
3607
|
+
if (typeof preset !== "string") return void 0;
|
|
3608
|
+
if (BITMAPS.has(preset)) return preset;
|
|
3609
|
+
return Object.hasOwn(PATTERN_PRESET_ALIASES, preset) ? PATTERN_PRESET_ALIASES[preset] : void 0;
|
|
3610
|
+
}
|
|
3611
|
+
function patternBitmap(preset) {
|
|
3612
|
+
const resolved = resolvePatternPreset(preset);
|
|
3613
|
+
return resolved === void 0 ? void 0 : BITMAPS.get(resolved);
|
|
3614
|
+
}
|
|
3615
|
+
function patternRuns(preset) {
|
|
3616
|
+
const bitmap = patternBitmap(preset);
|
|
3617
|
+
if (!bitmap) return void 0;
|
|
3618
|
+
const runs = [];
|
|
3619
|
+
bitmap.forEach((row, y) => {
|
|
3620
|
+
for (let x = 0; x < 8; x++) {
|
|
3621
|
+
if (!(row & 128 >> x)) continue;
|
|
3622
|
+
const start = x;
|
|
3623
|
+
while (x + 1 < 8 && row & 128 >> x + 1) x++;
|
|
3624
|
+
runs.push({ x: start, y, width: x - start + 1 });
|
|
3625
|
+
}
|
|
3626
|
+
});
|
|
3627
|
+
return runs;
|
|
3628
|
+
}
|
|
2666
3629
|
|
|
2667
3630
|
// src/annotations.ts
|
|
2668
3631
|
var CITATION_MARKER_SCALE = 2 / 3;
|
|
@@ -2676,6 +3639,7 @@ var isRecord3 = (value) => !!value && typeof value === "object" && !Array.isArra
|
|
|
2676
3639
|
var round = (value) => Math.round(value * 1e6) / 1e6 || value;
|
|
2677
3640
|
var regionKey = /^(top|middle|bottom|left|center|right)([+:]|$)/;
|
|
2678
3641
|
var TEXT_FIELDS = ["text", "items", "bullets"];
|
|
3642
|
+
var HEADING_FIELDS = ["tag", "title", "subtitle"];
|
|
2679
3643
|
function annotationText(value) {
|
|
2680
3644
|
if (typeof value === "string") return value;
|
|
2681
3645
|
if (Array.isArray(value)) return value.map((run) => typeof run === "string" ? run : record4(run).text ?? "").join("");
|
|
@@ -2723,8 +3687,10 @@ function walkCitationRuns(slide, basePath, visit) {
|
|
|
2723
3687
|
if (field === "text") runs(payload.text, `${path}.text`);
|
|
2724
3688
|
else list(payload[field], `${path}.${field}`);
|
|
2725
3689
|
}
|
|
3690
|
+
if (isRecord3(payload.quote)) runs(payload.quote.text, `${path}.quote.text`);
|
|
2726
3691
|
};
|
|
2727
3692
|
const value = record4(slide);
|
|
3693
|
+
for (const field of HEADING_FIELDS) runs(value[field], `${basePath}.${field}`);
|
|
2728
3694
|
const regions = Object.keys(value).filter((key) => regionKey.test(key)).sort();
|
|
2729
3695
|
if (regions.length) {
|
|
2730
3696
|
for (const key of regions) host(value[key], `${basePath}.${key}`, 0);
|
|
@@ -2846,23 +3812,36 @@ function referencesSlide(presentation, options = {}) {
|
|
|
2846
3812
|
return { title, items };
|
|
2847
3813
|
}
|
|
2848
3814
|
|
|
3815
|
+
// src/layout-content.ts
|
|
3816
|
+
var LAYOUT_BODY_KINDS = ["text", "list", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
|
|
3817
|
+
var bodyKinds = new Set(LAYOUT_BODY_KINDS);
|
|
3818
|
+
function layoutContent(record6) {
|
|
3819
|
+
const heading = { title: false, subtitle: false, tag: false };
|
|
3820
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3821
|
+
let count = 0;
|
|
3822
|
+
for (const placeholder of Array.isArray(record6?.placeholders) ? record6.placeholders : []) {
|
|
3823
|
+
const type = placeholder?.type;
|
|
3824
|
+
if (type === "title" || type === "subtitle" || type === "tag") heading[type] = true;
|
|
3825
|
+
else if (typeof type === "string" && bodyKinds.has(type)) {
|
|
3826
|
+
counts.set(type, (counts.get(type) ?? 0) + 1);
|
|
3827
|
+
count += 1;
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
let kind2 = "title", best = 0;
|
|
3831
|
+
for (const [candidate, total] of counts) if (total > best) {
|
|
3832
|
+
kind2 = candidate;
|
|
3833
|
+
best = total;
|
|
3834
|
+
}
|
|
3835
|
+
return { kind: kind2, count, heading };
|
|
3836
|
+
}
|
|
3837
|
+
|
|
2849
3838
|
// src/composition.ts
|
|
2850
3839
|
var MAX_COMPOSITION_DEPTH = 32;
|
|
2851
3840
|
var FALLBACK_CODE_FAMILY = "Roboto Mono";
|
|
2852
|
-
var
|
|
2853
|
-
var DEFAULT_FONT_FAMILIES = { heading: "Aptos Display", body: "Aptos" };
|
|
2854
|
-
function resolveFontSchemeReference(reference, lookup, path = "design.fontScheme") {
|
|
2855
|
-
const overrides = typeof reference === "object" && reference !== null && !Array.isArray(reference) ? reference : void 0;
|
|
2856
|
-
const id = typeof reference === "string" ? reference : typeof overrides?.id === "string" ? overrides.id : void 0;
|
|
2857
|
-
const found = id === void 0 ? void 0 : lookup(id);
|
|
2858
|
-
const base = record5(found ?? lookup(DEFAULT_FONT_SCHEME));
|
|
2859
|
-
const scheme = overrides ? { ...base, ...overrides } : { ...base };
|
|
2860
|
-
if (id === void 0 || found !== void 0) return { scheme };
|
|
2861
|
-
return { scheme, diagnostic: { code: "unresolved-font-scheme", path, id, fallback: DEFAULT_FONT_SCHEME, message: `Font scheme '${id}' is not in the inline or bundled catalogs; using the default font scheme '${DEFAULT_FONT_SCHEME}'.` } };
|
|
2862
|
-
}
|
|
3841
|
+
var DEFAULT_FONT_FAMILIES = { heading: String(ENGINE_DEFAULT_FONT_SCHEME.major), body: String(ENGINE_DEFAULT_FONT_SCHEME.minor) };
|
|
2863
3842
|
function resolveFontFamilies(input) {
|
|
2864
3843
|
const scheme = record5(input);
|
|
2865
|
-
const family = (value) => typeof value === "string" ? value :
|
|
3844
|
+
const family = (value) => typeof value === "string" && value ? value : void 0;
|
|
2866
3845
|
const accent = family(scheme.accent);
|
|
2867
3846
|
return {
|
|
2868
3847
|
heading: family(scheme.heading) ?? scheme.major ?? scheme.minor ?? DEFAULT_FONT_FAMILIES.heading,
|
|
@@ -2945,19 +3924,32 @@ var OPFCompositionError = class extends Error {
|
|
|
2945
3924
|
};
|
|
2946
3925
|
var fields = ["text", "items", "bullets", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
|
|
2947
3926
|
var headings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
|
|
2948
|
-
var
|
|
2949
|
-
var rows = ["top", "middle", "bottom"];
|
|
3927
|
+
var rows2 = ["top", "middle", "bottom"];
|
|
2950
3928
|
var columns = ["left", "center", "right"];
|
|
2951
3929
|
var record5 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2952
3930
|
var kind = (field) => field === "items" ? "list" : field === "bullets" ? "text" : field;
|
|
2953
3931
|
var round2 = (value) => Math.round(value * 1e6) / 1e6 || value;
|
|
2954
|
-
var
|
|
2955
|
-
var
|
|
3932
|
+
var PLACEMENT_BAND = 0.5;
|
|
3933
|
+
var IMAGE_EDGES = ["left", "right", "top", "bottom"];
|
|
3934
|
+
var IMAGE_FITS = ["cover", "contain", "stretch"];
|
|
3935
|
+
var BACKGROUND_FITS = ["cover", "contain", "stretch", "tile"];
|
|
3936
|
+
var IMAGE_SOURCE = /^(asset:|https:\/\/|data:|\.\/|\.\.\/)/;
|
|
3937
|
+
var IMAGE_OPTION_KEYS = ["fit", "focus", "aspectRatio", "shape", "cornerRadius", "border", "opacity", "recolor", "overlay", "placement"];
|
|
3938
|
+
var imagePayload = (host) => {
|
|
3939
|
+
const payload = { type: host.type ?? "image", image: host.image };
|
|
3940
|
+
for (const key of IMAGE_OPTION_KEYS) if (host[key] !== void 0) payload[key] = host[key];
|
|
3941
|
+
return payload;
|
|
3942
|
+
};
|
|
2956
3943
|
var assetSource = (value) => typeof value === "string" ? value : record5(value).src;
|
|
2957
3944
|
var finite = (value, min, max) => typeof value === "number" && Number.isFinite(value) && value >= min && value <= max ? value : void 0;
|
|
2958
3945
|
var pathNumber = (value) => String(round2(value));
|
|
2959
|
-
var
|
|
2960
|
-
|
|
3946
|
+
var IMAGE_SHAPES = { rectangle: "rect", rounded: "roundRect", circle: "ellipse", hexagon: "hexagon" };
|
|
3947
|
+
var roundBox = (box) => ({ x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) });
|
|
3948
|
+
var imageFocus = (value) => {
|
|
3949
|
+
const focus = record5(value), x = finite(focus.x, 0, 1), y = finite(focus.y, 0, 1);
|
|
3950
|
+
return x !== void 0 && y !== void 0 ? { x, y } : { x: 0.5, y: 0.5 };
|
|
3951
|
+
};
|
|
3952
|
+
function imageShape(kind2, box, cornerRadius = 1 / 6) {
|
|
2961
3953
|
const { x, y, width: w, height: h } = box, r = x + w, b = y + h, ss = Math.min(w, h), n = pathNumber;
|
|
2962
3954
|
const rect = `M${n(x)} ${n(y)}H${n(r)}V${n(b)}H${n(x)}Z`;
|
|
2963
3955
|
if (kind2 === "rounded") {
|
|
@@ -2976,66 +3968,96 @@ function slideImageShape(kind2, box, cornerRadius = 1 / 6) {
|
|
|
2976
3968
|
}
|
|
2977
3969
|
return { kind: "rectangle", preset: "rect", adjust: {}, path: rect };
|
|
2978
3970
|
}
|
|
2979
|
-
function
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
const
|
|
2983
|
-
|
|
2984
|
-
const
|
|
2985
|
-
const
|
|
2986
|
-
const
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
const
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
const
|
|
2999
|
-
|
|
3000
|
-
const
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3971
|
+
function fitImage(frame, fit, aspect, focus = { x: 0.5, y: 0.5 }) {
|
|
3972
|
+
if (![frame.x, frame.y, frame.width, frame.height].every(Number.isFinite) || frame.width <= 0 || frame.height <= 0) throw new RangeError("An image frame needs finite coordinates and a positive size.");
|
|
3973
|
+
if (fit === "stretch" || !Number.isFinite(aspect) || aspect <= 0) return { image: roundBox(frame), crop: { left: 0, top: 0, right: 0, bottom: 0 } };
|
|
3974
|
+
const wide = aspect > frame.width / frame.height, cover = fit === "cover";
|
|
3975
|
+
const width = wide === cover ? frame.height * aspect : frame.width, height = wide === cover ? frame.height : frame.width / aspect;
|
|
3976
|
+
const point = imageFocus(focus);
|
|
3977
|
+
const place = (start, span, size, at3) => cover ? Math.min(start, Math.max(start + span - size, start + span / 2 - at3 * size)) : start + (span - size) / 2;
|
|
3978
|
+
const image = { x: place(frame.x, frame.width, width, point.x), y: place(frame.y, frame.height, height, point.y), width, height };
|
|
3979
|
+
const crop = {
|
|
3980
|
+
left: round2((frame.x - image.x) / width),
|
|
3981
|
+
top: round2((frame.y - image.y) / height),
|
|
3982
|
+
right: round2((image.x + width - frame.x - frame.width) / width),
|
|
3983
|
+
bottom: round2((image.y + height - frame.y - frame.height) / height)
|
|
3984
|
+
};
|
|
3985
|
+
for (const key of ["left", "top", "right", "bottom"]) if (Object.is(crop[key], -0)) crop[key] = 0;
|
|
3986
|
+
return { image: roundBox(image), crop };
|
|
3987
|
+
}
|
|
3988
|
+
function imageBackground(value) {
|
|
3989
|
+
if (typeof value === "string") return IMAGE_SOURCE.test(value) ? { src: value, fit: "cover", focus: { x: 0.5, y: 0.5 } } : void 0;
|
|
3990
|
+
const background = record5(value);
|
|
3991
|
+
if (background.type !== "image" || typeof background.src !== "string" || !background.src) return void 0;
|
|
3992
|
+
const opacity = finite(background.opacity, 0, 1);
|
|
3993
|
+
return {
|
|
3994
|
+
src: background.src,
|
|
3995
|
+
...typeof background.alt === "string" ? { alt: background.alt } : {},
|
|
3996
|
+
fit: BACKGROUND_FITS.includes(background.fit) ? background.fit : "cover",
|
|
3997
|
+
focus: imageFocus(background.focus),
|
|
3998
|
+
...opacity !== void 0 ? { opacity } : {},
|
|
3999
|
+
...background.recolor !== void 0 ? { recolor: background.recolor } : {},
|
|
4000
|
+
...background.overlay !== void 0 ? { overlay: background.overlay } : {}
|
|
4001
|
+
};
|
|
4002
|
+
}
|
|
4003
|
+
function composeRecolor(value) {
|
|
4004
|
+
if (value === "grayscale") return { type: "grayscale" };
|
|
4005
|
+
const duotone = record5(value);
|
|
4006
|
+
return duotone.dark !== void 0 && duotone.light !== void 0 ? { type: "duotone", dark: duotone.dark, light: duotone.light } : void 0;
|
|
4007
|
+
}
|
|
4008
|
+
function composeOverlay(value, frame, shape, path, mirrorSide, diagnostics) {
|
|
4009
|
+
const overlay = record5(value), opacity = finite(overlay.opacity, 0, 1);
|
|
4010
|
+
if (overlay.color === void 0 || opacity === void 0) return void 0;
|
|
4011
|
+
const edge = IMAGE_EDGES.includes(overlay.edge) ? mirrorSide(overlay.edge) : void 0;
|
|
4012
|
+
if (edge && shape.kind !== "rectangle") {
|
|
4013
|
+
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." });
|
|
4014
|
+
return void 0;
|
|
4015
|
+
}
|
|
4016
|
+
const part = finite(overlay.size, 0.05, 1) ?? 0.3;
|
|
4017
|
+
const box = !edge ? frame : edge === "top" ? { ...frame, height: round2(frame.height * part) } : edge === "bottom" ? { ...frame, y: round2(frame.y + frame.height * (1 - part)), height: round2(frame.height * part) } : edge === "left" ? { ...frame, width: round2(frame.width * part) } : { ...frame, x: round2(frame.x + frame.width * (1 - part)), width: round2(frame.width * part) };
|
|
4018
|
+
return { path, color: overlay.color, opacity, ...edge ? { edge } : {}, box, shape: edge ? imageShape("rectangle", box) : shape };
|
|
4019
|
+
}
|
|
4020
|
+
function composeImage(host, hostPath, region, frameArea, context) {
|
|
4021
|
+
const kindName = Object.hasOwn(IMAGE_SHAPES, host.shape) ? host.shape : "rectangle";
|
|
4022
|
+
const { scale } = context;
|
|
4023
|
+
let box = { ...frameArea };
|
|
4024
|
+
const aspect = kindName === "circle" ? 1 : finite(host.aspectRatio, Number.MIN_VALUE, 10);
|
|
3006
4025
|
if (aspect) {
|
|
3007
4026
|
const frameWidth = Math.min(box.width, box.height * aspect), frameHeight = frameWidth / aspect;
|
|
3008
4027
|
box = { x: box.x + (box.width - frameWidth) / 2, y: box.y + (box.height - frameHeight) / 2, width: frameWidth, height: frameHeight };
|
|
3009
4028
|
}
|
|
3010
|
-
box =
|
|
3011
|
-
const
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
fill,
|
|
3017
|
-
region,
|
|
3018
|
-
box,
|
|
3019
|
-
replacesContent,
|
|
3020
|
-
shape: slideImageShape(kind2, box, finite(t.cornerRadius, 0, 0.5))
|
|
3021
|
-
};
|
|
3022
|
-
if (typeof t.alt === "string") result.alt = t.alt;
|
|
3023
|
-
const border = record5(t.border), borderWidth = finite(border.width, 0, 64);
|
|
4029
|
+
box = roundBox(box);
|
|
4030
|
+
const fit = IMAGE_FITS.includes(host.fit) ? host.fit : context.fit ?? "cover";
|
|
4031
|
+
const focus = imageFocus(host.focus);
|
|
4032
|
+
const shape = imageShape(kindName, box, finite(host.cornerRadius, 0, 0.5));
|
|
4033
|
+
const result = { region: roundBox(region), box, fit, focus, shape };
|
|
4034
|
+
const border = record5(host.border), borderWidth = finite(border.width, 0, 64);
|
|
3024
4035
|
if (border.color !== void 0 && borderWidth) result.border = { color: border.color, width: round2(borderWidth * scale) };
|
|
3025
|
-
const opacity = finite(
|
|
4036
|
+
const opacity = finite(host.opacity, 0, 1);
|
|
3026
4037
|
if (opacity !== void 0 && opacity < 1) result.opacity = opacity;
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
const overlay =
|
|
3030
|
-
if (overlay.
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
}
|
|
4038
|
+
const recolor = composeRecolor(host.recolor);
|
|
4039
|
+
if (recolor) result.recolor = recolor;
|
|
4040
|
+
const overlay = composeOverlay(host.overlay, box, shape, `${hostPath}.overlay`, context.mirrorSide, context.diagnostics);
|
|
4041
|
+
if (overlay) result.overlay = overlay;
|
|
4042
|
+
if (context.placement) result.placement = context.placement;
|
|
4043
|
+
const pictureAspect = intrinsicImageAspect(host.image, context.assets);
|
|
4044
|
+
if (pictureAspect) result.picture = fitImage(box, fit, pictureAspect, focus);
|
|
4045
|
+
return result;
|
|
4046
|
+
}
|
|
4047
|
+
function resolveBackgroundImage(slide, presentation, themeBackground, width, height, path, mirrorSide, diagnostics) {
|
|
4048
|
+
const own2 = record5(slide.design), deck = record5(record5(presentation).design);
|
|
4049
|
+
const [value, at3] = own2.background !== void 0 ? [own2.background, `${path}.design.background`] : deck.background !== void 0 ? [deck.background, "design.background"] : [themeBackground, "theme"];
|
|
4050
|
+
const background = imageBackground(value);
|
|
4051
|
+
if (!background) return void 0;
|
|
4052
|
+
const box = { x: 0, y: 0, width, height };
|
|
4053
|
+
const result = { path: at3, src: background.src, ...background.alt !== void 0 ? { alt: background.alt } : {}, fit: background.fit, focus: background.focus, box };
|
|
4054
|
+
if (background.opacity !== void 0 && background.opacity < 1) result.opacity = background.opacity;
|
|
4055
|
+
const recolor = composeRecolor(background.recolor);
|
|
4056
|
+
if (recolor) result.recolor = recolor;
|
|
4057
|
+
const overlay = composeOverlay(background.overlay, box, imageShape("rectangle", box), `${at3}.overlay`, mirrorSide, diagnostics);
|
|
4058
|
+
if (overlay) result.overlay = overlay;
|
|
4059
|
+
const aspect = background.fit === "tile" ? void 0 : intrinsicImageAspect(background.src, record5(presentation).assets);
|
|
4060
|
+
if (aspect) result.picture = fitImage(box, background.fit, aspect, background.focus);
|
|
3039
4061
|
return result;
|
|
3040
4062
|
}
|
|
3041
4063
|
var LOGO_LOCKUP_CHAINS = {
|
|
@@ -3058,10 +4080,10 @@ function resolveLogo(presentation, slide, options = {}) {
|
|
|
3058
4080
|
if (typeof value === "string" || typeof value === "object" && !Array.isArray(value) && "src" in record5(value)) {
|
|
3059
4081
|
return usable(value) ? { source: value, path, variant: "default", slot } : null;
|
|
3060
4082
|
}
|
|
3061
|
-
const
|
|
3062
|
-
if (!Object.keys(
|
|
4083
|
+
const set2 = record5(value);
|
|
4084
|
+
if (!Object.keys(set2).some((key) => LOGO_SET_KEYS.has(key))) return null;
|
|
3063
4085
|
for (const key of chain) {
|
|
3064
|
-
const variant =
|
|
4086
|
+
const variant = set2[key];
|
|
3065
4087
|
if (variant !== void 0 && usable(variant)) return { source: variant, path: `${path}.${key}`, variant: key, slot };
|
|
3066
4088
|
}
|
|
3067
4089
|
return null;
|
|
@@ -3078,11 +4100,11 @@ function resolveLogo(presentation, slide, options = {}) {
|
|
|
3078
4100
|
return pick(record5(organizations[index]).logo, Array.isArray(deck.organization) ? `organization.${index}.logo` : "organization.logo");
|
|
3079
4101
|
}
|
|
3080
4102
|
var webUrl = /^https?:\/\/\S+$/i;
|
|
3081
|
-
function resolveSocialProfile(platform, value,
|
|
4103
|
+
function resolveSocialProfile(platform, value, owner = "organization") {
|
|
3082
4104
|
const raw = String(value).trim().replace(/\s+/gu, " ");
|
|
3083
4105
|
const display = (url2) => url2.replace(/^https:\/\//i, "");
|
|
3084
4106
|
if (webUrl.test(raw)) return { text: display(raw), href: raw, resolved: false };
|
|
3085
|
-
const platformRecord =
|
|
4107
|
+
const platformRecord = Object.hasOwn(SOCIAL_PLATFORMS, platform) ? SOCIAL_PLATFORMS[platform] : void 0;
|
|
3086
4108
|
const base = typeof platformRecord?.baseUrl === "string" && webUrl.test(platformRecord.baseUrl) ? `${platformRecord.baseUrl.replace(/\/+$/u, "")}/{handle}` : void 0;
|
|
3087
4109
|
const pattern = (owner === "organization" ? platformRecord?.companyUrlPattern : void 0) ?? platformRecord?.profileUrlPattern ?? base;
|
|
3088
4110
|
const prefix = platformRecord?.handlePrefix ?? "";
|
|
@@ -3108,8 +4130,8 @@ function layoutFurniture(input, options = {}) {
|
|
|
3108
4130
|
const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
|
|
3109
4131
|
const primaryIndex = organizations.findIndex((item) => record5(item).role === "primary"), organizationIndex = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
|
|
3110
4132
|
const organization = record5(organizations[organizationIndex]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex}` : "organization", organizationPath = `${organizationRoot}.name`;
|
|
3111
|
-
const
|
|
3112
|
-
const fontFamily = options.
|
|
4133
|
+
const speakers = Array.isArray(options.presentation?.speaker) ? options.presentation.speaker : [options.presentation?.speaker], speaker = record5(speakers[0]), speakerRoot = Array.isArray(options.presentation?.speaker) ? "speaker.0" : "speaker";
|
|
4134
|
+
const fontFamily = options.fontFamilies?.body ?? "sans-serif";
|
|
3113
4135
|
let headerBottom = 0, footerTop = height, configured = false;
|
|
3114
4136
|
const error = (path, message, code = "text-overflow") => diagnostics.push({ code, path, message });
|
|
3115
4137
|
for (const kind2 of ["header", "footer"]) {
|
|
@@ -3179,8 +4201,12 @@ function layoutFurniture(input, options = {}) {
|
|
|
3179
4201
|
if (typeof organization.name === "string") add("organization", organization.name, true, organizationPath);
|
|
3180
4202
|
else error(`${path}.organization`, "Generated organization name needs a named organization in the presentation.", "unresolved-content");
|
|
3181
4203
|
}
|
|
4204
|
+
if (content.speaker === true) {
|
|
4205
|
+
if (typeof speaker.name === "string" && speaker.name.trim()) add("speaker", typeof speaker.title === "string" && speaker.title.trim() ? `${speaker.name}, ${speaker.title}` : speaker.name, true, `${speakerRoot}.name`);
|
|
4206
|
+
else error(`${path}.speaker`, "Generated speaker needs a named speaker in the presentation.", "unresolved-content");
|
|
4207
|
+
}
|
|
3182
4208
|
if (content.socials === true) {
|
|
3183
|
-
const links = Object.entries(record5(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2,
|
|
4209
|
+
const links = Object.entries(record5(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2, "organization") }));
|
|
3184
4210
|
if (links.length) add("socials", links.map((link) => link.text).join("\n"), true, `${organizationRoot}.socials`, { links });
|
|
3185
4211
|
else error(`${path}.socials`, "Generated social profiles need a primary organization with socials.", "unresolved-content");
|
|
3186
4212
|
}
|
|
@@ -3272,12 +4298,25 @@ function fitAtSizes(layout, requested, minimum, step = 1, snap = true) {
|
|
|
3272
4298
|
}
|
|
3273
4299
|
throw new Error("Text fitting did not evaluate its bounded floor trial.");
|
|
3274
4300
|
}
|
|
4301
|
+
var PHOTO_RATIO = 3;
|
|
4302
|
+
var PHOTO_GAP = 0.75;
|
|
4303
|
+
function quoteBodyRuns(runs) {
|
|
4304
|
+
if (!runs.length) return ['""'];
|
|
4305
|
+
const last = runs.length - 1;
|
|
4306
|
+
return runs.map((run, index) => {
|
|
4307
|
+
const before = index === 0 ? '"' : "", after = index === last ? '"' : "";
|
|
4308
|
+
return typeof run === "string" ? before + run + after : { ...run, text: before + run.text + after };
|
|
4309
|
+
});
|
|
4310
|
+
}
|
|
3275
4311
|
function layoutQuote(value, box, options = {}) {
|
|
3276
4312
|
const shorthand = typeof value === "string";
|
|
3277
4313
|
const quote = shorthand ? { text: value } : value;
|
|
3278
|
-
|
|
3279
|
-
|
|
4314
|
+
const photoValue = quote?.photo;
|
|
4315
|
+
if (!quote || Array.isArray(quote) || typeof quote.text !== "string" && !Array.isArray(quote.text) || [quote.attribution, quote.role, quote.source].some((field) => field !== void 0 && typeof field !== "string") || photoValue !== void 0 && typeof photoValue !== "string" && !(typeof photoValue === "object" && photoValue !== null && typeof photoValue.src === "string")) {
|
|
4316
|
+
throw new TypeError("Quote content must be a string or a text object (text a string or TextRun[]) with optional string attribution/role/source and an asset photo.");
|
|
3280
4317
|
}
|
|
4318
|
+
const richBody = Array.isArray(quote.text) ? quote.text : void 0;
|
|
4319
|
+
const quoteText = richBody ? annotationText(richBody) : quote.text;
|
|
3281
4320
|
const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale);
|
|
3282
4321
|
if (![box.x, box.y, box.width, box.height, scale, minimum].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) {
|
|
3283
4322
|
throw new RangeError("Quote dimensions, scale and minimum font size must be finite and positive.");
|
|
@@ -3287,78 +4326,96 @@ function layoutQuote(value, box, options = {}) {
|
|
|
3287
4326
|
const diagnostics = [], parts = [];
|
|
3288
4327
|
const report = (reason, diagnosticPath, roles, message) => diagnostics.push({ code: "text-overflow", reason, path: diagnosticPath, parts: roles, message });
|
|
3289
4328
|
const source = (sourcePath, text2, outputStart) => ({ path: sourcePath, start: 0, end: text2.length, outputStart, outputEnd: outputStart + text2.length });
|
|
3290
|
-
const add = (role, text2, sources, area, fontSize, fontFamily, fontWeight, partPath) => {
|
|
4329
|
+
const add = (role, text2, sources, area, fontSize, fontFamily, fontWeight, partPath, runs) => {
|
|
3291
4330
|
const requestedStyle = { fontFamily, fontWeight, italic: false, path: partPath };
|
|
3292
4331
|
const style = resolveTextStyle({ ...requestedStyle }, options.textMeasurement);
|
|
3293
4332
|
const requestedFontSize = gridFontSize(fontSize * scale, minimum);
|
|
3294
|
-
const part = { role, path: partPath, text: text2, sources, box: area, requestedFontSize, minFontSize: minimum, requestedStyle, style };
|
|
4333
|
+
const part = { role, path: partPath, text: text2, sources, box: area, requestedFontSize, minFontSize: minimum, requestedStyle, style, ...runs ? { runs } : {} };
|
|
3295
4334
|
parts.push(part);
|
|
3296
4335
|
return part;
|
|
3297
4336
|
};
|
|
3298
4337
|
let footer = "";
|
|
3299
4338
|
const footerSources = [];
|
|
3300
|
-
for (const field of ["attribution", "source"]) {
|
|
4339
|
+
for (const field of ["attribution", "role", "source"]) {
|
|
3301
4340
|
const text2 = quote[field];
|
|
3302
4341
|
if (!text2) continue;
|
|
3303
|
-
if (footer) footer += " - ";
|
|
4342
|
+
if (footer) footer += field === "role" ? "\n" : " - ";
|
|
3304
4343
|
footerSources.push(source(`${path}.${field}`, text2, footer.length));
|
|
3305
4344
|
footer += text2;
|
|
3306
4345
|
}
|
|
4346
|
+
const hasPhoto = photoValue !== void 0, hasFooter = footer !== "", hasBlock = hasPhoto || hasFooter;
|
|
4347
|
+
const photoPath = `${path}.photo`, rtl = options.direction === "rtl";
|
|
3307
4348
|
const bodyPath = shorthand ? path : `${path}.text`;
|
|
3308
4349
|
const body = add(
|
|
3309
4350
|
"body",
|
|
3310
|
-
`"${
|
|
3311
|
-
[source(bodyPath,
|
|
3312
|
-
{ x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - (
|
|
4351
|
+
`"${quoteText}"`,
|
|
4352
|
+
[source(bodyPath, quoteText, 1)],
|
|
4353
|
+
{ x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - (hasBlock ? 94 : 36) },
|
|
3313
4354
|
28,
|
|
3314
|
-
options.
|
|
4355
|
+
options.fontFamilies?.accent ?? options.fontFamilies?.heading ?? "sans-serif",
|
|
3315
4356
|
600,
|
|
3316
|
-
bodyPath
|
|
4357
|
+
bodyPath,
|
|
4358
|
+
richBody ? quoteBodyRuns(richBody) : void 0
|
|
3317
4359
|
);
|
|
3318
|
-
const attribution =
|
|
4360
|
+
const attribution = hasFooter ? add(
|
|
3319
4361
|
"footer",
|
|
3320
4362
|
footer,
|
|
3321
4363
|
footerSources,
|
|
3322
4364
|
{ x: box.x + 18, y: box.y + box.height - 58, width: box.width - 36, height: 40 },
|
|
3323
4365
|
17,
|
|
3324
|
-
options.
|
|
4366
|
+
options.fontFamilies?.body ?? "sans-serif",
|
|
3325
4367
|
500,
|
|
3326
4368
|
path
|
|
3327
4369
|
) : void 0;
|
|
4370
|
+
const footerRequested = attribution?.requestedFontSize ?? gridFontSize(17 * scale, minimum);
|
|
3328
4371
|
const usable = (area) => [area.x, area.y, area.width, area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
|
|
3329
|
-
const fit = (part, area, size = part.requestedFontSize, floor = minimum) => usable(area) ? fitText(part.text, area, size, floor, textWidthMeasurer(part.style, options.textMeasurement), options.direction)
|
|
4372
|
+
const fit = (part, area, size = part.requestedFontSize, floor = minimum) => !usable(area) ? void 0 : part.runs ? fitRichText(part.runs, area, size, floor, { style: part.style, textMeasurement: options.textMeasurement, ...options.citationMarker ? { citationMarker: options.citationMarker } : {}, ...options.direction ? { direction: options.direction } : {} }) : fitText(part.text, area, size, floor, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
|
|
4373
|
+
const heightOf = (fit2) => "richLines" in fit2 ? fit2.height : fit2.lines.length * fit2.lineHeight;
|
|
3330
4374
|
const inner = { x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - 36 };
|
|
3331
|
-
|
|
4375
|
+
let photo, photoFits = true;
|
|
4376
|
+
if (!hasBlock) body.fit = fit(body, body.box);
|
|
3332
4377
|
else if (usable(inner) && inner.height > 18) {
|
|
3333
4378
|
const available = inner.height - 18;
|
|
3334
4379
|
const preferredBody = fit(body, inner, body.requestedFontSize, body.requestedFontSize);
|
|
3335
4380
|
const minimumBody = body.requestedFontSize === minimum ? preferredBody : fit(body, inner, minimum, minimum);
|
|
3336
|
-
const preferredBodyHeight = preferredBody
|
|
3337
|
-
const minimumBodyHeight = minimumBody
|
|
4381
|
+
const preferredBodyHeight = heightOf(preferredBody);
|
|
4382
|
+
const minimumBodyHeight = heightOf(minimumBody);
|
|
3338
4383
|
let selected;
|
|
3339
|
-
for (const size of /* @__PURE__ */ new Set([
|
|
3340
|
-
const
|
|
3341
|
-
const
|
|
3342
|
-
const
|
|
3343
|
-
const
|
|
3344
|
-
const
|
|
4384
|
+
for (const size of /* @__PURE__ */ new Set([footerRequested, minimum])) {
|
|
4385
|
+
const diameter = hasPhoto ? PHOTO_RATIO * size : 0, gap = hasPhoto ? PHOTO_GAP * size : 0;
|
|
4386
|
+
const textArea = { ...inner, width: inner.width - diameter - gap, x: rtl ? inner.x : inner.x + diameter + gap };
|
|
4387
|
+
const natural = attribution ? fit(attribution, textArea, size, size) : void 0;
|
|
4388
|
+
const naturalHeight = natural ? natural.lines.length * natural.lineHeight : 0;
|
|
4389
|
+
const blockHeight = Math.max(naturalHeight, diameter);
|
|
4390
|
+
const lineHeight = natural?.lineHeight ?? size * 1.22;
|
|
4391
|
+
const preferredHeight = Math.max(40, blockHeight);
|
|
4392
|
+
const bodyReservation = Math.min(minimumBodyHeight, Math.max(minimumBody.lineHeight, available - lineHeight));
|
|
4393
|
+
const footerHeight = preferredBodyHeight + preferredHeight <= available + 0.01 ? preferredHeight : Math.min(blockHeight, Math.max(0, available - bodyReservation));
|
|
3345
4394
|
const bodyBox = { ...inner, height: available - footerHeight };
|
|
3346
4395
|
const footerBox = { ...inner, y: inner.y + inner.height - footerHeight, height: footerHeight };
|
|
3347
4396
|
const bodyFit = fit(body, bodyBox);
|
|
3348
|
-
const
|
|
3349
|
-
const
|
|
3350
|
-
const
|
|
4397
|
+
const photoBox = hasPhoto ? { x: rtl ? inner.x + inner.width - diameter : inner.x, y: footerBox.y + (footerHeight - diameter) / 2, width: diameter, height: diameter } : void 0;
|
|
4398
|
+
const textBox = attribution ? hasPhoto ? { ...textArea, y: footerBox.y + Math.max(0, footerHeight - naturalHeight) / 2, height: Math.min(naturalHeight, footerHeight) } : footerBox : void 0;
|
|
4399
|
+
const footerFit = attribution && natural && usable(footerBox) ? { ...natural, overflow: natural.overflow || naturalHeight > footerHeight + 0.01 } : void 0;
|
|
4400
|
+
const fitsPhoto = !hasPhoto || diameter <= footerHeight + 0.01 && (!attribution || usable(textArea));
|
|
4401
|
+
const overflow = !bodyFit || bodyFit.overflow || (attribution ? !footerFit || footerFit.overflow : false) || !fitsPhoto;
|
|
4402
|
+
const score = (body.requestedFontSize - (bodyFit?.fontSize ?? minimum) + footerRequested - size) / scale;
|
|
3351
4403
|
if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) {
|
|
3352
|
-
selected = { bodyBox, footerBox, bodyFit, footerFit, score, overflow };
|
|
4404
|
+
selected = { bodyBox, footerBox, textBox, photoBox, bodyFit, footerFit, score, overflow, photoFits: fitsPhoto };
|
|
3353
4405
|
}
|
|
3354
4406
|
}
|
|
3355
4407
|
if (selected) {
|
|
3356
4408
|
body.box = selected.bodyBox;
|
|
3357
4409
|
body.fit = selected.bodyFit;
|
|
3358
|
-
attribution
|
|
3359
|
-
|
|
4410
|
+
if (attribution) {
|
|
4411
|
+
attribution.box = selected.textBox ?? selected.footerBox;
|
|
4412
|
+
attribution.fit = selected.footerFit;
|
|
4413
|
+
}
|
|
4414
|
+
if (selected.photoBox) photo = { path: photoPath, value: photoValue, box: selected.photoBox, shape: imageShape("circle", selected.photoBox) };
|
|
4415
|
+
photoFits = selected.photoFits;
|
|
3360
4416
|
}
|
|
3361
4417
|
}
|
|
4418
|
+
if (hasPhoto && !photo) photoFits = false;
|
|
3362
4419
|
for (const part of parts) {
|
|
3363
4420
|
const area = part.box;
|
|
3364
4421
|
if (!part.fit) {
|
|
@@ -3370,17 +4427,20 @@ function layoutQuote(value, box, options = {}) {
|
|
|
3370
4427
|
report("part-outside-cell", part.path, [part.role], `Quote ${part.role} extends outside its cell; increase the cell size or change the arrangement.`);
|
|
3371
4428
|
}
|
|
3372
4429
|
}
|
|
3373
|
-
if (
|
|
4430
|
+
if (hasPhoto && !photoFits) report("photo-fit", photoPath, ["footer"], "Quote photo does not fit beside the attribution at the readability floor; increase the cell size, shorten the text or remove the photo.");
|
|
4431
|
+
if (body?.fit && attribution?.fit && body.box.y + heightOf(body.fit) > attribution.box.y + 0.01 && attribution.box.y + attribution.fit.lines.length * attribution.fit.lineHeight > body.box.y + 0.01) {
|
|
3374
4432
|
report("part-overlap", path, ["body", "footer"], "Quote body and footer line boxes overlap; do not accept this layout without more space.");
|
|
4433
|
+
} else if (body?.fit && photo && body.box.y + heightOf(body.fit) > photo.box.y + 0.01) {
|
|
4434
|
+
report("part-overlap", path, ["body", "footer"], "Quote body and photo overlap; do not accept this layout without more space.");
|
|
3375
4435
|
}
|
|
3376
4436
|
if (diagnostics.length && options.overflow === "error") throw new OPFCompositionError(diagnostics);
|
|
3377
|
-
return { algorithm: "quote-flow-v1", textMeasurement: options.textMeasurement ? "provided" : "estimated", parts, diagnostics, overflow: diagnostics.length > 0 };
|
|
4437
|
+
return { algorithm: "quote-flow-v1", textMeasurement: options.textMeasurement ? "provided" : "estimated", parts, ...photo ? { photo } : {}, diagnostics, overflow: diagnostics.length > 0 };
|
|
3378
4438
|
}
|
|
3379
4439
|
function layoutMetric(value, box, options = {}) {
|
|
3380
4440
|
const scalar = typeof value === "string" || typeof value === "number";
|
|
3381
4441
|
const metric = scalar ? { value } : value;
|
|
3382
4442
|
const isValue = (input) => typeof input === "string" || typeof input === "number" && Number.isFinite(input);
|
|
3383
|
-
if (!metric || Array.isArray(metric) || !isValue(metric.value) || [metric.label, metric.description, metric.unit].some((field) => field !== void 0 && typeof field !== "string") || metric.delta !== void 0 && !isValue(metric.delta) || metric.trend !== void 0 && !["up", "down", "flat"].includes(metric.trend)) {
|
|
4443
|
+
if (!metric || Array.isArray(metric) || !isValue(metric.value) || [metric.label, metric.description, metric.unit].some((field) => field !== void 0 && typeof field !== "string") || metric.delta !== void 0 && !isValue(metric.delta) || metric.trend !== void 0 && !["up", "down", "flat"].includes(metric.trend) || metric.sentiment !== void 0 && !["positive", "negative", "neutral"].includes(metric.sentiment)) {
|
|
3384
4444
|
throw new TypeError("Metric content requires a finite numeric or string value and schema-valid display metadata.");
|
|
3385
4445
|
}
|
|
3386
4446
|
const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale);
|
|
@@ -3398,7 +4458,7 @@ function layoutMetric(value, box, options = {}) {
|
|
|
3398
4458
|
if (sourceValue === void 0) continue;
|
|
3399
4459
|
const text2 = String(sourceValue), path = scalar ? sourcePath : `${sourcePath}.${role}`;
|
|
3400
4460
|
const nominal = role === "value" ? Math.min(76 * scale, box.height * 0.28) : (role === "description" ? 20 : role === "trend" ? 18 : 23) * scale;
|
|
3401
|
-
const requestedStyle = { fontFamily: (role === "value" ? options.
|
|
4461
|
+
const requestedStyle = { fontFamily: (role === "value" ? options.fontFamilies?.heading : options.fontFamilies?.body) ?? "sans-serif", fontWeight: role === "value" ? 800 : role === "description" ? 400 : 500, italic: false, path };
|
|
3402
4462
|
const part = {
|
|
3403
4463
|
role,
|
|
3404
4464
|
path,
|
|
@@ -3544,24 +4604,28 @@ function layoutMetric(value, box, options = {}) {
|
|
|
3544
4604
|
}
|
|
3545
4605
|
}
|
|
3546
4606
|
if (diagnostics.length && options.overflow === "error") throw new OPFCompositionError(diagnostics);
|
|
3547
|
-
return { algorithm: "metric-flow-v1", alignment, textMeasurement: options.textMeasurement ? "provided" : "estimated", arrangement: selected.arrangement, attempts, parts, diagnostics, overflow: diagnostics.length > 0 };
|
|
4607
|
+
return { algorithm: "metric-flow-v1", alignment, textMeasurement: options.textMeasurement ? "provided" : "estimated", arrangement: selected.arrangement, ...metric.sentiment === void 0 ? {} : { sentiment: metric.sentiment }, attempts, parts, diagnostics, overflow: diagnostics.length > 0 };
|
|
3548
4608
|
}
|
|
4609
|
+
var TIMELINE_STATUS_VALUES = ["done", "current", "planned"];
|
|
4610
|
+
var TIMELINE_RING_RATIO = 1.6;
|
|
3549
4611
|
function layoutTimeline(value, box, options = {}) {
|
|
3550
4612
|
const shorthand = Array.isArray(value), timeline = shorthand ? { events: value } : value;
|
|
3551
4613
|
if (!timeline || !Array.isArray(timeline.events) || !timeline.events.length || [timeline.name, timeline.description].some((field) => field !== void 0 && typeof field !== "string") || timeline.events.some((event) => !event || typeof event.what !== "string" || [event.when, event.description].some((field) => field !== void 0 && typeof field !== "string"))) {
|
|
3552
4614
|
throw new TypeError("Timeline content requires ordered events with string labels and optional string metadata.");
|
|
3553
4615
|
}
|
|
4616
|
+
if (timeline.events.some((event) => event.status !== void 0 && !TIMELINE_STATUS_VALUES.includes(event.status))) throw new TypeError("Timeline event status must be 'done', 'current' or 'planned'.");
|
|
3554
4617
|
const scale = options.scale ?? 1, minimum = snapFontSizeUp((options.minFontSize ?? 16) * scale), padding = (options.textRasterPadding ?? 1) * scale;
|
|
3555
4618
|
if (![box.x, box.y, box.width, box.height, scale, minimum, padding].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0 || padding < 0) throw new RangeError("Timeline dimensions, scale and minimum must be positive, with finite nonnegative raster padding.");
|
|
3556
4619
|
if (options.overflow !== void 0 && !["warn", "error"].includes(options.overflow)) throw new RangeError("Invalid timeline overflow policy.");
|
|
3557
4620
|
const outlines = options.textMeasurement?.outlineBounds !== void 0, rtl = options.direction === "rtl";
|
|
3558
4621
|
if (outlines && typeof options.textMeasurement?.outlineBounds !== "function") throw new TypeError("Text outline provider must be a function.");
|
|
3559
4622
|
const path = options.path ?? "timeline", eventPath = (index) => shorthand ? `${path}.${index}` : `${path}.events.${index}`;
|
|
3560
|
-
const fonts = resolveFontFamilies(options.
|
|
4623
|
+
const fonts = resolveFontFamilies(options.fontFamilies), source = [];
|
|
3561
4624
|
const add = (role, text2, partPath, size, weight, eventIndex) => {
|
|
3562
4625
|
if (text2 === void 0) return;
|
|
3563
|
-
const
|
|
3564
|
-
|
|
4626
|
+
const status = eventIndex === void 0 ? void 0 : timeline.events[eventIndex].status;
|
|
4627
|
+
const requestedStyle = { fontFamily: fonts.body, fontWeight: status === "current" && role === "what" ? 700 : weight, italic: false, path: partPath };
|
|
4628
|
+
source.push({ role, eventIndex, ...status ? { status } : {}, path: partPath, text: text2, sources: [{ path: partPath, start: 0, end: text2.length }], box: { ...box }, alignment: "center", requestedFontSize: gridFontSize(size * scale, minimum), minFontSize: minimum, requestedStyle, style: resolveTextStyle({ ...requestedStyle }, options.textMeasurement) });
|
|
3565
4629
|
};
|
|
3566
4630
|
add("name", timeline.name, `${path}.name`, 24, 700);
|
|
3567
4631
|
add("description", timeline.description, `${path}.description`, 18, 400);
|
|
@@ -3631,12 +4695,18 @@ function layoutTimeline(value, box, options = {}) {
|
|
|
3631
4695
|
y += placed.box.height + 8 * scale;
|
|
3632
4696
|
}
|
|
3633
4697
|
const available = box.y + box.height - y, count = events.length, radius = Math.min(9 * scale, box.width / Math.max(2, count) / 5, Math.max(scale, available) * 0.04);
|
|
4698
|
+
const statusOf = (index) => timeline.events[index].status, ringRadius = radius * TIMELINE_RING_RATIO, strokeWidth = Math.min(2 * scale, radius / 2);
|
|
4699
|
+
const hasRing = timeline.events.some((event) => event.status === "current");
|
|
4700
|
+
const marker = (index, x, y2) => {
|
|
4701
|
+
const status = statusOf(index);
|
|
4702
|
+
return { path: eventPath(index), eventIndex: index, x, y: y2, radius, ...status ? { status } : {}, ...status === "current" ? { ring: { radius: ringRadius } } : {}, ...status === "current" || status === "planned" ? { strokeWidth } : {} };
|
|
4703
|
+
};
|
|
3634
4704
|
if (arrangement === "alternating") {
|
|
3635
4705
|
const width = box.width / Math.max(2, count), step = (box.width - width) / Math.max(1, count - 1), start = count === 1 ? box.x + box.width / 2 : box.x + width / 2;
|
|
3636
4706
|
const lineY = y + Math.max(scale, available) * 0.46;
|
|
3637
4707
|
events.forEach((fields2, index) => {
|
|
3638
4708
|
const x = start + (rtl ? count - 1 - index : index) * step, top = index % 2 === 0 ? y : lineY + 24 * scale, bottom = index % 2 === 0 ? lineY - 24 * scale : box.y + box.height;
|
|
3639
|
-
markers.push(
|
|
4709
|
+
markers.push(marker(index, x, lineY));
|
|
3640
4710
|
let cursor = top;
|
|
3641
4711
|
for (const part of fields2) {
|
|
3642
4712
|
const placed = place(part, x - width / 2, cursor, width, "center");
|
|
@@ -3645,7 +4715,8 @@ function layoutTimeline(value, box, options = {}) {
|
|
|
3645
4715
|
}
|
|
3646
4716
|
});
|
|
3647
4717
|
} else {
|
|
3648
|
-
const
|
|
4718
|
+
const lead = hasRing ? ringRadius + strokeWidth / 2 : radius, gap = 24 * scale + (lead - radius);
|
|
4719
|
+
const x = rtl ? box.x + box.width - lead : box.x + lead, textX = rtl ? box.x : box.x + gap, width = box.width - gap;
|
|
3649
4720
|
events.forEach((fields2, index) => {
|
|
3650
4721
|
const top = y;
|
|
3651
4722
|
let first2;
|
|
@@ -3654,13 +4725,16 @@ function layoutTimeline(value, box, options = {}) {
|
|
|
3654
4725
|
first2 ??= placed;
|
|
3655
4726
|
y += placed.box.height;
|
|
3656
4727
|
}
|
|
3657
|
-
markers.push(
|
|
4728
|
+
markers.push(marker(index, x, top + Math.min(first2?.box.height ?? 2 * radius, 2 * radius) / 2));
|
|
3658
4729
|
y += 16 * scale;
|
|
3659
4730
|
});
|
|
3660
4731
|
}
|
|
3661
|
-
for (const
|
|
3662
|
-
|
|
3663
|
-
|
|
4732
|
+
for (const marker2 of markers) {
|
|
4733
|
+
const extent = (marker2.ring?.radius ?? marker2.radius) + (marker2.strokeWidth ?? 0) / 2;
|
|
4734
|
+
if (marker2.x - extent < box.x - 0.01 || marker2.y - extent < box.y - 0.01 || marker2.x + extent > box.x + box.width + 0.01 || marker2.y + extent > box.y + box.height + 0.01) {
|
|
4735
|
+
diagnostics.push({ code: "text-overflow", reason: "event-space", path: marker2.path, message: "Timeline marker has no usable space; increase the cell or paginate events." });
|
|
4736
|
+
score2 += 1;
|
|
4737
|
+
}
|
|
3664
4738
|
}
|
|
3665
4739
|
const first = markers[0], last = markers.at(-1), connector = rtl ? { x1: Math.min(first.x, last.x), y1: first.y, x2: Math.max(first.x, last.x), y2: last.y } : { x1: first.x, y1: first.y, x2: last.x, y2: last.y };
|
|
3666
4740
|
const candidate = { arrangement, parts, markers, connector, diagnostics, score: score2 };
|
|
@@ -3771,7 +4845,7 @@ function layoutCode(value, box, options = {}) {
|
|
|
3771
4845
|
const path = options.path ?? "code", inner = { x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - 36 };
|
|
3772
4846
|
const parts = [], diagnostics = [];
|
|
3773
4847
|
const add = (role, text2, partPath, generated = false) => {
|
|
3774
|
-
const requestedStyle = { fontFamily: options.
|
|
4848
|
+
const requestedStyle = { fontFamily: options.fontFamilies?.code ?? "monospace", fontWeight: role === "body" ? 400 : 700, italic: false, path: partPath };
|
|
3775
4849
|
const part = {
|
|
3776
4850
|
role,
|
|
3777
4851
|
path: partPath,
|
|
@@ -3857,7 +4931,8 @@ function richTextLayouter(input, box, requestedSize, options, minimum = 0) {
|
|
|
3857
4931
|
if (typeof run?.text !== "string" || run.fontSize !== void 0 && (!Number.isFinite(run.fontSize) || run.fontSize <= 0)) throw new RangeError("Rich text runs need text and a positive finite font size.");
|
|
3858
4932
|
const start = offset;
|
|
3859
4933
|
offset += run.text.length;
|
|
3860
|
-
const
|
|
4934
|
+
const resolvedStyle = resolveTextStyle({ ...options.style, fontFamily: run.fontFamily ?? (run.code === true ? options.codeFontFamily ?? "monospace" : options.style.fontFamily), fontWeight: run.bold === void 0 ? options.style.fontWeight : run.bold ? 700 : 400, italic: run.italic ?? options.style.italic, path: options.style.path ? `${options.style.path}.${runIndex}` : void 0 }, options.textMeasurement);
|
|
4935
|
+
const style = typeof run.lang === "string" && run.lang ? { ...resolvedStyle, lang: run.lang } : resolvedStyle;
|
|
3861
4936
|
const marker = options.citationMarker && options.style.path && run.text ? options.citationMarker(`${options.style.path}.${runIndex}`) : void 0;
|
|
3862
4937
|
return { run, runIndex, start, end: offset, style, ...marker ? { marker } : {} };
|
|
3863
4938
|
});
|
|
@@ -3974,15 +5049,15 @@ var PICTURE_BULLET_SCALE = 0.65;
|
|
|
3974
5049
|
function fitList(input, box, requestedSize = 25, minFontSize = 16, options = { style: { fontFamily: "sans-serif", fontWeight: 400 } }) {
|
|
3975
5050
|
if (!Array.isArray(input) || ![box.width, box.height, requestedSize, minFontSize].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("List content, dimensions and font sizes must be valid.");
|
|
3976
5051
|
const source = input.map((value, index) => {
|
|
3977
|
-
const
|
|
3978
|
-
const text2 =
|
|
5052
|
+
const object2 = typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
5053
|
+
const text2 = object2 ? object2.text : value, description = object2?.description, level = object2?.level ?? 0;
|
|
3979
5054
|
if (!Number.isInteger(level) || level < 0) throw new RangeError("List levels must be nonnegative integers.");
|
|
3980
5055
|
const runs = (value2) => typeof value2 === "string" ? [value2] : value2;
|
|
3981
5056
|
if (!Array.isArray(runs(text2)) || description !== void 0 && !Array.isArray(runs(description))) throw new TypeError("List text and descriptions must be strings or text runs.");
|
|
3982
5057
|
const base = options.style.path ? `${options.style.path}.${index}` : void 0;
|
|
3983
5058
|
const plain = (value2) => typeof value2 === "string" ? value2 : value2.map((run) => typeof run === "string" ? run : run.text).join("");
|
|
3984
5059
|
const direction = options.direction === "rtl" ? paragraphDirection(plain(text2), "rtl") : void 0;
|
|
3985
|
-
return { index, level, direction, value: text2, descriptionValue: description, textPath: base ? base + (
|
|
5060
|
+
return { index, level, direction, value: text2, descriptionValue: description, textPath: base ? base + (object2 ? ".text" : "") : void 0, descriptionPath: base ? base + ".description" : void 0, runs: runs(text2), descriptionRuns: description === void 0 ? void 0 : runs(description) };
|
|
3986
5061
|
});
|
|
3987
5062
|
const numbers = options.numbering === void 0 ? void 0 : listNumbers(input, options.numbering);
|
|
3988
5063
|
const markerStyleFor = (item) => {
|
|
@@ -4079,13 +5154,13 @@ function layoutTable(value, box, options = {}) {
|
|
|
4079
5154
|
const cellMinimum = (cell) => Array.isArray(cell.value) ? richMinimum(cell.value, requested, minimum) : minimum;
|
|
4080
5155
|
const fitCell = (cell, height, min) => {
|
|
4081
5156
|
const textBox = { width: Math.max(scale, cell.width), height: Math.max(scale, height) };
|
|
4082
|
-
return Array.isArray(cell.value) ? fitRichText(cell.value, textBox, requested, min, { style: cell.textStyle, textMeasurement: options.textMeasurement, uniformLineHeight: true, direction: options.direction }) : fitText(flatten(cell.value), textBox, requested, min, textWidthMeasurer(resolveTextStyle(cell.textStyle, options.textMeasurement), options.textMeasurement), options.direction);
|
|
5157
|
+
return Array.isArray(cell.value) ? fitRichText(cell.value, textBox, requested, min, { style: cell.textStyle, ...options.codeFontFamily ? { codeFontFamily: options.codeFontFamily } : {}, textMeasurement: options.textMeasurement, uniformLineHeight: true, direction: options.direction }) : fitText(flatten(cell.value), textBox, requested, min, textWidthMeasurer(resolveTextStyle(cell.textStyle, options.textMeasurement), options.textMeasurement), options.direction);
|
|
4083
5158
|
};
|
|
4084
5159
|
const textHeight = (fit) => "height" in fit ? fit.height : fit.lines.length * fit.lineHeight;
|
|
4085
5160
|
const required = (cell, natural2) => {
|
|
4086
5161
|
const floor = cellMinimum(cell), size = gridFontSize(natural2 ? Math.max(requested, floor) : floor, floor);
|
|
4087
5162
|
const textBox = { width: Math.max(scale, cell.width), height: scale };
|
|
4088
|
-
const fit = Array.isArray(cell.value) ? richTextLayouter(cell.value, textBox, requested, { style: cell.textStyle, textMeasurement: options.textMeasurement, uniformLineHeight: true }, minimum)(size) : fitText(flatten(cell.value), textBox, size, size, textWidthMeasurer(resolveTextStyle(cell.textStyle, options.textMeasurement), options.textMeasurement));
|
|
5163
|
+
const fit = Array.isArray(cell.value) ? richTextLayouter(cell.value, textBox, requested, { style: cell.textStyle, ...options.codeFontFamily ? { codeFontFamily: options.codeFontFamily } : {}, textMeasurement: options.textMeasurement, uniformLineHeight: true }, minimum)(size) : fitText(flatten(cell.value), textBox, size, size, textWidthMeasurer(resolveTextStyle(cell.textStyle, options.textMeasurement), options.textMeasurement));
|
|
4089
5164
|
return textHeight(fit) + (cell.padding.top + cell.padding.bottom) * scale;
|
|
4090
5165
|
};
|
|
4091
5166
|
const natural = Array(grid.rowCount).fill(0), needed = Array(grid.rowCount).fill(0);
|
|
@@ -4106,7 +5181,7 @@ function layoutTable(value, box, options = {}) {
|
|
|
4106
5181
|
const ys = [box.y];
|
|
4107
5182
|
for (const height of heights) ys.push(ys.at(-1) + height);
|
|
4108
5183
|
let overflow = false;
|
|
4109
|
-
const
|
|
5184
|
+
const rows3 = heights.map((height, r) => ({ box: { x: box.x, y: ys[r], width: box.width, height }, cells: [] }));
|
|
4110
5185
|
for (const cell of cells) {
|
|
4111
5186
|
const cellBox = { x: box.x + (options.direction === "rtl" ? columnCount - cell.column - cell.colSpan : cell.column) * cellWidth, y: ys[cell.row], width: cell.colSpan * cellWidth, height: ys[cell.row + cell.rowSpan] - ys[cell.row] };
|
|
4112
5187
|
const available = cellBox.height - (cell.padding.top + cell.padding.bottom) * scale;
|
|
@@ -4114,12 +5189,12 @@ function layoutTable(value, box, options = {}) {
|
|
|
4114
5189
|
const offset = cell.style.verticalAlign === "bottom" ? Math.max(0, available - height) : cell.style.verticalAlign === "middle" ? Math.max(0, (available - height) / 2) : 0;
|
|
4115
5190
|
const textBox = { x: cellBox.x + cell.padding.left * scale, y: cellBox.y + cell.padding.top * scale + offset, width: Math.max(scale, cell.width), height: Math.max(scale, available - offset) };
|
|
4116
5191
|
overflow ||= cell.width <= 0 || available <= 0 || fit.overflow;
|
|
4117
|
-
|
|
5192
|
+
rows3[cell.row].cells.push({ value: cell.value, input: cell.input, path: cell.valuePath, sourcePath: cell.path, style: cell.style, row: cell.row, column: cell.column, rowSpan: cell.rowSpan, colSpan: cell.colSpan, header: cell.header, rich: Array.isArray(cell.value), box: cellBox, textBox, textStyle: resolveTextStyle(cell.textStyle, options.textMeasurement), fit, ...fit.directions ? { direction: fit.directions[0] } : {} });
|
|
4118
5193
|
}
|
|
4119
|
-
return { rows:
|
|
5194
|
+
return { rows: rows3, columnCount, height: sum(heights), overflow };
|
|
4120
5195
|
}
|
|
4121
5196
|
function tableOverflows(value, box, scale, settings, options, path) {
|
|
4122
|
-
return box.width <= 0 || box.height <= 0 || layoutTable(value, box, { scale, minFontSize: settings.minFontSize, fontFamily: options.
|
|
5197
|
+
return box.width <= 0 || box.height <= 0 || layoutTable(value, box, { scale, minFontSize: settings.minFontSize, fontFamily: options.fontFamilies?.body, ...options.fontFamilies?.code ? { codeFontFamily: options.fontFamilies.code } : {}, textMeasurement: options.textMeasurement, path, presentation: options.presentation }).overflow;
|
|
4123
5198
|
}
|
|
4124
5199
|
function flatten(value) {
|
|
4125
5200
|
if (value == null) return "";
|
|
@@ -4135,10 +5210,10 @@ function regionParts(key) {
|
|
|
4135
5210
|
};
|
|
4136
5211
|
const parts = key.split(":");
|
|
4137
5212
|
if (parts.length === 2) {
|
|
4138
|
-
const r = span(parts[0],
|
|
5213
|
+
const r = span(parts[0], rows2), c = span(parts[1], columns);
|
|
4139
5214
|
if (r && c) return [r, c];
|
|
4140
5215
|
} else if (parts.length === 1) {
|
|
4141
|
-
const r = span(key,
|
|
5216
|
+
const r = span(key, rows2), c = span(key, columns);
|
|
4142
5217
|
if (r) return [r, [0, 1, 2]];
|
|
4143
5218
|
if (c) return [[0, 1, 2], c];
|
|
4144
5219
|
}
|
|
@@ -4187,7 +5262,8 @@ function composeSlide(input, options = {}) {
|
|
|
4187
5262
|
const scale = Math.min(width, height) / 720;
|
|
4188
5263
|
const deckDirection = options.direction ?? resolveSlideDirection(options.presentation, options.slideIndex);
|
|
4189
5264
|
const rtl = deckDirection === "rtl", textDirection = rtl ? "rtl" : void 0;
|
|
4190
|
-
const
|
|
5265
|
+
const hints = resolveDesignHints({ slide, layout, presentation: options.presentation, slideIndex: options.slideIndex, deck: { titleAlignment: options.titleAlignment, contentAlignment: options.contentAlignment, contentBox: options.contentBox } });
|
|
5266
|
+
const hasCards = hints.contentBox ?? false;
|
|
4191
5267
|
const composition = { ...record5(layout.composition), ...record5(slide.composition) };
|
|
4192
5268
|
assertComposition(composition);
|
|
4193
5269
|
const padding = (composition.padding ?? 0.08) * Math.min(width, height);
|
|
@@ -4196,15 +5272,13 @@ function composeSlide(input, options = {}) {
|
|
|
4196
5272
|
const rasterPadding = (options.textRasterPadding ?? 1) * scale;
|
|
4197
5273
|
if (!Number.isFinite(rasterPadding) || rasterPadding < 0) throw new RangeError("Text raster padding must be finite and nonnegative.");
|
|
4198
5274
|
let coverGroup = false;
|
|
4199
|
-
const alignmentFor = (field) => (field === "title" || coverGroup && (field === "tag" || field === "subtitle") &&
|
|
5275
|
+
const alignmentFor = (field) => (field === "title" || coverGroup && (field === "tag" || field === "subtitle") && hints.sources.contentAlignment !== "slide" ? hints.titleAlignment : hints.contentAlignment) ?? "left";
|
|
4200
5276
|
const styleFor = (field, path2) => resolveTextStyle({
|
|
4201
|
-
fontFamily: (field === "title" ? options.
|
|
5277
|
+
fontFamily: (field === "title" ? options.fontFamilies?.heading : field === "code" ? options.fontFamilies?.code : field === "tag" ? options.fontFamilies?.accent ?? options.fontFamilies?.body : options.fontFamilies?.body) ?? (field === "code" ? "monospace" : "sans-serif"),
|
|
4202
5278
|
fontWeight: field === "title" ? 700 : 400,
|
|
4203
5279
|
path: path2
|
|
4204
5280
|
}, options.textMeasurement);
|
|
4205
|
-
const
|
|
4206
|
-
const designHint = (field) => slideDesign[field] !== void 0 ? { value: slideDesign[field], path: `slides.${options.slideIndex ?? 0}.design.${field}` } : deckDesign[field] !== void 0 ? { value: deckDesign[field], path: `design.${field}` } : void 0;
|
|
4207
|
-
const listBullet = designHint("listBullet");
|
|
5281
|
+
const listBullet = hints.listBullet !== void 0 ? { value: hints.listBullet, path: hints.paths.listBullet } : void 0;
|
|
4208
5282
|
const bulletImage = listBullet?.value === "image" ? (() => {
|
|
4209
5283
|
const resolved = resolveLogo(options.presentation, slide, { slot: "icon", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
4210
5284
|
return resolved ? { source: resolved.source, path: resolved.path } : void 0;
|
|
@@ -4212,9 +5286,9 @@ function composeSlide(input, options = {}) {
|
|
|
4212
5286
|
const widthFor = (field, path2) => textWidthMeasurer(styleFor(field, path2), options.textMeasurement);
|
|
4213
5287
|
const citations = slideCitations(slide, options.slideIndex ?? 0, options.presentation);
|
|
4214
5288
|
const citationMarker = citations ? (runPath) => citations.markers.get(runPath) : void 0;
|
|
4215
|
-
const richOptions = (style) => ({ style, textMeasurement: options.textMeasurement, ...citationMarker ? { citationMarker } : {}, ...rtl ? { direction: "rtl" } : {} });
|
|
5289
|
+
const richOptions = (style) => ({ style, textMeasurement: options.textMeasurement, ...options.fontFamilies?.code ? { codeFontFamily: options.fontFamilies.code } : {}, ...citationMarker ? { citationMarker } : {}, ...rtl ? { direction: "rtl" } : {} });
|
|
4216
5290
|
const fitPlacedText = (field, value, text2, box, size, minimum, path2, explicitAlignment) => {
|
|
4217
|
-
const style = styleFor(field, path2), rich = field === "text" && Array.isArray(value);
|
|
5291
|
+
const style = styleFor(field, path2), rich = (field === "text" || headings.has(field)) && Array.isArray(value);
|
|
4218
5292
|
if (!options.textMeasurement?.outlineBounds) return rich ? fitRichText(value, box, size, minimum, richOptions(style)) : fitText(text2, box, size, minimum, textWidthMeasurer(style, options.textMeasurement), textDirection);
|
|
4219
5293
|
const alignment = explicitAlignment ?? alignmentFor(field);
|
|
4220
5294
|
const richLayout = rich ? richTextLayouter(value, box, size, richOptions(style), minimum) : void 0;
|
|
@@ -4267,13 +5341,37 @@ function composeSlide(input, options = {}) {
|
|
|
4267
5341
|
const path = `slides.${options.slideIndex ?? 0}`;
|
|
4268
5342
|
const annotationFit = (value, box, requestedSize, minFontSize, fitPath, alignment) => fitPlacedText("text", value, annotationText(value), box, requestedSize, minFontSize, fitPath, alignment);
|
|
4269
5343
|
const annotationOptions = { scale, minFontSize: minSize, fit: annotationFit, textStyle: (fitPath) => styleFor("text", fitPath) };
|
|
4270
|
-
const
|
|
4271
|
-
const
|
|
5344
|
+
const imageDiagnostics = [];
|
|
5345
|
+
const mirrorSide = (side) => !rtl ? side : side === "left" ? "right" : side === "right" ? "left" : side;
|
|
5346
|
+
const backgroundImage = resolveBackgroundImage(slide, options.presentation, options.themeBackground, width, height, path, mirrorSide, imageDiagnostics);
|
|
5347
|
+
const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
|
|
5348
|
+
const assets = record5(options.presentation).assets;
|
|
5349
|
+
const imageContext = (placement) => ({ fit: hints.imageFit, scale, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
|
|
4272
5350
|
const area = { left: 0, top: 0, right: width, bottom: height };
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
5351
|
+
const imagePlaceholders = (Array.isArray(layout.placeholders) ? layout.placeholders : []).flatMap((placeholder, index) => record5(placeholder).type === "image" ? [{ placeholder: record5(placeholder), index }] : []);
|
|
5352
|
+
const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record5(block).blocks) && record5(block).image !== void 0 ? [{ host: record5(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
|
|
5353
|
+
const placed = [], usedEdges = /* @__PURE__ */ new Set();
|
|
5354
|
+
topImages.forEach((node, order) => {
|
|
5355
|
+
const slot = imagePlaceholders[order];
|
|
5356
|
+
const own2 = node.block !== void 0 && node.host.placement !== void 0 ? record5(node.host.placement) : void 0;
|
|
5357
|
+
const value = own2 ?? (slot?.placeholder.placement !== void 0 ? record5(slot.placeholder.placement) : void 0);
|
|
5358
|
+
if (!value || !IMAGE_EDGES.includes(value.edge)) return;
|
|
5359
|
+
const edge = mirrorSide(value.edge);
|
|
5360
|
+
if (usedEdges.has(edge)) return;
|
|
5361
|
+
usedEdges.add(edge);
|
|
5362
|
+
const size = finite(value.size, 0.1, 0.9) ?? PLACEMENT_BAND;
|
|
5363
|
+
const across = edge === "left" || edge === "right" ? area.right - area.left : area.bottom - area.top;
|
|
5364
|
+
const band = Math.max(0, Math.min(across, round2((edge === "left" || edge === "right" ? width : height) * size)));
|
|
5365
|
+
const region = edge === "left" ? { x: area.left, y: area.top, width: band, height: area.bottom - area.top } : edge === "right" ? { x: round2(area.right - band), y: area.top, width: band, height: area.bottom - area.top } : edge === "top" ? { x: area.left, y: area.top, width: area.right - area.left, height: band } : { x: area.left, y: round2(area.bottom - band), width: area.right - area.left, height: band };
|
|
5366
|
+
if (edge === "left") area.left += band;
|
|
5367
|
+
else if (edge === "right") area.right = region.x;
|
|
5368
|
+
else if (edge === "top") area.top += band;
|
|
5369
|
+
else area.bottom = region.y;
|
|
5370
|
+
const placement = { edge, size, inset: value.inset === true, path: own2 ? `${node.hostPath}.placement` : `layout.placeholders.${slot.index}.placement` };
|
|
5371
|
+
placed.push({ ...node, placement, region, slot: order });
|
|
5372
|
+
});
|
|
5373
|
+
const placedBlocks = new Set(placed.flatMap((entry) => entry.block !== void 0 ? [entry.block] : []));
|
|
5374
|
+
const placedRoot = placed.some((entry) => entry.block === void 0);
|
|
4277
5375
|
const items = [], diagnostics = [];
|
|
4278
5376
|
const measuredFurniture = layoutFurniture(slide, options);
|
|
4279
5377
|
const furniture = measuredFurniture.configured || measuredFurniture.diagnostics.length ? measuredFurniture : void 0;
|
|
@@ -4287,12 +5385,13 @@ function composeSlide(input, options = {}) {
|
|
|
4287
5385
|
bodyBottom = footnotes.box.y - gap * 0.5;
|
|
4288
5386
|
}
|
|
4289
5387
|
const layoutPlaceholders = Array.isArray(layout.placeholders) ? layout.placeholders : [];
|
|
4290
|
-
const
|
|
4291
|
-
const
|
|
5388
|
+
const hasLayoutRecord = options.layout !== void 0 && options.layout !== null && typeof options.layout === "object";
|
|
5389
|
+
const headingOnlyLayout = layoutPlaceholders.length > 0 && layoutPlaceholders.every((placeholder) => headings.has(placeholder.type ?? "") || placeholder.type === "image" && typeof placeholder.placement === "object" && placeholder.placement !== null);
|
|
4292
5390
|
const emptyPayload = (value) => value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
|
|
4293
5391
|
const emptyHost = (host) => emptyPayload(host.blocks) && fields.every((field) => emptyPayload(host[field]));
|
|
4294
|
-
const
|
|
4295
|
-
const
|
|
5392
|
+
const flowBlocks = Array.isArray(slide.blocks) ? slide.blocks.filter((_, index) => !placedBlocks.has(index)) : slide.blocks;
|
|
5393
|
+
const hasBodyPayload = regions.some((key) => !emptyHost(record5(slide[key]))) || !emptyPayload(flowBlocks) || fields.some((field) => !(placedRoot && field === "image") && !emptyPayload(slide[field]));
|
|
5394
|
+
const isCover = !hasBodyPayload && (headingOnlyLayout || !hasLayoutRecord);
|
|
4296
5395
|
coverGroup = isCover;
|
|
4297
5396
|
let logo;
|
|
4298
5397
|
if (isCover) {
|
|
@@ -4307,12 +5406,12 @@ function composeSlide(input, options = {}) {
|
|
|
4307
5406
|
let y = logo ? logo.box.y + logo.box.height + gap : headingTop;
|
|
4308
5407
|
const headingItems = [];
|
|
4309
5408
|
for (const field of ["tag", "title", "subtitle"]) {
|
|
4310
|
-
if (!slide[field]) continue;
|
|
5409
|
+
if (!slide[field] || Array.isArray(slide[field]) && !annotationText(slide[field])) continue;
|
|
4311
5410
|
const requested = (field === "title" ? 54 : field === "tag" ? 16 : 25) * scale;
|
|
4312
5411
|
const maxHeight = Math.max(height * (field === "title" ? 0.26 : field === "subtitle" ? 0.12 : 0.045), minSize * 1.22 + 2 * rasterPadding);
|
|
4313
5412
|
const box = { x: area.left + padding, y, width: area.right - area.left - padding * 2, height: maxHeight };
|
|
4314
|
-
const text2 = fitPlacedText(field, slide[field],
|
|
4315
|
-
box.height = Math.min(maxHeight, Math.max(text2.lines.length * text2.lineHeight, text2.placement?.height ?? 0));
|
|
5413
|
+
const text2 = fitPlacedText(field, slide[field], annotationText(slide[field]), box, requested, minSize, `${path}.${field}`);
|
|
5414
|
+
box.height = Math.min(maxHeight, Math.max("richLines" in text2 ? text2.height : text2.lines.length * text2.lineHeight, text2.placement?.height ?? 0));
|
|
4316
5415
|
if (furniture && box.y + box.height > bodyBottom + 0.01) diagnostics.push({ code: "text-overflow", path: `${path}.${field}`, message: "Repeated furniture leaves too little room for this heading. Change the header/footer or slide design." });
|
|
4317
5416
|
const item = { 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) };
|
|
4318
5417
|
headingItems.push(item);
|
|
@@ -4330,6 +5429,30 @@ function composeSlide(input, options = {}) {
|
|
|
4330
5429
|
y = last.box.y + last.box.height + gap;
|
|
4331
5430
|
} else y += gap * 0.5;
|
|
4332
5431
|
}
|
|
5432
|
+
for (const entry of placed) {
|
|
5433
|
+
const { host, hostPath, region, placement } = entry;
|
|
5434
|
+
let frameArea = placement.inset ? { x: region.x + padding, y: region.y + padding, width: Math.max(scale, region.width - 2 * padding), height: Math.max(scale, region.height - 2 * padding) } : { ...region };
|
|
5435
|
+
const caption = host.caption !== void 0 && entry.block !== void 0 ? layoutCaption(host.caption, roundBox(frameArea), `${hostPath}.caption`, annotationOptions) : void 0;
|
|
5436
|
+
if (caption) {
|
|
5437
|
+
frameArea = caption.mediaBox;
|
|
5438
|
+
diagnostics.push(...caption.diagnostics);
|
|
5439
|
+
}
|
|
5440
|
+
const image = composeImage(host, hostPath, region, frameArea, imageContext(placement));
|
|
5441
|
+
const type = host.type ?? "image";
|
|
5442
|
+
items.push({
|
|
5443
|
+
path: `${hostPath}.image`,
|
|
5444
|
+
field: "image",
|
|
5445
|
+
type,
|
|
5446
|
+
value: host.image,
|
|
5447
|
+
payload: imagePayload(host),
|
|
5448
|
+
box: { ...region },
|
|
5449
|
+
image,
|
|
5450
|
+
textStyle: styleFor("image", `${hostPath}.image`),
|
|
5451
|
+
composition,
|
|
5452
|
+
alignment: alignmentFor("image"),
|
|
5453
|
+
...caption ? { caption } : {}
|
|
5454
|
+
});
|
|
5455
|
+
}
|
|
4333
5456
|
const contentBox = { x: area.left + padding, y, width: area.right - area.left - padding * 2, height: Math.max(scale, bodyBottom - y) };
|
|
4334
5457
|
const collect = (host, basePath, depth = 0, ancestors = []) => {
|
|
4335
5458
|
if (Array.isArray(host.blocks)) {
|
|
@@ -4353,12 +5476,13 @@ function composeSlide(input, options = {}) {
|
|
|
4353
5476
|
type: host.type ?? kind(field),
|
|
4354
5477
|
value: fieldValue(field),
|
|
4355
5478
|
path: `${basePath}.${field}`,
|
|
4356
|
-
payload: { type: host.type ?? kind(field), [field]: fieldValue(field), ...host.numbering !== void 0 && (field === "items" || field === "bullets") ? { numbering: host.numbering } : {} },
|
|
5479
|
+
payload: field === "image" ? imagePayload(host) : { type: host.type ?? kind(field), [field]: fieldValue(field), ...host.numbering !== void 0 && (field === "items" || field === "bullets") ? { numbering: host.numbering } : {} },
|
|
5480
|
+
...field === "image" ? { host, hostPath: basePath } : {},
|
|
4357
5481
|
...captioned.length === 1 && captioned[0] === field ? { caption: host.caption, captionPath: `${basePath}.caption` } : {}
|
|
4358
5482
|
}));
|
|
4359
5483
|
};
|
|
4360
5484
|
const regionsInReadingOrder = visualReadingOrder(regions.map((key) => ({ key, box: regionBox(regionParts(key), contentBox, gap) }))).map((entry) => entry.key);
|
|
4361
|
-
const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(record5(slide[key]), `${path}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => collect(record5(block), `${path}.blocks.${index}`)) : collect(
|
|
5485
|
+
const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(record5(slide[key]), `${path}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => placedBlocks.has(index) ? [] : collect(record5(block), `${path}.blocks.${index}`)) : collect(placedRoot ? { ...slide, image: void 0 } : slide, path);
|
|
4362
5486
|
const groups = [], flows = [];
|
|
4363
5487
|
const decisions = options.explain ? [] : void 0;
|
|
4364
5488
|
const inheritedSettings = (parent, own2 = {}) => ({
|
|
@@ -4377,22 +5501,23 @@ function composeSlide(input, options = {}) {
|
|
|
4377
5501
|
return acceptedBox({ x: frame.x + padding2, y: frame.y + padding2, width: frame.width - 2 * padding2, height: frame.height - 2 * padding2 });
|
|
4378
5502
|
};
|
|
4379
5503
|
const measureQuote = (node, box, settings) => layoutQuote(node.value, acceptedBox(box), {
|
|
4380
|
-
|
|
5504
|
+
fontFamilies: options.fontFamilies,
|
|
4381
5505
|
textMeasurement: options.textMeasurement,
|
|
4382
5506
|
scale,
|
|
4383
5507
|
minFontSize: settings.minFontSize,
|
|
4384
5508
|
path: node.path,
|
|
4385
|
-
direction: textDirection
|
|
5509
|
+
direction: textDirection,
|
|
5510
|
+
...citationMarker ? { citationMarker } : {}
|
|
4386
5511
|
});
|
|
4387
5512
|
const measureCode = (node, box, settings) => layoutCode(node.value, acceptedBox(box), {
|
|
4388
|
-
|
|
5513
|
+
fontFamilies: options.fontFamilies,
|
|
4389
5514
|
textMeasurement: options.textMeasurement,
|
|
4390
5515
|
scale,
|
|
4391
5516
|
minFontSize: settings.minFontSize,
|
|
4392
5517
|
path: node.path
|
|
4393
5518
|
});
|
|
4394
5519
|
const measureMetric = (node, box, settings) => layoutMetric(node.value, acceptedBox(box), {
|
|
4395
|
-
|
|
5520
|
+
fontFamilies: options.fontFamilies,
|
|
4396
5521
|
textMeasurement: options.textMeasurement,
|
|
4397
5522
|
scale,
|
|
4398
5523
|
minFontSize: settings.minFontSize,
|
|
@@ -4402,7 +5527,7 @@ function composeSlide(input, options = {}) {
|
|
|
4402
5527
|
direction: textDirection
|
|
4403
5528
|
});
|
|
4404
5529
|
const measureTimeline = (node, box, settings) => layoutTimeline(node.value, acceptedBox(box), {
|
|
4405
|
-
|
|
5530
|
+
fontFamilies: options.fontFamilies,
|
|
4406
5531
|
textMeasurement: options.textMeasurement,
|
|
4407
5532
|
scale,
|
|
4408
5533
|
minFontSize: settings.minFontSize,
|
|
@@ -4514,6 +5639,7 @@ function composeSlide(input, options = {}) {
|
|
|
4514
5639
|
const timelineLayout = node.field === "timeline" ? measureTimeline(node, box, settings) : void 0;
|
|
4515
5640
|
const internal = quoteLayout ?? codeLayout ?? metricLayout ?? timelineLayout, body = internal?.parts.find((part) => part.role === "body" || part.role === "value");
|
|
4516
5641
|
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;
|
|
5642
|
+
const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext()) : void 0;
|
|
4517
5643
|
items.push({
|
|
4518
5644
|
path: node.path,
|
|
4519
5645
|
field: node.field,
|
|
@@ -4521,6 +5647,7 @@ function composeSlide(input, options = {}) {
|
|
|
4521
5647
|
value: node.value,
|
|
4522
5648
|
payload: node.payload,
|
|
4523
5649
|
box: internal ? acceptedBox(box) : box,
|
|
5650
|
+
...image ? { image } : {},
|
|
4524
5651
|
...frameBox ? { frameBox } : {},
|
|
4525
5652
|
text: text2,
|
|
4526
5653
|
textStyle: body?.style ?? styleFor(node.field, node.path),
|
|
@@ -4538,19 +5665,18 @@ function composeSlide(input, options = {}) {
|
|
|
4538
5665
|
});
|
|
4539
5666
|
};
|
|
4540
5667
|
const placeholders = Array.isArray(layout.placeholders) ? layout.placeholders.filter((p) => !headings.has(p.type)) : [];
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
5668
|
+
const placedSlots = new Set(placed.flatMap((entry) => imagePlaceholders[entry.slot] ? [imagePlaceholders[entry.slot].placeholder] : []));
|
|
5669
|
+
if (placedSlots.size) {
|
|
5670
|
+
for (let index = placeholders.length - 1; index >= 0; index--) if (placedSlots.has(placeholders[index])) placeholders.splice(index, 1);
|
|
4544
5671
|
}
|
|
4545
5672
|
const ownMode = record5(slide.composition).mode;
|
|
4546
|
-
const direction =
|
|
4547
|
-
const directionMode = direction === "vertical" ? "column" : direction === "horizontal" ? "row" :
|
|
4548
|
-
const
|
|
4549
|
-
const chartHint = designHint("chartPrimary")?.value ?? (typeof layout.contentTypeChartPrimary === "string" ? layout.contentTypeChartPrimary.toLowerCase() : void 0);
|
|
5673
|
+
const direction = hints.contentDirection;
|
|
5674
|
+
const directionMode = direction === "vertical" ? "column" : direction === "horizontal" ? "row" : "auto";
|
|
5675
|
+
const chartHint = hints.chartPrimary;
|
|
4550
5676
|
const chartSide = chartHint === "left" || chartHint === "right" || chartHint === "top" || chartHint === "bottom" ? chartHint : void 0;
|
|
4551
5677
|
const chartIndex = pending.findIndex((node) => !node.children && node.field === "chart");
|
|
4552
5678
|
const chartPrimary = chartSide !== void 0 && !ownMode && !regions.length && chartIndex >= 0 && pending.some((node) => node.children || node.field !== "chart") ? chartSide : void 0;
|
|
4553
|
-
const rootSettings = chartPrimary ? { ...composition, mode: chartPrimary === "left" || chartPrimary === "right" ? "row" : "column", columns: void 0, weights: chartPrimary === "left" || chartPrimary === "top" ? [3, 2] : [2, 3] } : { ...composition, mode: composition.mode ?? directionMode
|
|
5679
|
+
const rootSettings = chartPrimary ? { ...composition, mode: chartPrimary === "left" || chartPrimary === "right" ? "row" : "column", columns: void 0, weights: chartPrimary === "left" || chartPrimary === "top" ? [3, 2] : [2, 3] } : { ...composition, mode: composition.mode ?? directionMode };
|
|
4554
5680
|
if (chartPrimary) {
|
|
4555
5681
|
const primary = pending[chartIndex], rest = pending.filter((_, index) => index !== chartIndex);
|
|
4556
5682
|
const container = { field: "blocks", type: "group", value: rest.map((node) => node.payload), path, payload: {}, children: rest, composition: {}, synthetic: true };
|
|
@@ -4594,8 +5720,8 @@ function composeSlide(input, options = {}) {
|
|
|
4594
5720
|
unmeasuredPayloads: items.filter((item) => !headings.has(item.field) && !item.quoteLayout && !item.codeLayout && !item.metricLayout && !item.timelineLayout && !["text", "items", "bullets", "table"].includes(item.field)).map((item) => item.path)
|
|
4595
5721
|
} : void 0;
|
|
4596
5722
|
if (failures.length) throw new OPFCompositionError(failures, explanation);
|
|
4597
|
-
diagnostics.push(...
|
|
4598
|
-
return { width, height, contentBox, items, groups, flows, diagnostics, composition, ...furniture ? { furniture } : {}, ...
|
|
5723
|
+
diagnostics.push(...imageDiagnostics, ...numberingDiagnostics);
|
|
5724
|
+
return { width, height, contentBox, items, groups, flows, diagnostics, composition, design: hints, ...furniture ? { furniture } : {}, ...backgroundImage ? { backgroundImage } : {}, ...logo ? { logo } : {}, ...rtl ? { direction: "rtl" } : {}, ...footnotes ? { footnotes } : {}, ...explanation ? { explanation } : {} };
|
|
4599
5725
|
}
|
|
4600
5726
|
function resolveCanvasDimensions(input) {
|
|
4601
5727
|
const presets = {
|
|
@@ -4604,6 +5730,9 @@ function resolveCanvasDimensions(input) {
|
|
|
4604
5730
|
standard: [10, 7.5],
|
|
4605
5731
|
"4:3": [10, 7.5],
|
|
4606
5732
|
"16:10": [10, 6.25],
|
|
5733
|
+
"1:1": [7.5, 7.5],
|
|
5734
|
+
"4:5": [7.5, 9.375],
|
|
5735
|
+
"9:16": [7.5, 40 / 3],
|
|
4607
5736
|
letter: [11, 8.5],
|
|
4608
5737
|
a4: [11.69, 8.27]
|
|
4609
5738
|
};
|
|
@@ -4615,4 +5744,4 @@ function resolveCanvasDimensions(input) {
|
|
|
4615
5744
|
return { width, height };
|
|
4616
5745
|
}
|
|
4617
5746
|
|
|
4618
|
-
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE,
|
|
5747
|
+
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_SLIDE_NUMBER_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, LANGUAGES, LAYOUT_BODY_KINDS, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_ROMAN_VALUE, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCompositionError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, annotationText, captionSettings, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeSlide, datasetDiagnostics, defaultSlideBackground, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatSlideNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutTable, layoutTimeline, layoutWatermark, listBuiltinVariables, listNumbers, listVariables, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, promotedRegionKeys, readingRows, referencesSlide, resolveCanvasDimensions, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveScriptFonts, resolveSlideDirection, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, scriptFontRole, sliceNumberedItems, slideCitations, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unusedDatasets, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
|