@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
@@ -3,7 +3,7 @@ var presentation = {
3
3
  "$schema": "https://json-schema.org/draft/2020-12/schema",
4
4
  "$id": "https://openpresentation.org/schema/opf/v1",
5
5
  "title": "Presentation",
6
- "description": "Open-source JSON format for describing PowerPoint presentations. Agents describe narratives, content, audience, reusable assets, and design \u2014 the engine handles OOXML complexity.\n\nFields that reference catalog records (narrative, language, tone, audience, purpose, design.theme / design.theme.id, design.colorScheme / design.colorScheme.id, design.fontScheme / design.fontScheme.id, Slide.layout, Chart.type, Organization.socials / Speaker.socials) resolve through the catalog system: inline 'catalogs.<kind>.records[]' on the document \u2192 'catalogs.<kind>.source' on the document \u2192 engine defaults \u2192 the default catalog at https://www.pptx.gallery/<kind>. The default catalog is published by pptx.gallery: the index at https://www.pptx.gallery/<kind>/index.json (also GET https://www.pptx.gallery/<kind> with Accept: application/json) and each record at https://www.pptx.gallery/<kind>/<id>.json. Engines resolve it from the pinned snapshot bundled in @openpresentation/opf (spec/catalogs, pinned by spec/catalogs/manifest.json) and never fetch it at run time; fetching a document's catalogs.<kind>.source is an explicit opt-in by the caller. Every reference resolves to the catalog record's 'id' field. When an OPF document omits a reference entirely, the engine falls back to engine defaults (see /spec/reference/engine-defaults.json for a reference example). The defaults file is engine configuration; it is not part of the OPF document contract and has no JSON Schema.\n\nMost catalog references accept the bare 'id' as a string for the common case (e.g. narrative = 'classic-story', design.colorScheme = 'cool-horizon'). Audience, purpose, tone, design, and language object forms use 'id' as a base catalog reference plus inline overrides. Asset references use 'asset:<id>' strings that point into the top-level assets registry, and content color fields (rich-text runs, styled table cells) accept hex values, color-scheme slot/role names, or 'var:<id>' references into the top-level variables map.",
6
+ "description": "Open-source JSON format for describing PowerPoint presentations. Agents describe narratives, content, audience, reusable assets, and design \u2014 the engine handles OOXML complexity.\n\nContent references (Slide.layout, design.theme, design.colorScheme / design.colorScheme.id, design.fontScheme / design.fontScheme.id, narrative, audience, purpose and tone, and the colorScheme / fontScheme a theme record names) point at catalog records. Each is a bare 'id' or a 'name:id' whose prefix names a group in 'catalogs'. A bare id resolves in catalogs.custom, then in the records embedded under catalogs.default, then in the catalog the host registered for catalogs.default.source (or the host's default catalog when 'default' is omitted); 'name:id' resolves in catalogs.<name>, then in the catalog the host registered for its source. A reference that resolves nowhere is the warning opf/unresolved-reference, and the slide uses automatic composition or the engine default. Engines never fetch a catalog: a saved document embeds every record it uses, and hosts register any other catalog by its source string. See docs/default-catalog.md.\n\nchart.type, the language tag and the keys of Organization.socials / Speaker.socials are engine vocabularies, validated directly with no catalog lookup. When a document names no theme, colour scheme or font scheme, every engine uses the same small engine defaults (spec/reference/engine-defaults.json). Asset references use 'asset:<id>' strings that point into the top-level assets registry, and content color fields (rich-text runs, styled table cells) accept hex values, color-scheme slot/role names, or 'var:<id>' references into the top-level variables map.",
7
7
  "type": "object",
8
8
  "required": [
9
9
  "slides"
@@ -114,7 +114,7 @@ var presentation = {
114
114
  "minItems": 1
115
115
  }
116
116
  ],
117
- "description": "Intended audiences for the presentation. Accepts any of:\n- A single string shorthand: free-form description ('Series B investors'), an audiences catalog id ('executive'), an HTTPS URL, or a 'pkg:' reference.\n- A single inline Audience object, like purpose and tone, for custom audience metadata or catalog-backed overrides. Object form mirrors https://openpresentation.org/schema/opf-audience/v1 without '$schema'.\n- An array of string shorthands and/or inline Audience objects, for more than one audience.\n\nResolution order for catalog ids and references: inline catalogs.audiences.records[] \u2192 catalogs.audiences.source \u2192 default catalog at https://www.pptx.gallery/audiences.",
117
+ "description": "Intended audiences for the presentation. Accepts any of:\n- A single string: an audiences reference ('executive', or 'acme:board' for a record of the catalogs.acme group), or free-form text ('Series B investors'). A string that is a bare id or 'name:id' is a reference; any other string is free text and is never looked up.\n- A single inline Audience object, for custom audience metadata or overrides on a referenced record. Object form has the fields of https://openpresentation.org/schema/opf-audience/v1.\n- An array of strings and/or inline Audience objects, for more than one audience.\n\nA reference resolves like every content reference (see catalogs); one that resolves nowhere is the warning opf/unresolved-reference. Nothing is drawn from the audience.",
118
118
  "examples": [
119
119
  "executive",
120
120
  "Biology Students and Wildlife Enthusiasts",
@@ -131,7 +131,7 @@ var presentation = {
131
131
  },
132
132
  [
133
133
  "Series B investors",
134
- "https://acme.com/decks/audiences/acme-board.json"
134
+ "acme:board"
135
135
  ],
136
136
  [
137
137
  {
@@ -156,13 +156,12 @@ var presentation = {
156
156
  "$ref": "#/$defs/Purpose"
157
157
  }
158
158
  ],
159
- "description": "Primary goal of the presentation. Accepts either:\n- A string shorthand: free-form goal ('Raise a Series B round of $30M'), a purposes catalog id ('decide', 'align'), an HTTPS URL, or a 'pkg:' reference.\n- An inline Purpose object for custom purpose metadata or catalog-backed overrides. Object form mirrors https://openpresentation.org/schema/opf-purpose/v1 without '$schema'.\n\nResolution order for catalog ids and references: inline catalogs.purposes.records[] \u2192 catalogs.purposes.source \u2192 default catalog at https://www.pptx.gallery/purposes.",
159
+ "description": "Primary goal of the presentation. Accepts either:\n- A string: a purposes reference ('decide', or 'acme:fundraise' for a record of the catalogs.acme group), or a free-form goal ('Raise a Series B round of $30M'). A string that is a bare id or 'name:id' is a reference; any other string is free text and is never looked up.\n- An inline Purpose object for custom purpose metadata or overrides on a referenced record. Object form has the fields of https://openpresentation.org/schema/opf-purpose/v1.\n\nA reference resolves like every content reference (see catalogs); one that resolves nowhere is the warning opf/unresolved-reference. Nothing is drawn from the purpose.",
160
160
  "examples": [
161
161
  "Raise a Series B round of $30M",
162
162
  "align",
163
163
  "educate",
164
- "https://acme.com/decks/purposes/fundraise.json",
165
- "pkg:@acme/decks/purposes/fundraise",
164
+ "acme:fundraise",
166
165
  {
167
166
  "id": "decide",
168
167
  "outcome": "Approve the Q4 hiring plan"
@@ -176,25 +175,20 @@ var presentation = {
176
175
  "language": {
177
176
  "oneOf": [
178
177
  {
179
- "type": "string"
178
+ "$ref": "#/$defs/LanguageTag"
180
179
  },
181
180
  {
182
181
  "$ref": "#/$defs/Language"
183
182
  }
184
183
  ],
185
- "description": "Language for the presentation content. Accepts either:\n- A string shorthand: a BCP-47 language tag ('en-US', 'en-GB', 'ja-JP', 'fr'), a languages catalog id ('english', 'japanese'), an HTTPS URL, or a 'pkg:' reference.\n- An inline Language object for custom language metadata or catalog-backed overrides. Object form mirrors https://openpresentation.org/schema/opf-language/v1 without '$schema'.\n\nResolution order for catalog ids and references: inline catalogs.languages.records[] \u2192 catalogs.languages.source \u2192 default catalog at https://www.pptx.gallery/languages.",
184
+ "description": "Language of the presentation content, an engine vocabulary: a BCP-47 language tag, validated directly with no catalog lookup. Accepts either:\n- A BCP-47 tag ('en-US', 'en-GB', 'ja', 'zh-Hans', 'ar-SA').\n- An inline Language object: a 'bcp47' tag plus overrides of what engines know about it (name, ooxmlLang, script, direction, the script font schemes).\n\nEngines know the script, base direction, OOXML language tag and default script fonts of the tags in spec/reference/engine-vocabularies.json; any other well-formed tag is accepted and its script is inferred from the tag. Language names and descriptions are catalog display metadata, not part of the document.",
186
185
  "examples": [
187
186
  "en-US",
188
187
  "en-GB",
189
188
  "es-MX",
190
- "ja-JP",
189
+ "ja",
191
190
  "fr",
192
- "english",
193
- "japanese",
194
- "https://acme.com/decks/languages/en-acme.json",
195
- "pkg:@acme/decks/languages/en-acme",
196
191
  {
197
- "id": "english",
198
192
  "bcp47": "en-US",
199
193
  "fontScheme": "aptos",
200
194
  "googleFontScheme": "roboto"
@@ -210,21 +204,20 @@ var presentation = {
210
204
  "tone": {
211
205
  "oneOf": [
212
206
  {
213
- "type": "string"
207
+ "$ref": "#/$defs/CatalogReference"
214
208
  },
215
209
  {
216
210
  "$ref": "#/$defs/Tone"
217
211
  }
218
212
  ],
219
- "description": "Desired tone for the presentation. Accepts either:\n- A string shorthand: a tones catalog id ('formal'), an HTTPS URL, or a 'pkg:' reference.\n- An inline Tone object for custom tone metadata or catalog-backed overrides. Object form mirrors https://openpresentation.org/schema/opf-tone/v1 without '$schema'.\n\nResolution order for catalog ids and references: inline catalogs.tones.records[] \u2192 catalogs.tones.source \u2192 default catalog at https://www.pptx.gallery/tones.",
213
+ "description": "Desired tone for the presentation. Accepts either:\n- A tones reference: a bare id ('formal') or 'name:id' for a record of a named catalogs group.\n- An inline Tone object for custom tone metadata or overrides on a referenced record. Object form has the fields of https://openpresentation.org/schema/opf-tone/v1.\n\nA reference resolves like every content reference (see catalogs); one that resolves nowhere is the warning opf/unresolved-reference. Nothing is drawn from the tone.",
220
214
  "examples": [
221
215
  "formal",
222
216
  "casual",
223
217
  "inspirational",
224
218
  "technical",
225
219
  "persuasive",
226
- "https://acme.com/decks/tones/acme-voice.json",
227
- "pkg:@acme/decks/tones/acme-voice",
220
+ "acme:house-voice",
228
221
  {
229
222
  "id": "formal",
230
223
  "voiceCues": [
@@ -301,15 +294,14 @@ var presentation = {
301
294
  "default": false
302
295
  },
303
296
  "narrative": {
304
- "type": "string",
305
- "description": "The deck's narrative plan, by reference: the 'id' of a 'narratives' catalog record, an HTTPS URL pointing at a record file, or a 'pkg:' reference to a locally-installed package. The deck holds only this pointer; the plan (the arc, its beats and what each beat must do) lives in the catalog record, which validates against https://openpresentation.org/schema/opf-narrative/v1. A custom narrative is a record in catalogs.narratives.records, referenced here by its id.\n\nSlides link themselves to beats with slides[].beat. Core validate warns about a slides[].beat id the resolved narrative does not define and about a root 'duration' outside its 'duration' range, and reports a beat that no slide references. The preview and the PPTX export draw nothing from the narrative; opf-pptx stores the reference for round-trip.\n\nResolution order: inline catalogs.narratives.records[] \u2192 catalogs.narratives.source \u2192 default catalog at https://www.pptx.gallery/narratives. Unknown ids produce a validation warning, not an error.\n\nDeck-level concerns that are not part of the storyline (audience, tone, takeaway, duration) live as siblings on the presentation root.",
297
+ "$ref": "#/$defs/CatalogReference",
298
+ "description": "The deck's narrative plan, by reference: a bare narratives id ('classic-story') or 'name:id' for a record of a named catalogs group ('acme:founder-pitch'). The deck holds only this pointer; the plan (the arc, its beats and what each beat must do) lives in the record, which has the fields of https://openpresentation.org/schema/opf-narrative/v1. A narrative the document defines itself is a record in catalogs.custom.narratives, referenced here by its key.\n\nSlides link themselves to beats with slides[].beat. Core validate warns about a slides[].beat id the resolved narrative does not define and about a root 'duration' outside its 'duration' range, and reports a beat that no slide references. The preview and the PPTX export draw nothing from the narrative; opf-pptx stores the reference for round-trip.\n\nThe reference resolves like every content reference (see catalogs); one that resolves nowhere is the warning opf/unresolved-reference, never an error.\n\nDeck-level concerns that are not part of the storyline (audience, tone, takeaway, duration) live as siblings on the presentation root.",
306
299
  "examples": [
307
300
  "classic-story",
308
301
  "problem-solution",
309
302
  "scqa",
310
303
  "pitch-deck",
311
- "https://acme.com/decks/narratives/founder-pitch.json",
312
- "pkg:@acme/decks/narratives/founder-pitch"
304
+ "acme:founder-pitch"
313
305
  ]
314
306
  },
315
307
  "slides": {
@@ -346,7 +338,7 @@ var presentation = {
346
338
  },
347
339
  "catalogs": {
348
340
  "$ref": "#/$defs/Catalogs",
349
- "description": "Optional per-kind catalog overrides. Each kind may declare a non-default 'source' and/or inline 'records' that override or supplement the default catalog at https://www.pptx.gallery/<kind>. References elsewhere in the document (e.g. design.theme, narrative) resolve through this section before falling back to the default catalog."
341
+ "description": "The catalog records this document embeds, grouped by the catalog they came from: 'default' (the catalog bare ids come from), 'custom' (records the document defines itself) and any number of named catalogs ('acme', referenced as 'acme:<id>'). A saved document embeds every record it references, so it renders the same with no catalog registered. See Catalogs."
350
342
  },
351
343
  "extensions": {
352
344
  "type": "object",
@@ -435,7 +427,7 @@ var presentation = {
435
427
  },
436
428
  "Audience": {
437
429
  "type": "object",
438
- "description": "Inline audience metadata for the presentation. Use 'id' to reference an audiences catalog record and override selected fields, or use 'name' for a custom inline audience.",
430
+ "description": "Inline audience metadata for the presentation. Use 'id' to reference an audiences record (a bare id or 'name:id') and override selected fields, or use 'name' for a custom inline audience.",
439
431
  "anyOf": [
440
432
  {
441
433
  "required": [
@@ -450,9 +442,8 @@ var presentation = {
450
442
  ],
451
443
  "properties": {
452
444
  "id": {
453
- "type": "string",
454
- "pattern": "^[a-z][a-z0-9-]*$",
455
- "description": "Optional audiences catalog id to resolve before applying inline overrides.",
445
+ "$ref": "#/$defs/CatalogReference",
446
+ "description": "Optional audiences reference (a bare id or 'name:id') resolved before applying the inline overrides.",
456
447
  "examples": [
457
448
  "executive",
458
449
  "board",
@@ -512,14 +503,14 @@ var presentation = {
512
503
  "items": {
513
504
  "type": "string"
514
505
  },
515
- "description": "Soft cross-link: narrative-catalog ids that work well for this audience."
506
+ "description": "Soft cross-link: narrative ids that work well for this audience, for picker UIs. Never resolved, embedded or validated as references."
516
507
  },
517
508
  "recommendedTones": {
518
509
  "type": "array",
519
510
  "items": {
520
511
  "type": "string"
521
512
  },
522
- "description": "Soft cross-link: tone-catalog ids that work well for this audience."
513
+ "description": "Soft cross-link: tone ids that work well for this audience, for picker UIs. Never resolved, embedded or validated as references."
523
514
  },
524
515
  "tags": {
525
516
  "type": "array",
@@ -532,7 +523,7 @@ var presentation = {
532
523
  },
533
524
  "Purpose": {
534
525
  "type": "object",
535
- "description": "Inline purpose metadata for the presentation. Use 'id' to reference a purposes catalog record and override selected fields, or use 'name' for a custom inline purpose.",
526
+ "description": "Inline purpose metadata for the presentation. Use 'id' to reference a purposes record (a bare id or 'name:id') and override selected fields, or use 'name' for a custom inline purpose.",
536
527
  "anyOf": [
537
528
  {
538
529
  "required": [
@@ -547,9 +538,8 @@ var presentation = {
547
538
  ],
548
539
  "properties": {
549
540
  "id": {
550
- "type": "string",
551
- "pattern": "^[a-z][a-z0-9-]*$",
552
- "description": "Optional purposes catalog id to resolve before applying inline overrides.",
541
+ "$ref": "#/$defs/CatalogReference",
542
+ "description": "Optional purposes reference (a bare id or 'name:id') resolved before applying the inline overrides.",
553
543
  "examples": [
554
544
  "inform",
555
545
  "decide",
@@ -586,14 +576,14 @@ var presentation = {
586
576
  "items": {
587
577
  "type": "string"
588
578
  },
589
- "description": "Soft cross-link: narrative-catalog ids that work well for this purpose."
579
+ "description": "Soft cross-link: narrative ids that work well for this purpose, for picker UIs. Never resolved, embedded or validated as references."
590
580
  },
591
581
  "recommendedTones": {
592
582
  "type": "array",
593
583
  "items": {
594
584
  "type": "string"
595
585
  },
596
- "description": "Soft cross-link: tone-catalog ids that work well for this purpose."
586
+ "description": "Soft cross-link: tone ids that work well for this purpose, for picker UIs. Never resolved, embedded or validated as references."
597
587
  },
598
588
  "tags": {
599
589
  "type": "array",
@@ -606,31 +596,16 @@ var presentation = {
606
596
  },
607
597
  "Language": {
608
598
  "type": "object",
609
- "description": "Inline language metadata for the presentation. Use 'id' to reference a languages catalog record and override selected fields, or use 'bcp47' for a custom language tag without a catalog record.",
610
- "anyOf": [
611
- {
612
- "required": [
613
- "id"
614
- ]
615
- },
616
- {
617
- "required": [
618
- "bcp47"
619
- ]
620
- }
599
+ "description": "Inline language metadata for the presentation: a BCP-47 'bcp47' tag plus overrides of what engines know about it. Languages are an engine vocabulary, not catalog records, so there is no 'id'.",
600
+ "required": [
601
+ "bcp47"
621
602
  ],
603
+ "not": {
604
+ "required": [
605
+ "id"
606
+ ]
607
+ },
622
608
  "properties": {
623
- "id": {
624
- "type": "string",
625
- "pattern": "^[a-z][a-z0-9-]*$",
626
- "description": "Optional languages catalog id to resolve before applying inline overrides.",
627
- "examples": [
628
- "english",
629
- "japanese",
630
- "chinese-simplified",
631
- "english-uk"
632
- ]
633
- },
634
609
  "name": {
635
610
  "type": "string",
636
611
  "description": "Human-readable language name.",
@@ -641,7 +616,7 @@ var presentation = {
641
616
  ]
642
617
  },
643
618
  "bcp47": {
644
- "type": "string",
619
+ "$ref": "#/$defs/LanguageTag",
645
620
  "description": "BCP-47 language tag used for locale-aware rendering, proofing, and accessibility metadata. Use 'en-GB' for UK English; 'en-UK' is not a valid BCP-47 region form.",
646
621
  "examples": [
647
622
  "en",
@@ -653,7 +628,7 @@ var presentation = {
653
628
  },
654
629
  "ooxmlLang": {
655
630
  "type": "string",
656
- "description": "Curated culture tag for OOXML text-run language attributes (a:rPr/@lang, a:endParaRPr/@lang), in the language-[Script-]REGION form Office recognizes (e.g. 'ja-JP', 'ar-SA', 'ms-MY', 'nb-NO', 'fil-PH', 'zh-CN'). Engines emit it instead of 'bcp47' when the document names the language by catalog id or by a tag without a region; a region-bearing tag written by the author is emitted as written. Curated rather than inferred so output does not depend on the runtime's locale data.",
631
+ "description": "Culture tag for OOXML text-run language attributes (a:rPr/@lang, a:endParaRPr/@lang), in the language-[Script-]REGION form Office recognizes (e.g. 'ja-JP', 'ar-SA', 'ms-MY', 'nb-NO', 'fil-PH', 'zh-CN'). Without it, engines emit the curated tag of their language vocabulary (spec/reference/engine-vocabularies.json) for a tag without a region, and a region-bearing tag as written. Curated rather than inferred so output does not depend on the runtime's locale data.",
657
632
  "examples": [
658
633
  "en-US",
659
634
  "ja-JP",
@@ -679,11 +654,11 @@ var presentation = {
679
654
  "ltr",
680
655
  "rtl"
681
656
  ],
682
- "description": "Base text direction for the language. When omitted, engines derive it from the script: Arabic (Arab), Hebrew (Hebr), Syriac (Syrc), Thaana (Thaa), N'Ko (Nkoo), Adlam (Adlm), Samaritan (Samr), Mandaic (Mand) and Hanifi Rohingya (Rohg) are right-to-left; every other script is left-to-right. Bundled language records state it explicitly."
657
+ "description": "Base text direction for the language. When omitted, engines derive it from the script: Arabic (Arab), Hebrew (Hebr), Syriac (Syrc), Thaana (Thaa), N'Ko (Nkoo), Adlam (Adlm), Samaritan (Samr), Mandaic (Mand) and Hanifi Rohingya (Rohg) are right-to-left; every other script is left-to-right. The engine language vocabulary (spec/reference/engine-vocabularies.json) states it for the tags it knows."
683
658
  },
684
659
  "script": {
685
660
  "type": "string",
686
- "description": "ISO 15924 script code of the language's writing system. The script selects the OOXML font slot the language's text uses: East Asian scripts (Hans, Hant, Hani, Jpan, Kore, Hang, Hira, Kana, Bopo, Yiii) use the eastAsian slot; complex scripts (for example Arab, Hebr, Syrc, Thaa, Deva, Beng, Guru, Gujr, Orya, Taml, Telu, Knda, Mlym, Sinh, Thai, Laoo, Tibt, Mymr, Khmr, Mong) use the complexScript slot; every other script (Latn, Cyrl, Grek, Armn, Geor, Ethi, ...) uses the latin slot. When omitted, engines infer it from the BCP-47 tag. Bundled language records state it explicitly. See docs/programs/font-fidelity-everywhere/script-font-model.md.",
661
+ "description": "ISO 15924 script code of the language's writing system. The script selects the OOXML font slot the language's text uses: East Asian scripts (Hans, Hant, Hani, Jpan, Kore, Hang, Hira, Kana, Bopo, Yiii) use the eastAsian slot; complex scripts (for example Arab, Hebr, Syrc, Thaa, Deva, Beng, Guru, Gujr, Orya, Taml, Telu, Knda, Mlym, Sinh, Thai, Laoo, Tibt, Mymr, Khmr, Mong) use the complexScript slot; every other script (Latn, Cyrl, Grek, Armn, Geor, Ethi, ...) uses the latin slot. When omitted, engines infer it from the BCP-47 tag. The engine language vocabulary (spec/reference/engine-vocabularies.json) states it for the tags it knows. See docs/programs/font-fidelity-everywhere/script-font-model.md.",
687
662
  "examples": [
688
663
  "Latn",
689
664
  "Cyrl",
@@ -699,12 +674,12 @@ var presentation = {
699
674
  ]
700
675
  },
701
676
  "fontScheme": {
702
- "type": "string",
703
- "description": "Default font-scheme id for this language when targeting PowerPoint output. Resolves against catalogs.fontSchemes the same way design.fontScheme or design.fontScheme.id does. Its major/minor families fill the language's script slot (eastAsian or complexScript, chosen by 'script') unless the effective design font scheme sets that slot itself; the latin slot always follows the design font scheme."
677
+ "$ref": "#/$defs/CatalogReference",
678
+ "description": "Font-scheme reference (a bare id or 'name:id') for this language's script slot when targeting PowerPoint output. Its major/minor families fill the language's script slot (eastAsian or complexScript, chosen by 'script') unless the effective design font scheme sets that slot itself; the latin slot always follows the design font scheme. Without it, engines use the default script fonts of their language vocabulary."
704
679
  },
705
680
  "googleFontScheme": {
706
- "type": "string",
707
- "description": "Default font-scheme id for this language when targeting Google Slides output. Resolves against catalogs.fontSchemes the same way design.fontScheme or design.fontScheme.id does. Used in place of 'fontScheme' when resolving script fonts for Google Slides output."
681
+ "$ref": "#/$defs/CatalogReference",
682
+ "description": "Font-scheme reference (a bare id or 'name:id') used in place of 'fontScheme' when resolving script fonts for Google Slides output."
708
683
  },
709
684
  "summary": {
710
685
  "type": "string",
@@ -725,7 +700,7 @@ var presentation = {
725
700
  },
726
701
  "Tone": {
727
702
  "type": "object",
728
- "description": "Inline tone metadata for the presentation. Use 'id' to reference a tones catalog record and override selected fields, or use 'name' for a custom inline tone.",
703
+ "description": "Inline tone metadata for the presentation. Use 'id' to reference a tones record (a bare id or 'name:id') and override selected fields, or use 'name' for a custom inline tone.",
729
704
  "anyOf": [
730
705
  {
731
706
  "required": [
@@ -740,9 +715,8 @@ var presentation = {
740
715
  ],
741
716
  "properties": {
742
717
  "id": {
743
- "type": "string",
744
- "pattern": "^[a-z][a-z0-9-]*$",
745
- "description": "Optional tones catalog id to resolve before applying inline overrides.",
718
+ "$ref": "#/$defs/CatalogReference",
719
+ "description": "Optional tones reference (a bare id or 'name:id') resolved before applying the inline overrides.",
746
720
  "examples": [
747
721
  "formal",
748
722
  "casual",
@@ -788,7 +762,7 @@ var presentation = {
788
762
  "items": {
789
763
  "type": "string"
790
764
  },
791
- "description": "Soft cross-link: narrative-catalog ids this tone pairs well with."
765
+ "description": "Soft cross-link: narrative ids this tone pairs well with, for picker UIs. Never resolved, embedded or validated as references."
792
766
  },
793
767
  "tags": {
794
768
  "type": "array",
@@ -985,7 +959,7 @@ var presentation = {
985
959
  },
986
960
  "Socials": {
987
961
  "type": "object",
988
- "description": "Social media handles or URLs, keyed by platform id from the 'socialPlatforms' catalog. Each value is a string \u2014 either a full URL or a platform handle (e.g., '@acme'). The catalog record for each platform carries the URL pattern and handle prefix that engines use to render and link the profile URL, plus brand color and themed icons as catalog metadata for authoring UIs (engines render the profile URL, not icons or brand colors).\n\nKeys resolve to the 'id' of a 'socialPlatforms' catalog record. Resolution order: inline catalogs.socialPlatforms.records[] \u2192 catalogs.socialPlatforms.source \u2192 default catalog at https://www.pptx.gallery/social-platforms. Unknown platform keys render with engine fallbacks (the raw value as text). Used both for organization and speaker records.",
962
+ "description": "Social media handles or URLs, keyed by platform. The keys are an engine vocabulary validated directly (no catalog lookup): engines link a handle with the platform's URL pattern and handle prefix (spec/reference/engine-vocabularies.json). Each value is a string, either a full URL or a platform handle (e.g., '@acme'). Brand colours and icons are catalog display metadata for authoring UIs; engines render the profile URL, not icons or brand colours. Used both for organization and speaker records.",
989
963
  "additionalProperties": {
990
964
  "type": "string",
991
965
  "description": "Handle or URL for the platform identified by the property key."
@@ -1003,8 +977,19 @@ var presentation = {
1003
977
  }
1004
978
  ],
1005
979
  "propertyNames": {
1006
- "pattern": "^[a-z][a-z0-9-]*$",
1007
- "description": "Platform id (lowercase kebab-case). Common ids include 'linkedin', 'x', 'github', 'youtube', 'instagram', 'facebook', 'tiktok', 'threads', 'mastodon', 'bluesky'."
980
+ "enum": [
981
+ "linkedin",
982
+ "x",
983
+ "github",
984
+ "youtube",
985
+ "instagram",
986
+ "facebook",
987
+ "tiktok",
988
+ "threads",
989
+ "mastodon",
990
+ "bluesky"
991
+ ],
992
+ "description": "Platform key, one of the engine's social platforms."
1008
993
  }
1009
994
  },
1010
995
  "Design": {
@@ -1012,35 +997,14 @@ var presentation = {
1012
997
  "description": "Visual design system applied to the presentation; individual slides may override fields via Slide.design.",
1013
998
  "properties": {
1014
999
  "theme": {
1015
- "oneOf": [
1016
- {
1017
- "type": "string"
1018
- },
1019
- {
1020
- "$ref": "#/$defs/Theme"
1021
- }
1022
- ],
1023
- "description": `Theme for the deck. Accepts two forms:
1024
- - String shorthand: 'design.theme = "minimal"'. Bare id, HTTPS URL, or 'pkg:' reference resolved as the 'id' of a 'themes' catalog record.
1025
- - Object form: a Theme with an optional 'id' base reference plus theme-level overrides.
1026
-
1027
- Inline overrides on design.colorScheme / design.fontScheme / design.background / design.dimensions take precedence over the resolved theme.
1028
-
1029
- Resolution order: inline catalogs.themes.records[] -> catalogs.themes.source -> default catalog at https://www.pptx.gallery/themes.`,
1000
+ "$ref": "#/$defs/CatalogReference",
1001
+ "description": "Theme for the deck: a themes reference, a bare id ('minimal') or 'name:id' ('acme:brand'). The theme supplies the default colour scheme, font scheme, background and dimensions; design.colorScheme, design.fontScheme, design.background and design.dimensions override it field by field. A reference that resolves nowhere is the warning opf/unresolved-reference and engines use the engine default theme.",
1030
1002
  "examples": [
1031
1003
  "minimal",
1032
1004
  "classic",
1033
1005
  "dark",
1034
1006
  "bold",
1035
- "corporate-minimal",
1036
- "ocean-depth",
1037
- "https://acme.com/decks/themes/acme-brand.json",
1038
- "pkg:@acme/decks/themes/acme-brand",
1039
- {
1040
- "id": "minimal",
1041
- "background": "dark1",
1042
- "dimensions": "widescreen"
1043
- }
1007
+ "acme:brand"
1044
1008
  ]
1045
1009
  },
1046
1010
  "colorScheme": {
@@ -1052,11 +1016,7 @@ Resolution order: inline catalogs.themes.records[] -> catalogs.themes.source ->
1052
1016
  "$ref": "#/$defs/ColorScheme"
1053
1017
  }
1054
1018
  ],
1055
- "description": `Color scheme for the presentation. Accepts two forms:
1056
- - String shorthand: 'design.colorScheme = "cool-horizon"'. Bare id, HTTPS URL, or 'pkg:' reference resolved as the 'id' of a 'colorSchemes' catalog record.
1057
- - Object form: a ColorScheme with an optional 'id' base reference plus slot/role overrides.
1058
-
1059
- Resolution order: inline catalogs.colorSchemes.records[] -> catalogs.colorSchemes.source -> default catalog at https://www.pptx.gallery/color-schemes.`,
1019
+ "description": "Color scheme for the presentation. Accepts two forms:\n- A colorSchemes reference: a bare id ('cool-horizon') or 'name:id' ('acme:ocean').\n- Object form: a ColorScheme with an optional 'id' reference as the base plus slot/role overrides. Without 'id', the overrides apply on top of the engine default colour scheme.\n\nWithout either, the theme's colorScheme applies, then the engine default colour scheme.",
1060
1020
  "examples": [
1061
1021
  "cool-horizon",
1062
1022
  "boost",
@@ -1076,11 +1036,7 @@ Resolution order: inline catalogs.colorSchemes.records[] -> catalogs.colorScheme
1076
1036
  "$ref": "#/$defs/FontScheme"
1077
1037
  }
1078
1038
  ],
1079
- "description": `Font scheme for heading, body, accent, and code text. Accepts two forms:
1080
- - String shorthand: 'design.fontScheme = "aptos"'. Bare id, HTTPS URL, or 'pkg:' reference resolved as the 'id' of a 'fontSchemes' catalog record.
1081
- - Object form: a FontScheme with an optional 'id' base reference plus pair/role overrides.
1082
-
1083
- Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.source -> default catalog at https://www.pptx.gallery/font-schemes.`,
1039
+ "description": "Font scheme for heading, body, accent, and code text. Accepts two forms:\n- A fontSchemes reference: a bare id ('aptos') or 'name:id' ('acme:inter').\n- Object form: a FontScheme with an optional 'id' reference as the base plus pair/role overrides.\n\nWithout either, the theme's fontScheme applies, then the engine default font scheme.",
1084
1040
  "examples": [
1085
1041
  "aptos",
1086
1042
  "tenorite",
@@ -1117,7 +1073,7 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
1117
1073
  "$ref": "#/$defs/Background"
1118
1074
  }
1119
1075
  ],
1120
- "description": "Default slide background applied across the deck unless overridden on a slide. String shorthand accepts theme slots ('light1', 'light2', 'dark1', 'dark2') or hex colors; object forms support theme, solid, gradient, image, or pattern fills.",
1076
+ "description": "Default slide background applied across the deck unless overridden on a slide (slides.N.design.background); the resolved theme's background is the fallback. A background is the only canvas fill and never moves content. String shorthand accepts theme slots ('light1', 'light2', 'dark1', 'dark2'), hex colors, or an image source starting with 'asset:', 'https://', 'data:', './' or '../' (a cover image); object forms support theme, solid, gradient, image, or pattern fills.",
1121
1077
  "examples": [
1122
1078
  "dark1",
1123
1079
  "#ffff00",
@@ -1244,175 +1200,6 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
1244
1200
  "type": "boolean",
1245
1201
  "description": "Whether body/content regions are rendered inside a visible card or surface. Effective value: the slide's design, then the deck's design, then the layout record's design.contentBox, then the engine default."
1246
1202
  },
1247
- "slideImage": {
1248
- "oneOf": [
1249
- {
1250
- "$ref": "#/$defs/Asset"
1251
- },
1252
- {
1253
- "type": "object",
1254
- "additionalProperties": false,
1255
- "required": [
1256
- "position"
1257
- ],
1258
- "properties": {
1259
- "src": {
1260
- "type": "string",
1261
- "description": "Source for the slide-level image. When omitted in a design override, the object only configures how a slide-level image should be placed when one is supplied by a content payload, asset, or renderer convention."
1262
- },
1263
- "position": {
1264
- "type": "string",
1265
- "enum": [
1266
- "background",
1267
- "top",
1268
- "bottom",
1269
- "left",
1270
- "right"
1271
- ],
1272
- "description": "Where the slide-level image sits relative to the content. 'background' is a full-bleed image behind the content. The other positions give the image a band along that edge (see size) and compose headings and content in the rest of the slide."
1273
- },
1274
- "alt": {
1275
- "type": "string",
1276
- "description": "Alternative text for the slide-level image. Overrides the alt text of a referenced asset."
1277
- },
1278
- "fill": {
1279
- "type": "string",
1280
- "enum": [
1281
- "crop",
1282
- "fit"
1283
- ],
1284
- "description": "How the image fills its frame: 'crop' covers the frame from the center; 'fit' shows the whole image centered inside it. Overrides design.imageFill for this image. Default: design.imageFill, else 'crop'."
1285
- },
1286
- "size": {
1287
- "type": "number",
1288
- "minimum": 0.1,
1289
- "maximum": 0.9,
1290
- "description": "Share of the slide width (left/right) or height (top/bottom) given to the image band. Ignored for 'background'. Default 0.5."
1291
- },
1292
- "inset": {
1293
- "type": "boolean",
1294
- "description": "Place the frame inside the slide padding instead of edge to edge, like a card. Default false."
1295
- },
1296
- "aspectRatio": {
1297
- "type": "number",
1298
- "exclusiveMinimum": 0,
1299
- "maximum": 10,
1300
- "description": "Width-to-height ratio of the frame. The frame becomes the largest centered box with this ratio inside the band or slide, for example 2.39 for a cinematic letterbox or 0.5 for a phone-shaped frame. 'circle' always uses 1."
1301
- },
1302
- "shape": {
1303
- "type": "string",
1304
- "enum": [
1305
- "rectangle",
1306
- "rounded",
1307
- "circle",
1308
- "hexagon"
1309
- ],
1310
- "description": "Mask applied to the frame, exported as the picture's native preset geometry (rect, roundRect, ellipse, hexagon). 'circle' makes the frame square. Default 'rectangle'."
1311
- },
1312
- "cornerRadius": {
1313
- "type": "number",
1314
- "minimum": 0,
1315
- "maximum": 0.5,
1316
- "description": "Corner radius for shape 'rounded' as a fraction of the frame's shorter side. Default 0.16667, PowerPoint's roundRect default."
1317
- },
1318
- "border": {
1319
- "type": "object",
1320
- "additionalProperties": false,
1321
- "required": [
1322
- "color",
1323
- "width"
1324
- ],
1325
- "properties": {
1326
- "color": {
1327
- "$ref": "#/$defs/ColorRef",
1328
- "description": "Line color: a hex color, a color-scheme slot or role name, or a 'var:<id>' variable reference."
1329
- },
1330
- "width": {
1331
- "type": "number",
1332
- "minimum": 0,
1333
- "maximum": 64,
1334
- "description": "Line width in reference pixels at a 720-pixel short edge, centered on the frame outline like a native picture line. 0 removes the line."
1335
- }
1336
- },
1337
- "description": "Solid line along the frame's shape. A thick dark border on a rounded portrait frame gives a device bezel."
1338
- },
1339
- "opacity": {
1340
- "type": "number",
1341
- "minimum": 0,
1342
- "maximum": 1,
1343
- "description": "Image opacity from 0 to 1, exported as a native alphaModFix. The border and overlay keep their own opacity. Default 1."
1344
- },
1345
- "recolor": {
1346
- "oneOf": [
1347
- {
1348
- "type": "string",
1349
- "const": "grayscale",
1350
- "description": "Replace each pixel with its luminance, exported as native a:grayscl."
1351
- },
1352
- {
1353
- "type": "object",
1354
- "additionalProperties": false,
1355
- "required": [
1356
- "dark",
1357
- "light"
1358
- ],
1359
- "properties": {
1360
- "dark": {
1361
- "$ref": "#/$defs/ColorRef",
1362
- "description": "Color at luminance 0."
1363
- },
1364
- "light": {
1365
- "$ref": "#/$defs/ColorRef",
1366
- "description": "Color at luminance 1."
1367
- }
1368
- },
1369
- "description": "Duotone: map each pixel's luminance linearly from dark to light, exported as native a:duotone."
1370
- }
1371
- ],
1372
- "description": "Color treatment for the image pixels. Luminance uses Rec. 601 weights (0.299, 0.587, 0.114) on sRGB values."
1373
- },
1374
- "overlay": {
1375
- "type": "object",
1376
- "additionalProperties": false,
1377
- "required": [
1378
- "color",
1379
- "opacity"
1380
- ],
1381
- "properties": {
1382
- "color": {
1383
- "$ref": "#/$defs/ColorRef",
1384
- "description": "Overlay fill color."
1385
- },
1386
- "opacity": {
1387
- "type": "number",
1388
- "minimum": 0,
1389
- "maximum": 1,
1390
- "description": "Overlay fill opacity."
1391
- },
1392
- "edge": {
1393
- "type": "string",
1394
- "enum": [
1395
- "top",
1396
- "bottom",
1397
- "left",
1398
- "right"
1399
- ],
1400
- "description": "Cover only a band along this edge of the frame, for example a caption strip. Rectangle frames only; other shapes report unsupported-image-treatment and draw no overlay. Omit to cover the whole frame."
1401
- },
1402
- "size": {
1403
- "type": "number",
1404
- "minimum": 0.05,
1405
- "maximum": 1,
1406
- "description": "Band share of the frame for an edge overlay. Default 0.3."
1407
- }
1408
- },
1409
- "description": "Solid scrim drawn over the image in the frame's shape, beneath headings and content, for example to keep overlaid text readable. Exported as a native shape above the picture."
1410
- }
1411
- }
1412
- }
1413
- ],
1414
- "description": "Optional slide-level image, separate from content images. It applies to a slide that sets its own design.slideImage, and to slides whose layout record sets design.slideImage or whose root image is the same source as a deck-level value. A root image with the same source becomes the slide image instead of a content item. Blur, shadows, soft edges, background removal and device artwork are not part of the treatment vocabulary; see docs/image-treatments.md."
1415
- },
1416
1203
  "contentDirection": {
1417
1204
  "type": "string",
1418
1205
  "enum": [
@@ -1430,15 +1217,16 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
1430
1217
  "left",
1431
1218
  "right"
1432
1219
  ],
1433
- "description": "Where the primary chart sits relative to supporting content. Effective value: slide design, then deck design, then the layout record's design.chartPrimary. When the slide has no promoted regions and no composition.mode of its own, and its root nodes mix at least one chart with other content, the first chart becomes a primary track and the other nodes form one synthetic sub-grid: 'left'/'right' is a two-track row and 'top'/'bottom' a two-track column, weighted 3:2 in favor of the chart; explicit root columns and weights are ignored while it applies. 'none' (the default) keeps the ordinary automatic grid with equal weight."
1220
+ "description": "Where the primary chart sits relative to supporting content. Effective value: slide design, then deck design, then the layout record's design.chartPrimary. When the slide has no promoted regions and no composition.mode of its own, and its root nodes mix at least one chart with other content, the first chart becomes a primary track and the other nodes form one synthetic sub-grid: 'left'/'right' is a two-track row and 'top'/'bottom' a two-track column, weighted 3:2 in favor of the chart; explicit root columns and weights are ignored while it applies. 'none' (the default) keeps the ordinary automatic grid with equal weight. It is shorthand for a placeholder group (layout.schema.json PlaceholderGroup): the slide composes exactly as on a layout record whose root composition is that weighted row or column and whose placeholders are the chart and one automatic group of the other content, and while it applies it replaces the layout record's own placeholder groups as well."
1434
1221
  },
1435
- "imageFill": {
1222
+ "imageFit": {
1436
1223
  "type": "string",
1437
1224
  "enum": [
1438
- "crop",
1439
- "fit"
1225
+ "cover",
1226
+ "contain",
1227
+ "stretch"
1440
1228
  ],
1441
- "description": "How images fill their allocated region: crop covers the region, fit shows the whole image. Effective value: the slide's design, then the deck's design, then the layout record's design.imageFill, then the engine default."
1229
+ "description": "Default fit of image blocks (and Slide.image) that set no fit of their own: 'cover' fills the frame and crops what overflows around the block's focus, 'contain' shows the whole picture centered in the frame, 'stretch' scales it to the frame exactly. Effective value: the slide's design, then the deck's design, then the layout record's design.imageFit, then 'cover'. Backgrounds set their own fit."
1442
1230
  },
1443
1231
  "listBullet": {
1444
1232
  "type": "string",
@@ -1450,136 +1238,19 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
1450
1238
  }
1451
1239
  }
1452
1240
  },
1453
- "Theme": {
1454
- "type": "object",
1455
- "description": "Theme bundle used by the design system. In design.theme, 'id' resolves a themes catalog record as the base; any sibling fields override the resolved theme. The string shorthand on design.theme is equivalent to setting only 'id'.",
1456
- "properties": {
1457
- "id": {
1458
- "type": "string",
1459
- "description": "Theme reference. Resolves to the 'id' of a 'themes' catalog record. Accepts a bare id (lowercase kebab-case, e.g. 'minimal'), an HTTPS URL pointing at a record file, or a 'pkg:' reference. Field overrides on the surrounding Theme object take precedence over the resolved theme.\n\nResolution order: inline catalogs.themes.records[] -> catalogs.themes.source -> default catalog at https://www.pptx.gallery/themes.",
1460
- "examples": [
1461
- "minimal",
1462
- "classic",
1463
- "dark",
1464
- "bold",
1465
- "https://acme.com/decks/themes/acme-brand.json",
1466
- "pkg:@acme/decks/themes/acme-brand"
1467
- ]
1468
- },
1469
- "name": {
1470
- "type": "string",
1471
- "description": "Human-readable theme name shown in pickers.",
1472
- "examples": [
1473
- "Minimal",
1474
- "Classic",
1475
- "Dark",
1476
- "Bold"
1477
- ]
1478
- },
1479
- "summary": {
1480
- "type": "string",
1481
- "description": "One-sentence positioning of the theme - when to reach for it."
1482
- },
1483
- "description": {
1484
- "type": "string",
1485
- "description": "Longer prose describing what the theme looks and feels like and the kinds of decks it suits."
1486
- },
1487
- "colorScheme": {
1488
- "oneOf": [
1489
- {
1490
- "type": "string"
1491
- },
1492
- {
1493
- "$ref": "#/$defs/ColorScheme"
1494
- }
1495
- ],
1496
- "description": "Default color scheme for this theme. A string resolves against catalogs.colorSchemes; an object may provide an 'id' base reference plus overrides.",
1497
- "examples": [
1498
- "cool-horizon",
1499
- {
1500
- "id": "cool-horizon",
1501
- "accent1": "#FF6F61"
1502
- }
1503
- ]
1504
- },
1505
- "fontScheme": {
1506
- "oneOf": [
1507
- {
1508
- "type": "string"
1509
- },
1510
- {
1511
- "$ref": "#/$defs/FontScheme"
1512
- }
1513
- ],
1514
- "description": "Default font scheme for this theme. A string resolves against catalogs.fontSchemes; an object may provide an 'id' base reference plus overrides.",
1515
- "examples": [
1516
- "aptos",
1517
- {
1518
- "id": "aptos",
1519
- "heading": "Inter"
1520
- }
1521
- ]
1522
- },
1523
- "background": {
1524
- "oneOf": [
1525
- {
1526
- "$ref": "#/$defs/BackgroundShortcut"
1527
- },
1528
- {
1529
- "$ref": "#/$defs/Background"
1530
- }
1531
- ],
1532
- "description": "Default background for this theme. String shorthand accepts theme slots ('light1', 'light2', 'dark1', 'dark2') or hex colors.",
1533
- "examples": [
1534
- "dark1",
1535
- "#ffff00",
1536
- {
1537
- "type": "theme",
1538
- "slot": "dark2"
1539
- }
1540
- ]
1541
- },
1542
- "dimensions": {
1543
- "oneOf": [
1544
- {
1545
- "$ref": "#/$defs/DimensionPreset"
1546
- },
1547
- {
1548
- "$ref": "#/$defs/Dimensions"
1549
- }
1550
- ],
1551
- "description": "Default slide size for this theme. A string preset is equivalent to { preset: value }.",
1552
- "examples": [
1553
- "widescreen",
1554
- {
1555
- "preset": "16:9"
1556
- }
1557
- ]
1558
- },
1559
- "tags": {
1560
- "type": "array",
1561
- "items": {
1562
- "type": "string"
1563
- },
1564
- "description": "Free-form labels for filtering and search."
1565
- }
1566
- }
1567
- },
1568
1241
  "ColorScheme": {
1569
1242
  "type": "object",
1570
- "description": "Color palette used by the design system. Every slot and role is a hex color ('#RGB', '#RRGGBB' or '#RRGGBBAA'); a color-scheme name or a 'var:<id>' reference is not valid here, because those resolve through the scheme. The slot fields (accent1-accent6, dark1, dark2, light1, light2, hyperlink, followedHyperlink) mirror color-scheme.schema.json (https://openpresentation.org/schema/opf-color-scheme/v1) so library records and inline OPF overrides are interchangeable on those fields.\n\nTwo parallel models are supported and may be mixed:\n- OOXML slots - the 12-slot PowerPoint theme model that round-trips directly to OOXML. Use these for full control over the palette as PowerPoint sees it.\n- Abstract roles (primary, secondary, accent, background, surface, text, textSecondary) - OPF-specific semantic aliases the engine maps onto the OOXML slots. Convenient for inline overrides without thinking in slot numbers; not part of the catalog record schema.\n\nIn design.colorScheme, 'id' resolves a colorSchemes catalog record as the base; slot and role overrides on the same object take precedence over the resolved scheme. The string shorthand on design.colorScheme is equivalent to setting only 'id'.",
1243
+ "description": "Color palette used by the design system. Every slot and role is a hex color ('#RGB', '#RRGGBB' or '#RRGGBBAA'); a color-scheme name or a 'var:<id>' reference is not valid here, because those resolve through the scheme. The slot fields (accent1-accent6, dark1, dark2, light1, light2, hyperlink, followedHyperlink) mirror color-scheme.schema.json (https://openpresentation.org/schema/opf-color-scheme/v1) so library records and inline OPF overrides are interchangeable on those fields.\n\nTwo parallel models are supported and may be mixed:\n- OOXML slots - the 12-slot PowerPoint theme model that round-trips directly to OOXML. Use these for full control over the palette as PowerPoint sees it.\n- Abstract roles (primary, secondary, accent, background, surface, text, textSecondary) - OPF-specific semantic aliases the engine maps onto the OOXML slots. Convenient for inline overrides without thinking in slot numbers; not part of the catalog record schema.\n\nIn design.colorScheme, 'id' resolves a colorSchemes record as the base; slot and role overrides on the same object take precedence over the resolved scheme. The string form of design.colorScheme is equivalent to setting only 'id'.",
1571
1244
  "properties": {
1572
1245
  "id": {
1573
- "type": "string",
1574
- "description": "Color scheme reference. Resolves to the 'id' of a 'colorSchemes' catalog record. Accepts a bare id (lowercase kebab-case, e.g. 'cool-horizon'), an HTTPS URL pointing at a record file, or a 'pkg:' reference. Slot and role overrides on the surrounding ColorScheme object take precedence over the resolved scheme.\n\nResolution order: inline catalogs.colorSchemes.records[] -> catalogs.colorSchemes.source -> default catalog at https://www.pptx.gallery/color-schemes.",
1246
+ "$ref": "#/$defs/CatalogReference",
1247
+ "description": "Colour-scheme reference (a bare id or 'name:id') resolved as the base; slot and role overrides on the surrounding ColorScheme object take precedence over the resolved scheme.",
1575
1248
  "examples": [
1576
1249
  "cool-horizon",
1577
1250
  "boost",
1578
1251
  "burnt-orange",
1579
1252
  "ocean-depth",
1580
- "corporate-blue",
1581
- "https://acme.com/decks/color-schemes/acme.json",
1582
- "pkg:@acme/decks/color-schemes/acme"
1253
+ "corporate-blue"
1583
1254
  ]
1584
1255
  },
1585
1256
  "accent1": {
@@ -1742,20 +1413,18 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
1742
1413
  },
1743
1414
  "FontScheme": {
1744
1415
  "type": "object",
1745
- "description": "Typography selections used by the design system. The pair fields (major, minor) and refinement fields (type, app, languageFamily) mirror font-scheme.schema.json (https://openpresentation.org/schema/opf-font-scheme/v1) so library records and inline OPF overrides are interchangeable on those fields.\n\nTwo parallel models are supported and may be mixed:\n- OOXML pairs (major, minor) - heading and body family names that round-trip directly to PowerPoint majorFont/minorFont entries.\n- Abstract roles (heading, body, accent, code) - OPF-specific font family names the engine maps onto the OOXML pair when serializing. Convenient for inline overrides and for adding accent/code roles that don't have a direct OOXML slot. Catalog records may also carry 'code' (for example the consolas and courier-new records); heading, body and accent are not part of the catalog record schema. A role is a family name only: weight, style and tracking come from the text styles, and PowerPoint has no numeric weight.\n\nIn design.fontScheme, 'id' resolves a fontSchemes catalog record as the base; pair and role overrides on the same object take precedence over the resolved scheme. The string shorthand on design.fontScheme is equivalent to setting only 'id'.",
1416
+ "description": "Typography selections used by the design system. The pair fields (major, minor) and refinement fields (type, app, languageFamily) mirror font-scheme.schema.json (https://openpresentation.org/schema/opf-font-scheme/v1) so library records and inline OPF overrides are interchangeable on those fields.\n\nTwo parallel models are supported and may be mixed:\n- OOXML pairs (major, minor) - heading and body family names that round-trip directly to PowerPoint majorFont/minorFont entries.\n- Abstract roles (heading, body, accent, code) - OPF-specific font family names the engine maps onto the OOXML pair when serializing. Convenient for inline overrides and for adding accent/code roles that don't have a direct OOXML slot. Catalog records may also carry 'code' (for example the consolas and courier-new records); heading, body and accent are not part of the catalog record schema. A role is a family name only: weight, style and tracking come from the text styles, and PowerPoint has no numeric weight.\n\nIn design.fontScheme, 'id' resolves a fontSchemes record as the base; pair and role overrides on the same object take precedence over the resolved scheme. The string form of design.fontScheme is equivalent to setting only 'id'.",
1746
1417
  "properties": {
1747
1418
  "id": {
1748
- "type": "string",
1749
- "description": "Font scheme reference. Resolves to the 'id' of a 'fontSchemes' catalog record. Accepts a bare id (lowercase kebab-case, e.g. 'aptos'), an HTTPS URL pointing at a record file, or a 'pkg:' reference. Field overrides on the surrounding FontScheme object take precedence over the resolved scheme.\n\nResolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.source -> default catalog at https://www.pptx.gallery/font-schemes.",
1419
+ "$ref": "#/$defs/CatalogReference",
1420
+ "description": "Font-scheme reference (a bare id or 'name:id') resolved as the base; field overrides on the surrounding FontScheme object take precedence over the resolved scheme.",
1750
1421
  "examples": [
1751
1422
  "aptos",
1752
1423
  "tenorite",
1753
1424
  "seaford",
1754
1425
  "noto-sans",
1755
1426
  "modern-sans",
1756
- "classic-serif",
1757
- "https://acme.com/decks/font-schemes/acme.json",
1758
- "pkg:@acme/decks/font-schemes/acme"
1427
+ "classic-serif"
1759
1428
  ]
1760
1429
  },
1761
1430
  "major": {
@@ -1872,7 +1541,7 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
1872
1541
  },
1873
1542
  "code": {
1874
1543
  "type": "string",
1875
- "description": "Abstract role: monospaced font family name used for code blocks and for inline code runs (TextRun.code). No direct OOXML slot. Resolution: this override, then the resolved catalog record's 'code' (for example Consolas for the consolas scheme), then the engine fallback Roboto Mono. Heading and body families are never used as the code fallback."
1544
+ "description": "Abstract role: monospaced font family name used for code blocks and for inline code runs (TextRun.code). No direct OOXML slot. Resolution: this override, then the resolved font-scheme record's 'code' (for example Consolas for the consolas scheme), then the engine fallback Roboto Mono. Heading and body families are never used as the code fallback."
1876
1545
  }
1877
1546
  }
1878
1547
  },
@@ -2389,13 +2058,28 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
2389
2058
  },
2390
2059
  {
2391
2060
  "$ref": "#/$defs/HexColor"
2061
+ },
2062
+ {
2063
+ "$ref": "#/$defs/ImageSource"
2392
2064
  }
2393
2065
  ],
2394
- "description": "String shorthand for a background. Theme slots ('light1', 'light2', 'dark1', 'dark2') are equivalent to { type: 'theme', slot: value }; hex colors are equivalent to { type: 'solid', color: value }.",
2066
+ "description": "String shorthand for a background. Theme slots ('light1', 'light2', 'dark1', 'dark2') are equivalent to { type: 'theme', slot: value }; hex colors are equivalent to { type: 'solid', color: value }; an image source (starting with 'asset:', 'https://', 'data:', './' or '../') is equivalent to { type: 'image', src: value }, a cover image. Any other string is invalid.",
2395
2067
  "examples": [
2396
2068
  "dark1",
2397
2069
  "light2",
2398
- "#ffff00"
2070
+ "#ffff00",
2071
+ "asset:cover-photo",
2072
+ "./images/harbour.jpg"
2073
+ ]
2074
+ },
2075
+ "ImageSource": {
2076
+ "type": "string",
2077
+ "pattern": "^(asset:|https://|data:|\\./|\\.\\./)",
2078
+ "description": "An image source in a string shorthand: an 'asset:<id>' reference, an HTTPS URL, a data URI, or a relative path starting with './' or '../' (resolved against the OPF file location).",
2079
+ "examples": [
2080
+ "asset:cover-photo",
2081
+ "https://cdn.acme.com/backgrounds/cover.jpg",
2082
+ "./images/harbour.jpg"
2399
2083
  ]
2400
2084
  },
2401
2085
  "Background": {
@@ -2528,66 +2212,263 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
2528
2212
  },
2529
2213
  "ImageBackground": {
2530
2214
  "type": "object",
2531
- "description": "Fixed image slide background fill.",
2215
+ "additionalProperties": false,
2216
+ "description": "Picture background: the image fills the whole canvas behind everything and never moves content (to push content aside, use an image block with placement). The string shorthand 'asset:x' (or any image source) is { type: 'image', src: 'asset:x' }, a cover image. Paint order: the colour scheme's default slide background, the picture, then the overlay, then furniture and content.",
2532
2217
  "required": [
2533
2218
  "type",
2534
- "image"
2219
+ "src"
2535
2220
  ],
2536
2221
  "properties": {
2537
2222
  "type": {
2538
2223
  "type": "string",
2539
2224
  "const": "image",
2540
- "description": "Fixed image background fill."
2225
+ "description": "Picture background."
2541
2226
  },
2542
- "image": {
2543
- "type": "object",
2544
- "description": "Image fill definition.",
2545
- "required": [
2546
- "src"
2227
+ "src": {
2228
+ "type": "string",
2229
+ "description": "Source for the background image: an 'asset:<id>' reference, HTTPS URL, data URI, or a relative path resolved against the OPF file location.",
2230
+ "examples": [
2231
+ "https://cdn.acme.com/backgrounds/cover.jpg",
2232
+ "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA...",
2233
+ "./backgrounds/cover.jpg",
2234
+ "asset:bg-cover"
2235
+ ]
2236
+ },
2237
+ "alt": {
2238
+ "type": "string",
2239
+ "description": "Alternative text. A background with alt is meaningful: PowerPoint export draws it as a full-slide picture at the back that carries the text, so screen readers see it. Without alt it is decorative and exports as the native slide background; the alt text of a referenced asset does not count, so a background is decorative unless it says otherwise."
2240
+ },
2241
+ "fit": {
2242
+ "type": "string",
2243
+ "enum": [
2244
+ "cover",
2245
+ "contain",
2246
+ "stretch",
2247
+ "tile"
2547
2248
  ],
2548
- "properties": {
2549
- "src": {
2550
- "type": "string",
2551
- "description": "Source for the background image.",
2552
- "examples": [
2553
- "https://cdn.acme.com/backgrounds/cover.jpg",
2554
- "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA...",
2555
- "./backgrounds/cover.jpg",
2556
- "asset:bg-cover"
2557
- ]
2558
- },
2559
- "fit": {
2560
- "type": "string",
2561
- "enum": [
2562
- "cover",
2563
- "contain",
2564
- "tile"
2565
- ],
2566
- "description": "How the image fills the slide background."
2567
- }
2568
- }
2249
+ "description": "How the picture fills the canvas: 'cover' fills it and crops what overflows around focus; 'contain' shows the whole picture centered over the colour scheme's default background; 'stretch' scales it to the canvas exactly; 'tile' repeats it at its own size from the top-left corner. Default 'cover'."
2250
+ },
2251
+ "focus": {
2252
+ "$ref": "#/$defs/ImageFocus",
2253
+ "description": "Point of the picture to keep in view when 'cover' crops it. Ignored by the other fits."
2569
2254
  },
2570
2255
  "opacity": {
2571
2256
  "type": "number",
2572
2257
  "minimum": 0,
2573
2258
  "maximum": 1,
2574
- "description": "Background opacity from 0 (fully transparent) to 1 (fully opaque)."
2259
+ "description": "Picture opacity from 0 (fully transparent) to 1 (fully opaque); the overlay keeps its own opacity. Default 1."
2260
+ },
2261
+ "recolor": {
2262
+ "$ref": "#/$defs/ImageRecolor",
2263
+ "description": "Grayscale or duotone treatment of the picture's pixels, as on an image block: recolor and opacity apply to the pixels, then the overlay is drawn above."
2264
+ },
2265
+ "overlay": {
2266
+ "$ref": "#/$defs/Overlay",
2267
+ "description": "Scrim over the whole picture or a band along one edge (edge, size), beneath furniture and content, for example to keep a title readable over a busy photo."
2575
2268
  }
2576
- }
2269
+ },
2270
+ "examples": [
2271
+ {
2272
+ "type": "image",
2273
+ "src": "asset:cover-photo"
2274
+ },
2275
+ {
2276
+ "type": "image",
2277
+ "src": "./images/harbour.jpg",
2278
+ "alt": "Container ships at dawn",
2279
+ "focus": {
2280
+ "x": 0.5,
2281
+ "y": 0.7
2282
+ },
2283
+ "overlay": {
2284
+ "color": "dark1",
2285
+ "opacity": 0.4
2286
+ }
2287
+ }
2288
+ ]
2577
2289
  },
2578
- "PatternBackground": {
2290
+ "ImageFocus": {
2579
2291
  "type": "object",
2580
- "description": "Fixed pattern slide background fill.",
2292
+ "additionalProperties": false,
2581
2293
  "required": [
2582
- "type",
2583
- "pattern"
2294
+ "x",
2295
+ "y"
2584
2296
  ],
2297
+ "description": "A point of a picture as fractions of its width and height, from the top-left corner. A cover fit centers this point in the frame as far as the picture still covers the frame, so it always stays in view: { x: 0.5, y: 0.5 } (the default) is a center crop, { x: 0, y: 0 } keeps the top-left corner.",
2585
2298
  "properties": {
2586
- "type": {
2587
- "type": "string",
2588
- "const": "pattern",
2589
- "description": "Fixed pattern background fill."
2590
- },
2299
+ "x": {
2300
+ "type": "number",
2301
+ "minimum": 0,
2302
+ "maximum": 1,
2303
+ "description": "Horizontal position, 0 (left edge) to 1 (right edge)."
2304
+ },
2305
+ "y": {
2306
+ "type": "number",
2307
+ "minimum": 0,
2308
+ "maximum": 1,
2309
+ "description": "Vertical position, 0 (top edge) to 1 (bottom edge)."
2310
+ }
2311
+ },
2312
+ "examples": [
2313
+ {
2314
+ "x": 0.5,
2315
+ "y": 0.7
2316
+ }
2317
+ ]
2318
+ },
2319
+ "Overlay": {
2320
+ "type": "object",
2321
+ "additionalProperties": false,
2322
+ "required": [
2323
+ "color",
2324
+ "opacity"
2325
+ ],
2326
+ "description": "Solid scrim over a picture: the whole frame in the frame's shape, or a band along one edge. Shared by image backgrounds and image blocks. Drawn directly above its picture and beneath headings and content; PowerPoint export writes one native shape above the picture.",
2327
+ "properties": {
2328
+ "color": {
2329
+ "$ref": "#/$defs/ColorRef",
2330
+ "description": "Overlay fill color: a hex color (eight-digit hex keeps its alpha), a color-scheme slot or role name, or a 'var:<id>' variable reference."
2331
+ },
2332
+ "opacity": {
2333
+ "type": "number",
2334
+ "minimum": 0,
2335
+ "maximum": 1,
2336
+ "description": "Overlay fill opacity."
2337
+ },
2338
+ "edge": {
2339
+ "type": "string",
2340
+ "enum": [
2341
+ "top",
2342
+ "bottom",
2343
+ "left",
2344
+ "right"
2345
+ ],
2346
+ "description": "Cover only a band along this edge of the frame, for example a caption strip. Backgrounds and rectangle image frames only; on another shape the overlay is not drawn and composition reports unsupported-image-treatment. Omit to cover the whole frame. In a right-to-left deck 'left' and 'right' are the start and end sides."
2347
+ },
2348
+ "size": {
2349
+ "type": "number",
2350
+ "minimum": 0.05,
2351
+ "maximum": 1,
2352
+ "description": "Band share of the frame for an edge overlay. Default 0.3. Ignored without edge."
2353
+ }
2354
+ },
2355
+ "examples": [
2356
+ {
2357
+ "color": "dark1",
2358
+ "opacity": 0.4
2359
+ },
2360
+ {
2361
+ "color": "#000000",
2362
+ "opacity": 0.75,
2363
+ "edge": "bottom",
2364
+ "size": 0.25
2365
+ }
2366
+ ]
2367
+ },
2368
+ "ImagePlacement": {
2369
+ "type": "object",
2370
+ "additionalProperties": false,
2371
+ "required": [
2372
+ "edge"
2373
+ ],
2374
+ "description": "Bleeds an image block to one edge of the slide: the image takes a band along that edge, edge to edge, and the headings and other content compose in the rest of the slide at the normal padding. Only top-level blocks (slides.N.blocks.I) can be placed, at most one per edge; a layout's image placeholder may carry the same placement for the slide's image. Bands are taken in block order, each spanning the free area left by earlier ones. Placement is the only mechanism that moves content aside; a background never does. A slide whose only body is placed images is composed like a cover: its headings center in the free area. In a right-to-left deck 'left' is the start side, drawn at the right.",
2375
+ "properties": {
2376
+ "edge": {
2377
+ "type": "string",
2378
+ "enum": [
2379
+ "left",
2380
+ "right",
2381
+ "top",
2382
+ "bottom"
2383
+ ],
2384
+ "description": "The slide edge the image bleeds to."
2385
+ },
2386
+ "size": {
2387
+ "type": "number",
2388
+ "minimum": 0.1,
2389
+ "maximum": 0.9,
2390
+ "description": "Share of the slide width (left, right) or height (top, bottom) given to the band. Default 0.5."
2391
+ },
2392
+ "inset": {
2393
+ "type": "boolean",
2394
+ "description": "Draw the frame inside the slide padding on every side of the band, like a card, instead of edge to edge. Default false."
2395
+ }
2396
+ },
2397
+ "examples": [
2398
+ {
2399
+ "edge": "left",
2400
+ "size": 0.45
2401
+ },
2402
+ {
2403
+ "edge": "right",
2404
+ "size": 0.4,
2405
+ "inset": true
2406
+ }
2407
+ ]
2408
+ },
2409
+ "ImageBorder": {
2410
+ "type": "object",
2411
+ "additionalProperties": false,
2412
+ "required": [
2413
+ "color",
2414
+ "width"
2415
+ ],
2416
+ "description": "Solid line along the image frame's shape, centered on the outline with a miter join, like a native picture line. A thick dark border on a rounded portrait frame gives a device bezel.",
2417
+ "properties": {
2418
+ "color": {
2419
+ "$ref": "#/$defs/ColorRef",
2420
+ "description": "Line color: a hex color, a color-scheme slot or role name, or a 'var:<id>' variable reference."
2421
+ },
2422
+ "width": {
2423
+ "type": "number",
2424
+ "minimum": 0,
2425
+ "maximum": 64,
2426
+ "description": "Line width in reference pixels at a 720-pixel short edge. 0 removes the line."
2427
+ }
2428
+ }
2429
+ },
2430
+ "ImageRecolor": {
2431
+ "oneOf": [
2432
+ {
2433
+ "type": "string",
2434
+ "const": "grayscale",
2435
+ "description": "Replace each pixel with its luminance, exported as native a:grayscl."
2436
+ },
2437
+ {
2438
+ "type": "object",
2439
+ "additionalProperties": false,
2440
+ "required": [
2441
+ "dark",
2442
+ "light"
2443
+ ],
2444
+ "properties": {
2445
+ "dark": {
2446
+ "$ref": "#/$defs/ColorRef",
2447
+ "description": "Color at luminance 0."
2448
+ },
2449
+ "light": {
2450
+ "$ref": "#/$defs/ColorRef",
2451
+ "description": "Color at luminance 1."
2452
+ }
2453
+ },
2454
+ "description": "Duotone: map each pixel's luminance linearly from dark to light, exported as native a:duotone."
2455
+ }
2456
+ ],
2457
+ "description": "Color treatment for the image pixels. Luminance uses Rec. 601 weights (0.299, 0.587, 0.114) on sRGB values."
2458
+ },
2459
+ "PatternBackground": {
2460
+ "type": "object",
2461
+ "description": "Fixed pattern slide background fill.",
2462
+ "required": [
2463
+ "type",
2464
+ "pattern"
2465
+ ],
2466
+ "properties": {
2467
+ "type": {
2468
+ "type": "string",
2469
+ "const": "pattern",
2470
+ "description": "Fixed pattern background fill."
2471
+ },
2591
2472
  "pattern": {
2592
2473
  "type": "object",
2593
2474
  "description": "Pattern fill definition.",
@@ -2685,7 +2566,7 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
2685
2566
  },
2686
2567
  "Watermark": {
2687
2568
  "type": "object",
2688
- "description": "Decorative watermark: an image ('src') or a text stamp ('text'), exactly one of the two, with its opacity. An image is drawn once per slide, contained and centered in a fixed frame (the middle 40% of the slide width and height, from 30% to 70% on each axis). A text watermark is one line of text in the heading font and the theme text color at the given opacity, centered on the slide and rotated 30 degrees counterclockwise (rising to the right), sized to span at most 70% of the slide width and at most 30% of the shorter slide edge in height; it is drawn behind the slide content and above the background and slide image. There is no option to move, scale, rotate or tile either form. PPTX export writes one native picture (image) or one native text box (text) per slide with the opacity as alpha, and import restores the watermark. A string or Asset (no opacity) is the image watermark at opacity 0.08. A watermark object needs opacity and exactly one of src and text; use a plain string or Asset for an image at the default opacity. Use design.watermark = false to disable an inherited watermark.",
2569
+ "description": "Decorative watermark: an image ('src') or a text stamp ('text'), exactly one of the two, with its opacity. An image is drawn once per slide, contained and centered in a fixed frame (the middle 40% of the slide width and height, from 30% to 70% on each axis). A text watermark is one line of text in the heading font and the theme text color at the given opacity, centered on the slide and rotated 30 degrees counterclockwise (rising to the right), sized to span at most 70% of the slide width and at most 30% of the shorter slide edge in height; it is drawn behind the slide content and above the background. There is no option to move, scale, rotate or tile either form. PPTX export writes one native picture (image) or one native text box (text) per slide with the opacity as alpha, and import restores the watermark. A string or Asset (no opacity) is the image watermark at opacity 0.08. A watermark object needs opacity and exactly one of src and text; use a plain string or Asset for an image at the default opacity. Use design.watermark = false to disable an inherited watermark.",
2689
2570
  "additionalProperties": false,
2690
2571
  "required": [
2691
2572
  "opacity"
@@ -2872,17 +2753,15 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
2872
2753
  "description": "Optional reference to one or more beats of the deck's narrative (each value is the id of a beat in the narrative record that the root 'narrative' resolves to). A single string declares the slide's primary beat; an array declares that one slide covers multiple beats. Declares the slide's role in the story arc; does not constrain ordering or structure. Core validate warns about a beat id the resolved narrative does not define, and reports a beat that no slide references. Slides without a beat are valid; multiple slides may share a beat."
2873
2754
  },
2874
2755
  "layout": {
2875
- "type": "string",
2876
- "description": "Optional. Resolves to the 'id' of a 'layouts' catalog record. When omitted, or when it names an id that no inline record, host catalog or default catalog defines, the slide is composed with no layout record: engines arrange title, subtitle, tag and content automatically, a slide with no body payload is a cover (vertically centered), and design hints apply. A layout never changes what a slide contains. An unresolved id is an `unresolved-layout` diagnostic and a `catalog-reference` warning, never an error. Engines must not substitute a different layout for an omitted one. Accepts a bare id (lowercase kebab-case, e.g. 'title-subtitle'), an HTTPS URL pointing at a record file, or a 'pkg:' reference.\n\nResolution order: inline catalogs.layouts.records[] \u2192 catalogs.layouts.source \u2192 default catalog at https://www.pptx.gallery/layouts.",
2756
+ "$ref": "#/$defs/CatalogReference",
2757
+ "description": "Optional layout: a layouts reference, a bare id ('title-subtitle') or 'name:id' ('acme:hero'). When omitted, the slide is composed with no layout record: engines arrange title, subtitle, tag and content automatically, a slide with no body payload is a cover (vertically centered), and design hints apply; there is no finding. A reference that resolves nowhere is the warning opf/unresolved-reference (and the 'unresolved-reference' diagnostic of resolveSlideContext), the slide composes automatically, and a strict export fails. A layout never changes what a slide contains, and engines never substitute a different layout.",
2877
2758
  "examples": [
2878
2759
  "title",
2879
2760
  "title-subtitle",
2880
2761
  "text-2x",
2881
2762
  "chart-3x",
2882
- "image-bleed",
2883
2763
  "blank",
2884
- "https://acme.com/decks/layouts/cover.json",
2885
- "pkg:@acme/decks/layouts/cover"
2764
+ "acme:hero"
2886
2765
  ]
2887
2766
  },
2888
2767
  "title": {
@@ -2967,14 +2846,14 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
2967
2846
  "items": {
2968
2847
  "$ref": "#/$defs/ListItem"
2969
2848
  },
2970
- "description": "Full-slide generic list payload. Presence of this field infers type 'list'. At slide root, multiple content payload kinds with no explicit type, blocks, or regions are accepted as shorthand for layout-agnostic blocks."
2849
+ "description": "Full-slide structured list payload. Presence of this field infers type 'list'. Entries are strings, TextRun[] or objects with `text`, optional `description` (supporting detail under the entry), `level` and `start`. Use `items` when entries share a shape (features, steps, options, risks) or any entry needs a `description`; use `bullets` for plain talking points. Both draw the same marker, nesting and numbering; they differ in the inferred kind and in `description`, which only `items` accepts. At slide root, multiple content payload kinds with no explicit type, blocks, or regions are accepted as shorthand for layout-agnostic blocks, so `items` next to `text` or `bullets` composes as separate blocks side by side."
2971
2850
  },
2972
2851
  "bullets": {
2973
2852
  "type": "array",
2974
2853
  "items": {
2975
2854
  "$ref": "#/$defs/BulletItem"
2976
2855
  },
2977
- "description": "Full-slide text-style bullet payload. Presence of this field infers type 'text'."
2856
+ "description": "Full-slide prose bullet payload: short talking points, each standing alone. Presence of this field infers type 'text', so it may sit beside `text` in one payload. Entries are strings, TextRun[] or objects with `text`, `level` and `start`; there is no `description` (use `items` for entries with supporting detail)."
2978
2857
  },
2979
2858
  "numbering": {
2980
2859
  "$ref": "#/$defs/NumberingSpec",
@@ -2999,7 +2878,7 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
2999
2878
  },
3000
2879
  "image": {
3001
2880
  "$ref": "#/$defs/Asset",
3002
- "description": "Full-slide image source. Presence of this field infers type 'image'."
2881
+ "description": "Shorthand for one image block: the picture composes as body content, like { type: 'image', image: value }, with the effective design.imageFit. A layout's image placeholder may place it along an edge (placement). For fit, focus, treatments or an explicit placement use an image block in blocks; for a full-slide picture behind the content use design.background. Presence of this field infers type 'image'."
3003
2882
  },
3004
2883
  "video": {
3005
2884
  "$ref": "#/$defs/Asset",
@@ -3308,7 +3187,7 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
3308
3187
  "items": {
3309
3188
  "$ref": "#/$defs/ListItem"
3310
3189
  },
3311
- "description": "Generic list payload. Each item is either a plain string, a TextRun[] rich text sequence, or a ListItem object. List nesting uses item.level rather than nested content payloads.",
3190
+ "description": "Structured list payload (type 'list'). Each item is either a plain string, a TextRun[] rich text sequence, or a ListItem object with optional `description`. List nesting uses item.level rather than nested content payloads. Use `items` when entries share a shape or any entry needs a `description`; use `bullets` for plain talking points. Both draw the same marker, nesting and numbering. A block or region holds `items` or `bullets`, never both, and `items` cannot sit beside `text`.",
3312
3191
  "examples": [
3313
3192
  [
3314
3193
  "Sub-second agent latency",
@@ -3331,7 +3210,7 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
3331
3210
  "items": {
3332
3211
  "$ref": "#/$defs/BulletItem"
3333
3212
  },
3334
- "description": "Text-style bullet payload. Presence of this field infers type 'text'.",
3213
+ "description": "Prose bullet payload: short talking points, each standing alone. Presence of this field infers type 'text', so it may sit beside `text` in one payload. Entries have no `description`; use `items` for entries with supporting detail.",
3335
3214
  "examples": [
3336
3215
  [
3337
3216
  "Sub-second agent latency",
@@ -3371,6 +3250,63 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
3371
3250
  "asset:img-diagram"
3372
3251
  ]
3373
3252
  },
3253
+ "fit": {
3254
+ "type": "string",
3255
+ "enum": [
3256
+ "cover",
3257
+ "contain",
3258
+ "stretch"
3259
+ ],
3260
+ "description": "Image payloads only. How the picture fills its frame: 'cover' fills it and crops what overflows around focus; 'contain' shows the whole picture centered; 'stretch' scales it to the frame exactly. Default: the effective design.imageFit, else 'cover'."
3261
+ },
3262
+ "focus": {
3263
+ "$ref": "#/$defs/ImageFocus",
3264
+ "description": "Image payloads only. Point of the picture to keep in view when 'cover' crops it. Ignored by the other fits."
3265
+ },
3266
+ "aspectRatio": {
3267
+ "type": "number",
3268
+ "exclusiveMinimum": 0,
3269
+ "maximum": 10,
3270
+ "description": "Image payloads only. Width-to-height ratio of the frame: the frame becomes the largest centered box with this ratio inside the block's region, for example 2.39 for a cinematic letterbox or 0.5 for a phone-shaped frame. shape 'circle' always uses 1."
3271
+ },
3272
+ "shape": {
3273
+ "type": "string",
3274
+ "enum": [
3275
+ "rectangle",
3276
+ "rounded",
3277
+ "circle",
3278
+ "hexagon"
3279
+ ],
3280
+ "description": "Image payloads only. Mask applied to the frame, exported as the picture's native preset geometry (rect, roundRect, ellipse, hexagon). 'circle' makes the frame square. Default 'rectangle'."
3281
+ },
3282
+ "cornerRadius": {
3283
+ "type": "number",
3284
+ "minimum": 0,
3285
+ "maximum": 0.5,
3286
+ "description": "Image payloads only. Corner radius for shape 'rounded' as a fraction of the frame's shorter side. Default 0.16667, PowerPoint's roundRect default."
3287
+ },
3288
+ "border": {
3289
+ "$ref": "#/$defs/ImageBorder",
3290
+ "description": "Image payloads only. Line along the frame's shape."
3291
+ },
3292
+ "opacity": {
3293
+ "type": "number",
3294
+ "minimum": 0,
3295
+ "maximum": 1,
3296
+ "description": "Image payloads only. Picture opacity from 0 to 1, exported as a native alphaModFix. The border and overlay keep their own opacity. Default 1."
3297
+ },
3298
+ "recolor": {
3299
+ "$ref": "#/$defs/ImageRecolor",
3300
+ "description": "Image payloads only. Grayscale or duotone treatment of the picture's pixels."
3301
+ },
3302
+ "overlay": {
3303
+ "$ref": "#/$defs/Overlay",
3304
+ "description": "Image payloads only. Scrim over the picture in the frame's shape, or a band along one edge of a rectangle frame."
3305
+ },
3306
+ "placement": {
3307
+ "$ref": "#/$defs/ImagePlacement",
3308
+ "description": "Image payloads only, and only on a top-level block (slides.N.blocks.I), at most one per edge. Bleeds the image to one slide edge; the headings and the other blocks compose in the rest of the slide."
3309
+ },
3374
3310
  "video": {
3375
3311
  "$ref": "#/$defs/Asset",
3376
3312
  "description": "Source for a video item. Engines do not play video: the preview draws a placeholder (a play badge with the asset's title or source as its caption), and PPTX export draws the same placeholder as native shapes linked to an http(s) source, with no embedded media. Native playback is out of scope (docs/programs/release-readiness).",
@@ -4545,7 +4481,36 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
4545
4481
  "properties": {
4546
4482
  "type": {
4547
4483
  "type": "string",
4548
- "description": "Chart type id. Resolves to the id of a chartTypes catalog record; renderers map that record through mappings.openxml and any renderer-specific mapping they understand. The bundled catalog covers the chart types Aspose.Slides officially supports, plus 'combo' (clustered columns with line series, see 'line' and 'secondaryAxis').",
4484
+ "enum": [
4485
+ "100pct-stacked-area",
4486
+ "100pct-stacked-bar",
4487
+ "100pct-stacked-column",
4488
+ "area",
4489
+ "bar",
4490
+ "box-and-whisker",
4491
+ "column",
4492
+ "combo",
4493
+ "doughnut",
4494
+ "filled-radar",
4495
+ "funnel",
4496
+ "histogram",
4497
+ "line",
4498
+ "line-with-markers",
4499
+ "pareto",
4500
+ "pie",
4501
+ "radar",
4502
+ "radar-with-markers",
4503
+ "scatter",
4504
+ "stacked-area",
4505
+ "stacked-bar",
4506
+ "stacked-column",
4507
+ "stacked-line",
4508
+ "stacked-line-with-markers",
4509
+ "treemap",
4510
+ "waterfall",
4511
+ "world"
4512
+ ],
4513
+ "description": "Chart type, an engine vocabulary validated directly (no catalog lookup): the chart types Aspose.Slides officially supports, plus 'combo' (clustered columns with line series, see 'line' and 'secondaryAxis'). Each engine maps a type to its own chart model; labels and picker groups are catalog display metadata.",
4549
4514
  "examples": [
4550
4515
  "column",
4551
4516
  "bar",
@@ -4857,6 +4822,13 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
4857
4822
  "fields": {
4858
4823
  "$ref": "#/$defs/DatasetFields",
4859
4824
  "description": "Dataset tables only: the dataset columns to show, by name and in order. Absent shows every column. An unknown name is a 'dataset-field-unknown' error."
4825
+ },
4826
+ "alt": {
4827
+ "type": "string",
4828
+ "description": "Text alternative for the table: what it shows (the point and the key numbers), not 'a table'. The preview exposes it as the table's accessible name (role group with aria-label; the cells stay readable) and the PowerPoint export writes it as the table frame's alternative text (descr); import reads it back. An empty string hides a purely decorative table, with the same meaning as an empty Asset alt. The alt is a summary read before the cells, which stay readable, so it is most useful for a large or dense table; validate does not require one and does not report a missing one.",
4829
+ "examples": [
4830
+ "North America grew 46% to $18.1M in Q4, ahead of EMEA at 40%."
4831
+ ]
4860
4832
  }
4861
4833
  }
4862
4834
  },
@@ -5475,97 +5447,275 @@ Resolution order: inline catalogs.fontSchemes.records[] -> catalogs.fontSchemes.
5475
5447
  },
5476
5448
  "Catalogs": {
5477
5449
  "type": "object",
5478
- "description": "Catalog overrides for the in-document references. Every property is optional. The default catalog for a kind lives at https://www.pptx.gallery/<kind> (e.g. https://www.pptx.gallery/narratives, https://www.pptx.gallery/themes). pptx.gallery is its canonical publisher: GET https://www.pptx.gallery/<kind>/index.json (or https://www.pptx.gallery/<kind> with Accept: application/json) returns a catalog index (https://openpresentation.org/schema/opf-catalog-index/v1) and https://www.pptx.gallery/<kind>/<id>.json returns one record that validates against the kind's companion schema; publisher metadata sits in top-level 'x-*' members that consumers ignore. Engines resolve the default catalog from the pinned snapshot bundled in @openpresentation/opf (spec/catalogs, pinned to a publisher commit and content hash by spec/catalogs/manifest.json), so resolution is deterministic offline and in the cloud; they do not fetch pptx.gallery at run time. For each kind, declaring a 'source' replaces the default registry and/or 'records' adds inline records that take precedence over anything fetched from a source.\n\nResolution order for any reference (e.g. narrative, design.theme): inline catalogs.<kind>.records[] \u2192 catalogs.<kind>.source \u2192 default catalog at https://www.pptx.gallery/<kind>. Every reference resolves to the catalog record's 'id' field. References that are themselves URLs or 'pkg:' references skip the catalog lookup and resolve directly.",
5479
- "properties": {
5480
- "narratives": {
5481
- "$ref": "#/$defs/CatalogEntry",
5482
- "description": "Catalog of narrative templates. Records validate against https://openpresentation.org/schema/opf-narrative/v1. A custom narrative goes in 'catalogs.narratives.records' and is referenced by its id from the root 'narrative'. Default source: https://www.pptx.gallery/narratives."
5483
- },
5484
- "themes": {
5485
- "$ref": "#/$defs/CatalogEntry",
5486
- "description": "Catalog of themes. Records validate against https://openpresentation.org/schema/opf-theme/v1. Default source: https://www.pptx.gallery/themes."
5487
- },
5488
- "colorSchemes": {
5489
- "$ref": "#/$defs/CatalogEntry",
5490
- "description": "Catalog of color schemes. Records validate against https://openpresentation.org/schema/opf-color-scheme/v1. Default source: https://www.pptx.gallery/color-schemes."
5491
- },
5492
- "fontSchemes": {
5493
- "$ref": "#/$defs/CatalogEntry",
5494
- "description": "Catalog of font schemes. Records validate against https://openpresentation.org/schema/opf-font-scheme/v1. Default source: https://www.pptx.gallery/font-schemes."
5495
- },
5496
- "languages": {
5497
- "$ref": "#/$defs/CatalogEntry",
5498
- "description": "Catalog of languages. Records validate against https://openpresentation.org/schema/opf-language/v1. Default source: https://www.pptx.gallery/languages."
5499
- },
5500
- "layouts": {
5501
- "$ref": "#/$defs/CatalogEntry",
5502
- "description": "Catalog of slide layouts. Records validate against https://openpresentation.org/schema/opf-layout/v1. Default source: https://www.pptx.gallery/layouts."
5503
- },
5504
- "chartTypes": {
5505
- "$ref": "#/$defs/CatalogEntry",
5506
- "description": "Catalog of chart types. Records validate against https://openpresentation.org/schema/opf-chart-type/v1. Default source: https://www.pptx.gallery/chart-types."
5507
- },
5508
- "tones": {
5509
- "$ref": "#/$defs/CatalogEntry",
5510
- "description": "Catalog of presentation tones. Records validate against https://openpresentation.org/schema/opf-tone/v1. Default source: https://www.pptx.gallery/tones. Referenced from tone."
5511
- },
5512
- "purposes": {
5513
- "$ref": "#/$defs/CatalogEntry",
5514
- "description": "Catalog of presentation purposes. Records validate against https://openpresentation.org/schema/opf-purpose/v1. Default source: https://www.pptx.gallery/purposes. Referenced from purpose."
5515
- },
5516
- "audiences": {
5517
- "$ref": "#/$defs/CatalogEntry",
5518
- "description": "Catalog of presentation audiences. Records validate against https://openpresentation.org/schema/opf-audience/v1. Default source: https://www.pptx.gallery/audiences. Referenced from audience."
5519
- },
5520
- "socialPlatforms": {
5521
- "$ref": "#/$defs/CatalogEntry",
5522
- "description": "Catalog of social-media platforms. Records validate against https://openpresentation.org/schema/opf-social-platform/v1. Default source: https://www.pptx.gallery/social-platforms. Referenced via the property keys of any Socials object (Organization.socials, Speaker.socials)."
5523
- }
5524
- }
5525
- },
5526
- "CatalogEntry": {
5527
- "type": "object",
5528
- "description": "A catalog override for one record kind. 'source' replaces the default registry; 'records' adds inline records that take precedence over anything fetched from a source. Either or both may be provided; both omitted means the kind uses its default catalog.",
5450
+ "description": "The catalog records a document embeds, grouped by the catalog they came from. Each property is a group; inside a group, records are keyed by kind and then by id.\n- 'default': the catalog bare ids come from. It needs a 'source' when it holds records. Omitted: bare ids fall back to the host's default catalog. false: no catalog fallback, so every bare id must be embedded (under 'custom' or 'default').\n- 'custom': the records the document defines itself. It has no source.\n- any other name ('acme'): an extra catalog, identified by its 'source'. The name is the prefix references use ('acme:hero'). Names are lowercase kebab-case; 'default' and 'custom' are reserved.\n\nResolution, for every kind: a bare id resolves in 'custom', then in the records embedded under 'default', then in the catalog the host registered for default.source (the host's default catalog when 'default' is omitted). 'name:id' resolves in that group's records, then in the catalog the host registered for its source. A reference written inside an embedded record (a theme's colorScheme) resolves in that record's own group first. A prefix that names no group is a validation error; a reference that resolves nowhere is the warning opf/unresolved-reference. Engines never fetch a source: hosts register catalogs by their source string, and authoring tools embed every record a document uses when they save it.",
5529
5451
  "properties": {
5530
- "source": {
5452
+ "default": {
5531
5453
  "oneOf": [
5532
5454
  {
5533
- "$ref": "#/$defs/CatalogSource"
5455
+ "allOf": [
5456
+ {
5457
+ "$ref": "#/$defs/CatalogGroup"
5458
+ },
5459
+ {
5460
+ "if": {
5461
+ "anyOf": [
5462
+ {
5463
+ "required": [
5464
+ "layouts"
5465
+ ]
5466
+ },
5467
+ {
5468
+ "required": [
5469
+ "themes"
5470
+ ]
5471
+ },
5472
+ {
5473
+ "required": [
5474
+ "colorSchemes"
5475
+ ]
5476
+ },
5477
+ {
5478
+ "required": [
5479
+ "fontSchemes"
5480
+ ]
5481
+ },
5482
+ {
5483
+ "required": [
5484
+ "narratives"
5485
+ ]
5486
+ },
5487
+ {
5488
+ "required": [
5489
+ "audiences"
5490
+ ]
5491
+ },
5492
+ {
5493
+ "required": [
5494
+ "purposes"
5495
+ ]
5496
+ },
5497
+ {
5498
+ "required": [
5499
+ "tones"
5500
+ ]
5501
+ }
5502
+ ]
5503
+ },
5504
+ "then": {
5505
+ "required": [
5506
+ "source"
5507
+ ]
5508
+ }
5509
+ }
5510
+ ]
5534
5511
  },
5535
5512
  {
5536
- "type": "array",
5537
- "items": {
5538
- "$ref": "#/$defs/CatalogSource"
5539
- },
5540
- "minItems": 1,
5541
- "description": "Ordered search path of sources. The engine tries each in order; first match wins. The default catalog for the kind is appended implicitly at the end."
5513
+ "const": false
5542
5514
  }
5543
5515
  ],
5544
- "description": "Single source or an ordered search path of sources. When omitted, the engine falls back to the default catalog at https://www.pptx.gallery/<kind>, resolved from its bundled snapshot. Engines never fetch a source. The host loads the records itself and passes them to the renderer and exporter as a 'catalogSources' map from the source string to its records; a source with no entry in that map contributes no records, except the default catalog's own URL and the '@openpresentation/opf' package, which resolve from the bundled snapshot."
5516
+ "description": "The catalog bare ids come from: its source and the records of it this document embeds. false turns off the catalog fallback for bare ids.",
5517
+ "examples": [
5518
+ {
5519
+ "source": "https://www.pptx.gallery",
5520
+ "layouts": {
5521
+ "two-column": {
5522
+ "name": "Two column",
5523
+ "placeholders": [
5524
+ {
5525
+ "type": "title"
5526
+ },
5527
+ {
5528
+ "type": "text"
5529
+ },
5530
+ {
5531
+ "type": "text"
5532
+ }
5533
+ ]
5534
+ }
5535
+ }
5536
+ },
5537
+ false
5538
+ ]
5545
5539
  },
5546
- "records": {
5547
- "type": "array",
5548
- "items": {
5549
- "type": "object"
5550
- },
5551
- "description": "Inline catalog records embedded in this OPF document. Each record validates against the kind's companion schema (e.g. https://openpresentation.org/schema/opf-narrative/v1 for narratives). Inline records win over anything resolved from 'source' and over the default catalog."
5540
+ "custom": {
5541
+ "allOf": [
5542
+ {
5543
+ "$ref": "#/$defs/CatalogGroup"
5544
+ },
5545
+ {
5546
+ "not": {
5547
+ "required": [
5548
+ "source"
5549
+ ]
5550
+ }
5551
+ }
5552
+ ],
5553
+ "description": "Records the document defines itself, referenced by bare id. Checked first for every bare id. Forking a catalog record copies it here under a new id, so the change of ownership is visible."
5552
5554
  }
5553
- }
5554
- },
5555
- "CatalogSource": {
5556
- "type": "string",
5557
- "description": "Catalog source location. Accepts:\n- A bare URL pointing at a catalog directory (e.g. 'https://acme.com/decks/narratives'); record ids resolve to '<base>/<id>.json'.\n- A URL pointing at an index file (e.g. 'https://acme.com/decks/narratives/index.json'); records are resolved relative to the index file's directory and the index entries describe what's available. Index files follow https://openpresentation.org/schema/opf-catalog-index/v1; the default catalog's index is https://www.pptx.gallery/<kind>/index.json.\n- A package reference of the form 'pkg:<package>[/<subpath>]'. 'pkg:@openpresentation/opf/...' resolves from the bundled snapshot; any other package reference needs the host to supply its records in 'catalogSources'.\n\nEngines never fetch or install anything for a source: the host supplies the records of every source other than the bundled default, as a 'catalogSources' map from the source string to its records.",
5555
+ },
5556
+ "propertyNames": {
5557
+ "pattern": "^[a-z][a-z0-9-]*$",
5558
+ "description": "Group name: lowercase kebab-case. 'default' and 'custom' are reserved."
5559
+ },
5560
+ "additionalProperties": {
5561
+ "allOf": [
5562
+ {
5563
+ "$ref": "#/$defs/CatalogGroup"
5564
+ },
5565
+ {
5566
+ "required": [
5567
+ "source"
5568
+ ]
5569
+ }
5570
+ ],
5571
+ "description": "A named catalog: its source and the records of it this document embeds. References name it as a prefix ('acme:hero')."
5572
+ },
5558
5573
  "examples": [
5559
- "https://www.pptx.gallery/narratives",
5560
- "https://acme.com/decks/narratives/index.json",
5561
- "pkg:@acme/decks/narratives",
5562
- "pkg:pptx-gallery"
5563
- ]
5564
- },
5574
+ {
5575
+ "default": {
5576
+ "source": "https://www.pptx.gallery",
5577
+ "themes": {
5578
+ "minimal": {
5579
+ "name": "Minimal",
5580
+ "colorScheme": "cool-horizon",
5581
+ "fontScheme": "aptos"
5582
+ }
5583
+ }
5584
+ },
5585
+ "acme": {
5586
+ "source": "pkg:@acme/opf-catalog",
5587
+ "layouts": {
5588
+ "hero": {
5589
+ "name": "Hero",
5590
+ "placeholders": [
5591
+ {
5592
+ "type": "title"
5593
+ }
5594
+ ]
5595
+ }
5596
+ }
5597
+ },
5598
+ "custom": {
5599
+ "layouts": {
5600
+ "q4-special": {
5601
+ "name": "Q4 special",
5602
+ "placeholders": [
5603
+ {
5604
+ "type": "title"
5605
+ },
5606
+ {
5607
+ "type": "chart"
5608
+ }
5609
+ ]
5610
+ }
5611
+ }
5612
+ }
5613
+ }
5614
+ ]
5615
+ },
5616
+ "CatalogGroup": {
5617
+ "type": "object",
5618
+ "additionalProperties": false,
5619
+ "description": "One catalog group: the catalog's source and the records of it the document embeds, by kind and then by id.",
5620
+ "properties": {
5621
+ "source": {
5622
+ "$ref": "#/$defs/CatalogSource"
5623
+ },
5624
+ "layouts": {
5625
+ "$ref": "#/$defs/CatalogRecords",
5626
+ "description": "Layout records keyed by id, each with the fields of https://openpresentation.org/schema/opf-layout/v1. Referenced from Slide.layout."
5627
+ },
5628
+ "themes": {
5629
+ "$ref": "#/$defs/CatalogRecords",
5630
+ "description": "Theme records keyed by id, each with the fields of https://openpresentation.org/schema/opf-theme/v1. Referenced from design.theme."
5631
+ },
5632
+ "colorSchemes": {
5633
+ "$ref": "#/$defs/CatalogRecords",
5634
+ "description": "Colour-scheme records keyed by id, each with the fields of https://openpresentation.org/schema/opf-color-scheme/v1. Referenced from design.colorScheme and a theme's colorScheme."
5635
+ },
5636
+ "fontSchemes": {
5637
+ "$ref": "#/$defs/CatalogRecords",
5638
+ "description": "Font-scheme records keyed by id, each with the fields of https://openpresentation.org/schema/opf-font-scheme/v1. Referenced from design.fontScheme, a theme's fontScheme and a language's font schemes."
5639
+ },
5640
+ "narratives": {
5641
+ "$ref": "#/$defs/CatalogRecords",
5642
+ "description": "Narrative records keyed by id, each with the fields of https://openpresentation.org/schema/opf-narrative/v1. Referenced from narrative."
5643
+ },
5644
+ "audiences": {
5645
+ "$ref": "#/$defs/CatalogRecords",
5646
+ "description": "Audience records keyed by id, each with the fields of https://openpresentation.org/schema/opf-audience/v1. Referenced from audience."
5647
+ },
5648
+ "purposes": {
5649
+ "$ref": "#/$defs/CatalogRecords",
5650
+ "description": "Purpose records keyed by id, each with the fields of https://openpresentation.org/schema/opf-purpose/v1. Referenced from purpose."
5651
+ },
5652
+ "tones": {
5653
+ "$ref": "#/$defs/CatalogRecords",
5654
+ "description": "Tone records keyed by id, each with the fields of https://openpresentation.org/schema/opf-tone/v1. Referenced from tone."
5655
+ }
5656
+ }
5657
+ },
5658
+ "CatalogSource": {
5659
+ "type": "string",
5660
+ "pattern": "^(?:https://[^\\s]+|pkg:[^\\s]+)$",
5661
+ "description": "Identity of a catalog: an HTTPS URL ('https://www.pptx.gallery') or a package reference ('pkg:@acme/opf-catalog'). It names the catalog; engines never fetch or install it. A host registers the catalog's records under this exact string, and copying slides between documents matches groups by it.",
5662
+ "examples": [
5663
+ "https://www.pptx.gallery",
5664
+ "pkg:@acme/opf-catalog"
5665
+ ]
5666
+ },
5667
+ "CatalogRecords": {
5668
+ "type": "object",
5669
+ "description": "Embedded records of one kind, keyed by id. The key is the record's id; an embedded record carries no '$schema', 'id', origin or digest. Catalog display metadata ('x-*' members) is stripped when a record is embedded.",
5670
+ "propertyNames": {
5671
+ "pattern": "^[a-z][a-z0-9-]*$"
5672
+ },
5673
+ "additionalProperties": {
5674
+ "type": "object",
5675
+ "not": {
5676
+ "anyOf": [
5677
+ {
5678
+ "required": [
5679
+ "$schema"
5680
+ ]
5681
+ },
5682
+ {
5683
+ "required": [
5684
+ "id"
5685
+ ]
5686
+ }
5687
+ ]
5688
+ },
5689
+ "description": "One embedded record: the fields of the kind's companion schema without '$schema' and 'id'."
5690
+ }
5691
+ },
5692
+ "CatalogReference": {
5693
+ "type": "string",
5694
+ "pattern": "^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$",
5695
+ "description": "A content reference: a bare id ('two-column') or 'name:id' ('acme:hero'), where the prefix names a group of 'catalogs'. URLs and 'pkg:' strings are not references; a named catalog group replaces them. See Catalogs for the resolution order.",
5696
+ "examples": [
5697
+ "two-column",
5698
+ "acme:hero",
5699
+ "default:minimal",
5700
+ "custom:q4-special"
5701
+ ]
5702
+ },
5703
+ "LanguageTag": {
5704
+ "type": "string",
5705
+ "pattern": "^(?:[A-Za-z]{2,3}|[iIxX])(?:-[A-Za-z0-9]{1,8})*$",
5706
+ "description": "A BCP-47 language tag ('en-US', 'ja', 'zh-Hans', 'sr-Latn-ME'), an engine vocabulary. Use 'en-GB' for UK English; 'en-UK' is not a valid region.",
5707
+ "examples": [
5708
+ "en-US",
5709
+ "en-GB",
5710
+ "ja",
5711
+ "zh-Hans",
5712
+ "ar-SA"
5713
+ ]
5714
+ },
5565
5715
  "Composition": {
5566
5716
  "type": "object",
5567
5717
  "additionalProperties": false,
5568
- "description": "Portable dynamic composition. Slide fields override the resolved layout. Nested groups arrange their children independently, inheriting only minFontSize and overflow. Explicit promoted regions retain their positions.",
5718
+ "description": "Portable dynamic composition. Slide fields override the resolved layout. Nested groups (content groups here, placeholder groups in a layout record) arrange their children independently, inheriting only minFontSize and overflow. Explicit promoted regions retain their positions.",
5569
5719
  "properties": {
5570
5720
  "mode": {
5571
5721
  "type": "string",
@@ -5628,7 +5778,7 @@ var audience = {
5628
5778
  "$schema": "https://json-schema.org/draft/2020-12/schema",
5629
5779
  "$id": "https://openpresentation.org/schema/opf-audience/v1",
5630
5780
  "title": "Audience",
5631
- "description": "Schema for audience records in the pptx.gallery library. Each record names an audience archetype (e.g. 'executive', 'engineering-team', 'investor') and carries seniority, technical-fluency, decision-power, and attention-budget hints used by AI-driven generation. Audiences are referenced from OPF documents via audience; the engine resolves the reference against catalogs.audiences (inline) \u2192 catalogs.audiences.source \u2192 the default catalog at https://www.pptx.gallery/audiences. The audience field also accepts free-form strings; this catalog is for engine-aware audience archetypes that carry generation hints.",
5781
+ "description": "Schema for audience records. Each record names an audience archetype (e.g. 'executive', 'engineering-team', 'investor') and carries seniority, technical-fluency, decision-power, and attention-budget hints used by AI-driven generation. Documents reference an audience from 'audience', which also accepts free-form text.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
5632
5782
  "type": "object",
5633
5783
  "required": [
5634
5784
  "$schema",
@@ -5639,12 +5789,12 @@ var audience = {
5639
5789
  "$schema": {
5640
5790
  "type": "string",
5641
5791
  "const": "https://openpresentation.org/schema/opf-audience/v1",
5642
- "description": "Identifies this record as an audience in the openpresentation.org catalog."
5792
+ "description": "Identifies a published record file as a audience record. Required in a published file; an embedded copy omits it."
5643
5793
  },
5644
5794
  "id": {
5645
5795
  "type": "string",
5646
5796
  "pattern": "^[a-z][a-z0-9-]*$",
5647
- "description": "Stable slug used by OPF documents to reference this audience via audience. Lowercase kebab-case.",
5797
+ "description": "The audience's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
5648
5798
  "examples": [
5649
5799
  "executive",
5650
5800
  "board",
@@ -5674,29 +5824,6 @@ var audience = {
5674
5824
  "Regulators"
5675
5825
  ]
5676
5826
  },
5677
- "deprecation": {
5678
- "type": "object",
5679
- "additionalProperties": false,
5680
- "required": [
5681
- "replacedBy"
5682
- ],
5683
- "description": "Present when this audience is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
5684
- "properties": {
5685
- "replacedBy": {
5686
- "type": "string",
5687
- "pattern": "^[a-z][a-z0-9-]*$",
5688
- "description": "Id of the non-deprecated audience record that documents should reference instead."
5689
- },
5690
- "reason": {
5691
- "type": "string",
5692
- "description": "Why the record is deprecated."
5693
- },
5694
- "removal": {
5695
- "type": "string",
5696
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
5697
- }
5698
- }
5699
- },
5700
5827
  "summary": {
5701
5828
  "type": "string",
5702
5829
  "description": "One-sentence positioning of the audience \u2014 who they are and what they care about.",
@@ -5753,7 +5880,7 @@ var audience = {
5753
5880
  "items": {
5754
5881
  "type": "string"
5755
5882
  },
5756
- "description": "Soft cross-link: narrative-catalog ids that work well for this audience. Used by picker UIs to suggest narratives once an audience is chosen. Validators warn on unknown ids; never error.",
5883
+ "description": "Soft cross-link: ids of narratives in the same catalog that work well for this audience. Used by picker UIs to suggest narratives once an audience is chosen. Never resolved, embedded or validated as references.",
5757
5884
  "examples": [
5758
5885
  [
5759
5886
  "scqa",
@@ -5767,7 +5894,7 @@ var audience = {
5767
5894
  "items": {
5768
5895
  "type": "string"
5769
5896
  },
5770
- "description": "Soft cross-link: tone-catalog ids that work well for this audience.",
5897
+ "description": "Soft cross-link: ids of tones in the same catalog that work well for this audience. Never resolved, embedded or validated as references.",
5771
5898
  "examples": [
5772
5899
  [
5773
5900
  "formal",
@@ -5823,7 +5950,7 @@ var purpose = {
5823
5950
  "$schema": "https://json-schema.org/draft/2020-12/schema",
5824
5951
  "$id": "https://openpresentation.org/schema/opf-purpose/v1",
5825
5952
  "title": "Purpose",
5826
- "description": "Schema for purpose records in the pptx.gallery library. Each record names a presentation objective such as informing, aligning, persuading, driving a decision, or selling. Purposes are referenced from OPF documents via purpose; the engine resolves the reference against catalogs.purposes (inline) \u2192 catalogs.purposes.source \u2192 the default catalog at https://www.pptx.gallery/purposes. The purpose field also accepts free-form strings and inline Purpose objects.",
5953
+ "description": "Schema for purpose records. Each record names a presentation objective such as informing, aligning, persuading, driving a decision, or selling. Documents reference a purpose from 'purpose', which also accepts free-form text and inline Purpose objects.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
5827
5954
  "type": "object",
5828
5955
  "required": [
5829
5956
  "$schema",
@@ -5834,12 +5961,12 @@ var purpose = {
5834
5961
  "$schema": {
5835
5962
  "type": "string",
5836
5963
  "const": "https://openpresentation.org/schema/opf-purpose/v1",
5837
- "description": "Identifies this record as a purpose in the openpresentation.org catalog."
5964
+ "description": "Identifies a published record file as a purpose record. Required in a published file; an embedded copy omits it."
5838
5965
  },
5839
5966
  "id": {
5840
5967
  "type": "string",
5841
5968
  "pattern": "^[a-z][a-z0-9-]*$",
5842
- "description": "Stable slug used by OPF documents to reference this purpose via purpose. Lowercase kebab-case.",
5969
+ "description": "The purpose's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
5843
5970
  "examples": [
5844
5971
  "inform",
5845
5972
  "decide",
@@ -5862,29 +5989,6 @@ var purpose = {
5862
5989
  "Persuade"
5863
5990
  ]
5864
5991
  },
5865
- "deprecation": {
5866
- "type": "object",
5867
- "additionalProperties": false,
5868
- "required": [
5869
- "replacedBy"
5870
- ],
5871
- "description": "Present when this purpose is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
5872
- "properties": {
5873
- "replacedBy": {
5874
- "type": "string",
5875
- "pattern": "^[a-z][a-z0-9-]*$",
5876
- "description": "Id of the non-deprecated purpose record that documents should reference instead."
5877
- },
5878
- "reason": {
5879
- "type": "string",
5880
- "description": "Why the record is deprecated."
5881
- },
5882
- "removal": {
5883
- "type": "string",
5884
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
5885
- }
5886
- }
5887
- },
5888
5992
  "summary": {
5889
5993
  "type": "string",
5890
5994
  "description": "One-sentence positioning of the purpose \u2014 what this deck is trying to accomplish."
@@ -5914,14 +6018,14 @@ var purpose = {
5914
6018
  "items": {
5915
6019
  "type": "string"
5916
6020
  },
5917
- "description": "Soft cross-link: narrative-catalog ids that work well for this purpose."
6021
+ "description": "Soft cross-link: ids of narratives in the same catalog that work well for this purpose. Never resolved, embedded or validated as references."
5918
6022
  },
5919
6023
  "recommendedTones": {
5920
6024
  "type": "array",
5921
6025
  "items": {
5922
6026
  "type": "string"
5923
6027
  },
5924
- "description": "Soft cross-link: tone-catalog ids that work well for this purpose."
6028
+ "description": "Soft cross-link: ids of tones in the same catalog that work well for this purpose. Never resolved, embedded or validated as references."
5925
6029
  },
5926
6030
  "tags": {
5927
6031
  "type": "array",
@@ -5957,7 +6061,7 @@ var tone = {
5957
6061
  "$schema": "https://json-schema.org/draft/2020-12/schema",
5958
6062
  "$id": "https://openpresentation.org/schema/opf-tone/v1",
5959
6063
  "title": "Tone",
5960
- "description": "Schema for tone records in the pptx.gallery library. Each record names a presentation tone (e.g. 'formal', 'casual', 'inspirational') and carries voice cues, anti-patterns, and sample phrases that AI-driven generation uses to shape output. Tones are referenced from OPF documents via tone; the engine resolves the reference against catalogs.tones (inline) \u2192 catalogs.tones.source \u2192 the default catalog at https://www.pptx.gallery/tones.",
6064
+ "description": "Schema for tone records. Each record names a presentation tone (e.g. 'formal', 'casual', 'inspirational') and carries voice cues, anti-patterns, and sample phrases that AI-driven generation uses to shape output. Documents reference a tone from 'tone'.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
5961
6065
  "type": "object",
5962
6066
  "required": [
5963
6067
  "$schema",
@@ -5968,12 +6072,12 @@ var tone = {
5968
6072
  "$schema": {
5969
6073
  "type": "string",
5970
6074
  "const": "https://openpresentation.org/schema/opf-tone/v1",
5971
- "description": "Identifies this record as a tone in the openpresentation.org catalog."
6075
+ "description": "Identifies a published record file as a tone record. Required in a published file; an embedded copy omits it."
5972
6076
  },
5973
6077
  "id": {
5974
6078
  "type": "string",
5975
6079
  "pattern": "^[a-z][a-z0-9-]*$",
5976
- "description": "Stable slug used by OPF documents to reference this tone via tone. Lowercase kebab-case.",
6080
+ "description": "The tone's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
5977
6081
  "examples": [
5978
6082
  "formal",
5979
6083
  "casual",
@@ -5997,29 +6101,6 @@ var tone = {
5997
6101
  "Conversational"
5998
6102
  ]
5999
6103
  },
6000
- "deprecation": {
6001
- "type": "object",
6002
- "additionalProperties": false,
6003
- "required": [
6004
- "replacedBy"
6005
- ],
6006
- "description": "Present when this tone is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
6007
- "properties": {
6008
- "replacedBy": {
6009
- "type": "string",
6010
- "pattern": "^[a-z][a-z0-9-]*$",
6011
- "description": "Id of the non-deprecated tone record that documents should reference instead."
6012
- },
6013
- "reason": {
6014
- "type": "string",
6015
- "description": "Why the record is deprecated."
6016
- },
6017
- "removal": {
6018
- "type": "string",
6019
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
6020
- }
6021
- }
6022
- },
6023
6104
  "summary": {
6024
6105
  "type": "string",
6025
6106
  "description": "One-sentence positioning of the tone \u2014 when to reach for it.",
@@ -6082,7 +6163,7 @@ var tone = {
6082
6163
  "items": {
6083
6164
  "type": "string"
6084
6165
  },
6085
- "description": "Soft cross-link: narrative-catalog ids this tone pairs well with. Used by picker UIs to suggest narratives once a tone is chosen. Validators warn on unknown ids; never error.",
6166
+ "description": "Soft cross-link: ids of narratives in the same catalog this tone pairs well with. Used by picker UIs to suggest narratives once a tone is chosen. Never resolved, embedded or validated as references.",
6086
6167
  "examples": [
6087
6168
  [
6088
6169
  "board-meeting",
@@ -6139,7 +6220,7 @@ var theme = {
6139
6220
  "$schema": "https://json-schema.org/draft/2020-12/schema",
6140
6221
  "$id": "https://openpresentation.org/schema/opf-theme/v1",
6141
6222
  "title": "Theme",
6142
- "description": "Schema for theme records in the pptx.gallery library. Each theme is a small, named bundle that pairs a color scheme, a font scheme, a default theme-controlled background, and a slide size. Themes are referenced from OPF documents via design.theme or design.theme.id; the engine resolves the reference against catalogs.themes (inline) \u2192 catalogs.themes.source \u2192 the default catalog at https://www.pptx.gallery/themes. Inline overrides on design.colorScheme / design.fontScheme / design.background / design.dimensions take precedence over a resolved theme.",
6223
+ "description": "Schema for theme records. Each theme is a small, named bundle that pairs a color scheme, a font scheme, a default theme-controlled background, and a slide size. Documents reference a theme from design.theme; design.colorScheme, design.fontScheme, design.background and design.dimensions take precedence over the resolved theme. The theme's own colorScheme and fontScheme references resolve in the theme's group first, so a catalog's theme finds that catalog's schemes.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
6143
6224
  "type": "object",
6144
6225
  "required": [
6145
6226
  "$schema",
@@ -6150,12 +6231,12 @@ var theme = {
6150
6231
  "$schema": {
6151
6232
  "type": "string",
6152
6233
  "const": "https://openpresentation.org/schema/opf-theme/v1",
6153
- "description": "Identifies this record as a theme in the openpresentation.org catalog."
6234
+ "description": "Identifies a published record file as a theme record. Required in a published file; an embedded copy omits it."
6154
6235
  },
6155
6236
  "id": {
6156
6237
  "type": "string",
6157
6238
  "pattern": "^[a-z][a-z0-9-]*$",
6158
- "description": "Stable slug used by OPF documents to reference this theme via design.theme. Lowercase kebab-case.",
6239
+ "description": "The theme's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
6159
6240
  "examples": [
6160
6241
  "minimal",
6161
6242
  "classic",
@@ -6173,29 +6254,6 @@ var theme = {
6173
6254
  "Bold"
6174
6255
  ]
6175
6256
  },
6176
- "deprecation": {
6177
- "type": "object",
6178
- "additionalProperties": false,
6179
- "required": [
6180
- "replacedBy"
6181
- ],
6182
- "description": "Present when this theme is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
6183
- "properties": {
6184
- "replacedBy": {
6185
- "type": "string",
6186
- "pattern": "^[a-z][a-z0-9-]*$",
6187
- "description": "Id of the non-deprecated theme record that documents should reference instead."
6188
- },
6189
- "reason": {
6190
- "type": "string",
6191
- "description": "Why the record is deprecated."
6192
- },
6193
- "removal": {
6194
- "type": "string",
6195
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
6196
- }
6197
- }
6198
- },
6199
6257
  "summary": {
6200
6258
  "type": "string",
6201
6259
  "description": "One-sentence positioning of the theme \u2014 when to reach for it.",
@@ -6213,7 +6271,8 @@ var theme = {
6213
6271
  },
6214
6272
  "colorScheme": {
6215
6273
  "type": "string",
6216
- "description": "Catalog reference to the theme's default color scheme \u2014 resolved against catalogs.colorSchemes the same way design.colorScheme or design.colorScheme.id is. Accepts a bare id, HTTPS URL, or 'pkg:' reference.",
6274
+ "pattern": "^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$",
6275
+ "description": "The theme's default colour scheme: a reference (a bare id or 'name:id') resolved like design.colorScheme, but in the theme's own catalogs group first.",
6217
6276
  "examples": [
6218
6277
  "cool-horizon",
6219
6278
  "boost",
@@ -6222,7 +6281,8 @@ var theme = {
6222
6281
  },
6223
6282
  "fontScheme": {
6224
6283
  "type": "string",
6225
- "description": "Catalog reference to the theme's default font scheme \u2014 resolved against catalogs.fontSchemes the same way design.fontScheme or design.fontScheme.id is. Accepts a bare id, HTTPS URL, or 'pkg:' reference.",
6284
+ "pattern": "^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$",
6285
+ "description": "The theme's default font scheme: a reference (a bare id or 'name:id') resolved like design.fontScheme, but in the theme's own catalogs group first.",
6226
6286
  "examples": [
6227
6287
  "aptos",
6228
6288
  "tenorite",
@@ -6344,7 +6404,7 @@ var layout = {
6344
6404
  "$schema": "https://json-schema.org/draft/2020-12/schema",
6345
6405
  "$id": "https://openpresentation.org/schema/opf-layout/v1",
6346
6406
  "title": "Slide Layout",
6347
- "description": "Schema for slide-layout records in the pptx.gallery library. Each record describes a semantic slide layout \u2014 what regions it exposes and what content kinds those regions are intended to hold. Layouts are referenced from OPF documents via Slide.layout; the engine resolves the reference against catalogs.layouts (inline) \u2192 catalogs.layouts.source \u2192 the default catalog at https://www.pptx.gallery/layouts. Free-form custom layout names that don't resolve through any catalog fall through to engine-defined layouts.",
6407
+ "description": "Schema for slide-layout records. Each record describes a semantic slide layout: what regions it exposes, what content kinds those regions are intended to hold, how they are arranged (composition) and its design hints. Documents reference a layout from Slide.layout; a slide without a layout, or whose layout resolves nowhere, composes automatically.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
6348
6408
  "type": "object",
6349
6409
  "required": [
6350
6410
  "$schema",
@@ -6355,17 +6415,17 @@ var layout = {
6355
6415
  "$schema": {
6356
6416
  "type": "string",
6357
6417
  "const": "https://openpresentation.org/schema/opf-layout/v1",
6358
- "description": "Identifies this record as a slide layout in the openpresentation.org catalog."
6418
+ "description": "Identifies a published record file as a layout record. Required in a published file; an embedded copy omits it."
6359
6419
  },
6360
6420
  "id": {
6361
6421
  "type": "string",
6362
6422
  "pattern": "^[a-z][a-z0-9-]*$",
6363
- "description": "Stable slug used by OPF documents to reference this layout via Slide.layout. Lowercase kebab-case.",
6423
+ "description": "The layout's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
6364
6424
  "examples": [
6365
6425
  "title",
6366
6426
  "title-subtitle",
6367
6427
  "chart-1x",
6368
- "image-bleed"
6428
+ "image-focus"
6369
6429
  ]
6370
6430
  },
6371
6431
  "name": {
@@ -6378,29 +6438,6 @@ var layout = {
6378
6438
  "Image Bleed"
6379
6439
  ]
6380
6440
  },
6381
- "deprecation": {
6382
- "type": "object",
6383
- "additionalProperties": false,
6384
- "required": [
6385
- "replacedBy"
6386
- ],
6387
- "description": "Present when this layout is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
6388
- "properties": {
6389
- "replacedBy": {
6390
- "type": "string",
6391
- "pattern": "^[a-z][a-z0-9-]*$",
6392
- "description": "Id of the non-deprecated layout record that documents should reference instead."
6393
- },
6394
- "reason": {
6395
- "type": "string",
6396
- "description": "Why the record is deprecated."
6397
- },
6398
- "removal": {
6399
- "type": "string",
6400
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
6401
- }
6402
- }
6403
- },
6404
6441
  "summary": {
6405
6442
  "type": "string",
6406
6443
  "description": "One-sentence positioning of the layout \u2014 when to reach for it.",
@@ -6418,14 +6455,14 @@ var layout = {
6418
6455
  },
6419
6456
  "design": {
6420
6457
  "$ref": "#/$defs/DesignHints",
6421
- "description": "The layout's design hints, with the same keys and values as the deck's design and a slide's design (a slide overrides exactly what its layout sets, by the same name). An absent key means the layout has no opinion. Every key is applied from the record as the lowest-precedence default, per key: the slide's design, then the deck's design, then this record's design, then the engine default, so a layout value nobody overrides is honored without copying it anywhere (a layout's composition.mode still ranks above contentDirection; slideImage.position is the fallback position of a slide image the layout reserves). Composition, the renderer and the PPTX exporter all read the one result."
6458
+ "description": "The layout's design hints, with the same keys and values as the deck's design and a slide's design (a slide overrides exactly what its layout sets, by the same name). An absent key means the layout has no opinion. Every key is applied from the record as the lowest-precedence default, per key: the slide's design, then the deck's design, then this record's design, then the engine default, so a layout value nobody overrides is honored without copying it anywhere (a layout's composition.mode still ranks above contentDirection). Composition, the renderer and the PPTX exporter all read the one result."
6422
6459
  },
6423
6460
  "placeholders": {
6424
6461
  "type": "array",
6425
6462
  "items": {
6426
- "$ref": "#/$defs/Placeholder"
6463
+ "$ref": "#/$defs/PlaceholderEntry"
6427
6464
  },
6428
- "description": "Ordered regions the layout exposes. This is the single source of truth for what the layout holds: the content kind, the number of body regions and whether it has a title, subtitle or tag are derived from it (layoutContent in @openpresentation/opf), never stored separately. The engine fills 'title', 'subtitle' and 'tag' placeholders from Slide.title, Slide.subtitle and Slide.tag. The other placeholders are content-kind regions that composition uses to size the body and that pickers use to match layouts. Slide content itself lives either in root payload fields or promoted region keys on Slide. Chrome (slide number, footer, date) is not included here; it is owned by Design.header / Design.footer."
6465
+ "description": `Ordered regions the layout exposes. This is the single source of truth for what the layout holds: the content kind, the number of body regions and whether it has a title, subtitle or tag are derived from it (layoutContent in @openpresentation/opf, which counts the leaves of placeholder groups), never stored separately. The engine fills 'title', 'subtitle' and 'tag' placeholders from Slide.title, Slide.subtitle and Slide.tag. The other placeholders are content-kind regions that composition uses to size the body and that pickers use to match layouts. An entry may instead be a placeholder group ({ "type": "group", "composition", "placeholders" }) that arranges its own regions inside one cell of this record's composition, so a record can say 'two stacked panels beside a chart' once; groups nest at most three levels. Slide content stays flat: its body payloads fill the leaf regions in reading order (depth first, in array order). Slide content itself lives either in root payload fields, blocks or promoted region keys on Slide. Chrome (slide number, footer, date) is not included here; it is owned by Design.header / Design.footer.`
6429
6466
  },
6430
6467
  "tags": {
6431
6468
  "type": "array",
@@ -6483,12 +6520,191 @@ var layout = {
6483
6520
  }
6484
6521
  },
6485
6522
  "$defs": {
6523
+ "PlaceholderEntry": {
6524
+ "description": "One entry of a layout's placeholders: a region (Placeholder) or, when its type is 'group', a placeholder group (PlaceholderGroup).",
6525
+ "if": {
6526
+ "type": "object",
6527
+ "required": [
6528
+ "type"
6529
+ ],
6530
+ "properties": {
6531
+ "type": {
6532
+ "const": "group"
6533
+ }
6534
+ }
6535
+ },
6536
+ "then": {
6537
+ "$ref": "#/$defs/PlaceholderGroup"
6538
+ },
6539
+ "else": {
6540
+ "$ref": "#/$defs/Placeholder"
6541
+ }
6542
+ },
6543
+ "PlaceholderGroup": {
6544
+ "type": "object",
6545
+ "additionalProperties": false,
6546
+ "required": [
6547
+ "type",
6548
+ "placeholders"
6549
+ ],
6550
+ "description": "A placeholder group: regions arranged by their own composition inside one cell of the record's composition, the way a content group (a block with blocks) arranges its children. Slide content fills the group's leaf regions in reading order, as part of one flat sequence for the whole record. A group holds body regions and groups only (no title, subtitle or tag, and no placement), and groups nest at most three levels inside a record: this is the first. Groups draw nothing of their own and have no slide path; design.chartPrimary is shorthand for a record whose root holds the chart and one group of the other content.",
6551
+ "properties": {
6552
+ "type": {
6553
+ "const": "group",
6554
+ "description": "Marks the entry as a placeholder group."
6555
+ },
6556
+ "composition": {
6557
+ "$ref": "#/$defs/Composition",
6558
+ "description": "How the group arranges its regions, with the semantics of a content group's composition: only minFontSize and overflow inherit from the enclosing composition; padding defaults to 0 and gap is a fraction of the group's short edge. Omitted, the group arranges its regions automatically."
6559
+ },
6560
+ "placeholders": {
6561
+ "type": "array",
6562
+ "minItems": 1,
6563
+ "items": {
6564
+ "$ref": "#/$defs/PlaceholderGroupEntry2"
6565
+ },
6566
+ "description": "The group's regions and nested groups, in reading order."
6567
+ }
6568
+ }
6569
+ },
6570
+ "PlaceholderGroupEntry2": {
6571
+ "description": "An entry of a first-level group: a region (GroupedPlaceholder) or a second-level group (PlaceholderGroup2).",
6572
+ "if": {
6573
+ "type": "object",
6574
+ "required": [
6575
+ "type"
6576
+ ],
6577
+ "properties": {
6578
+ "type": {
6579
+ "const": "group"
6580
+ }
6581
+ }
6582
+ },
6583
+ "then": {
6584
+ "$ref": "#/$defs/PlaceholderGroup2"
6585
+ },
6586
+ "else": {
6587
+ "$ref": "#/$defs/GroupedPlaceholder"
6588
+ }
6589
+ },
6590
+ "PlaceholderGroup2": {
6591
+ "type": "object",
6592
+ "additionalProperties": false,
6593
+ "required": [
6594
+ "type",
6595
+ "placeholders"
6596
+ ],
6597
+ "description": "A placeholder group nested in another (the second level). Same fields as PlaceholderGroup.",
6598
+ "properties": {
6599
+ "type": {
6600
+ "const": "group",
6601
+ "description": "Marks the entry as a placeholder group."
6602
+ },
6603
+ "composition": {
6604
+ "$ref": "#/$defs/Composition",
6605
+ "description": "How the group arranges its regions; see PlaceholderGroup.composition."
6606
+ },
6607
+ "placeholders": {
6608
+ "type": "array",
6609
+ "minItems": 1,
6610
+ "items": {
6611
+ "$ref": "#/$defs/PlaceholderGroupEntry3"
6612
+ },
6613
+ "description": "The group's regions and nested groups, in reading order."
6614
+ }
6615
+ }
6616
+ },
6617
+ "PlaceholderGroupEntry3": {
6618
+ "description": "An entry of a second-level group: a region (GroupedPlaceholder) or a third-level group (PlaceholderGroup3).",
6619
+ "if": {
6620
+ "type": "object",
6621
+ "required": [
6622
+ "type"
6623
+ ],
6624
+ "properties": {
6625
+ "type": {
6626
+ "const": "group"
6627
+ }
6628
+ }
6629
+ },
6630
+ "then": {
6631
+ "$ref": "#/$defs/PlaceholderGroup3"
6632
+ },
6633
+ "else": {
6634
+ "$ref": "#/$defs/GroupedPlaceholder"
6635
+ }
6636
+ },
6637
+ "PlaceholderGroup3": {
6638
+ "type": "object",
6639
+ "additionalProperties": false,
6640
+ "required": [
6641
+ "type",
6642
+ "placeholders"
6643
+ ],
6644
+ "description": "The innermost placeholder group (the third level): it holds regions only, never another group.",
6645
+ "properties": {
6646
+ "type": {
6647
+ "const": "group",
6648
+ "description": "Marks the entry as a placeholder group."
6649
+ },
6650
+ "composition": {
6651
+ "$ref": "#/$defs/Composition",
6652
+ "description": "How the group arranges its regions; see PlaceholderGroup.composition."
6653
+ },
6654
+ "placeholders": {
6655
+ "type": "array",
6656
+ "minItems": 1,
6657
+ "items": {
6658
+ "$ref": "#/$defs/GroupedPlaceholder"
6659
+ },
6660
+ "description": "The group's regions, in reading order."
6661
+ }
6662
+ }
6663
+ },
6664
+ "GroupedPlaceholder": {
6665
+ "type": "object",
6666
+ "additionalProperties": false,
6667
+ "required": [
6668
+ "type"
6669
+ ],
6670
+ "description": "A region inside a placeholder group: a body content kind only. Headings ('title', 'subtitle', 'tag') stay at the record's top level, and only a top-level image placeholder may carry a placement.",
6671
+ "properties": {
6672
+ "type": {
6673
+ "type": "string",
6674
+ "enum": [
6675
+ "text",
6676
+ "list",
6677
+ "image",
6678
+ "video",
6679
+ "chart",
6680
+ "table",
6681
+ "code",
6682
+ "metric",
6683
+ "quote",
6684
+ "timeline"
6685
+ ],
6686
+ "description": "The content kind of the region, from the one OPF content-kind vocabulary (see Placeholder.type)."
6687
+ }
6688
+ }
6689
+ },
6486
6690
  "Placeholder": {
6487
6691
  "type": "object",
6488
6692
  "required": [
6489
6693
  "type"
6490
6694
  ],
6491
6695
  "description": "A single region inside a slide layout. Title, subtitle, and tag placeholders bind to the corresponding Slide fields; every other placeholder describes the content kind that region holds. The array order in the surrounding 'placeholders' field preserves layout region order.",
6696
+ "if": {
6697
+ "required": [
6698
+ "placement"
6699
+ ]
6700
+ },
6701
+ "then": {
6702
+ "properties": {
6703
+ "type": {
6704
+ "const": "image"
6705
+ }
6706
+ }
6707
+ },
6492
6708
  "properties": {
6493
6709
  "type": {
6494
6710
  "type": "string",
@@ -6508,6 +6724,40 @@ var layout = {
6508
6724
  "timeline"
6509
6725
  ],
6510
6726
  "description": "The content kind of the region. This is the one OPF content-kind vocabulary: the same words name a slide's payload fields (text, items, image, video, chart, table, code, metric, quote, timeline). 'title', 'subtitle' and 'tag' are the heading kinds and bind to Slide.title, Slide.subtitle and Slide.tag. 'text' holds text and bullets; 'list' holds items. 'image' is filled by an image payload and 'video' by a video payload. 'metric', 'quote', 'timeline', 'chart', 'table' and 'code' are filled by the payload of the same name; a metric region shows the metric payload with its optional label, description, unit, delta, trend and sentiment."
6727
+ },
6728
+ "placement": {
6729
+ "$ref": "#/$defs/ImagePlacement",
6730
+ "description": "Image placeholders only. Bleeds the slide's image for this region to one slide edge, as an image block's placement does: the n-th image placeholder (counting the image regions of placeholder groups too, in reading order) places the slide's n-th top-level image (Slide.image or an image block in blocks) unless that block sets its own placement. Only a top-level image placeholder may carry a placement; a region inside a placeholder group cannot bleed to a slide edge. The headings and the other content compose in the rest of the slide."
6731
+ }
6732
+ }
6733
+ },
6734
+ "ImagePlacement": {
6735
+ "type": "object",
6736
+ "additionalProperties": false,
6737
+ "required": [
6738
+ "edge"
6739
+ ],
6740
+ "description": "The same object as ImagePlacement in opf.schema.json: a band along one slide edge for the image, edge to edge, with the rest of the slide left to the headings and the other content.",
6741
+ "properties": {
6742
+ "edge": {
6743
+ "type": "string",
6744
+ "enum": [
6745
+ "left",
6746
+ "right",
6747
+ "top",
6748
+ "bottom"
6749
+ ],
6750
+ "description": "The slide edge the image bleeds to. In a right-to-left deck 'left' is the start side, drawn at the right."
6751
+ },
6752
+ "size": {
6753
+ "type": "number",
6754
+ "minimum": 0.1,
6755
+ "maximum": 0.9,
6756
+ "description": "Share of the slide width (left, right) or height (top, bottom) given to the band. Default 0.5."
6757
+ },
6758
+ "inset": {
6759
+ "type": "boolean",
6760
+ "description": "Draw the frame inside the slide padding on every side of the band instead of edge to edge. Default false."
6511
6761
  }
6512
6762
  }
6513
6763
  },
@@ -6555,15 +6805,16 @@ var layout = {
6555
6805
  "left",
6556
6806
  "right"
6557
6807
  ],
6558
- "description": "Where the primary chart sits relative to the other body content. Composition applies it below the slide's and the deck's design.chartPrimary, with the semantics described there."
6808
+ "description": "Where the primary chart sits relative to the other body content. Composition applies it below the slide's and the deck's design.chartPrimary, with the semantics described there. It is shorthand for a placeholder group: a record can state the same structure explicitly as a root row or column of the chart and one PlaceholderGroup of the other regions, weighted 3:2."
6559
6809
  },
6560
- "imageFill": {
6810
+ "imageFit": {
6561
6811
  "type": "string",
6562
6812
  "enum": [
6563
- "crop",
6564
- "fit"
6813
+ "cover",
6814
+ "contain",
6815
+ "stretch"
6565
6816
  ],
6566
- "description": "How images fill their region: 'crop' covers the region, 'fit' shows the whole image."
6817
+ "description": "Default fit of the slide's image blocks: 'cover' fills the frame and crops around focus, 'contain' shows the whole picture, 'stretch' scales it to the frame."
6567
6818
  },
6568
6819
  "listBullet": {
6569
6820
  "type": "string",
@@ -6572,34 +6823,13 @@ var layout = {
6572
6823
  "image"
6573
6824
  ],
6574
6825
  "description": "Marker style of lists: 'character' draws the glyph, 'image' draws the deck's icon logo as a picture bullet."
6575
- },
6576
- "slideImage": {
6577
- "type": "object",
6578
- "additionalProperties": false,
6579
- "required": [
6580
- "position"
6581
- ],
6582
- "description": "A slide-level image region the layout reserves, separate from any content image. Its presence is what lets a deck-wide design.slideImage apply to slides on this layout. The image itself comes from the slide or the deck design.",
6583
- "properties": {
6584
- "position": {
6585
- "type": "string",
6586
- "enum": [
6587
- "background",
6588
- "top",
6589
- "bottom",
6590
- "left",
6591
- "right"
6592
- ],
6593
- "description": "Where the slide-level image sits relative to the content. 'background' is a full-bleed image behind the content; the other positions give the image a band along that edge. Used when the slide's or deck's design.slideImage gives no position."
6594
- }
6595
- }
6596
6826
  }
6597
6827
  }
6598
6828
  },
6599
6829
  "Composition": {
6600
6830
  "type": "object",
6601
6831
  "additionalProperties": false,
6602
- "description": "Portable dynamic composition. Slide fields override the resolved layout. Nested groups arrange their children independently, inheriting only minFontSize and overflow. Explicit promoted regions retain their positions.",
6832
+ "description": "Portable dynamic composition. Slide fields override the resolved layout. Nested groups (placeholder groups here, content groups in a slide) arrange their children independently, inheriting only minFontSize and overflow. Explicit promoted regions retain their positions.",
6603
6833
  "properties": {
6604
6834
  "mode": {
6605
6835
  "type": "string",
@@ -6662,7 +6892,7 @@ var chartType = {
6662
6892
  "$schema": "https://json-schema.org/draft/2020-12/schema",
6663
6893
  "$id": "https://openpresentation.org/schema/opf-chart-type/v1",
6664
6894
  "title": "Chart Type",
6665
- "description": `Schema for chart-type records in the pptx.gallery catalog. The bundled catalog holds one record per chart type that Aspose.Slides officially supports (see mappings.renderers["aspose-slides"].chartType), plus the column-and-line combination 'combo' (mappings.openxml.composition "mixed"). Each record names a chart variant, its Open XML mapping, how many data series it expects and how pickers group it. Chart types are referenced from OPF chart content payloads; the engine resolves the reference against catalogs.chartTypes (inline) -> catalogs.chartTypes.source -> the default catalog at https://www.pptx.gallery/chart-types.`,
6895
+ "description": `Schema for chart-type records: display metadata for chart pickers (name, group, expected series, complexity) and the Open XML mapping a picker can describe. One record per chart type that Aspose.Slides officially supports (see mappings.renderers["aspose-slides"].chartType), plus the column-and-line combination 'combo'. A document's chart.type is an engine vocabulary validated directly; engines never look a chart-type record up. pptx.gallery publishes these records and @openpresentation/opf/catalog ships them as catalogDisplay.chartTypes.`,
6666
6896
  "type": "object",
6667
6897
  "additionalProperties": false,
6668
6898
  "patternProperties": {
@@ -6685,7 +6915,7 @@ var chartType = {
6685
6915
  "id": {
6686
6916
  "type": "string",
6687
6917
  "pattern": "^[a-z0-9][a-z0-9-]*$",
6688
- "description": "Stable slug used by OPF documents to reference this chart type (`chart.type`). Lowercase kebab-case. Chart type ids may start with a digit (e.g., '100pct-stacked-column', '3d-column') to mirror conventional chart naming.",
6918
+ "description": "The chart-type value (`chart.type`) this record describes. Lowercase kebab-case; it may start with a digit (e.g., '100pct-stacked-column') to mirror conventional chart naming.",
6689
6919
  "examples": [
6690
6920
  "column",
6691
6921
  "bar",
@@ -6724,10 +6954,6 @@ var chartType = {
6724
6954
  "$ref": "#/$defs/ChartTypeMappings",
6725
6955
  "description": "Canonical and optional renderer-specific mappings used by engines to render this chart type."
6726
6956
  },
6727
- "deprecation": {
6728
- "$ref": "#/$defs/ChartTypeDeprecation",
6729
- "description": "Present when this chart type is deprecated. A deprecated record stays resolvable so existing documents keep validating, validators warn when a document references it, and pickers and generators should not offer it. The bundled default catalog holds no deprecated records; a publisher or an inline `catalogs.chartTypes.records` entry can still use the field."
6730
- },
6731
6957
  "group": {
6732
6958
  "type": "string",
6733
6959
  "description": "Top-level grouping in the chart picker.",
@@ -6825,35 +7051,6 @@ var chartType = {
6825
7051
  }
6826
7052
  },
6827
7053
  "$defs": {
6828
- "ChartTypeDeprecation": {
6829
- "type": "object",
6830
- "additionalProperties": false,
6831
- "required": [
6832
- "replacedBy"
6833
- ],
6834
- "properties": {
6835
- "replacedBy": {
6836
- "type": "string",
6837
- "pattern": "^[a-z0-9][a-z0-9-]*$",
6838
- "description": "Id of the non-deprecated chart type that documents should reference instead.",
6839
- "examples": [
6840
- "column",
6841
- "stacked-column"
6842
- ]
6843
- },
6844
- "reason": {
6845
- "type": "string",
6846
- "description": "Why the record is deprecated."
6847
- },
6848
- "removal": {
6849
- "type": "string",
6850
- "description": "Package version in which the record is scheduled for removal from the bundled catalog.",
6851
- "examples": [
6852
- "0.12.0"
6853
- ]
6854
- }
6855
- }
6856
- },
6857
7054
  "ChartTypeMappings": {
6858
7055
  "type": "object",
6859
7056
  "additionalProperties": false,
@@ -6973,7 +7170,7 @@ var narrative = {
6973
7170
  "$schema": "https://json-schema.org/draft/2020-12/schema",
6974
7171
  "$id": "https://openpresentation.org/schema/opf-narrative/v1",
6975
7172
  "title": "Narrative Template",
6976
- "description": "Schema for narrative template files in the openpresentation.org catalog. A narrative is a plan: a named story arc (e.g. 'problem-solution', 'scqa') as an ordered list of beats, each saying what its slide must do. A document points at one with the string 'narrative' (a catalog id, an HTTPS URL or a 'pkg:' reference) and links its slides to beats with 'slides[].beat'. A custom narrative is a record in 'catalogs.narratives.records'. Core validate warns about a 'slides[].beat' id the resolved narrative does not define (opf/unknown-beat) and about a root 'duration' outside this record's 'duration' range (opf/duration-outside-narrative), and reports a beat no slide references (opf/unused-beat).",
7173
+ "description": "Schema for narrative records. A narrative is a plan: a named story arc (e.g. 'problem-solution', 'scqa') as an ordered list of beats, each saying what its slide must do. A document points at one with the string 'narrative' and links its slides to beats with 'slides[].beat'; a narrative the document defines itself is a record in catalogs.custom.narratives. Core validate warns about a 'slides[].beat' id the resolved narrative does not define (opf/unknown-beat) and about a root 'duration' outside this record's 'duration' range (opf/duration-outside-narrative), and reports a beat no slide references (opf/unused-beat).\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
6977
7174
  "type": "object",
6978
7175
  "required": [
6979
7176
  "$schema",
@@ -6984,40 +7181,18 @@ var narrative = {
6984
7181
  "properties": {
6985
7182
  "$schema": {
6986
7183
  "type": "string",
6987
- "const": "https://openpresentation.org/schema/opf-narrative/v1"
7184
+ "const": "https://openpresentation.org/schema/opf-narrative/v1",
7185
+ "description": "Identifies a published record file as a narrative record. Required in a published file; an embedded copy omits it."
6988
7186
  },
6989
7187
  "id": {
6990
7188
  "type": "string",
6991
7189
  "pattern": "^[a-z][a-z0-9-]*$",
6992
- "description": "Stable slug used by OPF documents to reference this template, e.g. 'problem-solution'. Lowercase kebab-case."
7190
+ "description": "The narrative's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field."
6993
7191
  },
6994
7192
  "name": {
6995
7193
  "type": "string",
6996
7194
  "description": "Human-readable template name, e.g. 'Problem \u2192 Solution'."
6997
7195
  },
6998
- "deprecation": {
6999
- "type": "object",
7000
- "additionalProperties": false,
7001
- "required": [
7002
- "replacedBy"
7003
- ],
7004
- "description": "Present when this narrative is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
7005
- "properties": {
7006
- "replacedBy": {
7007
- "type": "string",
7008
- "pattern": "^[a-z][a-z0-9-]*$",
7009
- "description": "Id of the non-deprecated narrative record that documents should reference instead."
7010
- },
7011
- "reason": {
7012
- "type": "string",
7013
- "description": "Why the record is deprecated."
7014
- },
7015
- "removal": {
7016
- "type": "string",
7017
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
7018
- }
7019
- }
7020
- },
7021
7196
  "summary": {
7022
7197
  "type": "string",
7023
7198
  "description": "One-sentence description of when and why to use this narrative."
@@ -7195,7 +7370,7 @@ var socialPlatform = {
7195
7370
  "$schema": "https://json-schema.org/draft/2020-12/schema",
7196
7371
  "$id": "https://openpresentation.org/schema/opf-social-platform/v1",
7197
7372
  "title": "Social Platform",
7198
- "description": "Schema for social-platform records in the pptx.gallery library. Each record describes a single social-media platform \u2014 its base URL, profile-URL pattern, handle prefix, and brand color. Records are referenced from OPF documents indirectly: the property keys of any Socials object (Organization.socials, Speaker.socials) match record ids, and engines use the catalog record's URL patterns and handle prefix to format and link the profile URL. The brand color is catalog metadata for authoring UIs: engines (opf-render, opf-pptx) render the profile URL, not brand colors. The engine resolves references against catalogs.socialPlatforms (inline) \u2192 catalogs.socialPlatforms.source \u2192 the default catalog at https://www.pptx.gallery/social-platforms.",
7373
+ "description": "Schema for social-platform records: display metadata for authoring UIs (name, brand color, handle example) alongside the URL patterns. The keys of a Socials object are an engine vocabulary validated directly; engines link a handle with the patterns in spec/reference/engine-vocabularies.json and never look a social-platform record up. pptx.gallery publishes these records and @openpresentation/opf/catalog ships them as catalogDisplay.socialPlatforms.",
7199
7374
  "type": "object",
7200
7375
  "required": [
7201
7376
  "$schema",
@@ -7211,7 +7386,7 @@ var socialPlatform = {
7211
7386
  "id": {
7212
7387
  "type": "string",
7213
7388
  "pattern": "^[a-z][a-z0-9-]*$",
7214
- "description": "Stable slug used by OPF documents to reference this platform \u2014 appears as a property key on Socials objects. Lowercase kebab-case.",
7389
+ "description": "The social platform's key, as written in a Socials object. Lowercase kebab-case.",
7215
7390
  "examples": [
7216
7391
  "linkedin",
7217
7392
  "x",
@@ -7241,29 +7416,6 @@ var socialPlatform = {
7241
7416
  "Bluesky"
7242
7417
  ]
7243
7418
  },
7244
- "deprecation": {
7245
- "type": "object",
7246
- "additionalProperties": false,
7247
- "required": [
7248
- "replacedBy"
7249
- ],
7250
- "description": "Present when this social platform is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
7251
- "properties": {
7252
- "replacedBy": {
7253
- "type": "string",
7254
- "pattern": "^[a-z][a-z0-9-]*$",
7255
- "description": "Id of the non-deprecated social platform record that documents should reference instead."
7256
- },
7257
- "reason": {
7258
- "type": "string",
7259
- "description": "Why the record is deprecated."
7260
- },
7261
- "removal": {
7262
- "type": "string",
7263
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
7264
- }
7265
- }
7266
- },
7267
7419
  "summary": {
7268
7420
  "type": "string",
7269
7421
  "description": "One-sentence positioning of the platform \u2014 what it's used for and who's on it.",
@@ -7392,7 +7544,7 @@ var language = {
7392
7544
  "$schema": "https://json-schema.org/draft/2020-12/schema",
7393
7545
  "$id": "https://openpresentation.org/schema/opf-language/v1",
7394
7546
  "title": "Language",
7395
- "description": "Schema for language records in the pptx.gallery library. Each record names a presentation language, carries a BCP-47 language tag, and pairs it with sensible default font schemes for PowerPoint and Google Slides output. Languages are referenced from OPF documents via language; the engine resolves the reference against catalogs.languages (inline) \u2192 catalogs.languages.source \u2192 the default catalog at https://www.pptx.gallery/languages. The presentation language field also accepts BCP-47 tags directly or inline Language objects for engine-aware language records that carry default-font hints.",
7547
+ "description": "Schema for language records: display metadata for the language pickers of authoring tools (name, ISO code, the default font schemes a picker suggests). The document's 'language' is an engine vocabulary, a BCP-47 tag validated directly; engines never look a language record up, and their script, direction, OOXML tag and default script fonts come from spec/reference/engine-vocabularies.json. pptx.gallery publishes these records and @openpresentation/opf/catalog ships them as catalogDisplay.languages.",
7396
7548
  "type": "object",
7397
7549
  "required": [
7398
7550
  "$schema",
@@ -7409,7 +7561,7 @@ var language = {
7409
7561
  "id": {
7410
7562
  "type": "string",
7411
7563
  "pattern": "^[a-z][a-z0-9-]*$",
7412
- "description": "Stable slug used by OPF documents to reference this language via language. Lowercase kebab-case.",
7564
+ "description": "The record's id in the gallery's language catalog, lowercase kebab-case. Documents name a language by its BCP-47 tag ('bcp47'), never by this id.",
7413
7565
  "examples": [
7414
7566
  "english",
7415
7567
  "spanish",
@@ -7427,29 +7579,6 @@ var language = {
7427
7579
  "Chinese (simplified)"
7428
7580
  ]
7429
7581
  },
7430
- "deprecation": {
7431
- "type": "object",
7432
- "additionalProperties": false,
7433
- "required": [
7434
- "replacedBy"
7435
- ],
7436
- "description": "Present when this language is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
7437
- "properties": {
7438
- "replacedBy": {
7439
- "type": "string",
7440
- "pattern": "^[a-z][a-z0-9-]*$",
7441
- "description": "Id of the non-deprecated language record that documents should reference instead."
7442
- },
7443
- "reason": {
7444
- "type": "string",
7445
- "description": "Why the record is deprecated."
7446
- },
7447
- "removal": {
7448
- "type": "string",
7449
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
7450
- }
7451
- }
7452
- },
7453
7582
  "code": {
7454
7583
  "type": "string",
7455
7584
  "description": "ISO 639-3 (or 639-2) three-letter language code. Carried for engines that prefer ISO codes.",
@@ -7475,7 +7604,7 @@ var language = {
7475
7604
  },
7476
7605
  "ooxmlLang": {
7477
7606
  "type": "string",
7478
- "description": "Curated culture tag for OOXML text-run language attributes (a:rPr/@lang, a:endParaRPr/@lang), in the language-[Script-]REGION form Office recognizes (e.g. 'ja-JP', 'ar-SA', 'ms-MY', 'nb-NO', 'fil-PH', 'zh-CN'). Engines emit it instead of 'bcp47' when the document names the language by catalog id or by a tag without a region; a region-bearing tag written by the author is emitted as written. Curated rather than inferred so output does not depend on the runtime's locale data.",
7607
+ "description": "Curated culture tag for OOXML text-run language attributes (a:rPr/@lang, a:endParaRPr/@lang), in the language-[Script-]REGION form Office recognizes (e.g. 'ja-JP', 'ar-SA', 'ms-MY', 'nb-NO', 'fil-PH', 'zh-CN'). Engines emit it instead of 'bcp47' for a tag without a region; a region-bearing tag written by the author is emitted as written. Display metadata here: engines take the curated tag from their language vocabulary. Curated rather than inferred so output does not depend on the runtime's locale data.",
7479
7608
  "examples": [
7480
7609
  "en-US",
7481
7610
  "ja-JP",
@@ -7491,7 +7620,7 @@ var language = {
7491
7620
  "ltr",
7492
7621
  "rtl"
7493
7622
  ],
7494
- "description": "Base text direction for the language. When omitted, engines derive it from the script: Arabic (Arab), Hebrew (Hebr), Syriac (Syrc), Thaana (Thaa), N'Ko (Nkoo), Adlam (Adlm), Samaritan (Samr), Mandaic (Mand) and Hanifi Rohingya (Rohg) are right-to-left; every other script is left-to-right. Bundled language records state it explicitly.",
7623
+ "description": "Base text direction for the language. When omitted, engines derive it from the script: Arabic (Arab), Hebrew (Hebr), Syriac (Syrc), Thaana (Thaa), N'Ko (Nkoo), Adlam (Adlm), Samaritan (Samr), Mandaic (Mand) and Hanifi Rohingya (Rohg) are right-to-left; every other script is left-to-right. The engine language vocabulary (spec/reference/engine-vocabularies.json) states it for the tags it knows.",
7495
7624
  "examples": [
7496
7625
  "ltr",
7497
7626
  "rtl"
@@ -7499,7 +7628,7 @@ var language = {
7499
7628
  },
7500
7629
  "script": {
7501
7630
  "type": "string",
7502
- "description": "ISO 15924 script code of the language's writing system. The script selects the OOXML font slot the language's text uses: East Asian scripts (Hans, Hant, Hani, Jpan, Kore, Hang, Hira, Kana, Bopo, Yiii) use the eastAsian slot; complex scripts (for example Arab, Hebr, Syrc, Thaa, Deva, Beng, Guru, Gujr, Orya, Taml, Telu, Knda, Mlym, Sinh, Thai, Laoo, Tibt, Mymr, Khmr, Mong) use the complexScript slot; every other script (Latn, Cyrl, Grek, Armn, Geor, Ethi, ...) uses the latin slot. When omitted, engines infer it from the BCP-47 tag. Bundled language records state it explicitly. See docs/programs/font-fidelity-everywhere/script-font-model.md.",
7631
+ "description": "ISO 15924 script code of the language's writing system. The script selects the OOXML font slot the language's text uses: East Asian scripts (Hans, Hant, Hani, Jpan, Kore, Hang, Hira, Kana, Bopo, Yiii) use the eastAsian slot; complex scripts (for example Arab, Hebr, Syrc, Thaa, Deva, Beng, Guru, Gujr, Orya, Taml, Telu, Knda, Mlym, Sinh, Thai, Laoo, Tibt, Mymr, Khmr, Mong) use the complexScript slot; every other script (Latn, Cyrl, Grek, Armn, Geor, Ethi, ...) uses the latin slot. When omitted, engines infer it from the BCP-47 tag. The engine language vocabulary (spec/reference/engine-vocabularies.json) states it for the tags it knows. See docs/programs/font-fidelity-everywhere/script-font-model.md.",
7503
7632
  "examples": [
7504
7633
  "Latn",
7505
7634
  "Cyrl",
@@ -7516,7 +7645,7 @@ var language = {
7516
7645
  },
7517
7646
  "fontScheme": {
7518
7647
  "type": "string",
7519
- "description": "Default font-scheme id for this language when targeting PowerPoint output. Resolves against catalogs.fontSchemes the same way design.fontScheme or design.fontScheme.id does. Its major/minor families fill the language's script slot (eastAsian or complexScript, chosen by 'script') unless the effective design font scheme sets that slot itself; the latin slot always follows the design font scheme.",
7648
+ "description": "The font-scheme id a picker suggests for this language when targeting PowerPoint output. Display metadata: engines take a language's default script fonts from their own vocabulary.",
7520
7649
  "examples": [
7521
7650
  "aptos",
7522
7651
  "microsoft-yahei",
@@ -7525,7 +7654,7 @@ var language = {
7525
7654
  },
7526
7655
  "googleFontScheme": {
7527
7656
  "type": "string",
7528
- "description": "Default font-scheme id for this language when targeting Google Slides output. Resolves against catalogs.fontSchemes the same way design.fontScheme or design.fontScheme.id does. Used in place of 'fontScheme' when resolving script fonts for Google Slides output.",
7657
+ "description": "The font-scheme id a picker suggests for this language when targeting Google Slides output. Display metadata.",
7529
7658
  "examples": [
7530
7659
  "roboto",
7531
7660
  "noto-sans",
@@ -7603,7 +7732,7 @@ var colorScheme = {
7603
7732
  "$schema": "https://json-schema.org/draft/2020-12/schema",
7604
7733
  "$id": "https://openpresentation.org/schema/opf-color-scheme/v1",
7605
7734
  "title": "Color Scheme",
7606
- "description": "Schema for color-scheme records in the pptx.gallery library. Each scheme is a named palette with the twelve PowerPoint color slots (six accents, two darks, two lights, plus hyperlink and followed-hyperlink), suitable for being mapped directly into OOXML theme XML. Color schemes are referenced from OPF documents via design.colorScheme or design.colorScheme.id; the engine resolves the reference against catalogs.colorSchemes (inline) -> catalogs.colorSchemes.source -> the default catalog at https://www.pptx.gallery/color-schemes. Slot overrides on design.colorScheme take precedence over the resolved scheme.\n\nThe slot fields here mirror the inline-override fields on the in-document ColorScheme type (in opf.schema.json), so library entries and inline OPF overrides are interchangeable.",
7735
+ "description": "Schema for color-scheme records. Each scheme is a named palette with the twelve PowerPoint color slots (six accents, two darks, two lights, plus hyperlink and followed-hyperlink), suitable for being mapped directly into OOXML theme XML. Documents reference a scheme from design.colorScheme (or design.colorScheme.id) and from a theme's colorScheme; slot overrides on design.colorScheme take precedence over the resolved scheme.\n\nThe slot fields here mirror the inline-override fields on the in-document ColorScheme type (in opf.schema.json), so records and inline OPF overrides are interchangeable.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
7607
7736
  "type": "object",
7608
7737
  "required": [
7609
7738
  "$schema",
@@ -7626,12 +7755,12 @@ var colorScheme = {
7626
7755
  "$schema": {
7627
7756
  "type": "string",
7628
7757
  "const": "https://openpresentation.org/schema/opf-color-scheme/v1",
7629
- "description": "Identifies this record as a color scheme in the openpresentation.org catalog."
7758
+ "description": "Identifies a published record file as a colour scheme record. Required in a published file; an embedded copy omits it."
7630
7759
  },
7631
7760
  "id": {
7632
7761
  "type": "string",
7633
7762
  "pattern": "^[a-z][a-z0-9-]*$",
7634
- "description": "Stable slug used by OPF documents to reference this color scheme. Lowercase kebab-case.",
7763
+ "description": "The colour scheme's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
7635
7764
  "examples": [
7636
7765
  "cool-horizon",
7637
7766
  "boost",
@@ -7649,29 +7778,6 @@ var colorScheme = {
7649
7778
  "Forest Green"
7650
7779
  ]
7651
7780
  },
7652
- "deprecation": {
7653
- "type": "object",
7654
- "additionalProperties": false,
7655
- "required": [
7656
- "replacedBy"
7657
- ],
7658
- "description": "Present when this color scheme is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
7659
- "properties": {
7660
- "replacedBy": {
7661
- "type": "string",
7662
- "pattern": "^[a-z][a-z0-9-]*$",
7663
- "description": "Id of the non-deprecated color scheme record that documents should reference instead."
7664
- },
7665
- "reason": {
7666
- "type": "string",
7667
- "description": "Why the record is deprecated."
7668
- },
7669
- "removal": {
7670
- "type": "string",
7671
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
7672
- }
7673
- }
7674
- },
7675
7781
  "summary": {
7676
7782
  "type": "string",
7677
7783
  "description": "One-sentence positioning of the palette \u2014 what mood it evokes and where to use it.",
@@ -7838,7 +7944,7 @@ var fontScheme = {
7838
7944
  "$schema": "https://json-schema.org/draft/2020-12/schema",
7839
7945
  "$id": "https://openpresentation.org/schema/opf-font-scheme/v1",
7840
7946
  "title": "Font Scheme",
7841
- "description": "Schema for font-scheme records in the pptx.gallery library. Each scheme pairs a major (heading) and minor (body) font family in the OOXML majorFont/minorFont sense, scoped to a target app (powerpoint or google-slides) and a language family (Latin, East Asian, or Complex Script). Font schemes are referenced from OPF documents via design.fontScheme or design.fontScheme.id; the engine resolves the reference against catalogs.fontSchemes (inline) \u2192 catalogs.fontSchemes.source \u2192 the default catalog at https://www.pptx.gallery/font-schemes. Role overrides on design.fontScheme (heading, body, accent, code), each a font family name, take precedence over the resolved scheme.",
7947
+ "description": "Schema for font-scheme records. Each scheme pairs a major (heading) and minor (body) font family in the OOXML majorFont/minorFont sense, scoped to a target app (powerpoint or google-slides) and a language family (Latin, East Asian, or Complex Script). Documents reference a scheme from design.fontScheme (or design.fontScheme.id), from a theme's fontScheme and from a language's fontScheme / googleFontScheme. Role overrides on design.fontScheme (heading, body, accent, code), each a font family name, take precedence over the resolved scheme.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
7842
7948
  "type": "object",
7843
7949
  "required": [
7844
7950
  "$schema",
@@ -7851,12 +7957,12 @@ var fontScheme = {
7851
7957
  "$schema": {
7852
7958
  "type": "string",
7853
7959
  "const": "https://openpresentation.org/schema/opf-font-scheme/v1",
7854
- "description": "Identifies this record as a font scheme in the openpresentation.org catalog."
7960
+ "description": "Identifies a published record file as a font scheme record. Required in a published file; an embedded copy omits it."
7855
7961
  },
7856
7962
  "id": {
7857
7963
  "type": "string",
7858
7964
  "pattern": "^[a-z][a-z0-9-]*$",
7859
- "description": "Stable slug used by OPF documents to reference this font scheme. Lowercase kebab-case.",
7965
+ "description": "The font scheme's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
7860
7966
  "examples": [
7861
7967
  "aptos",
7862
7968
  "tenorite",
@@ -7876,29 +7982,6 @@ var fontScheme = {
7876
7982
  "Microsoft Yahei"
7877
7983
  ]
7878
7984
  },
7879
- "deprecation": {
7880
- "type": "object",
7881
- "additionalProperties": false,
7882
- "required": [
7883
- "replacedBy"
7884
- ],
7885
- "description": "Present when this font scheme is deprecated, for example an alias kept for backward compatibility. Deprecated records stay resolvable so existing documents keep validating and rendering unchanged, but pickers and default listings exclude them and validators warn when a document references them. Same shape as the chart-type deprecation.",
7886
- "properties": {
7887
- "replacedBy": {
7888
- "type": "string",
7889
- "pattern": "^[a-z][a-z0-9-]*$",
7890
- "description": "Id of the non-deprecated font scheme record that documents should reference instead."
7891
- },
7892
- "reason": {
7893
- "type": "string",
7894
- "description": "Why the record is deprecated."
7895
- },
7896
- "removal": {
7897
- "type": "string",
7898
- "description": "Package version in which the record is scheduled for removal from the bundled catalog, if any."
7899
- }
7900
- }
7901
- },
7902
7985
  "major": {
7903
7986
  "type": "string",
7904
7987
  "description": "Heading (major) font family \u2014 mirrors the OOXML majorFont entry.",
@@ -8009,15 +8092,15 @@ var fontScheme = {
8009
8092
  "type": "array",
8010
8093
  "items": {
8011
8094
  "type": "string",
8012
- "pattern": "^[a-z][a-z0-9-]*$"
8095
+ "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{1,8})*$"
8013
8096
  },
8014
- "description": "Optional list of languages catalog ids (see the languages catalog, https://www.pptx.gallery/languages) this scheme is curated for. Useful for picker UIs that group fonts by language coverage. As the design font scheme, an 'ea' or 'cs' scheme fills its script slot only when this list is empty or names the presentation language by id.",
8097
+ "description": "Optional list of BCP-47 language tags this scheme is curated for. Useful for picker UIs that group fonts by language coverage. As the design font scheme, an 'ea' or 'cs' scheme fills its script slot only when this list is empty or names the presentation language: an entry matches a tag with the same language subtag (and the same script, when the entry names one).",
8015
8098
  "examples": [
8016
8099
  [
8017
- "chinese-simplified",
8018
- "chinese-traditional",
8019
- "japanese",
8020
- "korean"
8100
+ "zh-Hans",
8101
+ "zh-Hant",
8102
+ "ja",
8103
+ "ko"
8021
8104
  ]
8022
8105
  ]
8023
8106
  },
@@ -8365,7 +8448,7 @@ var finding = {
8365
8448
  },
8366
8449
  "origin": {
8367
8450
  "type": "string",
8368
- "description": "Where the suggestion comes from: `schema`, `built-in`, `loaded`, `document` or `contract`."
8451
+ "description": "Where the suggestion comes from: `schema`, `document` (a record the document embeds), `registered` (a catalog the host registered) or `contract`."
8369
8452
  },
8370
8453
  "definition": {
8371
8454
  "type": "string",