@openpresentation/opf 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. package/README.md +28 -38
  2. package/dist/catalog-refs-_anZs-Qz.d.ts +128 -0
  3. package/dist/catalog-schemas-BZCjgAxu.d.ts +12 -0
  4. package/dist/catalog.d.ts +91 -0
  5. package/dist/{chunk-XOZ4KMSR.js → catalog.js} +17018 -8816
  6. package/dist/{chart-data-B_3z9VTb.d.ts → chart-data-BnNqgnC-.d.ts} +1 -1
  7. package/dist/{chunk-BFLVSVA7.js → chunk-3XDRQYWZ.js} +1 -1
  8. package/dist/{chunk-6OXY2CP3.js → chunk-5PDN7BN6.js} +503 -239
  9. package/dist/{chunk-CSQHPVGL.js → chunk-5TO6I3GB.js} +1 -1
  10. package/dist/{chunk-4LDGKLUC.js → chunk-5UEUAW57.js} +4 -2
  11. package/dist/{chunk-5ZU6JAPP.js → chunk-6OR326EA.js} +1 -1
  12. package/dist/{chunk-XIZUK2XM.js → chunk-BSYQDWT4.js} +15 -3
  13. package/dist/{chunk-UPQQD7MA.js → chunk-FQSIIADJ.js} +15 -6
  14. package/dist/{chunk-D3TY4TT6.js → chunk-HXHOZ7AH.js} +1407 -154
  15. package/dist/chunk-K4DQQIT4.js +319 -0
  16. package/dist/chunk-KINQFU6X.js +51 -0
  17. package/dist/{chunk-4VJDTF55.js → chunk-NAWQR7MN.js} +1 -1
  18. package/dist/{chunk-JDJBDYSR.js → chunk-PX5AWL7Y.js} +333 -857
  19. package/dist/{chunk-Q2TCMN56.js → chunk-SMLMI6IZ.js} +5 -2
  20. package/dist/chunk-SPFV27O5.js +210 -0
  21. package/dist/chunk-TRDXRRQK.js +17 -0
  22. package/dist/{chunk-Z65B2B77.js → chunk-UM24JFUE.js} +2 -2
  23. package/dist/{chunk-LS2FMPI5.js → chunk-WEDGVC5W.js} +969 -886
  24. package/dist/{composition-_WEwBe2a.d.ts → composition-D4ADF5c-.d.ts} +319 -115
  25. package/dist/composition.d.ts +3 -2
  26. package/dist/composition.js +2 -2
  27. package/dist/convert.d.ts +14 -17
  28. package/dist/convert.js +36 -39
  29. package/dist/data.d.ts +28 -11
  30. package/dist/data.js +3 -3
  31. package/dist/deck.d.ts +77 -0
  32. package/dist/deck.js +12 -0
  33. package/dist/diff.d.ts +1 -1
  34. package/dist/diff.js +7 -7
  35. package/dist/docs.js +33 -33
  36. package/dist/examples.d.ts +1 -1
  37. package/dist/examples.js +51761 -4783
  38. package/dist/{finding-C_por275.d.ts → finding-CT_f_vbD.d.ts} +2 -2
  39. package/dist/format.js +2 -2
  40. package/dist/index.d.ts +227 -77
  41. package/dist/index.js +343 -258
  42. package/dist/json-BFSdESOE.d.ts +19 -0
  43. package/dist/markdown.d.ts +20 -9
  44. package/dist/markdown.js +9 -9
  45. package/dist/{pagination-BZpXLvFL.d.ts → pagination-DzZPFheM.d.ts} +31 -31
  46. package/dist/pagination.d.ts +4 -5
  47. package/dist/pagination.js +6 -6
  48. package/dist/patch.d.ts +1 -1
  49. package/dist/patch.js +6 -6
  50. package/dist/{presentation-C5eHkevA.d.ts → presentation-COrFuj2g.d.ts} +398 -558
  51. package/dist/repo-readme.js +1 -1
  52. package/dist/schemas.d.ts +298 -1
  53. package/dist/schemas.js +1 -1
  54. package/dist/spec/README.md +1 -1
  55. package/dist/spec/catalogs/font-schemes/angsana-new.json +1 -1
  56. package/dist/spec/catalogs/font-schemes/aparajita.json +2 -2
  57. package/dist/spec/catalogs/font-schemes/arabic-typesetting.json +1 -1
  58. package/dist/spec/catalogs/font-schemes/batang.json +1 -1
  59. package/dist/spec/catalogs/font-schemes/daunpenh.json +1 -1
  60. package/dist/spec/catalogs/font-schemes/david.json +1 -1
  61. package/dist/spec/catalogs/font-schemes/dilleniaupc.json +1 -1
  62. package/dist/spec/catalogs/font-schemes/fangsong.json +1 -1
  63. package/dist/spec/catalogs/font-schemes/gautami.json +1 -1
  64. package/dist/spec/catalogs/font-schemes/gisha.json +2 -2
  65. package/dist/spec/catalogs/font-schemes/gungsuh.json +1 -1
  66. package/dist/spec/catalogs/font-schemes/index.json +1 -1
  67. package/dist/spec/catalogs/font-schemes/kalinga.json +1 -1
  68. package/dist/spec/catalogs/font-schemes/kartika.json +1 -1
  69. package/dist/spec/catalogs/font-schemes/khmer-ui.json +1 -1
  70. package/dist/spec/catalogs/font-schemes/latha.json +1 -1
  71. package/dist/spec/catalogs/font-schemes/malgun-gothic.json +1 -1
  72. package/dist/spec/catalogs/font-schemes/mangal.json +3 -3
  73. package/dist/spec/catalogs/font-schemes/meiryo.json +1 -1
  74. package/dist/spec/catalogs/font-schemes/microsoft-jhenghei.json +1 -1
  75. package/dist/spec/catalogs/font-schemes/microsoft-yahei.json +4 -4
  76. package/dist/spec/catalogs/font-schemes/mingliu.json +1 -1
  77. package/dist/spec/catalogs/font-schemes/miriam.json +1 -1
  78. package/dist/spec/catalogs/font-schemes/ms-mincho.json +1 -1
  79. package/dist/spec/catalogs/font-schemes/nirmala-ui.json +1 -1
  80. package/dist/spec/catalogs/font-schemes/noto-naksh-arabic.json +1 -1
  81. package/dist/spec/catalogs/font-schemes/noto-nastaliq-urdu.json +2 -2
  82. package/dist/spec/catalogs/font-schemes/noto-sans-arabic.json +3 -3
  83. package/dist/spec/catalogs/font-schemes/noto-sans-armenian.json +1 -1
  84. package/dist/spec/catalogs/font-schemes/noto-sans-bengali.json +2 -2
  85. package/dist/spec/catalogs/font-schemes/noto-sans-devangari.json +2 -2
  86. package/dist/spec/catalogs/font-schemes/noto-sans-ethiopic.json +1 -1
  87. package/dist/spec/catalogs/font-schemes/noto-sans-georgian.json +1 -1
  88. package/dist/spec/catalogs/font-schemes/noto-sans-gujarati.json +1 -1
  89. package/dist/spec/catalogs/font-schemes/noto-sans-gurmukhi.json +1 -1
  90. package/dist/spec/catalogs/font-schemes/noto-sans-hebrew.json +1 -1
  91. package/dist/spec/catalogs/font-schemes/noto-sans-jp.json +1 -1
  92. package/dist/spec/catalogs/font-schemes/noto-sans-kannada.json +1 -1
  93. package/dist/spec/catalogs/font-schemes/noto-sans-khmer.json +1 -1
  94. package/dist/spec/catalogs/font-schemes/noto-sans-kr.json +1 -1
  95. package/dist/spec/catalogs/font-schemes/noto-sans-malayalam.json +1 -1
  96. package/dist/spec/catalogs/font-schemes/noto-sans-mongolian.json +1 -1
  97. package/dist/spec/catalogs/font-schemes/noto-sans-oriya.json +1 -1
  98. package/dist/spec/catalogs/font-schemes/noto-sans-sc.json +4 -4
  99. package/dist/spec/catalogs/font-schemes/noto-sans-tamil.json +1 -1
  100. package/dist/spec/catalogs/font-schemes/noto-sans-tc.json +1 -1
  101. package/dist/spec/catalogs/font-schemes/noto-sans-telugu.json +1 -1
  102. package/dist/spec/catalogs/font-schemes/noto-sans-thai.json +1 -1
  103. package/dist/spec/catalogs/font-schemes/noto-sans.json +4 -4
  104. package/dist/spec/catalogs/font-schemes/nyala.json +1 -1
  105. package/dist/spec/catalogs/font-schemes/pmingliu.json +1 -1
  106. package/dist/spec/catalogs/font-schemes/raavi.json +1 -1
  107. package/dist/spec/catalogs/font-schemes/sakkal-majalla.json +3 -3
  108. package/dist/spec/catalogs/font-schemes/shonar-bangla.json +2 -2
  109. package/dist/spec/catalogs/font-schemes/shruti.json +1 -1
  110. package/dist/spec/catalogs/font-schemes/simsun.json +1 -1
  111. package/dist/spec/catalogs/font-schemes/sylfaen.json +2 -2
  112. package/dist/spec/catalogs/font-schemes/traditional-arabic.json +3 -3
  113. package/dist/spec/catalogs/font-schemes/tunga.json +1 -1
  114. package/dist/spec/catalogs/font-schemes/vrinda.json +1 -1
  115. package/dist/spec/catalogs/font-schemes/yu-gothic.json +1 -1
  116. package/dist/spec/catalogs/layouts/business-model-canvas.json +66 -1
  117. package/dist/spec/catalogs/layouts/capability-map.json +53 -6
  118. package/dist/spec/catalogs/layouts/chart-1x-title-center.json +30 -0
  119. package/dist/spec/catalogs/layouts/chart-2x-title-center.json +36 -0
  120. package/dist/spec/catalogs/layouts/chart-2x-vertical-title-left.json +37 -0
  121. package/dist/spec/catalogs/layouts/chart-2x.json +32 -8
  122. package/dist/spec/catalogs/layouts/chart-3x-bottom-vertical-title-left.json +52 -0
  123. package/dist/spec/catalogs/layouts/chart-3x-left-title-center.json +51 -0
  124. package/dist/spec/catalogs/layouts/chart-3x-left.json +46 -0
  125. package/dist/spec/catalogs/layouts/chart-3x-right-title-center.json +51 -0
  126. package/dist/spec/catalogs/layouts/chart-3x-right.json +46 -0
  127. package/dist/spec/catalogs/layouts/chart-3x-title-center.json +39 -0
  128. package/dist/spec/catalogs/layouts/chart-3x-top-vertical-title-left.json +52 -0
  129. package/dist/spec/catalogs/layouts/chart-3x.json +48 -12
  130. package/dist/spec/catalogs/layouts/competitive-landscape.json +1 -4
  131. package/dist/spec/catalogs/layouts/customer-journey.json +1 -4
  132. package/dist/spec/catalogs/layouts/dashboard.json +37 -5
  133. package/dist/spec/catalogs/layouts/decision-tree.json +1 -4
  134. package/dist/spec/catalogs/layouts/ecosystem-map.json +1 -4
  135. package/dist/spec/catalogs/layouts/extract/canonical.json +0 -9
  136. package/dist/spec/catalogs/layouts/geographic-map.json +1 -4
  137. package/dist/spec/catalogs/layouts/icon-grid.json +1 -4
  138. package/dist/spec/catalogs/layouts/image-1x-crop-title-center.json +32 -0
  139. package/dist/spec/catalogs/layouts/image-1x-crop-title-left.json +32 -0
  140. package/dist/spec/catalogs/layouts/image-1x-crop.json +27 -0
  141. package/dist/spec/catalogs/layouts/image-1x-fit-title-center.json +32 -0
  142. package/dist/spec/catalogs/layouts/image-1x.json +3 -0
  143. package/dist/spec/catalogs/layouts/image-2x-crop-title-center.json +38 -0
  144. package/dist/spec/catalogs/layouts/image-2x-crop-vertical-title-left.json +39 -0
  145. package/dist/spec/catalogs/layouts/image-2x-crop-vertical.json +34 -0
  146. package/dist/spec/catalogs/layouts/image-2x-crop.json +33 -0
  147. package/dist/spec/catalogs/layouts/image-2x-fit-title-center.json +38 -0
  148. package/dist/spec/catalogs/layouts/image-2x-fit-vertical-title-left.json +39 -0
  149. package/dist/spec/catalogs/layouts/image-2x-fit-vertical.json +34 -0
  150. package/dist/spec/catalogs/layouts/image-2x.json +35 -8
  151. package/dist/spec/catalogs/layouts/image-3x-crop-title-center.json +41 -0
  152. package/dist/spec/catalogs/layouts/image-3x-crop-vertical-title-left.json +42 -0
  153. package/dist/spec/catalogs/layouts/image-3x-crop-vertical.json +37 -0
  154. package/dist/spec/catalogs/layouts/image-3x-crop.json +36 -0
  155. package/dist/spec/catalogs/layouts/image-3x-fit-title-center.json +41 -0
  156. package/dist/spec/catalogs/layouts/image-3x-fit-vertical-title-left.json +42 -0
  157. package/dist/spec/catalogs/layouts/image-3x-fit-vertical.json +37 -0
  158. package/dist/spec/catalogs/layouts/image-3x-fit.json +36 -0
  159. package/dist/spec/catalogs/layouts/image-3x.json +51 -12
  160. package/dist/spec/catalogs/layouts/image-focus.json +3 -6
  161. package/dist/spec/catalogs/layouts/image-only-1x-crop-title-center.json +31 -0
  162. package/dist/spec/catalogs/layouts/image-only-1x-fit-title-center.json +31 -0
  163. package/dist/spec/catalogs/layouts/image-only-2x-crop-title-center.json +37 -0
  164. package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical-title-left.json +38 -0
  165. package/dist/spec/catalogs/layouts/image-only-2x-crop-vertical.json +33 -0
  166. package/dist/spec/catalogs/layouts/image-only-2x-fit-title-center.json +37 -0
  167. package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical-title-left.json +38 -0
  168. package/dist/spec/catalogs/layouts/image-only-2x-fit-vertical.json +33 -0
  169. package/dist/spec/catalogs/layouts/image-only-3x-crop-title-center.json +40 -0
  170. package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical-title-left.json +41 -0
  171. package/dist/spec/catalogs/layouts/image-only-3x-crop-vertical.json +36 -0
  172. package/dist/spec/catalogs/layouts/image-only-3x-crop.json +35 -0
  173. package/dist/spec/catalogs/layouts/image-only-3x-fit-title-center.json +40 -0
  174. package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical-title-left.json +41 -0
  175. package/dist/spec/catalogs/layouts/image-only-3x-fit-vertical.json +36 -0
  176. package/dist/spec/catalogs/layouts/image-only-3x-fit.json +35 -0
  177. package/dist/spec/catalogs/layouts/index.json +1041 -151
  178. package/dist/spec/catalogs/layouts/kpi-scorecard.json +48 -3
  179. package/dist/spec/catalogs/layouts/list-1x-box-title-center.json +32 -0
  180. package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-center.json +33 -0
  181. package/dist/spec/catalogs/layouts/list-1x-box-vertical-title-left.json +33 -0
  182. package/dist/spec/catalogs/layouts/list-1x-box-vertical.json +28 -0
  183. package/dist/spec/catalogs/layouts/list-1x-box.json +27 -0
  184. package/dist/spec/catalogs/layouts/list-1x-itemimage-title-center.json +32 -0
  185. package/dist/spec/catalogs/layouts/list-1x-itemimage-vertical-title-center.json +33 -0
  186. package/dist/spec/catalogs/layouts/list-1x-title-center.json +31 -0
  187. package/dist/spec/catalogs/layouts/list-1x-vertical-title-center.json +32 -0
  188. package/dist/spec/catalogs/layouts/list-2x-box-title-center.json +38 -0
  189. package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-center.json +39 -0
  190. package/dist/spec/catalogs/layouts/list-2x-box-vertical-title-left.json +39 -0
  191. package/dist/spec/catalogs/layouts/list-2x-box-vertical.json +34 -0
  192. package/dist/spec/catalogs/layouts/list-2x-box.json +33 -0
  193. package/dist/spec/catalogs/layouts/list-2x-itemimage-title-center.json +38 -0
  194. package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-center.json +39 -0
  195. package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical-title-left.json +39 -0
  196. package/dist/spec/catalogs/layouts/list-2x-itemimage-vertical.json +34 -0
  197. package/dist/spec/catalogs/layouts/list-2x-title-center.json +37 -0
  198. package/dist/spec/catalogs/layouts/list-2x-vertical-title-center.json +38 -0
  199. package/dist/spec/catalogs/layouts/list-2x-vertical-title-left.json +38 -0
  200. package/dist/spec/catalogs/layouts/list-2x-vertical.json +33 -0
  201. package/dist/spec/catalogs/layouts/list-3x-box-title-center.json +41 -0
  202. package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-center.json +42 -0
  203. package/dist/spec/catalogs/layouts/list-3x-box-vertical-title-left.json +42 -0
  204. package/dist/spec/catalogs/layouts/list-3x-box-vertical.json +37 -0
  205. package/dist/spec/catalogs/layouts/list-3x-box.json +36 -0
  206. package/dist/spec/catalogs/layouts/list-3x-itemimage-title-center.json +41 -0
  207. package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-center.json +42 -0
  208. package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical-title-left.json +42 -0
  209. package/dist/spec/catalogs/layouts/list-3x-itemimage-vertical.json +37 -0
  210. package/dist/spec/catalogs/layouts/list-3x-itemimage.json +36 -0
  211. package/dist/spec/catalogs/layouts/list-3x-title-center.json +40 -0
  212. package/dist/spec/catalogs/layouts/list-3x-vertical-title-center.json +41 -0
  213. package/dist/spec/catalogs/layouts/list-3x-vertical-title-left.json +41 -0
  214. package/dist/spec/catalogs/layouts/list-3x-vertical.json +36 -0
  215. package/dist/spec/catalogs/layouts/list-4x-box-title-center.json +45 -0
  216. package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-center.json +45 -0
  217. package/dist/spec/catalogs/layouts/list-4x-box-vertical-title-left.json +45 -0
  218. package/dist/spec/catalogs/layouts/list-4x-box-vertical.json +40 -0
  219. package/dist/spec/catalogs/layouts/list-4x-box.json +40 -0
  220. package/dist/spec/catalogs/layouts/list-4x-itemimage-title-center.json +45 -0
  221. package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-center.json +45 -0
  222. package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical-title-left.json +45 -0
  223. package/dist/spec/catalogs/layouts/list-4x-itemimage-vertical.json +40 -0
  224. package/dist/spec/catalogs/layouts/list-4x-title-center.json +44 -0
  225. package/dist/spec/catalogs/layouts/list-4x-vertical-title-center.json +44 -0
  226. package/dist/spec/catalogs/layouts/list-4x-vertical-title-left.json +44 -0
  227. package/dist/spec/catalogs/layouts/list-4x-vertical.json +39 -0
  228. package/dist/spec/catalogs/layouts/list-5x-box-title-center.json +48 -0
  229. package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-center.json +50 -0
  230. package/dist/spec/catalogs/layouts/list-5x-box-vertical-title-left.json +50 -0
  231. package/dist/spec/catalogs/layouts/list-5x-box-vertical.json +45 -0
  232. package/dist/spec/catalogs/layouts/list-5x-box.json +43 -0
  233. package/dist/spec/catalogs/layouts/list-5x-itemimage-title-center.json +48 -0
  234. package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-center.json +48 -0
  235. package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical-title-left.json +48 -0
  236. package/dist/spec/catalogs/layouts/list-5x-itemimage-vertical.json +43 -0
  237. package/dist/spec/catalogs/layouts/list-5x-title-center.json +47 -0
  238. package/dist/spec/catalogs/layouts/list-5x-vertical-title-center.json +47 -0
  239. package/dist/spec/catalogs/layouts/list-5x-vertical-title-left.json +47 -0
  240. package/dist/spec/catalogs/layouts/list-5x-vertical.json +42 -0
  241. package/dist/spec/catalogs/layouts/list-6x-box-title-center.json +51 -0
  242. package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-center.json +53 -0
  243. package/dist/spec/catalogs/layouts/list-6x-box-vertical-title-left.json +53 -0
  244. package/dist/spec/catalogs/layouts/list-6x-box-vertical.json +48 -0
  245. package/dist/spec/catalogs/layouts/list-6x-box.json +46 -0
  246. package/dist/spec/catalogs/layouts/list-6x-itemimage-title-center.json +51 -0
  247. package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-center.json +51 -0
  248. package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical-title-left.json +51 -0
  249. package/dist/spec/catalogs/layouts/list-6x-itemimage-vertical.json +46 -0
  250. package/dist/spec/catalogs/layouts/list-6x-title-center.json +50 -0
  251. package/dist/spec/catalogs/layouts/list-6x-vertical-title-center.json +50 -0
  252. package/dist/spec/catalogs/layouts/list-6x-vertical-title-left.json +50 -0
  253. package/dist/spec/catalogs/layouts/list-6x-vertical.json +45 -0
  254. package/dist/spec/catalogs/layouts/logic-tree.json +69 -0
  255. package/dist/spec/catalogs/layouts/market-size.json +26 -2
  256. package/dist/spec/catalogs/layouts/network-dependency-map.json +1 -4
  257. package/dist/spec/catalogs/layouts/number-1x-box-title-center.json +30 -0
  258. package/dist/spec/catalogs/layouts/number-1x-box.json +25 -0
  259. package/dist/spec/catalogs/layouts/number-1x-title-center.json +29 -0
  260. package/dist/spec/catalogs/layouts/number-2x-box-title-center.json +36 -0
  261. package/dist/spec/catalogs/layouts/number-2x-box.json +31 -0
  262. package/dist/spec/catalogs/layouts/number-2x-title-center.json +35 -0
  263. package/dist/spec/catalogs/layouts/number-3x-box-title-center.json +39 -0
  264. package/dist/spec/catalogs/layouts/number-3x-box.json +34 -0
  265. package/dist/spec/catalogs/layouts/number-3x-title-center.json +38 -0
  266. package/dist/spec/catalogs/layouts/number-4x-box-title-center.json +43 -0
  267. package/dist/spec/catalogs/layouts/number-4x-box.json +38 -0
  268. package/dist/spec/catalogs/layouts/number-4x-title-center.json +42 -0
  269. package/dist/spec/catalogs/layouts/number-5x-box-title-center.json +46 -0
  270. package/dist/spec/catalogs/layouts/number-5x-box.json +41 -0
  271. package/dist/spec/catalogs/layouts/number-5x-title-center.json +45 -0
  272. package/dist/spec/catalogs/layouts/number-6x-box-title-center.json +49 -0
  273. package/dist/spec/catalogs/layouts/number-6x-box.json +44 -0
  274. package/dist/spec/catalogs/layouts/number-6x-title-center.json +48 -0
  275. package/dist/spec/catalogs/layouts/org-chart.json +53 -6
  276. package/dist/spec/catalogs/layouts/persona-grid.json +1 -4
  277. package/dist/spec/catalogs/layouts/photo-grid.json +1 -4
  278. package/dist/spec/catalogs/layouts/product-feature.json +1 -4
  279. package/dist/spec/catalogs/layouts/screenshot-walkthrough.json +1 -4
  280. package/dist/spec/catalogs/layouts/swimlane-process.json +1 -4
  281. package/dist/spec/catalogs/layouts/team-bio.json +1 -4
  282. package/dist/spec/catalogs/layouts/text-1x-box-title-center.json +31 -0
  283. package/dist/spec/catalogs/layouts/text-1x-box-title-left.json +31 -0
  284. package/dist/spec/catalogs/layouts/text-1x-center-box-title-center.json +31 -0
  285. package/dist/spec/catalogs/layouts/text-1x-center-box-title-left.json +31 -0
  286. package/dist/spec/catalogs/layouts/text-1x-center-box.json +26 -0
  287. package/dist/spec/catalogs/layouts/text-1x-center-title-center.json +30 -0
  288. package/dist/spec/catalogs/layouts/text-1x-center-title-left.json +30 -0
  289. package/dist/spec/catalogs/layouts/text-1x-center.json +25 -0
  290. package/dist/spec/catalogs/layouts/text-1x-left-box.json +26 -0
  291. package/dist/spec/catalogs/layouts/text-1x-title-center.json +30 -0
  292. package/dist/spec/catalogs/layouts/text-2x-box-title-center.json +37 -0
  293. package/dist/spec/catalogs/layouts/text-2x-box-vertical-title-left.json +37 -0
  294. package/dist/spec/catalogs/layouts/text-2x-center-box-title-center.json +37 -0
  295. package/dist/spec/catalogs/layouts/text-2x-center-box-vertical-title-left.json +37 -0
  296. package/dist/spec/catalogs/layouts/text-2x-center-box.json +32 -0
  297. package/dist/spec/catalogs/layouts/text-2x-center-title-center.json +36 -0
  298. package/dist/spec/catalogs/layouts/text-2x-center-vertical-title-left.json +36 -0
  299. package/dist/spec/catalogs/layouts/text-2x-center.json +31 -0
  300. package/dist/spec/catalogs/layouts/text-2x-left-box.json +32 -0
  301. package/dist/spec/catalogs/layouts/text-2x-title-center.json +36 -0
  302. package/dist/spec/catalogs/layouts/text-2x-vertical-title-left.json +36 -0
  303. package/dist/spec/catalogs/layouts/text-3x-box-title-center.json +40 -0
  304. package/dist/spec/catalogs/layouts/text-3x-box-vertical-title-left.json +41 -0
  305. package/dist/spec/catalogs/layouts/text-3x-center-box-title-center.json +40 -0
  306. package/dist/spec/catalogs/layouts/text-3x-center-box-vertical-title-left.json +41 -0
  307. package/dist/spec/catalogs/layouts/text-3x-center-box.json +35 -0
  308. package/dist/spec/catalogs/layouts/text-3x-center-title-center.json +39 -0
  309. package/dist/spec/catalogs/layouts/text-3x-center-vertical-title-left.json +40 -0
  310. package/dist/spec/catalogs/layouts/text-3x-center.json +34 -0
  311. package/dist/spec/catalogs/layouts/text-3x-left-box.json +35 -0
  312. package/dist/spec/catalogs/layouts/text-3x-left.json +34 -0
  313. package/dist/spec/catalogs/layouts/text-3x-title-center.json +39 -0
  314. package/dist/spec/catalogs/layouts/text-3x-vertical-title-left.json +40 -0
  315. package/dist/spec/catalogs/layouts/title-center-box.json +27 -0
  316. package/dist/spec/catalogs/layouts/title-center-image-bottom.json +34 -0
  317. package/dist/spec/catalogs/layouts/title-center-image-top.json +34 -0
  318. package/dist/spec/catalogs/layouts/title-center.json +26 -0
  319. package/dist/spec/catalogs/layouts/title-left-image-bottom.json +34 -0
  320. package/dist/spec/catalogs/layouts/title-left-image-left.json +34 -0
  321. package/dist/spec/catalogs/layouts/title-left-image-right.json +34 -0
  322. package/dist/spec/catalogs/layouts/title-left-image-top.json +34 -0
  323. package/dist/spec/catalogs/manifest.json +18 -18
  324. package/dist/spec/catalogs/narratives/heros-journey.json +1 -1
  325. package/dist/spec/catalogs/narratives/index.json +1 -1
  326. package/dist/spec/openapi.yaml +3 -3
  327. package/dist/spec/reference/engine-defaults.json +22 -30
  328. package/dist/spec/reference/engine-vocabularies.json +1577 -0
  329. package/dist/spec/schemas/audience.schema.json +5 -26
  330. package/dist/spec/schemas/catalog-manifest.schema.json +3 -3
  331. package/dist/spec/schemas/chart-type.schema.json +2 -35
  332. package/dist/spec/schemas/color-scheme.schema.json +3 -24
  333. package/dist/spec/schemas/finding.schema.json +1 -1
  334. package/dist/spec/schemas/font-scheme.schema.json +6 -37
  335. package/dist/spec/schemas/language.schema.json +7 -28
  336. package/dist/spec/schemas/layout.schema.json +227 -55
  337. package/dist/spec/schemas/narrative.schema.json +4 -24
  338. package/dist/spec/schemas/opf.schema.json +410 -374
  339. package/dist/spec/schemas/purpose.schema.json +5 -26
  340. package/dist/spec/schemas/social-platform.schema.json +2 -23
  341. package/dist/spec/schemas/theme.schema.json +9 -37
  342. package/dist/spec/schemas/tone.schema.json +4 -25
  343. package/dist/spec-files.d.ts +1 -1
  344. package/dist/spec-files.js +1 -1
  345. package/dist/types.d.ts +1103 -4
  346. package/dist/{validation-types-zh03LeZy.d.ts → validation-types-HxIgJfKx.d.ts} +7 -7
  347. package/dist/validator.d.ts +15 -12
  348. package/dist/validator.js +5 -5
  349. package/dist/yaml.d.ts +22 -7
  350. package/dist/yaml.js +9 -321
  351. package/package.json +9 -9
  352. package/dist/catalogs-D-yyQWCQ.d.ts +0 -1343
  353. package/dist/catalogs.d.ts +0 -2
  354. package/dist/catalogs.js +0 -2
  355. package/dist/chunk-PIQXLBBJ.js +0 -445
  356. package/dist/chunk-S5W34SIJ.js +0 -1
  357. package/dist/previews.d.ts +0 -40
  358. package/dist/previews.js +0 -1
  359. package/dist/schemas-DDpqAgyS.d.ts +0 -284
  360. package/dist/spec/catalogs/layouts/image-bleed.json +0 -20
@@ -1,4 +1,4 @@
1
- import { catalogs } from './chunk-XOZ4KMSR.js';
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 : {};
@@ -245,7 +245,6 @@ function isRecord(value) {
245
245
  function pathFor(parentPath, key) {
246
246
  return parentPath === "/" ? `/${key}` : `${parentPath}/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`;
247
247
  }
248
- var bareIdPattern = /^[a-z0-9][a-z0-9-]*$/;
249
248
  var promotedRegionKeys = [
250
249
  "left",
251
250
  "center",
@@ -1718,7 +1717,7 @@ function intrinsicImageAspect(value, assets) {
1718
1717
  }
1719
1718
 
1720
1719
  // src/design-hints.ts
1721
- var DESIGN_HINT_KEYS = ["titleAlignment", "contentAlignment", "contentBox", "contentDirection", "chartPrimary", "imageFill", "listBullet"];
1720
+ var DESIGN_HINT_KEYS = ["titleAlignment", "contentAlignment", "contentBox", "contentDirection", "chartPrimary", "imageFit", "listBullet"];
1722
1721
  var ALIGNMENTS = ["left", "center", "right"];
1723
1722
  var VALUES = {
1724
1723
  titleAlignment: ALIGNMENTS,
@@ -1726,7 +1725,7 @@ var VALUES = {
1726
1725
  contentBox: "boolean",
1727
1726
  contentDirection: ["horizontal", "vertical"],
1728
1727
  chartPrimary: ["none", "top", "bottom", "left", "right"],
1729
- imageFill: ["crop", "fit"],
1728
+ imageFit: ["cover", "contain", "stretch"],
1730
1729
  listBullet: ["character", "image"]
1731
1730
  };
1732
1731
  var accepts = (key, value) => VALUES[key] === "boolean" ? typeof value === "boolean" : VALUES[key].includes(value);
@@ -1772,6 +1771,75 @@ function readingRows(items) {
1772
1771
  return rows3.map((row) => row.items.sort((a, b) => index.get(a) - index.get(b)));
1773
1772
  }
1774
1773
 
1774
+ // src/layout-content.ts
1775
+ var LAYOUT_BODY_KINDS = ["text", "list", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
1776
+ var MAX_PLACEHOLDER_GROUP_DEPTH = 3;
1777
+ var bodyKinds = new Set(LAYOUT_BODY_KINDS);
1778
+ var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
1779
+ function isPlaceholderGroup(placeholder) {
1780
+ return record4(placeholder).type === "group";
1781
+ }
1782
+ function layoutSlots(layout, base = "layout.placeholders") {
1783
+ const walk2 = (entries, path, depth) => (Array.isArray(entries) ? entries : []).map((entry, index) => {
1784
+ const placeholder = record4(entry), slotPath = `${path}.${index}`;
1785
+ const type = typeof placeholder.type === "string" ? placeholder.type : "";
1786
+ if (type !== "group") {
1787
+ if (depth > 0 && !bodyKinds.has(type)) throw new RangeError(`${slotPath}: a placeholder group holds body regions only, not '${type}'.`);
1788
+ return { type, path: slotPath, depth, placeholder };
1789
+ }
1790
+ if (depth >= MAX_PLACEHOLDER_GROUP_DEPTH) throw new RangeError(`${slotPath}: placeholder groups nest at most ${MAX_PLACEHOLDER_GROUP_DEPTH} levels inside a layout record.`);
1791
+ if (!Array.isArray(placeholder.placeholders) || !placeholder.placeholders.length) throw new RangeError(`${slotPath}: a placeholder group needs at least one placeholder.`);
1792
+ return { type, path: slotPath, depth, placeholder, children: walk2(placeholder.placeholders, `${slotPath}.placeholders`, depth + 1) };
1793
+ });
1794
+ return walk2(layout?.placeholders, base, 0);
1795
+ }
1796
+ function layoutLeaves(layout) {
1797
+ const leaves = [];
1798
+ const visit = (slots) => {
1799
+ for (const slot of slots) slot.children ? visit(slot.children) : leaves.push({ type: slot.type, path: slot.path, depth: slot.depth, placeholder: slot.placeholder });
1800
+ };
1801
+ visit(layoutSlots(layout));
1802
+ return leaves;
1803
+ }
1804
+ function layoutStructure(layout) {
1805
+ const describe = (slots) => slots.map((slot) => {
1806
+ if (!slot.children) return slot.type;
1807
+ const mode = record4(slot.placeholder.composition).mode;
1808
+ return `${typeof mode === "string" && mode !== "auto" ? mode : "group"} (${describe(slot.children)})`;
1809
+ }).join(", ");
1810
+ return describe(layoutSlots(layout));
1811
+ }
1812
+ function hasPlaceholderGroups(layout) {
1813
+ return Array.isArray(layout?.placeholders) && layout.placeholders.some(isPlaceholderGroup);
1814
+ }
1815
+ function layoutContent(layout) {
1816
+ const heading = { title: false, subtitle: false, tag: false };
1817
+ const counts = /* @__PURE__ */ new Map();
1818
+ let count = 0;
1819
+ const visit = (entries, depth) => {
1820
+ for (const entry of Array.isArray(entries) ? entries : []) {
1821
+ const type = record4(entry).type;
1822
+ if (type === "group") {
1823
+ if (depth < MAX_PLACEHOLDER_GROUP_DEPTH) visit(record4(entry).placeholders, depth + 1);
1824
+ continue;
1825
+ }
1826
+ if (type === "title" || type === "subtitle" || type === "tag") {
1827
+ if (depth === 0) heading[type] = true;
1828
+ } else if (typeof type === "string" && bodyKinds.has(type)) {
1829
+ counts.set(type, (counts.get(type) ?? 0) + 1);
1830
+ count += 1;
1831
+ }
1832
+ }
1833
+ };
1834
+ visit(layout?.placeholders, 0);
1835
+ let kind2 = "title", best = 0;
1836
+ for (const [candidate, total] of counts) if (total > best) {
1837
+ kind2 = candidate;
1838
+ best = total;
1839
+ }
1840
+ return { kind: kind2, count, heading };
1841
+ }
1842
+
1775
1843
  // src/direction.ts
1776
1844
  var strongRtl = /[\u200F\u061C]|(?=\p{L})[\p{Script=Arabic}\p{Script=Hebrew}\p{Script=Syriac}\p{Script=Thaana}\p{Script=Nko}\p{Script=Adlam}\p{Script=Hanifi_Rohingya}\p{Script=Mandaic}\p{Script=Samaritan}\p{Script=Mende_Kikakui}\p{Script=Imperial_Aramaic}\p{Script=Phoenician}\p{Script=Kharoshthi}\p{Script=Old_South_Arabian}\p{Script=Old_North_Arabian}\p{Script=Avestan}\p{Script=Inscriptional_Parthian}\p{Script=Inscriptional_Pahlavi}\p{Script=Psalter_Pahlavi}\p{Script=Old_Turkic}\p{Script=Old_Hungarian}\p{Script=Nabataean}\p{Script=Palmyrene}\p{Script=Hatran}\p{Script=Manichaean}\p{Script=Sogdian}\p{Script=Old_Sogdian}\p{Script=Elymaic}\p{Script=Chorasmian}\p{Script=Yezidi}\p{Script=Cypriot}\p{Script=Lydian}\p{Script=Meroitic_Cursive}\p{Script=Meroitic_Hieroglyphs}\u{10F70}-\u{10FAF}\u{10D40}-\u{10D8F}]/u;
1777
1845
  var strongLtr = /[\u200E\p{L}\p{Nl}]/u;
@@ -1812,6 +1880,99 @@ function paragraphDirectionAt(text2, deckDirection) {
1812
1880
  };
1813
1881
  }
1814
1882
 
1883
+ // src/generated/engine-data.ts
1884
+ var engineDefaultsSource = {
1885
+ "theme": {
1886
+ "background": {
1887
+ "type": "theme",
1888
+ "slot": "dark2"
1889
+ },
1890
+ "dimensions": "widescreen"
1891
+ },
1892
+ "colorScheme": {
1893
+ "accent1": "#2874A6",
1894
+ "accent2": "#1B4F72",
1895
+ "accent3": "#5499C7",
1896
+ "accent4": "#7BDBB2",
1897
+ "accent5": "#3AC67A",
1898
+ "accent6": "#24A89E",
1899
+ "dark1": "#000000",
1900
+ "dark2": "#011842",
1901
+ "light1": "#FFFFFF",
1902
+ "light2": "#F0F0F0",
1903
+ "hyperlink": "#0000EE",
1904
+ "followedHyperlink": "#551A8B"
1905
+ },
1906
+ "fontScheme": {
1907
+ "major": "Aptos Display",
1908
+ "minor": "Aptos",
1909
+ "languageFamily": "latin"
1910
+ },
1911
+ "chartTypes": [
1912
+ "stacked-column",
1913
+ "stacked-area",
1914
+ "line-with-markers"
1915
+ ]
1916
+ };
1917
+ 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" } } }] };
1918
+
1919
+ // src/engine-vocabularies.ts
1920
+ var ENGINE_DEFAULT_THEME = engineDefaultsSource.theme;
1921
+ var ENGINE_DEFAULT_COLOR_SCHEME = engineDefaultsSource.colorScheme;
1922
+ var ENGINE_DEFAULT_FONT_SCHEME = engineDefaultsSource.fontScheme;
1923
+ var ENGINE_DEFAULT_CHART_TYPES = engineDefaultsSource.chartTypes;
1924
+ var CHART_TYPES = engineVocabulariesSource.chartTypes;
1925
+ var SOCIAL_PLATFORMS = engineVocabulariesSource.socialPlatforms;
1926
+ var LANGUAGES = engineVocabulariesSource.languages;
1927
+
1928
+ // src/design-records.ts
1929
+ var isRec = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1930
+ var rec = (value) => isRec(value) ? value : {};
1931
+ function resolveRecordReference(document, kind2, reference, path, fallback, options, diagnostics) {
1932
+ const object2 = isRec(reference) ? reference : void 0;
1933
+ const id = typeof reference === "string" ? reference : typeof object2?.id === "string" ? object2.id : void 0;
1934
+ if (id === void 0) return { record: { ...fallback, ...object2 } };
1935
+ const found = resolveReference(document, kind2, id, options);
1936
+ if (!found) diagnostics.push(unresolvedReference(document, kind2, id, object2 ? `${path}.id` : path, options));
1937
+ return { record: { ...found ? found.record : fallback, ...object2 }, ...found ? { provenance: provenanceOf(found) } : {} };
1938
+ }
1939
+ function resolveDesignRecords(document, slideIndex, options = {}) {
1940
+ checkCatalogsOption(options.catalogs, "resolveDesignRecords");
1941
+ const deck = rec(document);
1942
+ const slides = Array.isArray(deck.slides) ? deck.slides : [];
1943
+ const own2 = slideIndex === void 0 ? {} : rec(rec(slides[slideIndex]).design);
1944
+ const shared = rec(deck.design);
1945
+ const design = { ...shared, ...own2 };
1946
+ const slidePath = `slides.${slideIndex}.design`;
1947
+ const diagnostics = [];
1948
+ const themePath = own2.theme !== void 0 ? `${slidePath}.theme` : "design.theme";
1949
+ const themeFound = typeof design.theme === "string" ? resolveReference(document, "themes", design.theme, options) : void 0;
1950
+ if (typeof design.theme === "string" && !themeFound) diagnostics.push(unresolvedReference(document, "themes", design.theme, themePath, options));
1951
+ const theme = themeFound ? { ...themeFound.record } : { ...ENGINE_DEFAULT_THEME };
1952
+ const inTheme = { ...options, ...themeFound ? { group: themeFound.group } : {} };
1953
+ const inThemePath = (key) => themeFound?.origin === "document" ? `catalogs.${themeFound.group}.themes.${themeFound.id}.${key}` : themePath;
1954
+ const colorFromDesign = design.colorScheme !== void 0;
1955
+ const colorSchemePath = own2.colorScheme !== void 0 ? `${slidePath}.colorScheme` : shared.colorScheme !== void 0 ? "design.colorScheme" : inThemePath("colorScheme");
1956
+ const color = resolveRecordReference(document, "colorSchemes", colorFromDesign ? design.colorScheme : theme.colorScheme, colorFromDesign ? colorSchemePath : inThemePath("colorScheme"), ENGINE_DEFAULT_COLOR_SCHEME, colorFromDesign ? options : inTheme, diagnostics);
1957
+ const fontFromDesign = design.fontScheme !== void 0;
1958
+ const fontSchemePath = own2.fontScheme !== void 0 ? `${slidePath}.fontScheme` : shared.fontScheme !== void 0 ? "design.fontScheme" : inThemePath("fontScheme");
1959
+ const font = resolveRecordReference(document, "fontSchemes", fontFromDesign ? design.fontScheme : theme.fontScheme, fontSchemePath, ENGINE_DEFAULT_FONT_SCHEME, fontFromDesign ? options : inTheme, diagnostics);
1960
+ const fontReference = fontFromDesign ? design.fontScheme : theme.fontScheme;
1961
+ const fontSchemeReference = typeof fontReference === "string" ? fontReference : isRec(fontReference) && typeof fontReference.id === "string" ? fontReference.id : void 0;
1962
+ const provenance = {
1963
+ ...themeFound ? { theme: provenanceOf(themeFound) } : {},
1964
+ ...color.provenance ? { colorScheme: color.provenance } : {},
1965
+ ...font.provenance ? { fontScheme: font.provenance } : {}
1966
+ };
1967
+ return { theme, colorScheme: color.record, fontScheme: font.record, themePath, colorSchemePath, fontSchemePath, ...fontSchemeReference !== void 0 ? { fontSchemeReference } : {}, provenance, diagnostics };
1968
+ }
1969
+ function resolveFontScheme(document, reference, path, options = {}) {
1970
+ checkCatalogsOption(options.catalogs, "resolveFontScheme");
1971
+ const diagnostics = [];
1972
+ const { record: scheme } = resolveRecordReference(document, "fontSchemes", reference, path, ENGINE_DEFAULT_FONT_SCHEME, options, diagnostics);
1973
+ return { scheme, diagnostics };
1974
+ }
1975
+
1815
1976
  // src/script-fonts.ts
1816
1977
  function normalizeLanguageFamily(value) {
1817
1978
  if (value === "latin") return "latin";
@@ -1868,7 +2029,6 @@ var likelyScripts = {
1868
2029
  mn: { script: "Cyrl", regions: { CN: "Mong" } },
1869
2030
  ms: { script: "Latn" }
1870
2031
  };
1871
- var bareLanguageId = /^[a-z][a-z0-9-]*$/;
1872
2032
  function scriptFontRole(script) {
1873
2033
  const code = normalizeScript(script);
1874
2034
  if (code && eastAsianScripts.has(code)) return "eastAsian";
@@ -1927,56 +2087,36 @@ function inferScript(tag) {
1927
2087
  return void 0;
1928
2088
  }
1929
2089
  }
1930
- function inlineRecords(document, kind2) {
1931
- const kinds = isRecord(document.catalogs) ? document.catalogs : {};
1932
- const entry = kinds[kind2];
1933
- return isRecord(entry) && Array.isArray(entry.records) ? entry.records.filter(isRecord) : [];
1934
- }
1935
- function allRecords(document, kind2) {
1936
- return [...inlineRecords(document, kind2), ...catalogs[kind2]];
1937
- }
1938
- function resolveReference(lookup, kind2, reference) {
1939
- if (typeof reference === "string") return lookup(kind2, reference);
1940
- if (!isRecord(reference)) return void 0;
1941
- const base = typeof reference.id === "string" ? lookup(kind2, reference.id) : void 0;
1942
- return { ...base, ...reference };
1943
- }
1944
- function matchLanguageTag(document, tag) {
2090
+ function matchLanguageTag(tag) {
1945
2091
  const wanted = splitTag(tag);
1946
2092
  if (!wanted) return void 0;
1947
- const records = allRecords(document, "languages").filter((record6) => typeof record6.bcp47 === "string");
1948
2093
  const key = canonicalTag(tag).toLowerCase();
1949
- const exact = records.find((record6) => canonicalTag(record6.bcp47).toLowerCase() === key);
2094
+ const exact = LANGUAGES.find((entry) => canonicalTag(entry.tag).toLowerCase() === key);
1950
2095
  if (exact) return exact;
1951
2096
  const language = matchingLanguages[wanted.language] ?? wanted.language;
1952
2097
  const script = wanted.script ?? vendoredScript(language, wanted.region);
1953
- const candidates = records.flatMap((record6) => {
1954
- const parts = splitTag(record6.bcp47);
2098
+ const candidates = LANGUAGES.flatMap((entry) => {
2099
+ const parts = splitTag(entry.tag);
1955
2100
  if (!parts || (matchingLanguages[parts.language] ?? parts.language) !== language) return [];
1956
- const recordScript = normalizeScript(record6.script) ?? parts.script ?? vendoredScript(language, parts.region);
1957
- if (script && recordScript && script !== recordScript) return [];
1958
- return [{ record: record6, region: parts.region }];
2101
+ const entryScript = normalizeScript(entry.script) ?? parts.script ?? vendoredScript(language, parts.region);
2102
+ if (script && entryScript && script !== entryScript) return [];
2103
+ return [{ entry, region: parts.region }];
1959
2104
  });
1960
- return candidates.find((candidate) => wanted.region && candidate.region === wanted.region)?.record ?? candidates.find((candidate) => !candidate.region)?.record ?? candidates[0]?.record;
2105
+ return candidates.find((candidate) => wanted.region && candidate.region === wanted.region)?.entry ?? candidates.find((candidate) => !candidate.region)?.entry ?? candidates[0]?.entry;
1961
2106
  }
1962
- function resolveLanguage(document, lookup, reference) {
2107
+ function resolveLanguage(reference) {
1963
2108
  if (typeof reference === "string") {
1964
2109
  const value = reference.trim();
1965
- const byId = bareLanguageId.test(value) ? lookup("languages", value) : void 0;
1966
- if (byId) return { record: byId, languageId: value };
1967
- if (/^[a-z][a-z0-9+.-]*:/i.test(value) || !splitTag(value)) return void 0;
1968
- const matched = matchLanguageTag(document, value);
1969
- if (matched) return { record: matched, authoredTag: value, languageId: text(matched.id) };
1970
- return inferScript(value) ? { record: {}, authoredTag: value } : void 0;
2110
+ if (!splitTag(value)) return void 0;
2111
+ const known2 = matchLanguageTag(value);
2112
+ if (!known2 && !inferScript(value)) return void 0;
2113
+ return { tag: value, ...known2 ? { known: known2 } : {}, overrides: {} };
1971
2114
  }
1972
2115
  if (!isRecord(reference)) return void 0;
1973
- const authoredTag = text(reference.bcp47);
1974
- if (authoredTag !== void 0 && !splitTag(authoredTag)) return void 0;
1975
- const base = typeof reference.id === "string" ? lookup("languages", reference.id) : authoredTag ? matchLanguageTag(document, authoredTag) : void 0;
1976
- const record6 = { ...base, ...reference };
1977
- const tag = text(record6.bcp47);
2116
+ const tag = text(reference.bcp47);
1978
2117
  if (!tag || !splitTag(tag)) return void 0;
1979
- return { record: record6, authoredTag, authoredOoxmlLang: text(reference.ooxmlLang), languageId: text(base?.id) };
2118
+ const known = matchLanguageTag(tag);
2119
+ return { tag, ...known ? { known } : {}, overrides: reference };
1980
2120
  }
1981
2121
  function pairFamilies(value) {
1982
2122
  if (!isRecord(value)) return void 0;
@@ -1986,48 +2126,51 @@ function pairFamilies(value) {
1986
2126
  const body = minor ?? major;
1987
2127
  return heading && body ? { heading, body } : void 0;
1988
2128
  }
1989
- function schemeServesLanguage(scheme, language) {
2129
+ function schemeServesLanguage(scheme, tag, script) {
1990
2130
  const entries = Array.isArray(scheme.languages) ? scheme.languages.filter((entry) => typeof entry === "string") : [];
1991
2131
  if (entries.length === 0) return true;
1992
- const id = text(language.id);
1993
- return id !== void 0 && entries.includes(id);
2132
+ const wanted = splitTag(tag);
2133
+ if (!wanted) return false;
2134
+ const language = matchingLanguages[wanted.language] ?? wanted.language;
2135
+ return entries.some((entry) => {
2136
+ const parts = splitTag(entry);
2137
+ if (!parts || (matchingLanguages[parts.language] ?? parts.language) !== language) return false;
2138
+ const entryScript = parts.script ?? vendoredScript(language, parts.region);
2139
+ return !entryScript || entryScript === script;
2140
+ });
1994
2141
  }
1995
2142
  function resolveScriptFonts(input, options = {}) {
1996
2143
  const document = isRecord(input) ? input : {};
1997
- const lookup = (kind2, id) => inlineRecords(document, kind2).find((record7) => record7.id === id) ?? catalogs[kind2].find((record7) => record7.id === id);
1998
- let design = isRecord(document.design) ? document.design : {};
1999
2144
  if (options.slideIndex !== void 0) {
2000
2145
  const slides = Array.isArray(document.slides) ? document.slides : [];
2001
2146
  if (!Number.isInteger(options.slideIndex) || options.slideIndex < 0 || options.slideIndex >= slides.length) {
2002
2147
  throw new RangeError(`slideIndex must be an integer between 0 and ${slides.length - 1}.`);
2003
2148
  }
2004
- const slide = slides[options.slideIndex];
2005
- if (isRecord(slide) && isRecord(slide.design)) design = { ...design, ...slide.design };
2006
2149
  }
2007
- const theme = resolveReference(lookup, "themes", design.theme ?? "minimal") ?? {};
2008
- const scheme = resolveFontSchemeReference(design.fontScheme ?? theme.fontScheme ?? DEFAULT_FONT_SCHEME, (id) => lookup("fontSchemes", id)).scheme;
2150
+ const catalogs = { catalogs: checkCatalogsOption(options.catalogs, "resolveScriptFonts") };
2151
+ const scheme = resolveDesignRecords(document, options.slideIndex, catalogs).fontScheme;
2009
2152
  const latin = resolveFontFamilies(scheme);
2010
- const fromOption = options.language !== void 0 ? resolveLanguage(document, lookup, options.language) : void 0;
2011
- const fromDocument = fromOption ? void 0 : resolveLanguage(document, lookup, document.language);
2153
+ const fromOption = options.language !== void 0 ? resolveLanguage(options.language) : void 0;
2154
+ const fromDocument = fromOption ? void 0 : resolveLanguage(document.language);
2012
2155
  const requestedDefault = text(options.defaultLanguage);
2013
2156
  const fallbackTag = requestedDefault && splitTag(requestedDefault) ? requestedDefault : "en-US";
2014
- const language = fromOption ?? fromDocument ?? resolveLanguage(document, lookup, fallbackTag) ?? { record: {}, authoredTag: fallbackTag };
2157
+ const language = fromOption ?? fromDocument ?? resolveLanguage(fallbackTag) ?? { tag: fallbackTag, overrides: {} };
2015
2158
  const languageSource = fromOption ? "option" : fromDocument ? "document" : "default";
2016
- const record6 = language.record;
2017
- const bcp47 = canonicalTag(language.authoredTag ?? text(record6.bcp47) ?? fallbackTag);
2018
- const curated = text(record6.ooxmlLang);
2019
- const lang = language.authoredOoxmlLang ? canonicalTag(language.authoredOoxmlLang) : language.authoredTag && splitTag(language.authoredTag)?.region ? canonicalTag(language.authoredTag) : curated ? canonicalTag(curated) : bcp47;
2159
+ const overrides = language.overrides;
2160
+ const known = language.known;
2161
+ const bcp47 = canonicalTag(language.tag);
2162
+ const authoredOoxml = text(overrides.ooxmlLang);
2163
+ const lang = authoredOoxml ? canonicalTag(authoredOoxml) : splitTag(language.tag)?.region ? bcp47 : known ? canonicalTag(known.ooxmlLang) : bcp47;
2020
2164
  const parts = splitTag(bcp47);
2021
- const script = normalizeScript(record6.script) ?? (language.languageId ? parts?.script ?? (parts ? vendoredScript(matchingLanguages[parts.language] ?? parts.language, parts.region) : void 0) ?? normalizeScript(matchLanguageTag({}, bcp47)?.script) : inferScript(bcp47)) ?? "Zzzz";
2165
+ 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";
2022
2166
  const scriptRole = scriptFontRole(script);
2023
- const declaredDirection = record6.direction;
2167
+ const declaredDirection = overrides.direction ?? known?.direction;
2024
2168
  const direction = declaredDirection === "rtl" || declaredDirection === "ltr" ? declaredDirection : rtlScripts.has(script) ? "rtl" : "ltr";
2025
2169
  const app = options.app ?? "powerpoint";
2026
- const preferred = app === "google-slides" ? record6.googleFontScheme : record6.fontScheme;
2027
- const alternate = app === "google-slides" ? record6.fontScheme : record6.googleFontScheme;
2028
- const languageScheme = resolveReference(lookup, "fontSchemes", preferred) ?? resolveReference(lookup, "fontSchemes", alternate);
2170
+ const named = (key) => typeof overrides[key] === "string" ? resolveReference(document, "fontSchemes", overrides[key], catalogs)?.record : void 0;
2171
+ const languageScheme = app === "google-slides" ? named("googleFontScheme") ?? known?.fonts.google ?? named("fontScheme") : named("fontScheme") ?? known?.fonts.powerpoint ?? named("googleFontScheme");
2029
2172
  const languageFamilies = pairFamilies(languageScheme);
2030
- const schemeAdmitsLanguage = schemeServesLanguage(scheme, record6);
2173
+ const schemeAdmitsLanguage = schemeServesLanguage(scheme, bcp47, script);
2031
2174
  const slot = (role, family) => {
2032
2175
  const explicit = pairFamilies(scheme[role]);
2033
2176
  if (explicit) return { ...explicit, source: "fontScheme" };
@@ -2049,7 +2192,6 @@ function resolveScriptFonts(input, options = {}) {
2049
2192
  ...body,
2050
2193
  lang,
2051
2194
  bcp47,
2052
- ...language.languageId ? { languageId: language.languageId } : {},
2053
2195
  languageSource,
2054
2196
  script,
2055
2197
  scriptRole,
@@ -2539,7 +2681,7 @@ var set = (words) => new Set((words ?? "").split(/\s+/).filter(Boolean));
2539
2681
  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";
2540
2682
  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 };
2541
2683
  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";
2542
- var LANGUAGES = {
2684
+ var LANGUAGES2 = {
2543
2685
  javascript: JS,
2544
2686
  typescript: JS,
2545
2687
  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 },
@@ -2645,7 +2787,7 @@ var ALIASES = {
2645
2787
  dockerfile: "dockerfile",
2646
2788
  docker: "dockerfile"
2647
2789
  };
2648
- var CODE_HIGHLIGHT_LANGUAGES = Object.freeze(Object.keys(LANGUAGES));
2790
+ var CODE_HIGHLIGHT_LANGUAGES = Object.freeze(Object.keys(LANGUAGES2));
2649
2791
  function resolveCodeLanguage(language) {
2650
2792
  if (typeof language !== "string") return void 0;
2651
2793
  const key = language.trim().toLowerCase().replace(/^(?:language|lang)[-:]/, "").replace(/^\./, "");
@@ -2752,7 +2894,7 @@ function scanGeneric(source, def) {
2752
2894
  continue;
2753
2895
  }
2754
2896
  if (strings.includes(character)) {
2755
- if (def === LANGUAGES.rust && character === "'" && !/^'(?:\\.[^']*|[^\\'])'/.test(source.slice(index, index + 12))) {
2897
+ if (def === LANGUAGES2.rust && character === "'" && !/^'(?:\\.[^']*|[^\\'])'/.test(source.slice(index, index + 12))) {
2756
2898
  const match = /'[\p{L}_][\p{L}\p{N}_]*/uy;
2757
2899
  match.lastIndex = index;
2758
2900
  const found = match.exec(source);
@@ -2802,7 +2944,7 @@ function scanGeneric(source, def) {
2802
2944
  continue;
2803
2945
  }
2804
2946
  }
2805
- if (def === LANGUAGES.python && /[rRbBfFuU]/.test(character) && /^[rRbBfFuU]{1,2}['"]/.test(source.slice(index, index + 3)) && !isIdentChar(source[index - 1])) {
2947
+ if (def === LANGUAGES2.python && /[rRbBfFuU]/.test(character) && /^[rRbBfFuU]{1,2}['"]/.test(source.slice(index, index + 3)) && !isIdentChar(source[index - 1])) {
2806
2948
  const prefix = /^[rRbBfFuU]{1,2}/.exec(source.slice(index, index + 3))[0].length;
2807
2949
  const quote = source[index + prefix];
2808
2950
  const triple2 = source.startsWith(quote.repeat(3), index + prefix);
@@ -3139,7 +3281,7 @@ function scanCss(source) {
3139
3281
  function tokenizeCode(source, language) {
3140
3282
  const id = resolveCodeLanguage(language);
3141
3283
  if (id === void 0 || typeof source !== "string" || source.length === 0 || source.length > CODE_HIGHLIGHT_MAX_LENGTH) return [];
3142
- const def = LANGUAGES[id];
3284
+ const def = LANGUAGES2[id];
3143
3285
  let tokens;
3144
3286
  switch (def.kind) {
3145
3287
  case "yaml":
@@ -3210,8 +3352,8 @@ function codeSyntaxPalette(theme = {}, options = {}) {
3210
3352
  return palette;
3211
3353
  }
3212
3354
  function codeSyntaxPaletteForScheme(scheme, options = {}) {
3213
- const record6 = scheme && typeof scheme === "object" ? scheme : {};
3214
- const pick = (role, slot, fallback) => normalize(record6[role]) ?? normalize(record6[slot]) ?? fallback;
3355
+ const record7 = scheme && typeof scheme === "object" ? scheme : {};
3356
+ const pick = (role, slot, fallback) => normalize(record7[role]) ?? normalize(record7[slot]) ?? fallback;
3215
3357
  return codeSyntaxPalette({ primary: pick("primary", "accent1", "#2563EB"), secondary: pick("secondary", "accent2", "#0F766E"), accent: pick("accent", "accent3", "#F59E0B") }, options);
3216
3358
  }
3217
3359
 
@@ -3363,8 +3505,8 @@ var blend = (from, to, amount) => {
3363
3505
  return toHex(a.map((value, index) => value + (b[index] - value) * amount));
3364
3506
  };
3365
3507
  function codeHighlightColors(scheme, palette = codeSyntaxPaletteForScheme(scheme)) {
3366
- const record6 = scheme && typeof scheme === "object" ? scheme : {};
3367
- const primary = normalize(record6.primary) ?? normalize(record6.accent1) ?? "#2563EB";
3508
+ const record7 = scheme && typeof scheme === "object" ? scheme : {};
3509
+ const primary = normalize(record7.primary) ?? normalize(record7.accent1) ?? "#2563EB";
3368
3510
  const [hue, saturation] = toHsl(primary);
3369
3511
  const tint = fromHsl(hue, Math.min(saturation, 0.7), 0.45);
3370
3512
  const band = blend(CODE_PANEL_BACKGROUND, tint, CODE_HIGHLIGHT_BAND_TINT);
@@ -3561,7 +3703,7 @@ var CAPTION_FONT_RATIO = 0.6;
3561
3703
  var CAPTION_MAX_RATIO = 0.35;
3562
3704
  var FOOTNOTE_MAX_RATIO = 0.35;
3563
3705
  var CAPTIONABLE_FIELDS = Object.freeze(["image", "chart", "table", "video"]);
3564
- var record4 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
3706
+ var record5 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
3565
3707
  var isRecord3 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
3566
3708
  var round = (value) => Math.round(value * 1e6) / 1e6 || value;
3567
3709
  var regionKey = /^(top|middle|bottom|left|center|right)([+:]|$)/;
@@ -3569,7 +3711,7 @@ var TEXT_FIELDS = ["text", "items", "bullets"];
3569
3711
  var HEADING_FIELDS = ["tag", "title", "subtitle"];
3570
3712
  function annotationText(value) {
3571
3713
  if (typeof value === "string") return value;
3572
- if (Array.isArray(value)) return value.map((run) => typeof run === "string" ? run : record4(run).text ?? "").join("");
3714
+ if (Array.isArray(value)) return value.map((run) => typeof run === "string" ? run : record5(run).text ?? "").join("");
3573
3715
  if (isRecord3(value) && value.text !== void 0) return annotationText(value.text);
3574
3716
  return value === void 0 || value === null ? "" : String(value);
3575
3717
  }
@@ -3601,7 +3743,7 @@ function walkCitationRuns(slide, basePath, visit) {
3601
3743
  });
3602
3744
  };
3603
3745
  const host = (node, path, depth) => {
3604
- const payload = record4(node);
3746
+ const payload = record5(node);
3605
3747
  if (Array.isArray(payload.blocks)) {
3606
3748
  if (depth > 32) return;
3607
3749
  payload.blocks.forEach((block, index) => {
@@ -3616,7 +3758,7 @@ function walkCitationRuns(slide, basePath, visit) {
3616
3758
  }
3617
3759
  if (isRecord3(payload.quote)) runs(payload.quote.text, `${path}.quote.text`);
3618
3760
  };
3619
- const value = record4(slide);
3761
+ const value = record5(slide);
3620
3762
  for (const field of HEADING_FIELDS) runs(value[field], `${basePath}.${field}`);
3621
3763
  const regions = Object.keys(value).filter((key) => regionKey.test(key)).sort();
3622
3764
  if (regions.length) {
@@ -3633,7 +3775,7 @@ function walkCitationRuns(slide, basePath, visit) {
3633
3775
  }
3634
3776
  var citationMarkerText = (numbers) => numbers.join(",");
3635
3777
  function referenceList(presentation) {
3636
- const list = record4(presentation).references;
3778
+ const list = record5(presentation).references;
3637
3779
  return Array.isArray(list) ? list.filter((item) => isRecord3(item) && typeof item.id === "string") : [];
3638
3780
  }
3639
3781
  function numberSlide(slide, slideIndex, references, numbering) {
@@ -3666,7 +3808,7 @@ function numberSlide(slide, slideIndex, references, numbering) {
3666
3808
  }
3667
3809
  function collectCitations(presentation) {
3668
3810
  const references = referenceList(presentation), numbering = { notes: [], byId: /* @__PURE__ */ new Map() }, slides = /* @__PURE__ */ new Map();
3669
- const list = record4(presentation).slides;
3811
+ const list = record5(presentation).slides;
3670
3812
  if (Array.isArray(list)) list.forEach((slide, index) => {
3671
3813
  const result = numberSlide(slide, index, references, numbering);
3672
3814
  if (result) slides.set(index, result);
@@ -3676,7 +3818,7 @@ function collectCitations(presentation) {
3676
3818
  }
3677
3819
  function slideCitations(slide, slideIndex, presentation) {
3678
3820
  const references = referenceList(presentation), numbering = { notes: [], byId: /* @__PURE__ */ new Map() };
3679
- const list = record4(presentation).slides;
3821
+ const list = record5(presentation).slides;
3680
3822
  if (Array.isArray(list)) for (let index = 0; index < Math.min(slideIndex, list.length); index += 1) numberSlide(list[index], index, references, numbering);
3681
3823
  return numberSlide(slide, slideIndex, references, numbering);
3682
3824
  }
@@ -3739,45 +3881,12 @@ function referencesSlide(presentation, options = {}) {
3739
3881
  return { title, items };
3740
3882
  }
3741
3883
 
3742
- // src/layout-content.ts
3743
- var LAYOUT_BODY_KINDS = ["text", "list", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
3744
- var bodyKinds = new Set(LAYOUT_BODY_KINDS);
3745
- function layoutContent(record6) {
3746
- const heading = { title: false, subtitle: false, tag: false };
3747
- const counts = /* @__PURE__ */ new Map();
3748
- let count = 0;
3749
- for (const placeholder of Array.isArray(record6?.placeholders) ? record6.placeholders : []) {
3750
- const type = placeholder?.type;
3751
- if (type === "title" || type === "subtitle" || type === "tag") heading[type] = true;
3752
- else if (typeof type === "string" && bodyKinds.has(type)) {
3753
- counts.set(type, (counts.get(type) ?? 0) + 1);
3754
- count += 1;
3755
- }
3756
- }
3757
- let kind2 = "title", best = 0;
3758
- for (const [candidate, total] of counts) if (total > best) {
3759
- kind2 = candidate;
3760
- best = total;
3761
- }
3762
- return { kind: kind2, count, heading };
3763
- }
3764
-
3765
3884
  // src/composition.ts
3766
3885
  var MAX_COMPOSITION_DEPTH = 32;
3767
3886
  var FALLBACK_CODE_FAMILY = "Roboto Mono";
3768
- var DEFAULT_FONT_SCHEME = "aptos";
3769
- var DEFAULT_FONT_FAMILIES = { heading: "Aptos Display", body: "Aptos" };
3770
- function resolveFontSchemeReference(reference, lookup, path = "design.fontScheme") {
3771
- const overrides = typeof reference === "object" && reference !== null && !Array.isArray(reference) ? reference : void 0;
3772
- const id = typeof reference === "string" ? reference : typeof overrides?.id === "string" ? overrides.id : void 0;
3773
- const found = id === void 0 ? void 0 : lookup(id);
3774
- const base = record5(found ?? lookup(DEFAULT_FONT_SCHEME));
3775
- const scheme = overrides ? { ...base, ...overrides } : { ...base };
3776
- if (id === void 0 || found !== void 0) return { scheme };
3777
- 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}'.` } };
3778
- }
3887
+ var DEFAULT_FONT_FAMILIES = { heading: String(ENGINE_DEFAULT_FONT_SCHEME.major), body: String(ENGINE_DEFAULT_FONT_SCHEME.minor) };
3779
3888
  function resolveFontFamilies(input) {
3780
- const scheme = record5(input);
3889
+ const scheme = record6(input);
3781
3890
  const family = (value) => typeof value === "string" && value ? value : void 0;
3782
3891
  const accent = family(scheme.accent);
3783
3892
  return {
@@ -3848,6 +3957,12 @@ function translateTextFit(fit, dy) {
3848
3957
  }
3849
3958
  };
3850
3959
  }
3960
+ var FIELD_KINDS = { text: "text", bullets: "text", items: "list", image: "image", video: "video", chart: "chart", table: "table", code: "code", metric: "metric", quote: "quote", timeline: "timeline" };
3961
+ function chartPrimaryLayout(side, kinds) {
3962
+ const first = side === "left" || side === "top";
3963
+ const group = { type: "group", composition: {}, placeholders: kinds.map((type) => ({ type })) };
3964
+ return { composition: { mode: side === "left" || side === "right" ? "row" : "column", weights: first ? [3, 2] : [2, 3] }, placeholders: first ? [{ type: "chart" }, group] : [group, { type: "chart" }] };
3965
+ }
3851
3966
  var OPFCompositionError = class extends Error {
3852
3967
  constructor(diagnostics, explanation) {
3853
3968
  super("Slide content does not fit its composition.");
@@ -3861,19 +3976,32 @@ var OPFCompositionError = class extends Error {
3861
3976
  };
3862
3977
  var fields = ["text", "items", "bullets", "image", "video", "chart", "table", "code", "metric", "quote", "timeline"];
3863
3978
  var headings = /* @__PURE__ */ new Set(["title", "subtitle", "tag"]);
3864
- var COVER_LAYOUT_IDS = /* @__PURE__ */ new Set(["title", "title-subtitle"]);
3865
3979
  var rows2 = ["top", "middle", "bottom"];
3866
3980
  var columns = ["left", "center", "right"];
3867
- var record5 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
3981
+ var record6 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
3868
3982
  var kind = (field) => field === "items" ? "list" : field === "bullets" ? "text" : field;
3869
3983
  var round2 = (value) => Math.round(value * 1e6) / 1e6 || value;
3870
- var SLIDE_IMAGE_POSITIONS = ["background", "top", "bottom", "left", "right"];
3871
- var SLIDE_IMAGE_BAND = 0.5;
3872
- var assetSource = (value) => typeof value === "string" ? value : record5(value).src;
3984
+ var PLACEMENT_BAND = 0.5;
3985
+ var IMAGE_EDGES = ["left", "right", "top", "bottom"];
3986
+ var IMAGE_FITS = ["cover", "contain", "stretch"];
3987
+ var BACKGROUND_FITS = ["cover", "contain", "stretch", "tile"];
3988
+ var IMAGE_SOURCE = /^(asset:|https:\/\/|data:|\.\/|\.\.\/)/;
3989
+ var IMAGE_OPTION_KEYS = ["fit", "focus", "aspectRatio", "shape", "cornerRadius", "border", "opacity", "recolor", "overlay", "placement"];
3990
+ var imagePayload = (host) => {
3991
+ const payload = { type: host.type ?? "image", image: host.image };
3992
+ for (const key of IMAGE_OPTION_KEYS) if (host[key] !== void 0) payload[key] = host[key];
3993
+ return payload;
3994
+ };
3995
+ var assetSource = (value) => typeof value === "string" ? value : record6(value).src;
3873
3996
  var finite = (value, min, max) => typeof value === "number" && Number.isFinite(value) && value >= min && value <= max ? value : void 0;
3874
3997
  var pathNumber = (value) => String(round2(value));
3875
- var SLIDE_IMAGE_SHAPES = { rectangle: "rect", rounded: "roundRect", circle: "ellipse", hexagon: "hexagon" };
3876
- function slideImageShape(kind2, box, cornerRadius = 1 / 6) {
3998
+ var IMAGE_SHAPES = { rectangle: "rect", rounded: "roundRect", circle: "ellipse", hexagon: "hexagon" };
3999
+ var roundBox = (box) => ({ x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) });
4000
+ var imageFocus = (value) => {
4001
+ const focus = record6(value), x = finite(focus.x, 0, 1), y = finite(focus.y, 0, 1);
4002
+ return x !== void 0 && y !== void 0 ? { x, y } : { x: 0.5, y: 0.5 };
4003
+ };
4004
+ function imageShape(kind2, box, cornerRadius = 1 / 6) {
3877
4005
  const { x, y, width: w, height: h } = box, r = x + w, b = y + h, ss = Math.min(w, h), n = pathNumber;
3878
4006
  const rect = `M${n(x)} ${n(y)}H${n(r)}V${n(b)}H${n(x)}Z`;
3879
4007
  if (kind2 === "rounded") {
@@ -3892,66 +4020,96 @@ function slideImageShape(kind2, box, cornerRadius = 1 / 6) {
3892
4020
  }
3893
4021
  return { kind: "rectangle", preset: "rect", adjust: {}, path: rect };
3894
4022
  }
3895
- function resolveSlideImage(slide, layout, presentation, width, height, path, padding, scale, diagnostics, rtl = false) {
3896
- const own2 = record5(slide.design), deck = record5(record5(presentation).design);
3897
- const local = own2.slideImage !== void 0;
3898
- const configured = local ? own2.slideImage : deck.slideImage;
3899
- if (!configured || typeof configured !== "object" && typeof configured !== "string") return void 0;
3900
- const treatment = typeof configured === "object" && !Array.isArray(configured) && "position" in configured ? record5(configured) : void 0;
3901
- const layoutImage = record5(record5(layout.design).slideImage), layoutPosition = layoutImage.position;
3902
- const authoredPosition = treatment ? treatment.position : SLIDE_IMAGE_POSITIONS.find((value2) => value2 === layoutPosition) ?? "background";
3903
- if (!SLIDE_IMAGE_POSITIONS.includes(authoredPosition)) return void 0;
3904
- const mirrorSide = (side) => !rtl ? side : side === "left" ? "right" : side === "right" ? "left" : side;
3905
- const position = mirrorSide(authoredPosition);
3906
- const designSource = treatment ? treatment.src : configured;
3907
- const root = slide.image, sameSource = root !== void 0 && designSource !== void 0 && assetSource(root) === assetSource(designSource);
3908
- if (!local && record5(layout.design).slideImage === void 0 && !sameSource) return void 0;
3909
- const replacesContent = root !== void 0 && (designSource === void 0 || sameSource);
3910
- const value = replacesContent ? root : designSource;
3911
- const source = assetSource(value);
3912
- if (typeof source !== "string" || !source) return void 0;
3913
- const t = treatment ?? {};
3914
- const fill = t.fill === "crop" || t.fill === "fit" ? t.fill : (own2.imageFill ?? deck.imageFill) === "fit" ? "fit" : "crop";
3915
- const share = finite(t.size, 0.1, 0.9) ?? SLIDE_IMAGE_BAND;
3916
- const band = { width: round2(width * share), height: round2(height * share) };
3917
- const region = position === "left" ? { x: 0, y: 0, width: band.width, height } : position === "right" ? { x: round2(width - band.width), y: 0, width: band.width, height } : position === "top" ? { x: 0, y: 0, width, height: band.height } : position === "bottom" ? { x: 0, y: round2(height - band.height), width, height: band.height } : { x: 0, y: 0, width, height };
3918
- const designPath = local ? `${path}.design.slideImage` : "design.slideImage";
3919
- const kind2 = Object.hasOwn(SLIDE_IMAGE_SHAPES, t.shape) ? t.shape : "rectangle";
3920
- let box = t.inset === true ? { 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 };
3921
- const aspect = kind2 === "circle" ? 1 : finite(t.aspectRatio, Number.MIN_VALUE, 10);
4023
+ function fitImage(frame, fit, aspect, focus = { x: 0.5, y: 0.5 }) {
4024
+ 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.");
4025
+ if (fit === "stretch" || !Number.isFinite(aspect) || aspect <= 0) return { image: roundBox(frame), crop: { left: 0, top: 0, right: 0, bottom: 0 } };
4026
+ const wide = aspect > frame.width / frame.height, cover = fit === "cover";
4027
+ const width = wide === cover ? frame.height * aspect : frame.width, height = wide === cover ? frame.height : frame.width / aspect;
4028
+ const point = imageFocus(focus);
4029
+ const place = (start, span, size, at3) => cover ? Math.min(start, Math.max(start + span - size, start + span / 2 - at3 * size)) : start + (span - size) / 2;
4030
+ const image = { x: place(frame.x, frame.width, width, point.x), y: place(frame.y, frame.height, height, point.y), width, height };
4031
+ const crop = {
4032
+ left: round2((frame.x - image.x) / width),
4033
+ top: round2((frame.y - image.y) / height),
4034
+ right: round2((image.x + width - frame.x - frame.width) / width),
4035
+ bottom: round2((image.y + height - frame.y - frame.height) / height)
4036
+ };
4037
+ for (const key of ["left", "top", "right", "bottom"]) if (Object.is(crop[key], -0)) crop[key] = 0;
4038
+ return { image: roundBox(image), crop };
4039
+ }
4040
+ function imageBackground(value) {
4041
+ if (typeof value === "string") return IMAGE_SOURCE.test(value) ? { src: value, fit: "cover", focus: { x: 0.5, y: 0.5 } } : void 0;
4042
+ const background = record6(value);
4043
+ if (background.type !== "image" || typeof background.src !== "string" || !background.src) return void 0;
4044
+ const opacity = finite(background.opacity, 0, 1);
4045
+ return {
4046
+ src: background.src,
4047
+ ...typeof background.alt === "string" ? { alt: background.alt } : {},
4048
+ fit: BACKGROUND_FITS.includes(background.fit) ? background.fit : "cover",
4049
+ focus: imageFocus(background.focus),
4050
+ ...opacity !== void 0 ? { opacity } : {},
4051
+ ...background.recolor !== void 0 ? { recolor: background.recolor } : {},
4052
+ ...background.overlay !== void 0 ? { overlay: background.overlay } : {}
4053
+ };
4054
+ }
4055
+ function composeRecolor(value) {
4056
+ if (value === "grayscale") return { type: "grayscale" };
4057
+ const duotone = record6(value);
4058
+ return duotone.dark !== void 0 && duotone.light !== void 0 ? { type: "duotone", dark: duotone.dark, light: duotone.light } : void 0;
4059
+ }
4060
+ function composeOverlay(value, frame, shape, path, mirrorSide, diagnostics) {
4061
+ const overlay = record6(value), opacity = finite(overlay.opacity, 0, 1);
4062
+ if (overlay.color === void 0 || opacity === void 0) return void 0;
4063
+ const edge = IMAGE_EDGES.includes(overlay.edge) ? mirrorSide(overlay.edge) : void 0;
4064
+ if (edge && shape.kind !== "rectangle") {
4065
+ 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." });
4066
+ return void 0;
4067
+ }
4068
+ const part = finite(overlay.size, 0.05, 1) ?? 0.3;
4069
+ 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) };
4070
+ return { path, color: overlay.color, opacity, ...edge ? { edge } : {}, box, shape: edge ? imageShape("rectangle", box) : shape };
4071
+ }
4072
+ function composeImage(host, hostPath, region, frameArea, context) {
4073
+ const kindName = Object.hasOwn(IMAGE_SHAPES, host.shape) ? host.shape : "rectangle";
4074
+ const { scale } = context;
4075
+ let box = { ...frameArea };
4076
+ const aspect = kindName === "circle" ? 1 : finite(host.aspectRatio, Number.MIN_VALUE, 10);
3922
4077
  if (aspect) {
3923
4078
  const frameWidth = Math.min(box.width, box.height * aspect), frameHeight = frameWidth / aspect;
3924
4079
  box = { x: box.x + (box.width - frameWidth) / 2, y: box.y + (box.height - frameHeight) / 2, width: frameWidth, height: frameHeight };
3925
4080
  }
3926
- box = { x: round2(box.x), y: round2(box.y), width: round2(box.width), height: round2(box.height) };
3927
- const result = {
3928
- path: designPath,
3929
- sourcePath: replacesContent ? `${path}.image` : designPath,
3930
- value,
3931
- position,
3932
- fill,
3933
- region,
3934
- box,
3935
- replacesContent,
3936
- shape: slideImageShape(kind2, box, finite(t.cornerRadius, 0, 0.5))
3937
- };
3938
- if (typeof t.alt === "string") result.alt = t.alt;
3939
- const border = record5(t.border), borderWidth = finite(border.width, 0, 64);
4081
+ box = roundBox(box);
4082
+ const fit = IMAGE_FITS.includes(host.fit) ? host.fit : context.fit ?? "cover";
4083
+ const focus = imageFocus(host.focus);
4084
+ const shape = imageShape(kindName, box, finite(host.cornerRadius, 0, 0.5));
4085
+ const result = { region: roundBox(region), box, fit, focus, shape };
4086
+ const border = record6(host.border), borderWidth = finite(border.width, 0, 64);
3940
4087
  if (border.color !== void 0 && borderWidth) result.border = { color: border.color, width: round2(borderWidth * scale) };
3941
- const opacity = finite(t.opacity, 0, 1);
4088
+ const opacity = finite(host.opacity, 0, 1);
3942
4089
  if (opacity !== void 0 && opacity < 1) result.opacity = opacity;
3943
- if (t.recolor === "grayscale") result.recolor = { type: "grayscale" };
3944
- else if (record5(t.recolor).dark !== void 0 && record5(t.recolor).light !== void 0) result.recolor = { type: "duotone", dark: t.recolor.dark, light: t.recolor.light };
3945
- const overlay = record5(t.overlay), overlayOpacity = finite(overlay.opacity, 0, 1);
3946
- if (overlay.color !== void 0 && overlayOpacity !== void 0) {
3947
- const edge = ["top", "bottom", "left", "right"].includes(overlay.edge) ? mirrorSide(overlay.edge) : void 0;
3948
- if (edge && kind2 !== "rectangle") diagnostics.push({ code: "unsupported-image-treatment", path: `${designPath}.overlay.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." });
3949
- else {
3950
- const part = finite(overlay.size, 0.05, 1) ?? 0.3;
3951
- const bandBox = !edge ? box : edge === "top" ? { ...box, height: round2(box.height * part) } : edge === "bottom" ? { ...box, y: round2(box.y + box.height * (1 - part)), height: round2(box.height * part) } : edge === "left" ? { ...box, width: round2(box.width * part) } : { ...box, x: round2(box.x + box.width * (1 - part)), width: round2(box.width * part) };
3952
- result.overlay = { color: overlay.color, opacity: overlayOpacity, box: bandBox, shape: edge ? slideImageShape("rectangle", bandBox) : result.shape };
3953
- }
3954
- }
4090
+ const recolor = composeRecolor(host.recolor);
4091
+ if (recolor) result.recolor = recolor;
4092
+ const overlay = composeOverlay(host.overlay, box, shape, `${hostPath}.overlay`, context.mirrorSide, context.diagnostics);
4093
+ if (overlay) result.overlay = overlay;
4094
+ if (context.placement) result.placement = context.placement;
4095
+ const pictureAspect = intrinsicImageAspect(host.image, context.assets);
4096
+ if (pictureAspect) result.picture = fitImage(box, fit, pictureAspect, focus);
4097
+ return result;
4098
+ }
4099
+ function resolveBackgroundImage(slide, presentation, themeBackground, width, height, path, mirrorSide, diagnostics) {
4100
+ const own2 = record6(slide.design), deck = record6(record6(presentation).design);
4101
+ const [value, at3] = own2.background !== void 0 ? [own2.background, `${path}.design.background`] : deck.background !== void 0 ? [deck.background, "design.background"] : [themeBackground, "theme"];
4102
+ const background = imageBackground(value);
4103
+ if (!background) return void 0;
4104
+ const box = { x: 0, y: 0, width, height };
4105
+ const result = { path: at3, src: background.src, ...background.alt !== void 0 ? { alt: background.alt } : {}, fit: background.fit, focus: background.focus, box };
4106
+ if (background.opacity !== void 0 && background.opacity < 1) result.opacity = background.opacity;
4107
+ const recolor = composeRecolor(background.recolor);
4108
+ if (recolor) result.recolor = recolor;
4109
+ const overlay = composeOverlay(background.overlay, box, imageShape("rectangle", box), `${at3}.overlay`, mirrorSide, diagnostics);
4110
+ if (overlay) result.overlay = overlay;
4111
+ const aspect = background.fit === "tile" ? void 0 : intrinsicImageAspect(background.src, record6(presentation).assets);
4112
+ if (aspect) result.picture = fitImage(box, background.fit, aspect, background.focus);
3955
4113
  return result;
3956
4114
  }
3957
4115
  var LOGO_LOCKUP_CHAINS = {
@@ -3971,10 +4129,10 @@ function resolveLogo(presentation, slide, options = {}) {
3971
4129
  };
3972
4130
  const pick = (value, path) => {
3973
4131
  if (value === void 0 || value === null || value === false) return null;
3974
- if (typeof value === "string" || typeof value === "object" && !Array.isArray(value) && "src" in record5(value)) {
4132
+ if (typeof value === "string" || typeof value === "object" && !Array.isArray(value) && "src" in record6(value)) {
3975
4133
  return usable(value) ? { source: value, path, variant: "default", slot } : null;
3976
4134
  }
3977
- const set2 = record5(value);
4135
+ const set2 = record6(value);
3978
4136
  if (!Object.keys(set2).some((key) => LOGO_SET_KEYS.has(key))) return null;
3979
4137
  for (const key of chain) {
3980
4138
  const variant = set2[key];
@@ -3982,23 +4140,23 @@ function resolveLogo(presentation, slide, options = {}) {
3982
4140
  }
3983
4141
  return null;
3984
4142
  };
3985
- const deck = record5(presentation), slideIndex = Number.isSafeInteger(options.slideIndex) && options.slideIndex >= 0 ? options.slideIndex : 0;
3986
- const own2 = pick(record5(record5(slide).design).logo, `slides.${slideIndex}.design.logo`);
4143
+ const deck = record6(presentation), slideIndex = Number.isSafeInteger(options.slideIndex) && options.slideIndex >= 0 ? options.slideIndex : 0;
4144
+ const own2 = pick(record6(record6(slide).design).logo, `slides.${slideIndex}.design.logo`);
3987
4145
  if (own2) return own2;
3988
- const shared = pick(record5(deck.design).logo, "design.logo");
4146
+ const shared = pick(record6(deck.design).logo, "design.logo");
3989
4147
  if (shared) return shared;
3990
4148
  const organizations = Array.isArray(deck.organization) ? deck.organization : [deck.organization];
3991
- const primaryIndex = organizations.findIndex((item) => record5(item).role === "primary");
4149
+ const primaryIndex = organizations.findIndex((item) => record6(item).role === "primary");
3992
4150
  const index = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
3993
4151
  if (index < 0) return null;
3994
- return pick(record5(organizations[index]).logo, Array.isArray(deck.organization) ? `organization.${index}.logo` : "organization.logo");
4152
+ return pick(record6(organizations[index]).logo, Array.isArray(deck.organization) ? `organization.${index}.logo` : "organization.logo");
3995
4153
  }
3996
4154
  var webUrl = /^https?:\/\/\S+$/i;
3997
- function resolveSocialProfile(platform, value, records = [], owner = "organization") {
4155
+ function resolveSocialProfile(platform, value, owner = "organization") {
3998
4156
  const raw = String(value).trim().replace(/\s+/gu, " ");
3999
4157
  const display = (url2) => url2.replace(/^https:\/\//i, "");
4000
4158
  if (webUrl.test(raw)) return { text: display(raw), href: raw, resolved: false };
4001
- const platformRecord = records.find((item) => item?.id === platform);
4159
+ const platformRecord = Object.hasOwn(SOCIAL_PLATFORMS, platform) ? SOCIAL_PLATFORMS[platform] : void 0;
4002
4160
  const base = typeof platformRecord?.baseUrl === "string" && webUrl.test(platformRecord.baseUrl) ? `${platformRecord.baseUrl.replace(/\/+$/u, "")}/{handle}` : void 0;
4003
4161
  const pattern = (owner === "organization" ? platformRecord?.companyUrlPattern : void 0) ?? platformRecord?.profileUrlPattern ?? base;
4004
4162
  const prefix = platformRecord?.handlePrefix ?? "";
@@ -4009,8 +4167,8 @@ function resolveSocialProfile(platform, value, records = [], owner = "organizati
4009
4167
  return { text: display(url), href: encodeURI(url), resolved: true };
4010
4168
  }
4011
4169
  function layoutFurniture(input, options = {}) {
4012
- const slide = record5(input), width = options.width ?? 1280, height = options.height ?? 720, scale = Math.min(width, height) / 720;
4013
- const settings = { ...record5(record5(options.layout).composition), ...record5(slide.composition) };
4170
+ const slide = record6(input), width = options.width ?? 1280, height = options.height ?? 720, scale = Math.min(width, height) / 720;
4171
+ const settings = { ...record6(record6(options.layout).composition), ...record6(slide.composition) };
4014
4172
  assertComposition(settings);
4015
4173
  const furnitureRtl = (options.direction ?? resolveSlideDirection(options.presentation, options.slideIndex)) === "rtl";
4016
4174
  const minimum = snapFontSizeUp((settings.minFontSize ?? 16) * scale), size = gridFontSize(13 * scale, minimum), padding = (options.textRasterPadding ?? 2) * scale;
@@ -4022,15 +4180,14 @@ function layoutFurniture(input, options = {}) {
4022
4180
  if (options.date !== void 0 && (typeof options.date !== "string" || !parseIsoDate(options.date))) throw new RangeError("The furniture date option must be an ISO YYYY-MM-DD calendar date.");
4023
4181
  const outlines = options.textMeasurement?.outlineBounds !== void 0, parts = [], diagnostics = [];
4024
4182
  const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
4025
- const primaryIndex = organizations.findIndex((item) => record5(item).role === "primary"), organizationIndex = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
4026
- const organization = record5(organizations[organizationIndex]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex}` : "organization", organizationPath = `${organizationRoot}.name`;
4027
- 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";
4028
- const inlinePlatforms = record5(record5(options.presentation?.catalogs).socialPlatforms).records, platformRecords = [...Array.isArray(inlinePlatforms) ? inlinePlatforms : [], ...options.socialPlatforms ?? []];
4183
+ const primaryIndex = organizations.findIndex((item) => record6(item).role === "primary"), organizationIndex = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
4184
+ const organization = record6(organizations[organizationIndex]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex}` : "organization", organizationPath = `${organizationRoot}.name`;
4185
+ const speakers = Array.isArray(options.presentation?.speaker) ? options.presentation.speaker : [options.presentation?.speaker], speaker = record6(speakers[0]), speakerRoot = Array.isArray(options.presentation?.speaker) ? "speaker.0" : "speaker";
4029
4186
  const fontFamily = options.fontFamilies?.body ?? "sans-serif";
4030
4187
  let headerBottom = 0, footerTop = height, configured = false;
4031
4188
  const error = (path, message, code = "text-overflow") => diagnostics.push({ code, path, message });
4032
4189
  for (const kind2 of ["header", "footer"]) {
4033
- const local = record5(slide.design)[kind2] !== void 0, value = local ? record5(slide.design)[kind2] : options.presentation?.design?.[kind2];
4190
+ const local = record6(slide.design)[kind2] !== void 0, value = local ? record6(slide.design)[kind2] : options.presentation?.design?.[kind2];
4034
4191
  if (value === void 0 || value === false) continue;
4035
4192
  const root = local ? `${sourceRoot}.design.${kind2}` : `design.${kind2}`;
4036
4193
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("Header/footer content must be an object or false.");
@@ -4038,7 +4195,7 @@ function layoutFurniture(input, options = {}) {
4038
4195
  const zones = [];
4039
4196
  for (const [index, zone] of ["left", "center", "right"].entries()) {
4040
4197
  const side = furnitureRtl && zone !== "center" ? zone === "left" ? "right" : "left" : zone;
4041
- const content = record5(record5(value)[zone]), path = `${root}.${zone}`, x = width * (0.07 + (furnitureRtl ? 2 - index : index) * 0.3), zoneWidth = width * 0.26, zoneParts = [];
4198
+ const content = record6(record6(value)[zone]), path = `${root}.${zone}`, x = width * (0.07 + (furnitureRtl ? 2 - index : index) * 0.3), zoneWidth = width * 0.26, zoneParts = [];
4042
4199
  let y = 0;
4043
4200
  const add = (field, text2, generated = false, sourcePath, extras = {}) => {
4044
4201
  if (text2 === void 0) return;
@@ -4075,7 +4232,7 @@ function layoutFurniture(input, options = {}) {
4075
4232
  y += box.height;
4076
4233
  };
4077
4234
  const imageBox = (source) => {
4078
- const imageHeight = Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source, record5(options.presentation).assets) ?? 1));
4235
+ const imageHeight = Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source, record6(options.presentation).assets) ?? 1));
4079
4236
  return { x: side === "left" ? x : side === "center" ? x + (zoneWidth - imageWidth) / 2 : x + zoneWidth - imageWidth, y, width: imageWidth, height: imageHeight };
4080
4237
  };
4081
4238
  if (content.logo === true) {
@@ -4101,7 +4258,7 @@ function layoutFurniture(input, options = {}) {
4101
4258
  else error(`${path}.speaker`, "Generated speaker needs a named speaker in the presentation.", "unresolved-content");
4102
4259
  }
4103
4260
  if (content.socials === true) {
4104
- 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, platformRecords, "organization") }));
4261
+ const links = Object.entries(record6(organization.socials)).filter(([, value2]) => typeof value2 === "string" && value2.trim()).map(([platform, value2]) => ({ platform, sourcePath: `${organizationRoot}.socials.${platform}`, ...resolveSocialProfile(platform, value2, "organization") }));
4105
4262
  if (links.length) add("socials", links.map((link) => link.text).join("\n"), true, `${organizationRoot}.socials`, { links });
4106
4263
  else error(`${path}.socials`, "Generated social profiles need a primary organization with socials.", "unresolved-content");
4107
4264
  }
@@ -4306,7 +4463,7 @@ function layoutQuote(value, box, options = {}) {
4306
4463
  attribution.box = selected.textBox ?? selected.footerBox;
4307
4464
  attribution.fit = selected.footerFit;
4308
4465
  }
4309
- if (selected.photoBox) photo = { path: photoPath, value: photoValue, box: selected.photoBox, shape: slideImageShape("circle", selected.photoBox) };
4466
+ if (selected.photoBox) photo = { path: photoPath, value: photoValue, box: selected.photoBox, shape: imageShape("circle", selected.photoBox) };
4310
4467
  photoFits = selected.photoFits;
4311
4468
  }
4312
4469
  }
@@ -4650,19 +4807,19 @@ function fitSourceText(text2, box, size, minimum, step, measure, prose = false,
4650
4807
  const layout = (fontSize) => {
4651
4808
  const tabWidth = measure(" ", fontSize) * 4;
4652
4809
  if (!Number.isFinite(tabWidth) || text2.includes(" ") && tabWidth <= 0) throw new RangeError("Text tabs require a positive finite measured space advance.");
4653
- const measureLine = (start2, end2, record6 = false) => {
4810
+ const measureLine = (start2, end2, record7 = false) => {
4654
4811
  let x = 0, offset = start2;
4655
4812
  const segments = [];
4656
4813
  for (const [index, segment2] of text2.slice(start2, end2).split(" ").entries()) {
4657
4814
  if (index) {
4658
4815
  const next = (Math.floor(x / tabWidth + 1e-9) + 1) * tabWidth;
4659
- if (record6) segments.push({ kind: "tab", start: offset, end: offset + 1, x, width: next - x });
4816
+ if (record7) segments.push({ kind: "tab", start: offset, end: offset + 1, x, width: next - x });
4660
4817
  x = next;
4661
4818
  offset++;
4662
4819
  }
4663
4820
  if (segment2) {
4664
4821
  const advance = measure(segment2, fontSize);
4665
- if (record6) segments.push({ kind: "text", start: offset, end: offset + segment2.length, x, width: advance });
4822
+ if (record7) segments.push({ kind: "text", start: offset, end: offset + segment2.length, x, width: advance });
4666
4823
  x += advance;
4667
4824
  offset += segment2.length;
4668
4825
  }
@@ -5019,12 +5176,12 @@ function fitList(input, box, requestedSize = 25, minFontSize = 16, options = { s
5019
5176
  function contentText(field, value) {
5020
5177
  if (field === "text" || headings.has(field)) return flatten(value);
5021
5178
  if (field === "items" || field === "bullets") return (Array.isArray(value) ? value : [value]).map((item) => {
5022
- const entry = record5(item);
5179
+ const entry = record6(item);
5023
5180
  return `\u2022 ${flatten(item)}${entry.description ? `
5024
5181
  ${flatten(entry.description)}` : ""}`;
5025
5182
  }).join("\n");
5026
- if (field === "code") return flatten(record5(value).source ?? value);
5027
- if (field === "quote") return flatten(record5(value).text ?? value);
5183
+ if (field === "code") return flatten(record6(value).source ?? value);
5184
+ if (field === "quote") return flatten(record6(value).text ?? value);
5028
5185
  return void 0;
5029
5186
  }
5030
5187
  function layoutTable(value, box, options = {}) {
@@ -5095,7 +5252,7 @@ function flatten(value) {
5095
5252
  if (value == null) return "";
5096
5253
  if (typeof value !== "object") return String(value);
5097
5254
  if (Array.isArray(value)) return value.map(flatten).join("");
5098
- const item = record5(value);
5255
+ const item = record6(value);
5099
5256
  return flatten(item.text ?? item.value ?? item.source ?? JSON.stringify(value));
5100
5257
  }
5101
5258
  function regionParts(key) {
@@ -5151,7 +5308,7 @@ function assertComposition(value) {
5151
5308
  if (value.overflow !== void 0 && !["warn", "error"].includes(value.overflow)) throw new RangeError("Invalid composition.overflow.");
5152
5309
  }
5153
5310
  function composeSlide(input, options = {}) {
5154
- const slide = record5(input), layout = record5(options.layout);
5311
+ const slide = record6(input), layout = record6(options.layout);
5155
5312
  const width = options.width ?? 1280, height = options.height ?? 720;
5156
5313
  if (![width, height].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Canvas dimensions must be finite and positive.");
5157
5314
  const scale = Math.min(width, height) / 720;
@@ -5159,7 +5316,7 @@ function composeSlide(input, options = {}) {
5159
5316
  const rtl = deckDirection === "rtl", textDirection = rtl ? "rtl" : void 0;
5160
5317
  const hints = resolveDesignHints({ slide, layout, presentation: options.presentation, slideIndex: options.slideIndex, deck: { titleAlignment: options.titleAlignment, contentAlignment: options.contentAlignment, contentBox: options.contentBox } });
5161
5318
  const hasCards = hints.contentBox ?? false;
5162
- const composition = { ...record5(layout.composition), ...record5(slide.composition) };
5319
+ const composition = { ...record6(layout.composition), ...record6(slide.composition) };
5163
5320
  assertComposition(composition);
5164
5321
  const padding = (composition.padding ?? 0.08) * Math.min(width, height);
5165
5322
  const gap = (composition.gap ?? 1 / 30) * Math.min(width, height);
@@ -5236,13 +5393,37 @@ function composeSlide(input, options = {}) {
5236
5393
  const path = `slides.${options.slideIndex ?? 0}`;
5237
5394
  const annotationFit = (value, box, requestedSize, minFontSize, fitPath, alignment) => fitPlacedText("text", value, annotationText(value), box, requestedSize, minFontSize, fitPath, alignment);
5238
5395
  const annotationOptions = { scale, minFontSize: minSize, fit: annotationFit, textStyle: (fitPath) => styleFor("text", fitPath) };
5239
- const slideImageDiagnostics = [];
5240
- const slideImage = resolveSlideImage(slide, layout, options.presentation, width, height, path, padding, scale, slideImageDiagnostics, rtl);
5396
+ const imageDiagnostics = [];
5397
+ const mirrorSide = (side) => !rtl ? side : side === "left" ? "right" : side === "right" ? "left" : side;
5398
+ const backgroundImage = resolveBackgroundImage(slide, options.presentation, options.themeBackground, width, height, path, mirrorSide, imageDiagnostics);
5399
+ const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
5400
+ const assets = record6(options.presentation).assets;
5401
+ const imageContext = (placement) => ({ fit: hints.imageFit, scale, mirrorSide, diagnostics: imageDiagnostics, assets, ...placement ? { placement } : {} });
5241
5402
  const area = { left: 0, top: 0, right: width, bottom: height };
5242
- if (slideImage?.position === "left") area.left = slideImage.region.width;
5243
- else if (slideImage?.position === "right") area.right = slideImage.region.x;
5244
- else if (slideImage?.position === "top") area.top = slideImage.region.height;
5245
- else if (slideImage?.position === "bottom") area.bottom = slideImage.region.y;
5403
+ const imagePlaceholders = layoutLeaves(layout).flatMap((leaf) => leaf.type === "image" ? [{ placeholder: leaf.placeholder, path: leaf.path, depth: leaf.depth }] : []);
5404
+ const topImages = regions.length ? [] : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => !Array.isArray(record6(block).blocks) && record6(block).image !== void 0 ? [{ host: record6(block), hostPath: `${path}.blocks.${index}`, block: index }] : []) : slide.image !== void 0 ? [{ host: { type: "image", image: slide.image }, hostPath: path }] : [];
5405
+ const placed = [], usedEdges = /* @__PURE__ */ new Set();
5406
+ topImages.forEach((node, order) => {
5407
+ const slot = imagePlaceholders[order];
5408
+ const own2 = node.block !== void 0 && node.host.placement !== void 0 ? record6(node.host.placement) : void 0;
5409
+ const value = own2 ?? (slot?.depth === 0 && slot.placeholder.placement !== void 0 ? record6(slot.placeholder.placement) : void 0);
5410
+ if (!value || !IMAGE_EDGES.includes(value.edge)) return;
5411
+ const edge = mirrorSide(value.edge);
5412
+ if (usedEdges.has(edge)) return;
5413
+ usedEdges.add(edge);
5414
+ const size = finite(value.size, 0.1, 0.9) ?? PLACEMENT_BAND;
5415
+ const across = edge === "left" || edge === "right" ? area.right - area.left : area.bottom - area.top;
5416
+ const band = Math.max(0, Math.min(across, round2((edge === "left" || edge === "right" ? width : height) * size)));
5417
+ 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 };
5418
+ if (edge === "left") area.left += band;
5419
+ else if (edge === "right") area.right = region.x;
5420
+ else if (edge === "top") area.top += band;
5421
+ else area.bottom = region.y;
5422
+ const placement = { edge, size, inset: value.inset === true, path: own2 ? `${node.hostPath}.placement` : `${slot.path}.placement` };
5423
+ placed.push({ ...node, placement, region, slot: order });
5424
+ });
5425
+ const placedBlocks = new Set(placed.flatMap((entry) => entry.block !== void 0 ? [entry.block] : []));
5426
+ const placedRoot = placed.some((entry) => entry.block === void 0);
5246
5427
  const items = [], diagnostics = [];
5247
5428
  const measuredFurniture = layoutFurniture(slide, options);
5248
5429
  const furniture = measuredFurniture.configured || measuredFurniture.diagnostics.length ? measuredFurniture : void 0;
@@ -5256,12 +5437,13 @@ function composeSlide(input, options = {}) {
5256
5437
  bodyBottom = footnotes.box.y - gap * 0.5;
5257
5438
  }
5258
5439
  const layoutPlaceholders = Array.isArray(layout.placeholders) ? layout.placeholders : [];
5259
- const headingOnlyLayout = COVER_LAYOUT_IDS.has(String(layout.id ?? "")) || layoutPlaceholders.length > 0 && layoutPlaceholders.every((placeholder) => headings.has(placeholder.type ?? ""));
5260
- const regions = Object.keys(slide).filter((key) => regionParts(key)).sort();
5440
+ const hasLayoutRecord = options.layout !== void 0 && options.layout !== null && typeof options.layout === "object";
5441
+ const headingOnlyLayout = layoutPlaceholders.length > 0 && layoutPlaceholders.every((placeholder) => headings.has(placeholder.type ?? "") || placeholder.type === "image" && typeof placeholder.placement === "object" && placeholder.placement !== null);
5261
5442
  const emptyPayload = (value) => value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
5262
5443
  const emptyHost = (host) => emptyPayload(host.blocks) && fields.every((field) => emptyPayload(host[field]));
5263
- const hasBodyPayload = regions.some((key) => !emptyHost(record5(slide[key]))) || !emptyPayload(slide.blocks) || fields.some((field) => !emptyPayload(slide[field]));
5264
- const isCover = !hasBodyPayload && (headingOnlyLayout || !layout.id && !layoutPlaceholders.some((placeholder) => !headings.has(placeholder.type ?? "")));
5444
+ const flowBlocks = Array.isArray(slide.blocks) ? slide.blocks.filter((_, index) => !placedBlocks.has(index)) : slide.blocks;
5445
+ const hasBodyPayload = regions.some((key) => !emptyHost(record6(slide[key]))) || !emptyPayload(flowBlocks) || fields.some((field) => !(placedRoot && field === "image") && !emptyPayload(slide[field]));
5446
+ const isCover = !hasBodyPayload && (headingOnlyLayout || !hasLayoutRecord);
5265
5447
  coverGroup = isCover;
5266
5448
  let logo;
5267
5449
  if (isCover) {
@@ -5299,11 +5481,35 @@ function composeSlide(input, options = {}) {
5299
5481
  y = last.box.y + last.box.height + gap;
5300
5482
  } else y += gap * 0.5;
5301
5483
  }
5484
+ for (const entry of placed) {
5485
+ const { host, hostPath, region, placement } = entry;
5486
+ 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 };
5487
+ const caption = host.caption !== void 0 && entry.block !== void 0 ? layoutCaption(host.caption, roundBox(frameArea), `${hostPath}.caption`, annotationOptions) : void 0;
5488
+ if (caption) {
5489
+ frameArea = caption.mediaBox;
5490
+ diagnostics.push(...caption.diagnostics);
5491
+ }
5492
+ const image = composeImage(host, hostPath, region, frameArea, imageContext(placement));
5493
+ const type = host.type ?? "image";
5494
+ items.push({
5495
+ path: `${hostPath}.image`,
5496
+ field: "image",
5497
+ type,
5498
+ value: host.image,
5499
+ payload: imagePayload(host),
5500
+ box: { ...region },
5501
+ image,
5502
+ textStyle: styleFor("image", `${hostPath}.image`),
5503
+ composition,
5504
+ alignment: alignmentFor("image"),
5505
+ ...caption ? { caption } : {}
5506
+ });
5507
+ }
5302
5508
  const contentBox = { x: area.left + padding, y, width: area.right - area.left - padding * 2, height: Math.max(scale, bodyBottom - y) };
5303
5509
  const collect = (host, basePath, depth = 0, ancestors = []) => {
5304
5510
  if (Array.isArray(host.blocks)) {
5305
5511
  if (depth >= MAX_COMPOSITION_DEPTH || ancestors.includes(host)) throw new RangeError(`Content groups must be acyclic and nest at most ${MAX_COMPOSITION_DEPTH} levels.`);
5306
- const settings = record5(host.composition);
5512
+ const settings = record6(host.composition);
5307
5513
  assertComposition(settings);
5308
5514
  return [{
5309
5515
  field: "blocks",
@@ -5312,7 +5518,7 @@ function composeSlide(input, options = {}) {
5312
5518
  path: basePath,
5313
5519
  payload: host,
5314
5520
  composition: settings,
5315
- children: host.blocks.flatMap((block, index) => collect(record5(block), `${basePath}.blocks.${index}`, depth + 1, [...ancestors, host]))
5521
+ children: host.blocks.flatMap((block, index) => collect(record6(block), `${basePath}.blocks.${index}`, depth + 1, [...ancestors, host]))
5316
5522
  }];
5317
5523
  }
5318
5524
  const captioned = host.caption !== void 0 ? fields.filter((field) => host[field] !== void 0 && CAPTIONABLE_FIELDS.includes(field)) : [];
@@ -5322,12 +5528,13 @@ function composeSlide(input, options = {}) {
5322
5528
  type: host.type ?? kind(field),
5323
5529
  value: fieldValue(field),
5324
5530
  path: `${basePath}.${field}`,
5325
- payload: { type: host.type ?? kind(field), [field]: fieldValue(field), ...host.numbering !== void 0 && (field === "items" || field === "bullets") ? { numbering: host.numbering } : {} },
5531
+ payload: field === "image" ? imagePayload(host) : { type: host.type ?? kind(field), [field]: fieldValue(field), ...host.numbering !== void 0 && (field === "items" || field === "bullets") ? { numbering: host.numbering } : {} },
5532
+ ...field === "image" ? { host, hostPath: basePath } : {},
5326
5533
  ...captioned.length === 1 && captioned[0] === field ? { caption: host.caption, captionPath: `${basePath}.caption` } : {}
5327
5534
  }));
5328
5535
  };
5329
5536
  const regionsInReadingOrder = visualReadingOrder(regions.map((key) => ({ key, box: regionBox(regionParts(key), contentBox, gap) }))).map((entry) => entry.key);
5330
- 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(slideImage?.replacesContent ? { ...slide, image: void 0 } : slide, path);
5537
+ const pending = regions.length ? regionsInReadingOrder.flatMap((key) => collect(record6(slide[key]), `${path}.${key}`).map((item) => ({ ...item, region: regionParts(key) }))) : Array.isArray(slide.blocks) ? slide.blocks.flatMap((block, index) => placedBlocks.has(index) ? [] : collect(record6(block), `${path}.blocks.${index}`)) : collect(placedRoot ? { ...slide, image: void 0 } : slide, path);
5331
5538
  const groups = [], flows = [];
5332
5539
  const decisions = options.explain ? [] : void 0;
5333
5540
  const inheritedSettings = (parent, own2 = {}) => ({
@@ -5425,12 +5632,23 @@ function composeSlide(input, options = {}) {
5425
5632
  };
5426
5633
  const scoreNode = (node, box, settings, penalties) => {
5427
5634
  if (!node.children) return leafScore(node, box, settings, penalties);
5428
- const own2 = inheritedSettings(settings, node.composition), area2 = inset(box, own2);
5429
- const cols = defaultColumns(node.children.length, area2, own2);
5430
- const boxes = gridBoxes(node.children.length, area2, cols, (own2.gap ?? 1 / 30) * Math.min(box.width, box.height), own2.weights ?? [], modeFor(own2) === "column");
5635
+ const own2 = inheritedSettings(settings, node.composition), area2 = inset(box, own2), slotCount = Math.max(node.children.length, node.reserved ?? 0);
5636
+ const cols = defaultColumns(slotCount, area2, own2);
5637
+ const boxes = gridBoxes(slotCount, area2, cols, (own2.gap ?? 1 / 30) * Math.min(box.width, box.height), own2.weights ?? [], modeFor(own2) === "column");
5431
5638
  return node.children.reduce((score, child, index) => score + scoreNode(child, boxes[index], own2, penalties), 0);
5432
5639
  };
5433
- const arrange = (nodes, area2, settings, reserved = 0, gapOverride, containerPath = path, recorded = true) => {
5640
+ const slots = [];
5641
+ const emptySlots = (entries, boxes, settings) => entries.forEach((entry, index) => {
5642
+ const box = boxes[index];
5643
+ if (!box) return;
5644
+ slots.push({ path: entry.path, type: entry.type, depth: entry.depth, box: acceptedBox(box) });
5645
+ if (!entry.children) return;
5646
+ const own2 = inheritedSettings(settings, record6(entry.placeholder.composition)), inner = inset(box, own2);
5647
+ const cols = defaultColumns(entry.children.length, inner, own2);
5648
+ const mirror = (cell) => rtl ? { ...cell, x: inner.x + inner.width - (cell.x - inner.x) - cell.width } : cell;
5649
+ emptySlots(entry.children, gridBoxes(entry.children.length, inner, cols, (own2.gap ?? 1 / 30) * Math.min(box.width, box.height), own2.weights ?? [], modeFor(own2) === "column").map(mirror), own2);
5650
+ });
5651
+ const arrange = (nodes, area2, settings, reserved = 0, gapOverride, containerPath = path, recorded = true, template) => {
5434
5652
  const count = Math.max(nodes.length, reserved);
5435
5653
  if (!count) return;
5436
5654
  const mode = modeFor(settings), localGap = (settings.gap ?? 1 / 30) * Math.min(area2.width, area2.height);
@@ -5442,9 +5660,9 @@ function composeSlide(input, options = {}) {
5442
5660
  let best = Infinity;
5443
5661
  for (let candidate = 1; candidate <= Math.min(count, settings.columns ?? 6); candidate++) {
5444
5662
  const boxes2 = gridBoxes(count, area2, candidate, actualGap, settings.weights ?? [], false);
5445
- const emptySlots = (Math.ceil(count / candidate) * candidate - count) * 2;
5446
- const penalties = candidates ? { cellProportions: 0, fontReduction: 0, textOverflow: 0, tableOverflow: 0, smallCells: 0, emptySlots } : void 0;
5447
- const score = nodes.reduce((sum, node, i) => sum + scoreNode(node, boxes2[i], settings, penalties), 0) + emptySlots;
5663
+ const emptySlots2 = (Math.ceil(count / candidate) * candidate - count) * 2;
5664
+ const penalties = candidates ? { cellProportions: 0, fontReduction: 0, textOverflow: 0, tableOverflow: 0, smallCells: 0, emptySlots: emptySlots2 } : void 0;
5665
+ const score = nodes.reduce((sum, node, i) => sum + scoreNode(node, boxes2[i], settings, penalties), 0) + emptySlots2;
5448
5666
  if (penalties && candidates) candidates.push({ columns: candidate, rows: Math.ceil(count / candidate), score, penalties });
5449
5667
  if (score < best) {
5450
5668
  best = score;
@@ -5462,13 +5680,15 @@ function composeSlide(input, options = {}) {
5462
5680
  const grid = gridGeometry(count, area2, cols, actualGap, settings.weights ?? [], mode === "column");
5463
5681
  const mirrored = (box) => rtl ? { ...box, x: area2.x + area2.width - (box.x - area2.x) - box.width } : box;
5464
5682
  const boxes = grid.boxes.map(mirrored);
5683
+ if (template) emptySlots(template.slice(nodes.length), boxes.slice(nodes.length), settings);
5465
5684
  if (recorded && !hasRegions) flows.push({ path: containerPath, box: { ...area2 }, composition: { ...settings }, columns: rtl ? grid.columns.map((track) => ({ offset: area2.width - track.offset - track.size, size: track.size })) : grid.columns, rows: grid.rows, gap: grid.gap, itemCount: nodes.length, slotCount: count });
5466
5685
  nodes.forEach((node, index) => {
5467
5686
  let box = node.region ? mirrored(regionBox(node.region, area2, actualGap)) : boxes[index];
5687
+ if (node.slot) slots.push({ path: node.slot.path, type: node.slot.type, depth: node.slot.depth, box: acceptedBox(box), ...node.slot.children ? {} : { content: node.path } });
5468
5688
  if (node.children) {
5469
5689
  const own2 = inheritedSettings(settings, node.composition), inner = inset(box, own2);
5470
5690
  if (!node.synthetic) groups.push({ path: node.path, box, contentBox: inner, composition: own2 });
5471
- arrange(node.children, inner, own2, 0, (own2.gap ?? 1 / 30) * Math.min(box.width, box.height), node.path, !node.synthetic);
5691
+ arrange(node.children, inner, own2, node.reserved ?? 0, (own2.gap ?? 1 / 30) * Math.min(box.width, box.height), node.path, !node.synthetic, node.slots);
5472
5692
  } else {
5473
5693
  const frameBox = hasCards ? acceptedBox(box) : void 0;
5474
5694
  box = payloadBox(box);
@@ -5484,6 +5704,7 @@ function composeSlide(input, options = {}) {
5484
5704
  const timelineLayout = node.field === "timeline" ? measureTimeline(node, box, settings) : void 0;
5485
5705
  const internal = quoteLayout ?? codeLayout ?? metricLayout ?? timelineLayout, body = internal?.parts.find((part) => part.role === "body" || part.role === "value");
5486
5706
  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;
5707
+ const image = node.field === "image" ? composeImage(node.host ?? {}, node.hostPath ?? node.path, box, box, imageContext()) : void 0;
5487
5708
  items.push({
5488
5709
  path: node.path,
5489
5710
  field: node.field,
@@ -5491,6 +5712,7 @@ function composeSlide(input, options = {}) {
5491
5712
  value: node.value,
5492
5713
  payload: node.payload,
5493
5714
  box: internal ? acceptedBox(box) : box,
5715
+ ...image ? { image } : {},
5494
5716
  ...frameBox ? { frameBox } : {},
5495
5717
  text: text2,
5496
5718
  textStyle: body?.style ?? styleFor(node.field, node.path),
@@ -5508,22 +5730,63 @@ function composeSlide(input, options = {}) {
5508
5730
  });
5509
5731
  };
5510
5732
  const placeholders = Array.isArray(layout.placeholders) ? layout.placeholders.filter((p) => !headings.has(p.type)) : [];
5511
- if (slideImage?.replacesContent) {
5512
- const picture = placeholders.findIndex((p) => p.type === "image");
5513
- if (picture >= 0) placeholders.splice(picture, 1);
5733
+ const placedSlots = new Set(placed.flatMap((entry) => imagePlaceholders[entry.slot] ? [imagePlaceholders[entry.slot].placeholder] : []));
5734
+ if (placedSlots.size) {
5735
+ for (let index = placeholders.length - 1; index >= 0; index--) if (placedSlots.has(placeholders[index])) placeholders.splice(index, 1);
5514
5736
  }
5515
- const ownMode = record5(slide.composition).mode;
5737
+ const ownMode = record6(slide.composition).mode;
5516
5738
  const direction = hints.contentDirection;
5517
5739
  const directionMode = direction === "vertical" ? "column" : direction === "horizontal" ? "row" : "auto";
5518
5740
  const chartHint = hints.chartPrimary;
5519
5741
  const chartSide = chartHint === "left" || chartHint === "right" || chartHint === "top" || chartHint === "bottom" ? chartHint : void 0;
5520
5742
  const chartIndex = pending.findIndex((node) => !node.children && node.field === "chart");
5521
5743
  const chartPrimary = chartSide !== void 0 && !ownMode && !regions.length && chartIndex >= 0 && pending.some((node) => node.children || node.field !== "chart") ? chartSide : void 0;
5522
- 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 };
5523
- if (chartPrimary) {
5744
+ const kindOf = (node) => node.children ? node.children[0] ? kindOf(node.children[0]) : "text" : FIELD_KINDS[node.field] ?? "text";
5745
+ const sugar = chartPrimary ? chartPrimaryLayout(chartPrimary, pending.filter((_, index) => index !== chartIndex).map(kindOf)) : void 0;
5746
+ const rootSettings = sugar ? { ...composition, ...sugar.composition, columns: void 0 } : { ...composition, mode: composition.mode ?? directionMode };
5747
+ const recordSlots = sugar ? [] : layoutSlots(layout).filter((slot) => !headings.has(slot.type) && !placedSlots.has(slot.placeholder));
5748
+ const templated = !sugar && !regions.length && recordSlots.some((slot) => slot.children) && pending.every((node) => !node.children);
5749
+ const fillSlots = (entries, queue, cursor, recordSlot) => {
5750
+ const nodes = [];
5751
+ for (const entry of entries) {
5752
+ if (cursor.next >= queue.length) break;
5753
+ if (!entry.children) {
5754
+ nodes.push({ ...queue[cursor.next++], ...recordSlot ? { slot: entry } : {} });
5755
+ continue;
5756
+ }
5757
+ const own2 = record6(entry.placeholder.composition);
5758
+ assertComposition(own2);
5759
+ const children = fillSlots(entry.children, queue, cursor, recordSlot);
5760
+ nodes.push({
5761
+ field: "blocks",
5762
+ type: "group",
5763
+ value: children.map((child) => child.payload),
5764
+ path,
5765
+ payload: {},
5766
+ children,
5767
+ composition: own2,
5768
+ synthetic: true,
5769
+ reserved: own2.mode ? 0 : entry.children.length,
5770
+ ...recordSlot ? { slot: entry, slots: entry.children } : {}
5771
+ });
5772
+ }
5773
+ return nodes;
5774
+ };
5775
+ if (sugar) {
5524
5776
  const primary = pending[chartIndex], rest = pending.filter((_, index) => index !== chartIndex);
5525
- const container = { field: "blocks", type: "group", value: rest.map((node) => node.payload), path, payload: {}, children: rest, composition: {}, synthetic: true };
5526
- arrange(chartPrimary === "left" || chartPrimary === "top" ? [primary, container] : [container, primary], contentBox, rootSettings, 0);
5777
+ const queue = chartPrimary === "left" || chartPrimary === "top" ? [primary, ...rest] : [...rest, primary];
5778
+ arrange(fillSlots(layoutSlots(sugar, "design.chartPrimary"), queue, { next: 0 }, false), contentBox, rootSettings, 0);
5779
+ } else if (templated) {
5780
+ const cursor = { next: 0 };
5781
+ const nodes = fillSlots(recordSlots, pending, cursor, true);
5782
+ arrange([...nodes, ...pending.slice(cursor.next)], contentBox, rootSettings, composition.mode ? 0 : placeholders.length, void 0, path, true, recordSlots);
5783
+ const order = /* @__PURE__ */ new Map();
5784
+ const number = (entries) => entries.forEach((entry) => {
5785
+ order.set(entry.path, order.size);
5786
+ if (entry.children) number(entry.children);
5787
+ });
5788
+ number(recordSlots);
5789
+ slots.sort((a, b) => order.get(a.path) - order.get(b.path));
5527
5790
  } else arrange(pending, contentBox, rootSettings, composition.mode ? 0 : placeholders.length);
5528
5791
  if (listBullet?.value === "image" && !bulletImage && items.some((item) => (item.field === "items" || item.field === "bullets") && item.payload.numbering === void 0)) {
5529
5792
  diagnostics.push({ code: "unresolved-content", path: listBullet.path, message: "Picture bullets (listBullet: image) need design.logo or a primary organization logo; the marker glyph is drawn instead." });
@@ -5563,8 +5826,9 @@ function composeSlide(input, options = {}) {
5563
5826
  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)
5564
5827
  } : void 0;
5565
5828
  if (failures.length) throw new OPFCompositionError(failures, explanation);
5566
- diagnostics.push(...slideImageDiagnostics, ...numberingDiagnostics);
5567
- return { width, height, contentBox, items, groups, flows, diagnostics, composition, design: hints, ...furniture ? { furniture } : {}, ...slideImage ? { slideImage } : {}, ...logo ? { logo } : {}, ...rtl ? { direction: "rtl" } : {}, ...footnotes ? { footnotes } : {}, ...explanation ? { explanation } : {} };
5829
+ diagnostics.push(...imageDiagnostics, ...numberingDiagnostics);
5830
+ for (const slot of slots) for (const key of ["x", "y", "width", "height"]) slot.box[key] = round2(slot.box[key]);
5831
+ return { width, height, contentBox, items, groups, flows, ...slots.length ? { slots } : {}, diagnostics, composition, design: hints, ...furniture ? { furniture } : {}, ...backgroundImage ? { backgroundImage } : {}, ...logo ? { logo } : {}, ...rtl ? { direction: "rtl" } : {}, ...footnotes ? { footnotes } : {}, ...explanation ? { explanation } : {} };
5568
5832
  }
5569
5833
  function resolveCanvasDimensions(input) {
5570
5834
  const presets = {
@@ -5579,7 +5843,7 @@ function resolveCanvasDimensions(input) {
5579
5843
  letter: [11, 8.5],
5580
5844
  a4: [11.69, 8.27]
5581
5845
  };
5582
- const value = record5(input);
5846
+ const value = record6(input);
5583
5847
  const preset = presets[typeof input === "string" ? input : value.preset] ?? presets.widescreen;
5584
5848
  const width = (value.widthInches ?? preset[0]) * 96;
5585
5849
  const height = (value.heightInches ?? preset[1]) * 96;
@@ -5587,4 +5851,4 @@ function resolveCanvasDimensions(input) {
5587
5851
  return { width, height };
5588
5852
  }
5589
5853
 
5590
- 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, 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_FONT_SCHEME, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_SLIDE_NUMBER_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, 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, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, annotationText, bareIdPattern, 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, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatSlideNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, 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, resolveFontFamilies, resolveFontSchemeReference, resolveLogo, resolveNumbering, resolvePatternPreset, resolveScriptFonts, resolveSlideDirection, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, scriptFontRole, sliceNumberedItems, slideCitations, slideImageShape, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unusedDatasets, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
5854
+ 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_PLACEHOLDER_GROUP_DEPTH, 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, chartPrimaryLayout, 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, hasPlaceholderGroups, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isPlaceholderGroup, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutLeaves, layoutMetric, layoutQuote, layoutSlots, layoutStructure, 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 };