@bendyline/squisq 1.2.2 → 1.4.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 (427) hide show
  1. package/dist/{Doc-BfBhiCNr.d.ts → Doc-BeSeH2iX.d.ts} +141 -33
  2. package/dist/ImageEditDoc-BTIvw0oq.d.ts +84 -0
  3. package/dist/__tests__/colorUtils.test.d.ts +2 -0
  4. package/dist/__tests__/colorUtils.test.d.ts.map +1 -0
  5. package/dist/__tests__/colorUtils.test.js +94 -0
  6. package/dist/__tests__/colorUtils.test.js.map +1 -0
  7. package/dist/__tests__/getLayers.test.js +31 -7
  8. package/dist/__tests__/getLayers.test.js.map +1 -1
  9. package/dist/__tests__/iconResolve.test.d.ts +2 -0
  10. package/dist/__tests__/iconResolve.test.d.ts.map +1 -0
  11. package/dist/__tests__/iconResolve.test.js +99 -0
  12. package/dist/__tests__/iconResolve.test.js.map +1 -0
  13. package/dist/__tests__/imageEditState.test.d.ts +2 -0
  14. package/dist/__tests__/imageEditState.test.d.ts.map +1 -0
  15. package/dist/__tests__/imageEditState.test.js +61 -0
  16. package/dist/__tests__/imageEditState.test.js.map +1 -0
  17. package/dist/__tests__/imageEditVersions.test.d.ts +2 -0
  18. package/dist/__tests__/imageEditVersions.test.d.ts.map +1 -0
  19. package/dist/__tests__/imageEditVersions.test.js +141 -0
  20. package/dist/__tests__/imageEditVersions.test.js.map +1 -0
  21. package/dist/__tests__/inferDocumentTitle.test.d.ts +2 -0
  22. package/dist/__tests__/inferDocumentTitle.test.d.ts.map +1 -0
  23. package/dist/__tests__/inferDocumentTitle.test.js +42 -0
  24. package/dist/__tests__/inferDocumentTitle.test.js.map +1 -0
  25. package/dist/__tests__/jsonForm.chooseControl.test.d.ts +2 -0
  26. package/dist/__tests__/jsonForm.chooseControl.test.d.ts.map +1 -0
  27. package/dist/__tests__/jsonForm.chooseControl.test.js +74 -0
  28. package/dist/__tests__/jsonForm.chooseControl.test.js.map +1 -0
  29. package/dist/__tests__/jsonForm.evaluateWhen.test.d.ts +2 -0
  30. package/dist/__tests__/jsonForm.evaluateWhen.test.d.ts.map +1 -0
  31. package/dist/__tests__/jsonForm.evaluateWhen.test.js +51 -0
  32. package/dist/__tests__/jsonForm.evaluateWhen.test.js.map +1 -0
  33. package/dist/__tests__/jsonForm.inferSchema.test.d.ts +2 -0
  34. package/dist/__tests__/jsonForm.inferSchema.test.d.ts.map +1 -0
  35. package/dist/__tests__/jsonForm.inferSchema.test.js +23 -0
  36. package/dist/__tests__/jsonForm.inferSchema.test.js.map +1 -0
  37. package/dist/__tests__/jsonForm.pointer.test.d.ts +2 -0
  38. package/dist/__tests__/jsonForm.pointer.test.d.ts.map +1 -0
  39. package/dist/__tests__/jsonForm.pointer.test.js +94 -0
  40. package/dist/__tests__/jsonForm.pointer.test.js.map +1 -0
  41. package/dist/__tests__/markdown.test.js +40 -0
  42. package/dist/__tests__/markdown.test.js.map +1 -1
  43. package/dist/__tests__/markdownIcons.test.d.ts +2 -0
  44. package/dist/__tests__/markdownIcons.test.d.ts.map +1 -0
  45. package/dist/__tests__/markdownIcons.test.js +93 -0
  46. package/dist/__tests__/markdownIcons.test.js.map +1 -0
  47. package/dist/__tests__/markdownToDoc.test.js +15 -4
  48. package/dist/__tests__/markdownToDoc.test.js.map +1 -1
  49. package/dist/__tests__/recommendTemplates.test.d.ts +2 -0
  50. package/dist/__tests__/recommendTemplates.test.d.ts.map +1 -0
  51. package/dist/__tests__/recommendTemplates.test.js +158 -0
  52. package/dist/__tests__/recommendTemplates.test.js.map +1 -0
  53. package/dist/__tests__/scopedContentContainer.test.d.ts +2 -0
  54. package/dist/__tests__/scopedContentContainer.test.d.ts.map +1 -0
  55. package/dist/__tests__/scopedContentContainer.test.js +74 -0
  56. package/dist/__tests__/scopedContentContainer.test.js.map +1 -0
  57. package/dist/__tests__/slideshowGenerator.test.js +1 -1
  58. package/dist/__tests__/slideshowGenerator.test.js.map +1 -1
  59. package/dist/__tests__/surface.test.d.ts +2 -0
  60. package/dist/__tests__/surface.test.d.ts.map +1 -0
  61. package/dist/__tests__/surface.test.js +57 -0
  62. package/dist/__tests__/surface.test.js.map +1 -0
  63. package/dist/__tests__/templateAnnotationParse.test.d.ts +2 -0
  64. package/dist/__tests__/templateAnnotationParse.test.d.ts.map +1 -0
  65. package/dist/__tests__/templateAnnotationParse.test.js +42 -0
  66. package/dist/__tests__/templateAnnotationParse.test.js.map +1 -0
  67. package/dist/__tests__/templates.test.js +90 -9
  68. package/dist/__tests__/templates.test.js.map +1 -1
  69. package/dist/__tests__/themeCompile.test.d.ts +2 -0
  70. package/dist/__tests__/themeCompile.test.d.ts.map +1 -0
  71. package/dist/__tests__/themeCompile.test.js +134 -0
  72. package/dist/__tests__/themeCompile.test.js.map +1 -0
  73. package/dist/__tests__/themeValidator.test.d.ts +2 -0
  74. package/dist/__tests__/themeValidator.test.d.ts.map +1 -0
  75. package/dist/__tests__/themeValidator.test.js +107 -0
  76. package/dist/__tests__/themeValidator.test.js.map +1 -0
  77. package/dist/__tests__/versions.test.d.ts +2 -0
  78. package/dist/__tests__/versions.test.d.ts.map +1 -0
  79. package/dist/__tests__/versions.test.js +339 -0
  80. package/dist/__tests__/versions.test.js.map +1 -0
  81. package/dist/{chunk-CYQHG27J.js → chunk-2TMAWB4Y.js} +74 -1
  82. package/dist/chunk-2TMAWB4Y.js.map +1 -0
  83. package/dist/{chunk-LAZELBON.js → chunk-3K5OG6KI.js} +165 -17
  84. package/dist/chunk-3K5OG6KI.js.map +1 -0
  85. package/dist/chunk-57CVQCFX.js +193 -0
  86. package/dist/chunk-57CVQCFX.js.map +1 -0
  87. package/dist/{chunk-QM5PKNPW.js → chunk-5WFRKURX.js} +1 -1
  88. package/dist/chunk-5WFRKURX.js.map +1 -0
  89. package/dist/chunk-B4EEON3N.js +1317 -0
  90. package/dist/chunk-B4EEON3N.js.map +1 -0
  91. package/dist/chunk-DBS6RIFL.js +81 -0
  92. package/dist/chunk-DBS6RIFL.js.map +1 -0
  93. package/dist/{chunk-MIBRIRGJ.js → chunk-FR2RBTKO.js} +3 -3
  94. package/dist/{chunk-MIBRIRGJ.js.map → chunk-FR2RBTKO.js.map} +1 -1
  95. package/dist/chunk-H3AXU4MJ.js +179 -0
  96. package/dist/chunk-H3AXU4MJ.js.map +1 -0
  97. package/dist/chunk-JELIRVDP.js +24 -0
  98. package/dist/chunk-JELIRVDP.js.map +1 -0
  99. package/dist/chunk-K32VJONL.js +193 -0
  100. package/dist/chunk-K32VJONL.js.map +1 -0
  101. package/dist/{chunk-GAQLMORN.js → chunk-KSWJR66U.js} +248 -44
  102. package/dist/chunk-KSWJR66U.js.map +1 -0
  103. package/dist/{chunk-TSG2OSE6.js → chunk-MYIH7FWD.js} +3 -3
  104. package/dist/chunk-MYIH7FWD.js.map +1 -0
  105. package/dist/chunk-VLJJHDAC.js +218 -0
  106. package/dist/chunk-VLJJHDAC.js.map +1 -0
  107. package/dist/chunk-WMOI7FN3.js +182 -0
  108. package/dist/chunk-WMOI7FN3.js.map +1 -0
  109. package/dist/chunk-ZTX4PFFT.js +520 -0
  110. package/dist/chunk-ZTX4PFFT.js.map +1 -0
  111. package/dist/doc/audioMapping.d.ts.map +1 -1
  112. package/dist/doc/audioMapping.js +80 -9
  113. package/dist/doc/audioMapping.js.map +1 -1
  114. package/dist/doc/getLayers.d.ts.map +1 -1
  115. package/dist/doc/getLayers.js +29 -18
  116. package/dist/doc/getLayers.js.map +1 -1
  117. package/dist/doc/markdownToDoc.d.ts.map +1 -1
  118. package/dist/doc/markdownToDoc.js +40 -6
  119. package/dist/doc/markdownToDoc.js.map +1 -1
  120. package/dist/doc/templates/featureBlock.d.ts +18 -0
  121. package/dist/doc/templates/featureBlock.d.ts.map +1 -0
  122. package/dist/doc/templates/featureBlock.js +180 -0
  123. package/dist/doc/templates/featureBlock.js.map +1 -0
  124. package/dist/doc/templates/fullBleedQuote.d.ts +12 -0
  125. package/dist/doc/templates/fullBleedQuote.d.ts.map +1 -1
  126. package/dist/doc/templates/fullBleedQuote.js +12 -0
  127. package/dist/doc/templates/fullBleedQuote.js.map +1 -1
  128. package/dist/doc/templates/index.d.ts +28 -4
  129. package/dist/doc/templates/index.d.ts.map +1 -1
  130. package/dist/doc/templates/index.js +45 -12
  131. package/dist/doc/templates/index.js.map +1 -1
  132. package/dist/doc/templates/listBlock.d.ts.map +1 -1
  133. package/dist/doc/templates/listBlock.js +22 -5
  134. package/dist/doc/templates/listBlock.js.map +1 -1
  135. package/dist/doc/templates/statHighlight.d.ts +12 -0
  136. package/dist/doc/templates/statHighlight.d.ts.map +1 -1
  137. package/dist/doc/templates/statHighlight.js +12 -0
  138. package/dist/doc/templates/statHighlight.js.map +1 -1
  139. package/dist/doc/templates/titleBlock.d.ts +11 -0
  140. package/dist/doc/templates/titleBlock.d.ts.map +1 -1
  141. package/dist/doc/templates/titleBlock.js +8 -0
  142. package/dist/doc/templates/titleBlock.js.map +1 -1
  143. package/dist/doc/utils/themeUtils.d.ts +4 -4
  144. package/dist/doc/utils/themeUtils.d.ts.map +1 -1
  145. package/dist/doc/utils/themeUtils.js +8 -7
  146. package/dist/doc/utils/themeUtils.js.map +1 -1
  147. package/dist/generate/slideshowGenerator.js +1 -1
  148. package/dist/generate/slideshowGenerator.js.map +1 -1
  149. package/dist/generate/templateMapper.js +2 -2
  150. package/dist/generate/templateMapper.js.map +1 -1
  151. package/dist/icons/iconData.d.ts +26 -0
  152. package/dist/icons/iconData.d.ts.map +1 -0
  153. package/dist/icons/iconData.js +12 -0
  154. package/dist/icons/iconData.js.map +1 -0
  155. package/dist/icons/index.d.ts +12 -0
  156. package/dist/icons/index.d.ts.map +1 -0
  157. package/dist/icons/index.js +10 -0
  158. package/dist/icons/index.js.map +1 -0
  159. package/dist/icons/resolve.d.ts +61 -0
  160. package/dist/icons/resolve.d.ts.map +1 -0
  161. package/dist/icons/resolve.js +130 -0
  162. package/dist/icons/resolve.js.map +1 -0
  163. package/dist/imageEdit/ImageEditVersionManager.d.ts +31 -0
  164. package/dist/imageEdit/ImageEditVersionManager.d.ts.map +1 -0
  165. package/dist/imageEdit/ImageEditVersionManager.js +39 -0
  166. package/dist/imageEdit/ImageEditVersionManager.js.map +1 -0
  167. package/dist/imageEdit/export.d.ts +33 -0
  168. package/dist/imageEdit/export.d.ts.map +1 -0
  169. package/dist/imageEdit/export.js +253 -0
  170. package/dist/imageEdit/export.js.map +1 -0
  171. package/dist/imageEdit/index.d.ts +14 -0
  172. package/dist/imageEdit/index.d.ts.map +1 -0
  173. package/dist/imageEdit/index.js +22 -0
  174. package/dist/imageEdit/index.js.map +1 -0
  175. package/dist/imageEdit/persistence.d.ts +15 -0
  176. package/dist/imageEdit/persistence.d.ts.map +1 -0
  177. package/dist/imageEdit/persistence.js +49 -0
  178. package/dist/imageEdit/persistence.js.map +1 -0
  179. package/dist/imageEdit/state.d.ts +42 -0
  180. package/dist/imageEdit/state.d.ts.map +1 -0
  181. package/dist/imageEdit/state.js +98 -0
  182. package/dist/imageEdit/state.js.map +1 -0
  183. package/dist/imageEdit/versionPaths.d.ts +27 -0
  184. package/dist/imageEdit/versionPaths.d.ts.map +1 -0
  185. package/dist/imageEdit/versionPaths.js +57 -0
  186. package/dist/imageEdit/versionPaths.js.map +1 -0
  187. package/dist/imageEdit/versions.d.ts +67 -0
  188. package/dist/imageEdit/versions.d.ts.map +1 -0
  189. package/dist/imageEdit/versions.js +161 -0
  190. package/dist/imageEdit/versions.js.map +1 -0
  191. package/dist/index.d.ts +4 -0
  192. package/dist/index.d.ts.map +1 -1
  193. package/dist/index.js +4 -0
  194. package/dist/index.js.map +1 -1
  195. package/dist/jsonForm/chooseControl.d.ts +20 -0
  196. package/dist/jsonForm/chooseControl.d.ts.map +1 -0
  197. package/dist/jsonForm/chooseControl.js +82 -0
  198. package/dist/jsonForm/chooseControl.js.map +1 -0
  199. package/dist/jsonForm/evaluateWhen.d.ts +12 -0
  200. package/dist/jsonForm/evaluateWhen.d.ts.map +1 -0
  201. package/dist/jsonForm/evaluateWhen.js +65 -0
  202. package/dist/jsonForm/evaluateWhen.js.map +1 -0
  203. package/dist/jsonForm/index.d.ts +14 -0
  204. package/dist/jsonForm/index.d.ts.map +1 -0
  205. package/dist/jsonForm/index.js +12 -0
  206. package/dist/jsonForm/index.js.map +1 -0
  207. package/dist/jsonForm/inferSchema.d.ts +12 -0
  208. package/dist/jsonForm/inferSchema.d.ts.map +1 -0
  209. package/dist/jsonForm/inferSchema.js +15 -0
  210. package/dist/jsonForm/inferSchema.js.map +1 -0
  211. package/dist/jsonForm/pointer.d.ts +26 -0
  212. package/dist/jsonForm/pointer.d.ts.map +1 -0
  213. package/dist/jsonForm/pointer.js +102 -0
  214. package/dist/jsonForm/pointer.js.map +1 -0
  215. package/dist/jsonForm/types.d.ts +120 -0
  216. package/dist/jsonForm/types.d.ts.map +1 -0
  217. package/dist/jsonForm/types.js +10 -0
  218. package/dist/jsonForm/types.js.map +1 -0
  219. package/dist/markdown/convert.d.ts +11 -1
  220. package/dist/markdown/convert.d.ts.map +1 -1
  221. package/dist/markdown/convert.js +235 -15
  222. package/dist/markdown/convert.js.map +1 -1
  223. package/dist/markdown/index.d.ts +2 -2
  224. package/dist/markdown/index.d.ts.map +1 -1
  225. package/dist/markdown/index.js +1 -1
  226. package/dist/markdown/index.js.map +1 -1
  227. package/dist/markdown/types.d.ts +34 -1
  228. package/dist/markdown/types.d.ts.map +1 -1
  229. package/dist/markdown/utils.d.ts +40 -0
  230. package/dist/markdown/utils.d.ts.map +1 -1
  231. package/dist/markdown/utils.js +155 -0
  232. package/dist/markdown/utils.js.map +1 -1
  233. package/dist/recommend/index.d.ts +16 -0
  234. package/dist/recommend/index.d.ts.map +1 -0
  235. package/dist/recommend/index.js +15 -0
  236. package/dist/recommend/index.js.map +1 -0
  237. package/dist/recommend/templates.d.ts +39 -0
  238. package/dist/recommend/templates.d.ts.map +1 -0
  239. package/dist/recommend/templates.js +235 -0
  240. package/dist/recommend/templates.js.map +1 -0
  241. package/dist/schemas/BlockTemplates.d.ts +46 -8
  242. package/dist/schemas/BlockTemplates.d.ts.map +1 -1
  243. package/dist/schemas/BlockTemplates.js +3 -3
  244. package/dist/schemas/BlockTemplates.js.map +1 -1
  245. package/dist/schemas/ImageEditDoc.d.ts +81 -0
  246. package/dist/schemas/ImageEditDoc.d.ts.map +1 -0
  247. package/dist/schemas/ImageEditDoc.js +20 -0
  248. package/dist/schemas/ImageEditDoc.js.map +1 -0
  249. package/dist/schemas/Theme.d.ts +93 -23
  250. package/dist/schemas/Theme.d.ts.map +1 -1
  251. package/dist/schemas/Theme.js +80 -13
  252. package/dist/schemas/Theme.js.map +1 -1
  253. package/dist/schemas/colorUtils.d.ts +51 -0
  254. package/dist/schemas/colorUtils.d.ts.map +1 -0
  255. package/dist/schemas/colorUtils.js +154 -0
  256. package/dist/schemas/colorUtils.js.map +1 -0
  257. package/dist/schemas/fontStacks.d.ts +57 -0
  258. package/dist/schemas/fontStacks.d.ts.map +1 -0
  259. package/dist/schemas/fontStacks.js +227 -0
  260. package/dist/schemas/fontStacks.js.map +1 -0
  261. package/dist/schemas/index.d.ts +5 -0
  262. package/dist/schemas/index.d.ts.map +1 -1
  263. package/dist/schemas/index.js +4 -0
  264. package/dist/schemas/index.js.map +1 -1
  265. package/dist/schemas/themeCompile.d.ts +45 -0
  266. package/dist/schemas/themeCompile.d.ts.map +1 -0
  267. package/dist/schemas/themeCompile.js +160 -0
  268. package/dist/schemas/themeCompile.js.map +1 -0
  269. package/dist/schemas/themeLibrary.d.ts +11 -15
  270. package/dist/schemas/themeLibrary.d.ts.map +1 -1
  271. package/dist/schemas/themeLibrary.js +18 -499
  272. package/dist/schemas/themeLibrary.js.map +1 -1
  273. package/dist/schemas/themeValidator.d.ts +26 -0
  274. package/dist/schemas/themeValidator.d.ts.map +1 -0
  275. package/dist/schemas/themeValidator.js +352 -0
  276. package/dist/schemas/themeValidator.js.map +1 -0
  277. package/dist/schemas/themes/bold.json +48 -0
  278. package/dist/schemas/themes/cinematic.json +54 -0
  279. package/dist/schemas/themes/documentary.json +49 -0
  280. package/dist/schemas/themes/gezellig.json +44 -0
  281. package/dist/schemas/themes/index.d.ts +26 -0
  282. package/dist/schemas/themes/index.d.ts.map +1 -0
  283. package/dist/schemas/themes/index.js +49 -0
  284. package/dist/schemas/themes/index.js.map +1 -0
  285. package/dist/schemas/themes/magazine.json +44 -0
  286. package/dist/schemas/themes/minimalist.json +45 -0
  287. package/dist/schemas/themes/morning-light.json +42 -0
  288. package/dist/schemas/themes/standard-dark.json +50 -0
  289. package/dist/schemas/themes/standard.json +42 -0
  290. package/dist/schemas/themes/tech-dark.json +48 -0
  291. package/dist/schemas/themes/warm-earth.json +50 -0
  292. package/dist/storage/ScopedContentContainer.d.ts +44 -0
  293. package/dist/storage/ScopedContentContainer.d.ts.map +1 -0
  294. package/dist/storage/ScopedContentContainer.js +94 -0
  295. package/dist/storage/ScopedContentContainer.js.map +1 -0
  296. package/dist/storage/index.d.ts +1 -0
  297. package/dist/storage/index.d.ts.map +1 -1
  298. package/dist/storage/index.js +1 -0
  299. package/dist/storage/index.js.map +1 -1
  300. package/dist/story/index.d.ts +53 -13
  301. package/dist/story/index.js +12 -4
  302. package/dist/themeLibrary-BHjJ0Qx6.d.ts +40 -0
  303. package/dist/{types-DYAzisMG.d.ts → types-BdZkdJ3z.d.ts} +35 -2
  304. package/dist/types-D98li1gV.d.ts +93 -0
  305. package/dist/versions/DocumentVersionManager.d.ts +31 -0
  306. package/dist/versions/DocumentVersionManager.d.ts.map +1 -0
  307. package/dist/versions/DocumentVersionManager.js +33 -0
  308. package/dist/versions/DocumentVersionManager.js.map +1 -0
  309. package/dist/versions/index.d.ts +29 -0
  310. package/dist/versions/index.d.ts.map +1 -0
  311. package/dist/versions/index.js +28 -0
  312. package/dist/versions/index.js.map +1 -0
  313. package/dist/versions/operations.d.ts +44 -0
  314. package/dist/versions/operations.d.ts.map +1 -0
  315. package/dist/versions/operations.js +190 -0
  316. package/dist/versions/operations.js.map +1 -0
  317. package/dist/versions/paths.d.ts +29 -0
  318. package/dist/versions/paths.d.ts.map +1 -0
  319. package/dist/versions/paths.js +66 -0
  320. package/dist/versions/paths.js.map +1 -0
  321. package/dist/versions/timestamp.d.ts +22 -0
  322. package/dist/versions/timestamp.d.ts.map +1 -0
  323. package/dist/versions/timestamp.js +44 -0
  324. package/dist/versions/timestamp.js.map +1 -0
  325. package/dist/versions/types.d.ts +92 -0
  326. package/dist/versions/types.d.ts.map +1 -0
  327. package/dist/versions/types.js +11 -0
  328. package/dist/versions/types.js.map +1 -0
  329. package/package.json +28 -1
  330. package/src/__tests__/colorUtils.test.ts +112 -0
  331. package/src/__tests__/getLayers.test.ts +32 -7
  332. package/src/__tests__/iconResolve.test.ts +122 -0
  333. package/src/__tests__/imageEditState.test.ts +74 -0
  334. package/src/__tests__/imageEditVersions.test.ts +169 -0
  335. package/src/__tests__/inferDocumentTitle.test.ts +50 -0
  336. package/src/__tests__/jsonForm.chooseControl.test.ts +86 -0
  337. package/src/__tests__/jsonForm.evaluateWhen.test.ts +59 -0
  338. package/src/__tests__/jsonForm.inferSchema.test.ts +25 -0
  339. package/src/__tests__/jsonForm.pointer.test.ts +103 -0
  340. package/src/__tests__/markdown.test.ts +44 -0
  341. package/src/__tests__/markdownIcons.test.ts +104 -0
  342. package/src/__tests__/markdownToDoc.test.ts +19 -4
  343. package/src/__tests__/recommendTemplates.test.ts +183 -0
  344. package/src/__tests__/scopedContentContainer.test.ts +89 -0
  345. package/src/__tests__/slideshowGenerator.test.ts +1 -1
  346. package/src/__tests__/surface.test.ts +68 -0
  347. package/src/__tests__/templateAnnotationParse.test.ts +42 -0
  348. package/src/__tests__/templates.test.ts +93 -9
  349. package/src/__tests__/themeCompile.test.ts +156 -0
  350. package/src/__tests__/themeValidator.test.ts +125 -0
  351. package/src/__tests__/versions.test.ts +415 -0
  352. package/src/doc/audioMapping.ts +95 -13
  353. package/src/doc/getLayers.ts +32 -21
  354. package/src/doc/markdownToDoc.ts +45 -7
  355. package/src/doc/templates/featureBlock.ts +202 -0
  356. package/src/doc/templates/fullBleedQuote.ts +13 -0
  357. package/src/doc/templates/index.ts +50 -16
  358. package/src/doc/templates/listBlock.ts +24 -5
  359. package/src/doc/templates/statHighlight.ts +13 -0
  360. package/src/doc/templates/titleBlock.ts +9 -0
  361. package/src/doc/utils/themeUtils.ts +8 -7
  362. package/src/generate/slideshowGenerator.ts +1 -1
  363. package/src/generate/templateMapper.ts +2 -2
  364. package/src/icons/iconData.ts +31 -0
  365. package/src/icons/index.ts +18 -0
  366. package/src/icons/resolve.ts +139 -0
  367. package/src/imageEdit/ImageEditVersionManager.ts +73 -0
  368. package/src/imageEdit/export.ts +326 -0
  369. package/src/imageEdit/index.ts +71 -0
  370. package/src/imageEdit/persistence.ts +62 -0
  371. package/src/imageEdit/state.ts +112 -0
  372. package/src/imageEdit/versionPaths.ts +57 -0
  373. package/src/imageEdit/versions.ts +231 -0
  374. package/src/index.ts +4 -0
  375. package/src/jsonForm/chooseControl.ts +88 -0
  376. package/src/jsonForm/evaluateWhen.ts +59 -0
  377. package/src/jsonForm/index.ts +22 -0
  378. package/src/jsonForm/inferSchema.ts +25 -0
  379. package/src/jsonForm/pointer.ts +109 -0
  380. package/src/jsonForm/types.ts +167 -0
  381. package/src/markdown/convert.ts +248 -15
  382. package/src/markdown/index.ts +4 -0
  383. package/src/markdown/types.ts +38 -1
  384. package/src/markdown/utils.ts +159 -0
  385. package/src/recommend/index.ts +16 -0
  386. package/src/recommend/templates.ts +273 -0
  387. package/src/schemas/BlockTemplates.ts +50 -7
  388. package/src/schemas/ImageEditDoc.ts +95 -0
  389. package/src/schemas/Theme.ts +152 -23
  390. package/src/schemas/colorUtils.ts +186 -0
  391. package/src/schemas/fontStacks.ts +257 -0
  392. package/src/schemas/index.ts +12 -0
  393. package/src/schemas/themeCompile.ts +203 -0
  394. package/src/schemas/themeLibrary.ts +18 -524
  395. package/src/schemas/themeValidator.ts +388 -0
  396. package/src/schemas/themes/bold.json +48 -0
  397. package/src/schemas/themes/cinematic.json +54 -0
  398. package/src/schemas/themes/documentary.json +49 -0
  399. package/src/schemas/themes/gezellig.json +44 -0
  400. package/src/schemas/themes/index.ts +53 -0
  401. package/src/schemas/themes/magazine.json +44 -0
  402. package/src/schemas/themes/minimalist.json +45 -0
  403. package/src/schemas/themes/morning-light.json +42 -0
  404. package/src/schemas/themes/standard-dark.json +50 -0
  405. package/src/schemas/themes/standard.json +42 -0
  406. package/src/schemas/themes/tech-dark.json +48 -0
  407. package/src/schemas/themes/warm-earth.json +50 -0
  408. package/src/storage/ScopedContentContainer.ts +113 -0
  409. package/src/storage/index.ts +1 -0
  410. package/src/versions/DocumentVersionManager.ts +70 -0
  411. package/src/versions/index.ts +54 -0
  412. package/src/versions/operations.ts +230 -0
  413. package/src/versions/paths.ts +66 -0
  414. package/src/versions/timestamp.ts +48 -0
  415. package/src/versions/types.ts +91 -0
  416. package/dist/chunk-53TZ2UTL.js +0 -470
  417. package/dist/chunk-53TZ2UTL.js.map +0 -1
  418. package/dist/chunk-7GF6RDED.js +0 -82
  419. package/dist/chunk-7GF6RDED.js.map +0 -1
  420. package/dist/chunk-CYQHG27J.js.map +0 -1
  421. package/dist/chunk-GAQLMORN.js.map +0 -1
  422. package/dist/chunk-LAZELBON.js.map +0 -1
  423. package/dist/chunk-QM5PKNPW.js.map +0 -1
  424. package/dist/chunk-TSG2OSE6.js.map +0 -1
  425. package/dist/chunk-XM4WSOHB.js +0 -92
  426. package/dist/chunk-XM4WSOHB.js.map +0 -1
  427. package/dist/themeLibrary-IP7EdyRq.d.ts +0 -44
@@ -0,0 +1,193 @@
1
+ // src/jsonForm/chooseControl.ts
2
+ var ENUM_SEGMENTED_LIMIT = 4;
3
+ var MULTILINE_LENGTH_THRESHOLD = 200;
4
+ function chooseControl(schema) {
5
+ const hint = schema.squisq?.control;
6
+ if (hint) return hint;
7
+ const type = primaryType(schema);
8
+ if (schema.format && type === "string") {
9
+ switch (schema.format) {
10
+ case "color":
11
+ return "color";
12
+ case "date":
13
+ return "date";
14
+ case "time":
15
+ return "time";
16
+ case "date-time":
17
+ return "datetime";
18
+ case "markdown":
19
+ return "richtext";
20
+ case "textarea":
21
+ return "multiline";
22
+ }
23
+ }
24
+ if (schema.enum && schema.enum.length > 0) {
25
+ return schema.enum.length <= ENUM_SEGMENTED_LIMIT ? "segmented" : "combobox";
26
+ }
27
+ if (schema.oneOf || schema.anyOf) return "tabs";
28
+ switch (type) {
29
+ case "array":
30
+ return arrayItemKind(schema) === "object" ? "card-stack" : "chip-bin";
31
+ case "object":
32
+ return "group";
33
+ case "boolean":
34
+ return "toggle";
35
+ case "integer":
36
+ case "number":
37
+ return hasFiniteRange(schema) ? "slider" : "stepper";
38
+ case "string":
39
+ if (typeof schema.maxLength === "number" && schema.maxLength > MULTILINE_LENGTH_THRESHOLD) {
40
+ return "multiline";
41
+ }
42
+ return "text";
43
+ default:
44
+ return "text";
45
+ }
46
+ }
47
+ function primaryType(schema) {
48
+ const t = schema.type;
49
+ if (typeof t === "string") return t;
50
+ if (Array.isArray(t)) return t.find((x) => x !== "null");
51
+ return void 0;
52
+ }
53
+ function arrayItemKind(schema) {
54
+ const items = Array.isArray(schema.items) ? schema.items[0] : schema.items;
55
+ if (!items) return "primitive";
56
+ return primaryType(items) === "object" ? "object" : "primitive";
57
+ }
58
+ function hasFiniteRange(schema) {
59
+ const min = schema.minimum ?? schema.exclusiveMinimum;
60
+ const max = schema.maximum ?? schema.exclusiveMaximum;
61
+ return typeof min === "number" && typeof max === "number";
62
+ }
63
+
64
+ // src/jsonForm/pointer.ts
65
+ function toPointer(path) {
66
+ if (path === "" || path === "/") return "";
67
+ if (path.startsWith("/")) return path;
68
+ return "/" + path.split(".").map((seg) => seg.replace(/~/g, "~0").replace(/\//g, "~1")).join("/");
69
+ }
70
+ function pointerSegments(pointer) {
71
+ if (pointer === "") return [];
72
+ return pointer.slice(1).split("/").map((seg) => seg.replace(/~1/g, "/").replace(/~0/g, "~"));
73
+ }
74
+ function getByPointer(data, path) {
75
+ const segments = pointerSegments(toPointer(path));
76
+ let cur = data;
77
+ for (const seg of segments) {
78
+ if (cur === null || cur === void 0) return void 0;
79
+ if (Array.isArray(cur)) {
80
+ const idx = Number(seg);
81
+ if (!Number.isInteger(idx) || idx < 0 || idx >= cur.length) return void 0;
82
+ cur = cur[idx];
83
+ } else if (typeof cur === "object") {
84
+ cur = cur[seg];
85
+ } else {
86
+ return void 0;
87
+ }
88
+ }
89
+ return cur;
90
+ }
91
+ function setByPointer(data, path, value) {
92
+ const segments = pointerSegments(toPointer(path));
93
+ if (segments.length === 0) return value;
94
+ return setRec(data, segments, 0, value);
95
+ }
96
+ function setRec(node, segments, i, value) {
97
+ const seg = segments[i];
98
+ const isLast = i === segments.length - 1;
99
+ const nextSeg = isLast ? void 0 : segments[i + 1];
100
+ const writingArrayChild = nextSeg !== void 0 && /^\d+$/.test(nextSeg);
101
+ if (Array.isArray(node)) {
102
+ const idx = Number(seg);
103
+ const next = node.slice();
104
+ next[idx] = isLast ? value : setRec(node[idx] ?? (writingArrayChild ? [] : {}), segments, i + 1, value);
105
+ return next;
106
+ }
107
+ const obj = node && typeof node === "object" ? { ...node } : {};
108
+ obj[seg] = isLast ? value : setRec(obj[seg] ?? (writingArrayChild ? [] : {}), segments, i + 1, value);
109
+ return obj;
110
+ }
111
+ function resolveRef(schema, root) {
112
+ if (!schema.$ref) return schema;
113
+ const ref = schema.$ref;
114
+ if (!ref.startsWith("#/")) return void 0;
115
+ const segments = pointerSegments(ref.slice(1));
116
+ let cur = root;
117
+ for (const seg of segments) {
118
+ if (cur === null || cur === void 0 || typeof cur !== "object") return void 0;
119
+ cur = cur[seg];
120
+ }
121
+ return cur ?? void 0;
122
+ }
123
+
124
+ // src/jsonForm/evaluateWhen.ts
125
+ function evaluateWhen(when, rootData) {
126
+ const actual = getByPointer(rootData, when.field);
127
+ if (when.equals !== void 0) {
128
+ return deepEqual(actual, when.equals);
129
+ }
130
+ if (when.oneOf !== void 0) {
131
+ return when.oneOf.some((v) => deepEqual(actual, v));
132
+ }
133
+ if (when.matches !== void 0) {
134
+ if (typeof actual !== "string") return false;
135
+ try {
136
+ return new RegExp(when.matches).test(actual);
137
+ } catch {
138
+ return false;
139
+ }
140
+ }
141
+ if (when.truthy !== void 0) {
142
+ return Boolean(actual) === when.truthy;
143
+ }
144
+ return actual !== void 0 && actual !== null;
145
+ }
146
+ function resolveFlag(flag, rootData) {
147
+ if (flag === void 0) return false;
148
+ if (typeof flag === "boolean") return flag;
149
+ return evaluateWhen(flag, rootData);
150
+ }
151
+ function deepEqual(a, b) {
152
+ if (a === b) return true;
153
+ if (a === null || b === null) return false;
154
+ if (typeof a !== typeof b) return false;
155
+ if (typeof a !== "object") return false;
156
+ if (Array.isArray(a)) {
157
+ if (!Array.isArray(b) || a.length !== b.length) return false;
158
+ return a.every((v, i) => deepEqual(v, b[i]));
159
+ }
160
+ if (Array.isArray(b)) return false;
161
+ const ao = a;
162
+ const bo = b;
163
+ const ak = Object.keys(ao);
164
+ const bk = Object.keys(bo);
165
+ if (ak.length !== bk.length) return false;
166
+ return ak.every((k) => deepEqual(ao[k], bo[k]));
167
+ }
168
+
169
+ // src/jsonForm/inferSchema.ts
170
+ import { createSchema, mergeSchemas } from "genson-js";
171
+ function inferSchema(sample, options = {}) {
172
+ const base = createSchema(sample);
173
+ if (!options.additionalSamples || options.additionalSamples.length === 0) {
174
+ return base;
175
+ }
176
+ const extras = options.additionalSamples.map((s) => createSchema(s));
177
+ return mergeSchemas([base, ...extras]);
178
+ }
179
+
180
+ export {
181
+ chooseControl,
182
+ primaryType,
183
+ arrayItemKind,
184
+ toPointer,
185
+ pointerSegments,
186
+ getByPointer,
187
+ setByPointer,
188
+ resolveRef,
189
+ evaluateWhen,
190
+ resolveFlag,
191
+ inferSchema
192
+ };
193
+ //# sourceMappingURL=chunk-K32VJONL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/jsonForm/chooseControl.ts","../src/jsonForm/pointer.ts","../src/jsonForm/evaluateWhen.ts","../src/jsonForm/inferSchema.ts"],"sourcesContent":["/**\n * Pick a `ControlKind` for a schema node. The single dispatcher used by\n * both `<JsonView>` and `<JsonEditor>` so view and edit modes always\n * agree on what each field _is_, even when their UIs differ.\n *\n * Order of precedence:\n * 1. Explicit `squisq.control` hint\n * 2. `format` keyword (color/date/time/datetime/markdown/textarea)\n * 3. Enum cardinality (segmented vs. combobox)\n * 4. Numeric range (slider when both min and max present)\n * 5. String length (multiline when maxLength > 200)\n * 6. Type-default (object/array/boolean/string/number)\n */\n\nimport type { ControlKind, SquisqAnnotatedSchema } from './types.js';\n\nconst ENUM_SEGMENTED_LIMIT = 4;\nconst MULTILINE_LENGTH_THRESHOLD = 200;\n\nexport function chooseControl(schema: SquisqAnnotatedSchema): ControlKind {\n const hint = schema.squisq?.control;\n if (hint) return hint;\n\n const type = primaryType(schema);\n\n if (schema.format && type === 'string') {\n switch (schema.format) {\n case 'color':\n return 'color';\n case 'date':\n return 'date';\n case 'time':\n return 'time';\n case 'date-time':\n return 'datetime';\n case 'markdown':\n return 'richtext';\n case 'textarea':\n return 'multiline';\n }\n }\n\n if (schema.enum && schema.enum.length > 0) {\n return schema.enum.length <= ENUM_SEGMENTED_LIMIT ? 'segmented' : 'combobox';\n }\n\n if (schema.oneOf || schema.anyOf) return 'tabs';\n\n switch (type) {\n case 'array':\n return arrayItemKind(schema) === 'object' ? 'card-stack' : 'chip-bin';\n case 'object':\n return 'group';\n case 'boolean':\n return 'toggle';\n case 'integer':\n case 'number':\n return hasFiniteRange(schema) ? 'slider' : 'stepper';\n case 'string':\n if (typeof schema.maxLength === 'number' && schema.maxLength > MULTILINE_LENGTH_THRESHOLD) {\n return 'multiline';\n }\n return 'text';\n default:\n return 'text';\n }\n}\n\n/** Return the first concrete type of a schema, ignoring `null` for nullable shorthand. */\nexport function primaryType(schema: SquisqAnnotatedSchema): string | undefined {\n const t = schema.type;\n if (typeof t === 'string') return t;\n if (Array.isArray(t)) return t.find((x) => x !== 'null');\n return undefined;\n}\n\n/** Inspect `items` to decide whether an array holds objects or primitives. */\nexport function arrayItemKind(schema: SquisqAnnotatedSchema): 'object' | 'primitive' {\n const items = Array.isArray(schema.items) ? schema.items[0] : schema.items;\n if (!items) return 'primitive';\n return primaryType(items) === 'object' ? 'object' : 'primitive';\n}\n\nfunction hasFiniteRange(schema: SquisqAnnotatedSchema): boolean {\n const min = schema.minimum ?? schema.exclusiveMinimum;\n const max = schema.maximum ?? schema.exclusiveMaximum;\n return typeof min === 'number' && typeof max === 'number';\n}\n","/**\n * JSON Pointer helpers (RFC 6901) plus immutable get/set, plus a tiny\n * dotted-path normalizer so hosts can write `user.role` instead of\n * `/user/role`. `$ref` resolution is local-only (`#/$defs/Foo`).\n */\n\nimport type { SquisqAnnotatedSchema } from './types.js';\n\n/** Normalize a path to a JSON Pointer string. Accepts both forms. */\nexport function toPointer(path: string): string {\n if (path === '' || path === '/') return '';\n if (path.startsWith('/')) return path;\n // Dotted form: split on `.` and escape per RFC 6901.\n return (\n '/' +\n path\n .split('.')\n .map((seg) => seg.replace(/~/g, '~0').replace(/\\//g, '~1'))\n .join('/')\n );\n}\n\n/** Split a JSON Pointer into decoded segments. Empty string → []. */\nexport function pointerSegments(pointer: string): string[] {\n if (pointer === '') return [];\n return pointer\n .slice(1)\n .split('/')\n .map((seg) => seg.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\n/** Read a value from data by path (dotted or pointer). Returns undefined if missing. */\nexport function getByPointer(data: unknown, path: string): unknown {\n const segments = pointerSegments(toPointer(path));\n let cur: unknown = data;\n for (const seg of segments) {\n if (cur === null || cur === undefined) return undefined;\n if (Array.isArray(cur)) {\n const idx = Number(seg);\n if (!Number.isInteger(idx) || idx < 0 || idx >= cur.length) return undefined;\n cur = cur[idx];\n } else if (typeof cur === 'object') {\n cur = (cur as Record<string, unknown>)[seg];\n } else {\n return undefined;\n }\n }\n return cur;\n}\n\n/**\n * Return a structurally-shared copy of `data` with the value at `path`\n * replaced. Intermediate objects/arrays are cloned along the path; the\n * rest is shared by reference. Creates intermediate objects if missing.\n */\nexport function setByPointer<T>(data: T, path: string, value: unknown): T {\n const segments = pointerSegments(toPointer(path));\n if (segments.length === 0) return value as T;\n return setRec(data, segments, 0, value) as T;\n}\n\nfunction setRec(node: unknown, segments: string[], i: number, value: unknown): unknown {\n const seg = segments[i];\n const isLast = i === segments.length - 1;\n\n // Decide whether the slot we're about to write into is an array index.\n const nextSeg = isLast ? undefined : segments[i + 1];\n const writingArrayChild = nextSeg !== undefined && /^\\d+$/.test(nextSeg);\n\n if (Array.isArray(node)) {\n const idx = Number(seg);\n const next = node.slice();\n next[idx] = isLast\n ? value\n : setRec(node[idx] ?? (writingArrayChild ? [] : {}), segments, i + 1, value);\n return next;\n }\n\n const obj = (node && typeof node === 'object' ? { ...(node as object) } : {}) as Record<\n string,\n unknown\n >;\n obj[seg] = isLast\n ? value\n : setRec(obj[seg] ?? (writingArrayChild ? [] : {}), segments, i + 1, value);\n return obj;\n}\n\n/**\n * Resolve a local `$ref` (e.g. `#/$defs/Foo`) against the root schema.\n * Returns the original schema if no `$ref` is present, or `undefined`\n * if the reference cannot be resolved. Cross-document refs are not\n * supported.\n */\nexport function resolveRef(\n schema: SquisqAnnotatedSchema,\n root: SquisqAnnotatedSchema,\n): SquisqAnnotatedSchema | undefined {\n if (!schema.$ref) return schema;\n const ref = schema.$ref;\n if (!ref.startsWith('#/')) return undefined;\n const segments = pointerSegments(ref.slice(1));\n let cur: unknown = root;\n for (const seg of segments) {\n if (cur === null || cur === undefined || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[seg];\n }\n return (cur as SquisqAnnotatedSchema | undefined) ?? undefined;\n}\n","/**\n * Evaluate a `SquisqWhen` rule against the current root data. Pure;\n * renderers call this on every render with fresh data.\n */\n\nimport type { SquisqWhen } from './types.js';\nimport { getByPointer } from './pointer.js';\n\nexport function evaluateWhen(when: SquisqWhen, rootData: unknown): boolean {\n const actual = getByPointer(rootData, when.field);\n\n if (when.equals !== undefined) {\n return deepEqual(actual, when.equals);\n }\n if (when.oneOf !== undefined) {\n return when.oneOf.some((v) => deepEqual(actual, v));\n }\n if (when.matches !== undefined) {\n if (typeof actual !== 'string') return false;\n try {\n return new RegExp(when.matches).test(actual);\n } catch {\n return false;\n }\n }\n if (when.truthy !== undefined) {\n return Boolean(actual) === when.truthy;\n }\n // No operator specified — defaults to \"field has any defined value\".\n return actual !== undefined && actual !== null;\n}\n\n/**\n * Resolve a `boolean | SquisqWhen` flag (used by `hidden`/`disabled`)\n * to a final boolean. Literal booleans pass through.\n */\nexport function resolveFlag(flag: boolean | SquisqWhen | undefined, rootData: unknown): boolean {\n if (flag === undefined) return false;\n if (typeof flag === 'boolean') return flag;\n return evaluateWhen(flag, rootData);\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object') return false;\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) return false;\n return a.every((v, i) => deepEqual(v, b[i]));\n }\n if (Array.isArray(b)) return false;\n const ao = a as Record<string, unknown>;\n const bo = b as Record<string, unknown>;\n const ak = Object.keys(ao);\n const bk = Object.keys(bo);\n if (ak.length !== bk.length) return false;\n return ak.every((k) => deepEqual(ao[k], bo[k]));\n}\n","/**\n * Infer a JSON Schema from an example JSON value. Thin facade over\n * `genson-js` so consumers don't depend on it directly and we can swap\n * the implementation later.\n */\n\nimport { createSchema, mergeSchemas } from 'genson-js';\nimport type { SquisqAnnotatedSchema } from './types.js';\n\nexport interface InferSchemaOptions {\n /** Additional samples merged into the inferred schema for broader coverage. */\n additionalSamples?: readonly unknown[];\n}\n\nexport function inferSchema(\n sample: unknown,\n options: InferSchemaOptions = {},\n): SquisqAnnotatedSchema {\n const base = createSchema(sample) as SquisqAnnotatedSchema;\n if (!options.additionalSamples || options.additionalSamples.length === 0) {\n return base;\n }\n const extras = options.additionalSamples.map((s) => createSchema(s) as SquisqAnnotatedSchema);\n return mergeSchemas([base, ...extras] as never[]) as SquisqAnnotatedSchema;\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,7 @@
1
1
  import {
2
- DEFAULT_THEME
3
- } from "./chunk-53TZ2UTL.js";
2
+ DEFAULT_THEME,
3
+ resolveFontFamily
4
+ } from "./chunk-B4EEON3N.js";
4
5
  import {
5
6
  VIEWPORT_PRESETS,
6
7
  createTemplateContext,
@@ -8,10 +9,10 @@ import {
8
9
  isPersistentLayerTemplate,
9
10
  isTemplateBlock,
10
11
  scaledFontSize2 as scaledFontSize
11
- } from "./chunk-QM5PKNPW.js";
12
+ } from "./chunk-5WFRKURX.js";
12
13
  import {
13
14
  extractPlainText
14
- } from "./chunk-7GF6RDED.js";
15
+ } from "./chunk-H3AXU4MJ.js";
15
16
  import {
16
17
  estimateReadingTime
17
18
  } from "./chunk-4X3JQXNM.js";
@@ -388,11 +389,11 @@ function getThemeFont(context, role) {
388
389
  const { typography } = context.theme;
389
390
  switch (role) {
390
391
  case "title":
391
- return typography.titleFontFamily || FALLBACK_TITLE;
392
+ return resolveFontFamily(typography.titleFont, FALLBACK_TITLE);
392
393
  case "body":
393
- return typography.bodyFontFamily || FALLBACK_BODY;
394
+ return resolveFontFamily(typography.bodyFont, FALLBACK_BODY);
394
395
  case "mono":
395
- return typography.monoFontFamily || FALLBACK_MONO;
396
+ return resolveFontFamily(typography.monoFont, FALLBACK_MONO);
396
397
  }
397
398
  }
398
399
  function themedFontSize(basePx, context, isTitle = false) {
@@ -1495,6 +1496,122 @@ function imageWithCaption(input, context) {
1495
1496
  return layers;
1496
1497
  }
1497
1498
 
1499
+ // src/doc/templates/featureBlock.ts
1500
+ function buildFeatureLayers(input, context, side) {
1501
+ const { imageSrc, imageAlt, imageWidth, imageHeight, title, body } = input;
1502
+ const { theme, layout } = context;
1503
+ const sized = (imageWidth ?? 0) > 0 || (imageHeight ?? 0) > 0;
1504
+ const stack = layout.stackColumns;
1505
+ const titleFontSize = scaledFontSize(48, context, true);
1506
+ const bodyFontSize = scaledFontSize(24, context, false);
1507
+ let imgX;
1508
+ let imgY;
1509
+ let imgW;
1510
+ let imgH;
1511
+ let imageFit;
1512
+ if (stack) {
1513
+ imgX = "0";
1514
+ imgY = "0";
1515
+ imgW = "100%";
1516
+ imgH = "50%";
1517
+ imageFit = sized ? "contain" : "cover";
1518
+ } else if (sized) {
1519
+ const halfStart = side === "left" ? 5 : 55;
1520
+ imgX = `${halfStart}%`;
1521
+ imgY = "5%";
1522
+ imgW = "40%";
1523
+ imgH = "90%";
1524
+ imageFit = "contain";
1525
+ } else {
1526
+ imgX = side === "left" ? "0" : "50%";
1527
+ imgY = "0";
1528
+ imgW = "50%";
1529
+ imgH = "100%";
1530
+ imageFit = "cover";
1531
+ }
1532
+ const COLUMN_INSET = 4;
1533
+ const textColumnWidth = stack ? 90 : 42;
1534
+ const textX = stack ? `${(100 - textColumnWidth) / 2}%` : side === "left" ? `${50 + COLUMN_INSET}%` : `${50 - COLUMN_INSET}%`;
1535
+ const titleY = stack ? "60%" : body ? "42%" : "50%";
1536
+ const bodyY = stack ? "78%" : title ? "55%" : "50%";
1537
+ const textAnchor = side === "right" && !stack ? "top-right" : "top-left";
1538
+ const textAlign = side === "right" && !stack ? "right" : "left";
1539
+ const layers = [
1540
+ {
1541
+ type: "shape",
1542
+ id: "feature-bg",
1543
+ content: { shape: "rect", fill: theme.colors.background },
1544
+ position: { x: 0, y: 0, width: "100%", height: "100%" }
1545
+ }
1546
+ ];
1547
+ if (imageSrc) {
1548
+ layers.push({
1549
+ type: "image",
1550
+ id: "feature-image",
1551
+ content: {
1552
+ src: imageSrc,
1553
+ alt: imageAlt ?? title ?? "",
1554
+ fit: imageFit
1555
+ },
1556
+ position: { x: imgX, y: imgY, width: imgW, height: imgH }
1557
+ });
1558
+ }
1559
+ if (title) {
1560
+ layers.push({
1561
+ type: "text",
1562
+ id: "feature-title",
1563
+ content: {
1564
+ text: title,
1565
+ style: {
1566
+ fontSize: titleFontSize,
1567
+ fontFamily: getThemeFont(context, "title"),
1568
+ fontWeight: "bold",
1569
+ color: theme.colors.text,
1570
+ textAlign,
1571
+ lineHeight: 1.2
1572
+ }
1573
+ },
1574
+ position: {
1575
+ x: textX,
1576
+ y: titleY,
1577
+ anchor: textAnchor,
1578
+ width: `${textColumnWidth}%`
1579
+ },
1580
+ animation: { type: "fadeIn", duration: 0.8 }
1581
+ });
1582
+ }
1583
+ if (body) {
1584
+ layers.push({
1585
+ type: "text",
1586
+ id: "feature-body",
1587
+ content: {
1588
+ text: body,
1589
+ style: {
1590
+ fontSize: bodyFontSize,
1591
+ fontFamily: getThemeFont(context, "body"),
1592
+ color: theme.colors.textMuted,
1593
+ textAlign,
1594
+ lineHeight: 1.5
1595
+ }
1596
+ },
1597
+ position: {
1598
+ x: textX,
1599
+ y: bodyY,
1600
+ anchor: textAnchor,
1601
+ width: `${textColumnWidth}%`
1602
+ },
1603
+ animation: { type: "fadeIn", duration: 0.8, delay: 0.2 }
1604
+ });
1605
+ }
1606
+ return layers;
1607
+ }
1608
+ function leftFeature(input, context) {
1609
+ return buildFeatureLayers(input, context, "left");
1610
+ }
1611
+ function rightFeature(input, context) {
1612
+ return buildFeatureLayers(input, context, "right");
1613
+ }
1614
+
1498
1615
  // src/doc/templates/mapBlock.ts
1499
1616
  function mapBlock(input, context) {
1500
1617
  const {
@@ -1643,7 +1760,8 @@ function fullBleedQuote(input, context) {
1643
1760
 
1644
1761
  // src/doc/templates/listBlock.ts
1645
1762
  function listBlock(input, context) {
1646
- const { items, title, accentImage } = input;
1763
+ const { title, accentImage } = input;
1764
+ const items = Array.isArray(input.items) ? input.items : [];
1647
1765
  const { theme } = context;
1648
1766
  const accentLayout = accentImage ? getAccentLayout(accentImage.position) : DEFAULT_LAYOUT;
1649
1767
  const titleFontSize = scaledFontSize(44, context, true);
@@ -1687,6 +1805,9 @@ function listBlock(input, context) {
1687
1805
  animation: { type: "fadeIn", duration: 1 }
1688
1806
  });
1689
1807
  }
1808
+ const centerX = parseFloat(accentLayout.textCenterX);
1809
+ const widthPct = parseFloat(accentLayout.textWidth);
1810
+ const leftX = Number.isFinite(centerX) && Number.isFinite(widthPct) ? `${centerX - widthPct / 2}%` : "8%";
1690
1811
  const endY = 80;
1691
1812
  const spacing = items.length > 1 ? (endY - startY) / (items.length - 1) : 0;
1692
1813
  for (let i = 0; i < items.length; i++) {
@@ -1701,14 +1822,14 @@ function listBlock(input, context) {
1701
1822
  fontSize: itemFontSize,
1702
1823
  fontFamily: getThemeFont(context, "body"),
1703
1824
  color: theme.colors.text,
1704
- lineHeight: 1.4,
1825
+ textAlign: "left",
1826
+ lineHeight: 1.2,
1705
1827
  shadow: !!accentImage
1706
1828
  }
1707
1829
  },
1708
1830
  position: {
1709
- x: accentLayout.textCenterX,
1831
+ x: leftX,
1710
1832
  y: adjustY(`${y}%`, accentLayout),
1711
- anchor: "center",
1712
1833
  width: accentLayout.textWidth
1713
1834
  },
1714
1835
  animation: { type: "fadeIn", duration: 0.8, delay: 0.3 + 0.3 * i }
@@ -2579,17 +2700,19 @@ function expandCoverBlock(config, context) {
2579
2700
 
2580
2701
  // src/doc/templates/index.ts
2581
2702
  var templateRegistry = {
2582
- titleBlock,
2703
+ title: titleBlock,
2583
2704
  sectionHeader,
2584
2705
  statHighlight,
2585
- quoteBlock,
2706
+ quote: quoteBlock,
2586
2707
  factCard,
2587
2708
  twoColumn,
2588
2709
  dateEvent,
2589
2710
  imageWithCaption,
2590
- mapBlock,
2711
+ leftFeature,
2712
+ rightFeature,
2713
+ map: mapBlock,
2591
2714
  fullBleedQuote,
2592
- listBlock,
2715
+ list: listBlock,
2593
2716
  photoGrid,
2594
2717
  definitionCard,
2595
2718
  comparisonBar,
@@ -2598,8 +2721,18 @@ var templateRegistry = {
2598
2721
  videoPullQuote,
2599
2722
  dataTable
2600
2723
  };
2724
+ var TEMPLATE_ALIASES = {
2725
+ titleBlock: "title",
2726
+ quoteBlock: "quote",
2727
+ mapBlock: "map",
2728
+ listBlock: "list"
2729
+ };
2730
+ function resolveTemplateName(name) {
2731
+ return TEMPLATE_ALIASES[name] ?? name;
2732
+ }
2601
2733
  function expandTemplateBlock(templateBlock, context) {
2602
- const templateFn = templateRegistry[templateBlock.template];
2734
+ const resolved = resolveTemplateName(templateBlock.template);
2735
+ const templateFn = templateRegistry[resolved];
2603
2736
  if (!templateFn) {
2604
2737
  console.warn(`Unknown template: ${templateBlock.template}`);
2605
2738
  return {
@@ -2614,10 +2747,7 @@ function expandTemplateBlock(templateBlock, context) {
2614
2747
  }
2615
2748
  let layers;
2616
2749
  try {
2617
- layers = templateFn(
2618
- templateBlock,
2619
- context
2620
- );
2750
+ layers = templateFn(templateBlock, context);
2621
2751
  if (!Array.isArray(layers)) {
2622
2752
  console.error(
2623
2753
  `Template ${templateBlock.template} did not return an array, got:`,
@@ -2862,7 +2992,7 @@ function getAvailableTemplates() {
2862
2992
  return Object.keys(templateRegistry);
2863
2993
  }
2864
2994
  function hasTemplate(name) {
2865
- return name in templateRegistry;
2995
+ return resolveTemplateName(name) in templateRegistry;
2866
2996
  }
2867
2997
 
2868
2998
  // src/doc/utils/animationUtils.ts
@@ -2983,7 +3113,8 @@ function markdownToDoc(markdownDoc, options) {
2983
3113
  function makeBlock(heading) {
2984
3114
  const id = heading ? generateId(heading, headingIndex++) : "preamble";
2985
3115
  const annotation = heading?.templateAnnotation;
2986
- const template = annotation?.template ?? (heading ? defaultTemplate : void 0);
3116
+ const rawTemplate = annotation?.template ?? (heading ? defaultTemplate : void 0);
3117
+ const template = rawTemplate != null ? resolveTemplateName(rawTemplate) : void 0;
2987
3118
  const title = heading ? extractPlainText(heading) : void 0;
2988
3119
  const block = {
2989
3120
  id,
@@ -3161,8 +3292,29 @@ function splitIntoSentences(text) {
3161
3292
  }
3162
3293
  return merged;
3163
3294
  }
3295
+ function findFirstHtmlImage(nodes) {
3296
+ for (const node of nodes) {
3297
+ if (node.type !== "htmlElement") continue;
3298
+ if (node.tagName === "img" && node.attributes.src) {
3299
+ return { url: node.attributes.src, alt: node.attributes.alt };
3300
+ }
3301
+ const nested = findFirstHtmlImage(node.children);
3302
+ if (nested) return nested;
3303
+ }
3304
+ return void 0;
3305
+ }
3164
3306
  function findFirstImage(node) {
3165
- if (node.type === "image") return node;
3307
+ if (node.type === "image") {
3308
+ const img = node;
3309
+ return { url: img.url, alt: img.alt };
3310
+ }
3311
+ if (node.type === "htmlBlock" || node.type === "htmlInline") {
3312
+ const html = node;
3313
+ if (html.htmlChildren) {
3314
+ const found = findFirstHtmlImage(html.htmlChildren);
3315
+ if (found) return found;
3316
+ }
3317
+ }
3166
3318
  if ("children" in node && Array.isArray(node.children)) {
3167
3319
  for (const child of node.children) {
3168
3320
  const found = findFirstImage(child);
@@ -3237,22 +3389,25 @@ function getLayers(block, context = {}) {
3237
3389
  if (existingLayers && existingLayers.length > 0 && !isTemplateBlock(block)) {
3238
3390
  return injectPersistentLayers(existingLayers, block, context);
3239
3391
  }
3240
- if (isTemplateBlock(block) && block.template in templateRegistry) {
3241
- const templateName = block.template;
3242
- const templateCtx = createTemplateContext(theme, blockIndex, totalBlocks, viewport);
3243
- let layers;
3244
- try {
3245
- const templateFn = templateRegistry[templateName];
3246
- layers = templateFn(block, templateCtx);
3247
- if (!Array.isArray(layers)) {
3248
- console.error(`Template ${templateName} did not return an array, got:`, typeof layers);
3392
+ if (isTemplateBlock(block)) {
3393
+ const resolved = resolveTemplateName(block.template);
3394
+ if (resolved in templateRegistry) {
3395
+ const templateName = resolved;
3396
+ const templateCtx = createTemplateContext(theme, blockIndex, totalBlocks, viewport);
3397
+ let layers;
3398
+ try {
3399
+ const templateFn = templateRegistry[templateName];
3400
+ layers = templateFn(block, templateCtx);
3401
+ if (!Array.isArray(layers)) {
3402
+ console.error(`Template ${templateName} did not return an array, got:`, typeof layers);
3403
+ layers = [];
3404
+ }
3405
+ } catch (err) {
3406
+ console.error(`Error expanding template ${templateName}:`, err);
3249
3407
  layers = [];
3250
3408
  }
3251
- } catch (err) {
3252
- console.error(`Error expanding template ${templateName}:`, err);
3253
- layers = [];
3409
+ return injectPersistentLayers(layers, block, context);
3254
3410
  }
3255
- return injectPersistentLayers(layers, block, context);
3256
3411
  }
3257
3412
  return injectPersistentLayers([], block, context);
3258
3413
  }
@@ -3324,17 +3479,62 @@ function flattenForAudio(blocks) {
3324
3479
  }
3325
3480
  return result;
3326
3481
  }
3482
+ var AUDIO_ONLY_EXTENSIONS = [".mp3", ".wav", ".ogg", ".m4a"];
3483
+ var AMBIGUOUS_EXTENSIONS = [".webm", ".mp4"];
3484
+ function isNarrationAudioPath(path) {
3485
+ const lower = path.toLowerCase();
3486
+ if (AUDIO_ONLY_EXTENSIONS.some((ext) => lower.endsWith(ext))) return true;
3487
+ if (AMBIGUOUS_EXTENSIONS.some((ext) => lower.endsWith(ext))) {
3488
+ return lower.startsWith("audio/");
3489
+ }
3490
+ return false;
3491
+ }
3492
+ function stripAudioExtension(filename) {
3493
+ const lower = filename.toLowerCase();
3494
+ for (const ext of [...AUDIO_ONLY_EXTENSIONS, ...AMBIGUOUS_EXTENSIONS]) {
3495
+ if (lower.endsWith(ext)) return filename.slice(0, -ext.length);
3496
+ }
3497
+ return filename;
3498
+ }
3499
+ function parseConsolidatedTiming(data) {
3500
+ try {
3501
+ const text = new TextDecoder().decode(data);
3502
+ const parsed = JSON.parse(text);
3503
+ if (parsed && parsed.version === 2 && parsed.sections) {
3504
+ return parsed.sections;
3505
+ }
3506
+ return null;
3507
+ } catch {
3508
+ return null;
3509
+ }
3510
+ }
3327
3511
  async function discoverMp3s(container) {
3328
3512
  const files = await container.listFiles();
3329
- const mp3Files = files.filter((f) => f.path.endsWith(".mp3"));
3513
+ const audioFiles = files.filter((f) => isNarrationAudioPath(f.path));
3330
3514
  const results = [];
3331
- for (const file of mp3Files) {
3515
+ let consolidatedSections = null;
3516
+ const consolidatedData = await container.readFile("timing.json");
3517
+ if (consolidatedData) {
3518
+ consolidatedSections = parseConsolidatedTiming(consolidatedData);
3519
+ }
3520
+ for (const file of audioFiles) {
3332
3521
  const filename = file.path.split("/").pop() ?? file.path;
3333
3522
  let timing = null;
3334
- const timingPath = `${file.path}.timing.json`;
3335
- const timingData = await container.readFile(timingPath);
3336
- if (timingData) {
3337
- timing = parseTimingJson(timingData);
3523
+ if (consolidatedSections) {
3524
+ const audioBase = stripAudioExtension(filename);
3525
+ for (const [sectionName, sectionTiming] of Object.entries(consolidatedSections)) {
3526
+ if (audioBase.endsWith(`-${sectionName}`)) {
3527
+ timing = sectionTiming;
3528
+ break;
3529
+ }
3530
+ }
3531
+ }
3532
+ if (!timing) {
3533
+ const timingPath = `${file.path}.timing.json`;
3534
+ const timingData = await container.readFile(timingPath);
3535
+ if (timingData) {
3536
+ timing = parseTimingJson(timingData);
3537
+ }
3338
3538
  }
3339
3539
  results.push({ path: file.path, filename, timing });
3340
3540
  }
@@ -3373,7 +3573,7 @@ function autoMatchBlocks(blocks, mp3s) {
3373
3573
  }
3374
3574
  if (score < MIN_CONTENT_SIMILARITY && block.title) {
3375
3575
  const titleSlug = slugify2(block.title);
3376
- const fileSlug = slugify2(mp3.filename.replace(/\.mp3$/, ""));
3576
+ const fileSlug = slugify2(stripAudioExtension(mp3.filename));
3377
3577
  if (fileSlug.includes(titleSlug) && titleSlug.length >= 3) {
3378
3578
  score = Math.max(score, MIN_FILENAME_SIMILARITY + 0.1);
3379
3579
  }
@@ -3469,6 +3669,8 @@ export {
3469
3669
  twoColumn,
3470
3670
  dateEvent,
3471
3671
  imageWithCaption,
3672
+ leftFeature,
3673
+ rightFeature,
3472
3674
  mapBlock,
3473
3675
  fullBleedQuote,
3474
3676
  listBlock,
@@ -3482,6 +3684,8 @@ export {
3482
3684
  coverBlock,
3483
3685
  expandCoverBlock,
3484
3686
  templateRegistry,
3687
+ TEMPLATE_ALIASES,
3688
+ resolveTemplateName,
3485
3689
  expandTemplateBlock,
3486
3690
  expandDocBlocks,
3487
3691
  getAvailableTemplates,
@@ -3499,4 +3703,4 @@ export {
3499
3703
  scoreTextSimilarity,
3500
3704
  resolveAudioMapping
3501
3705
  };
3502
- //# sourceMappingURL=chunk-GAQLMORN.js.map
3706
+ //# sourceMappingURL=chunk-KSWJR66U.js.map