@bendyline/squisq 2.1.0 → 2.3.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 (442) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +24 -0
  3. package/README.md +8 -8
  4. package/dist/{ContentContainer-BXUlIf18.d.ts → ContentContainer-B2w9sUoL.d.ts} +15 -0
  5. package/dist/{Doc-DynJleo-.d.ts → Doc-COe-rPQB.d.ts} +7 -5
  6. package/dist/{ImageEditDoc-Ca4Tr9uN.d.ts → ImageEditDoc-dtKahVyD.d.ts} +1 -1
  7. package/dist/{annotationCoercion-Dr_DY9Hx.d.ts → annotationCoercion-PtRQhk5V.d.ts} +1 -1
  8. package/dist/{chunk-VWCJ2WXC.js → chunk-2ZWIXGAC.js} +0 -1
  9. package/dist/{chunk-VYFRI7R6.js → chunk-32R2RZAO.js} +72 -3
  10. package/dist/chunk-3IGPAPQ7.js +645 -0
  11. package/dist/{chunk-QE7TWGVT.js → chunk-4VOD55SX.js} +0 -1
  12. package/dist/{chunk-3E5F2XMR.js → chunk-67L6WRJN.js} +0 -1
  13. package/dist/{chunk-5DKBFXPY.js → chunk-6ECMNUIP.js} +26 -18
  14. package/dist/{chunk-DBS6RIFL.js → chunk-7N4G32LG.js} +0 -1
  15. package/dist/{chunk-JOQYPRDZ.js → chunk-7YEZFHLS.js} +10 -8
  16. package/dist/{chunk-2UQOHYE2.js → chunk-7ZAAICW4.js} +0 -1
  17. package/dist/{chunk-66QO7XFB.js → chunk-ACZOVWX3.js} +117 -7
  18. package/dist/{chunk-5J4HKRJF.js → chunk-BAOV476U.js} +0 -1
  19. package/dist/chunk-BCCXTMN5.js +699 -0
  20. package/dist/{chunk-JHZWYRSW.js → chunk-C33GTPUZ.js} +11 -4
  21. package/dist/{chunk-XNLB57UD.js → chunk-EK446BUE.js} +18 -2
  22. package/dist/{chunk-VR7UPJ7C.js → chunk-FCG3BIZN.js} +12 -1
  23. package/dist/{chunk-JI77MGAK.js → chunk-GIIOY6XR.js} +2178 -1291
  24. package/dist/{chunk-Q7LROV2H.js → chunk-NKNMGIIN.js} +0 -1
  25. package/dist/chunk-OPO5K4DZ.js +241 -0
  26. package/dist/{chunk-TUWMK62B.js → chunk-PUS54YU6.js} +45 -2
  27. package/dist/{chunk-OTKVFVL6.js → chunk-QNTQIEIV.js} +130 -47
  28. package/dist/{chunk-5UYI3RJB.js → chunk-QWCFK5FN.js} +55 -40
  29. package/dist/{chunk-GZY66SDN.js → chunk-R3KTTOMS.js} +0 -1
  30. package/dist/{chunk-ILWDXLUK.js → chunk-RS5AP3J4.js} +49 -10
  31. package/dist/{chunk-QUUPYOSP.js → chunk-SPTY4C6F.js} +136 -5
  32. package/dist/{chunk-4X3JQXNM.js → chunk-XOFT65EX.js} +1 -2
  33. package/dist/{chunk-FVTQSNR7.js → chunk-XRW6P7IF.js} +13 -5
  34. package/dist/{chunk-R2YZTCLO.js → chunk-ZQKZSJAX.js} +1 -2
  35. package/dist/doc/index.d.ts +311 -13
  36. package/dist/doc/index.js +25 -17
  37. package/dist/generate/index.d.ts +2 -2
  38. package/dist/generate/index.js +1 -3
  39. package/dist/icons/index.js +2 -4
  40. package/dist/icons/inlineIconMarker.js +1 -2
  41. package/dist/imageEdit/index.d.ts +48 -17
  42. package/dist/imageEdit/index.js +3 -4
  43. package/dist/index.d.ts +13 -13
  44. package/dist/index.js +67 -33
  45. package/dist/jsonForm/index.d.ts +10 -3
  46. package/dist/jsonForm/index.js +8 -7
  47. package/dist/markdown/index.d.ts +75 -11
  48. package/dist/markdown/index.js +32 -7
  49. package/dist/{materializePageSection-DDzubQXo.d.ts → materializePageSection-BSMOocve.d.ts} +2 -2
  50. package/dist/narration/index.d.ts +16 -3
  51. package/dist/narration/index.js +12 -14
  52. package/dist/random/index.d.ts +11 -2
  53. package/dist/random/index.js +1 -3
  54. package/dist/recommend/index.d.ts +1 -1
  55. package/dist/recommend/index.js +2 -4
  56. package/dist/schemas/index.d.ts +18 -6
  57. package/dist/schemas/index.js +7 -6
  58. package/dist/spatial/index.d.ts +2 -1
  59. package/dist/spatial/index.js +1 -2
  60. package/dist/storage/index.d.ts +4 -2
  61. package/dist/storage/index.js +1 -2
  62. package/dist/{themeLibrary-B72m0W1y.d.ts → themeLibrary-BUTWjufL.d.ts} +1 -1
  63. package/dist/timing/index.js +2 -4
  64. package/dist/transform/index.d.ts +3 -3
  65. package/dist/transform/index.js +6 -7
  66. package/dist/{types-C4kiRn_k.d.ts → types-8QjefM9J.d.ts} +38 -2
  67. package/dist/{types-BwMPl2CB.d.ts → types-CUNc9biN.d.ts} +24 -1
  68. package/dist/versions/index.d.ts +14 -11
  69. package/dist/versions/index.js +2 -3
  70. package/package.json +8 -3
  71. package/dist/chunk-2UQOHYE2.js.map +0 -1
  72. package/dist/chunk-3E5F2XMR.js.map +0 -1
  73. package/dist/chunk-4X3JQXNM.js.map +0 -1
  74. package/dist/chunk-5DKBFXPY.js.map +0 -1
  75. package/dist/chunk-5J4HKRJF.js.map +0 -1
  76. package/dist/chunk-5UYI3RJB.js.map +0 -1
  77. package/dist/chunk-66QO7XFB.js.map +0 -1
  78. package/dist/chunk-AMIR72JP.js +0 -380
  79. package/dist/chunk-AMIR72JP.js.map +0 -1
  80. package/dist/chunk-DBS6RIFL.js.map +0 -1
  81. package/dist/chunk-DNJKBAI7.js +0 -1
  82. package/dist/chunk-DNJKBAI7.js.map +0 -1
  83. package/dist/chunk-ET53IIEP.js +0 -1
  84. package/dist/chunk-ET53IIEP.js.map +0 -1
  85. package/dist/chunk-FVTQSNR7.js.map +0 -1
  86. package/dist/chunk-GZY66SDN.js.map +0 -1
  87. package/dist/chunk-ILWDXLUK.js.map +0 -1
  88. package/dist/chunk-JHZWYRSW.js.map +0 -1
  89. package/dist/chunk-JI77MGAK.js.map +0 -1
  90. package/dist/chunk-JOQYPRDZ.js.map +0 -1
  91. package/dist/chunk-OTKVFVL6.js.map +0 -1
  92. package/dist/chunk-PGGGKYWG.js +0 -1
  93. package/dist/chunk-PGGGKYWG.js.map +0 -1
  94. package/dist/chunk-Q7LROV2H.js.map +0 -1
  95. package/dist/chunk-QE7TWGVT.js.map +0 -1
  96. package/dist/chunk-QUUPYOSP.js.map +0 -1
  97. package/dist/chunk-R2GC6RLD.js +0 -344
  98. package/dist/chunk-R2GC6RLD.js.map +0 -1
  99. package/dist/chunk-R2YZTCLO.js.map +0 -1
  100. package/dist/chunk-S7A5D7ZJ.js +0 -174
  101. package/dist/chunk-S7A5D7ZJ.js.map +0 -1
  102. package/dist/chunk-TUWMK62B.js.map +0 -1
  103. package/dist/chunk-V543AI2F.js +0 -1
  104. package/dist/chunk-V543AI2F.js.map +0 -1
  105. package/dist/chunk-VR7UPJ7C.js.map +0 -1
  106. package/dist/chunk-VWCJ2WXC.js.map +0 -1
  107. package/dist/chunk-VYFRI7R6.js.map +0 -1
  108. package/dist/chunk-XNLB57UD.js.map +0 -1
  109. package/dist/chunk-ZLQKNOZQ.js +0 -1
  110. package/dist/chunk-ZLQKNOZQ.js.map +0 -1
  111. package/dist/doc/index.js.map +0 -1
  112. package/dist/generate/index.js.map +0 -1
  113. package/dist/icons/index.js.map +0 -1
  114. package/dist/icons/inlineIconMarker.js.map +0 -1
  115. package/dist/imageEdit/index.js.map +0 -1
  116. package/dist/index.js.map +0 -1
  117. package/dist/jsonForm/index.js.map +0 -1
  118. package/dist/markdown/index.js.map +0 -1
  119. package/dist/narration/index.js.map +0 -1
  120. package/dist/random/index.js.map +0 -1
  121. package/dist/recommend/index.js.map +0 -1
  122. package/dist/schemas/index.js.map +0 -1
  123. package/dist/spatial/index.js.map +0 -1
  124. package/dist/storage/index.js.map +0 -1
  125. package/dist/timing/index.js.map +0 -1
  126. package/dist/transform/index.js.map +0 -1
  127. package/dist/versions/index.js.map +0 -1
  128. package/src/__tests__/animationUtils.test.ts +0 -117
  129. package/src/__tests__/annotationCoercion.test.ts +0 -243
  130. package/src/__tests__/applyNarrationTiming.test.ts +0 -190
  131. package/src/__tests__/applyRenderStyle.test.ts +0 -146
  132. package/src/__tests__/asciiDiagramBattle.test.ts +0 -246
  133. package/src/__tests__/asciiDiagramDetect.test.ts +0 -162
  134. package/src/__tests__/asciiDiagramMapping.test.ts +0 -38
  135. package/src/__tests__/asciiDiagramParse.test.ts +0 -233
  136. package/src/__tests__/asciiDiagramPipeline.test.ts +0 -273
  137. package/src/__tests__/asciiDiagramRender.test.ts +0 -162
  138. package/src/__tests__/asciiDiagramRepair.test.ts +0 -84
  139. package/src/__tests__/asciiTimelineDetect.test.ts +0 -157
  140. package/src/__tests__/asciiTimelineParse.test.ts +0 -205
  141. package/src/__tests__/asciiTimelinePipeline.test.ts +0 -349
  142. package/src/__tests__/asciiTimelineRender.test.ts +0 -376
  143. package/src/__tests__/atmosphereLayers.test.ts +0 -108
  144. package/src/__tests__/attrTokens.test.ts +0 -167
  145. package/src/__tests__/colorUtils.test.ts +0 -112
  146. package/src/__tests__/contentContainer.test.ts +0 -325
  147. package/src/__tests__/contentExtractor.test.ts +0 -243
  148. package/src/__tests__/coverBlock.test.ts +0 -310
  149. package/src/__tests__/customTemplateSample.test.ts +0 -144
  150. package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -221
  151. package/src/__tests__/customThemesFrontmatter.test.ts +0 -146
  152. package/src/__tests__/dataTable.test.ts +0 -145
  153. package/src/__tests__/diagramBlock.test.ts +0 -122
  154. package/src/__tests__/diagramLayout.test.ts +0 -134
  155. package/src/__tests__/diagramText.test.ts +0 -26
  156. package/src/__tests__/docToMarkdownMedia.test.ts +0 -83
  157. package/src/__tests__/drawing.test.ts +0 -109
  158. package/src/__tests__/drawingBlock.test.ts +0 -124
  159. package/src/__tests__/drawingLayout.test.ts +0 -171
  160. package/src/__tests__/fixtures/asciiDiagramBattle.ts +0 -512
  161. package/src/__tests__/fixtures/asciiDiagrams.ts +0 -287
  162. package/src/__tests__/fixtures/asciiTimelines.ts +0 -35
  163. package/src/__tests__/fixtures/treeviewFixtures.ts +0 -243
  164. package/src/__tests__/geohash.test.ts +0 -110
  165. package/src/__tests__/getLayers.test.ts +0 -243
  166. package/src/__tests__/getLayersFallback.test.ts +0 -103
  167. package/src/__tests__/haversine.test.ts +0 -63
  168. package/src/__tests__/iconResolve.test.ts +0 -122
  169. package/src/__tests__/imageEditExportSvg.test.ts +0 -70
  170. package/src/__tests__/imageEditState.test.ts +0 -74
  171. package/src/__tests__/imageEditVersions.test.ts +0 -243
  172. package/src/__tests__/inferDocumentTitle.test.ts +0 -50
  173. package/src/__tests__/inlineIconMarker.test.ts +0 -36
  174. package/src/__tests__/inputDescriptors.test.ts +0 -162
  175. package/src/__tests__/jsonForm.chooseControl.test.ts +0 -86
  176. package/src/__tests__/jsonForm.evaluateWhen.test.ts +0 -59
  177. package/src/__tests__/jsonForm.inferSchema.test.ts +0 -25
  178. package/src/__tests__/jsonForm.pointer.test.ts +0 -149
  179. package/src/__tests__/jsonForm.tokens.test.ts +0 -84
  180. package/src/__tests__/layoutBlock.test.ts +0 -83
  181. package/src/__tests__/layoutLayout.test.ts +0 -169
  182. package/src/__tests__/localForageAdapter.test.ts +0 -155
  183. package/src/__tests__/majorApiTypes.test.ts +0 -18
  184. package/src/__tests__/markdown.test.ts +0 -1009
  185. package/src/__tests__/markdownIcons.test.ts +0 -104
  186. package/src/__tests__/markdownSanitize.test.ts +0 -81
  187. package/src/__tests__/markdownToDoc.test.ts +0 -957
  188. package/src/__tests__/matchFontFamily.test.ts +0 -114
  189. package/src/__tests__/materializeBlockLayers.test.ts +0 -167
  190. package/src/__tests__/materializePageSections.test.ts +0 -404
  191. package/src/__tests__/materializeTestUtils.ts +0 -17
  192. package/src/__tests__/mediaAnnotations.test.ts +0 -91
  193. package/src/__tests__/mediaSchedule.test.ts +0 -118
  194. package/src/__tests__/narrationAlign.test.ts +0 -150
  195. package/src/__tests__/narrationFeatures.test.ts +0 -71
  196. package/src/__tests__/narrationNuclei.test.ts +0 -45
  197. package/src/__tests__/narrationPacing.test.ts +0 -189
  198. package/src/__tests__/narrationScript.test.ts +0 -149
  199. package/src/__tests__/narrationSessionRepro.test.ts +0 -62
  200. package/src/__tests__/narrationSidecar.test.ts +0 -88
  201. package/src/__tests__/narrationSyllables.test.ts +0 -65
  202. package/src/__tests__/narrationTestSignals.ts +0 -167
  203. package/src/__tests__/narrationVad.test.ts +0 -66
  204. package/src/__tests__/pageStyle.test.ts +0 -258
  205. package/src/__tests__/pandocAttrParse.test.ts +0 -187
  206. package/src/__tests__/recommendTemplates.test.ts +0 -183
  207. package/src/__tests__/resolveDocTheme.test.ts +0 -69
  208. package/src/__tests__/rootExports.test.ts +0 -61
  209. package/src/__tests__/scopedContentContainer.test.ts +0 -109
  210. package/src/__tests__/seededRandom.test.ts +0 -142
  211. package/src/__tests__/shapeGeometry.test.ts +0 -138
  212. package/src/__tests__/shapeVocabulary.test.ts +0 -133
  213. package/src/__tests__/storage.test.ts +0 -60
  214. package/src/__tests__/structuredData.test.ts +0 -249
  215. package/src/__tests__/surface.test.ts +0 -68
  216. package/src/__tests__/templateAnnotationParse.test.ts +0 -173
  217. package/src/__tests__/templateInputs.test.ts +0 -69
  218. package/src/__tests__/templateMetadata.test.ts +0 -32
  219. package/src/__tests__/templates.test.ts +0 -710
  220. package/src/__tests__/themeCompile.test.ts +0 -225
  221. package/src/__tests__/themeValidator.test.ts +0 -131
  222. package/src/__tests__/timing.test.ts +0 -167
  223. package/src/__tests__/transformProvenance.test.ts +0 -160
  224. package/src/__tests__/transformV2.test.ts +0 -163
  225. package/src/__tests__/transitionNormalize.test.ts +0 -61
  226. package/src/__tests__/treeviewBattle.test.ts +0 -76
  227. package/src/__tests__/treeviewDetect.test.ts +0 -168
  228. package/src/__tests__/treeviewParse.test.ts +0 -118
  229. package/src/__tests__/treeviewPipeline.test.ts +0 -183
  230. package/src/__tests__/treeviewRender.test.ts +0 -91
  231. package/src/__tests__/validateDoc.test.ts +0 -260
  232. package/src/__tests__/versions.test.ts +0 -459
  233. package/src/doc/annotationBlocks.ts +0 -117
  234. package/src/doc/applyNarrationTiming.ts +0 -244
  235. package/src/doc/asciiDiagram/chars.ts +0 -210
  236. package/src/doc/asciiDiagram/detect.ts +0 -175
  237. package/src/doc/asciiDiagram/index.ts +0 -38
  238. package/src/doc/asciiDiagram/mapping.ts +0 -225
  239. package/src/doc/asciiDiagram/parse.ts +0 -1095
  240. package/src/doc/asciiDiagram/render.ts +0 -963
  241. package/src/doc/asciiDiagram/repair.ts +0 -400
  242. package/src/doc/asciiDiagram/types.ts +0 -65
  243. package/src/doc/asciiTimeline/detect.ts +0 -138
  244. package/src/doc/asciiTimeline/index.ts +0 -26
  245. package/src/doc/asciiTimeline/mapping.ts +0 -43
  246. package/src/doc/asciiTimeline/parse.ts +0 -870
  247. package/src/doc/asciiTimeline/render.ts +0 -427
  248. package/src/doc/asciiTimeline/types.ts +0 -73
  249. package/src/doc/asciiTimeline/wrappedFlow.ts +0 -427
  250. package/src/doc/audioMapping.ts +0 -442
  251. package/src/doc/customTemplatesFrontmatter.ts +0 -273
  252. package/src/doc/customThemesFrontmatter.ts +0 -95
  253. package/src/doc/docToMarkdown.ts +0 -284
  254. package/src/doc/index.ts +0 -161
  255. package/src/doc/markdownToDoc.ts +0 -1054
  256. package/src/doc/materializeBlockLayers.ts +0 -465
  257. package/src/doc/mediaAnnotations.ts +0 -120
  258. package/src/doc/page/PageSection.ts +0 -174
  259. package/src/doc/page/materializePageSection.ts +0 -616
  260. package/src/doc/page/resolvePageBlock.ts +0 -108
  261. package/src/doc/page/sectionExtractors.ts +0 -466
  262. package/src/doc/pageCss.ts +0 -628
  263. package/src/doc/resolveDocTheme.ts +0 -56
  264. package/src/doc/standaloneAnnotation.ts +0 -58
  265. package/src/doc/structuredData.ts +0 -301
  266. package/src/doc/templateInputs.ts +0 -424
  267. package/src/doc/templates/__tests__/customTemplate.test.ts +0 -170
  268. package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +0 -124
  269. package/src/doc/templates/__tests__/listBlock.test.ts +0 -64
  270. package/src/doc/templates/accentImage.ts +0 -362
  271. package/src/doc/templates/captionUtils.ts +0 -56
  272. package/src/doc/templates/comparisonBar.ts +0 -173
  273. package/src/doc/templates/coverBlock.ts +0 -255
  274. package/src/doc/templates/customTemplate.ts +0 -51
  275. package/src/doc/templates/dataTable.ts +0 -102
  276. package/src/doc/templates/dateEvent.ts +0 -147
  277. package/src/doc/templates/definitionCard.ts +0 -140
  278. package/src/doc/templates/diagramBlock.ts +0 -403
  279. package/src/doc/templates/diagramLayout.ts +0 -159
  280. package/src/doc/templates/drawingBlock.ts +0 -325
  281. package/src/doc/templates/drawingLayout.ts +0 -539
  282. package/src/doc/templates/factCard.ts +0 -146
  283. package/src/doc/templates/fallbackBlock.ts +0 -123
  284. package/src/doc/templates/featureBlock.ts +0 -209
  285. package/src/doc/templates/fullBleedQuote.ts +0 -83
  286. package/src/doc/templates/imageWithCaption.ts +0 -186
  287. package/src/doc/templates/index.ts +0 -642
  288. package/src/doc/templates/inputDescriptors.ts +0 -451
  289. package/src/doc/templates/layoutBlock.ts +0 -43
  290. package/src/doc/templates/layoutLayout.ts +0 -243
  291. package/src/doc/templates/listBlock.ts +0 -207
  292. package/src/doc/templates/mapBlock.ts +0 -138
  293. package/src/doc/templates/metadata.ts +0 -130
  294. package/src/doc/templates/persistentLayers.ts +0 -526
  295. package/src/doc/templates/photoGrid.ts +0 -190
  296. package/src/doc/templates/pullQuote.ts +0 -141
  297. package/src/doc/templates/quoteBlock.ts +0 -141
  298. package/src/doc/templates/registry.ts +0 -88
  299. package/src/doc/templates/sectionHeader.ts +0 -120
  300. package/src/doc/templates/statHighlight.ts +0 -146
  301. package/src/doc/templates/templateNames.ts +0 -22
  302. package/src/doc/templates/timelineBlock.ts +0 -613
  303. package/src/doc/templates/titleBlock.ts +0 -150
  304. package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +0 -487
  305. package/src/doc/templates/tokens/resolveTokens.ts +0 -453
  306. package/src/doc/templates/treeBlock.ts +0 -131
  307. package/src/doc/templates/twoColumn.ts +0 -263
  308. package/src/doc/templates/videoPullQuote.ts +0 -142
  309. package/src/doc/templates/videoWithCaption.ts +0 -135
  310. package/src/doc/treeview/chars.ts +0 -72
  311. package/src/doc/treeview/detect.ts +0 -145
  312. package/src/doc/treeview/index.ts +0 -30
  313. package/src/doc/treeview/mapping.ts +0 -95
  314. package/src/doc/treeview/parse.ts +0 -201
  315. package/src/doc/treeview/render.ts +0 -41
  316. package/src/doc/treeview/types.ts +0 -43
  317. package/src/doc/utils/animationUtils.ts +0 -399
  318. package/src/doc/utils/applyRenderStyle.ts +0 -106
  319. package/src/doc/utils/diagramText.ts +0 -78
  320. package/src/doc/utils/imageTreatment.ts +0 -70
  321. package/src/doc/utils/nearest.ts +0 -59
  322. package/src/doc/utils/shapeGeometry.ts +0 -614
  323. package/src/doc/utils/themeUtils.ts +0 -243
  324. package/src/doc/validate.ts +0 -575
  325. package/src/generate/contentExtractor.ts +0 -921
  326. package/src/generate/index.ts +0 -18
  327. package/src/generate/templateMapper.ts +0 -177
  328. package/src/icons/iconData.ts +0 -31
  329. package/src/icons/index.ts +0 -26
  330. package/src/icons/inlineIconMarker.ts +0 -73
  331. package/src/icons/resolve.ts +0 -139
  332. package/src/imageEdit/ImageEditVersionManager.ts +0 -73
  333. package/src/imageEdit/export.ts +0 -410
  334. package/src/imageEdit/index.ts +0 -72
  335. package/src/imageEdit/persistence.ts +0 -113
  336. package/src/imageEdit/state.ts +0 -112
  337. package/src/imageEdit/versionPaths.ts +0 -44
  338. package/src/imageEdit/versions.ts +0 -152
  339. package/src/index.ts +0 -15
  340. package/src/internal/immutable.ts +0 -58
  341. package/src/jsonForm/chooseControl.ts +0 -88
  342. package/src/jsonForm/evaluateWhen.ts +0 -59
  343. package/src/jsonForm/index.ts +0 -32
  344. package/src/jsonForm/inferSchema.ts +0 -25
  345. package/src/jsonForm/pointer.ts +0 -154
  346. package/src/jsonForm/tokens.ts +0 -78
  347. package/src/jsonForm/types.ts +0 -167
  348. package/src/markdown/annotationCoercion.ts +0 -295
  349. package/src/markdown/attrTokens.ts +0 -243
  350. package/src/markdown/convert.ts +0 -1353
  351. package/src/markdown/htmlParse.ts +0 -212
  352. package/src/markdown/index.ts +0 -152
  353. package/src/markdown/parse.ts +0 -103
  354. package/src/markdown/sanitize.ts +0 -318
  355. package/src/markdown/stringify.ts +0 -207
  356. package/src/markdown/types.ts +0 -710
  357. package/src/markdown/utils.ts +0 -459
  358. package/src/narration/align.ts +0 -514
  359. package/src/narration/features.ts +0 -231
  360. package/src/narration/index.ts +0 -86
  361. package/src/narration/nuclei.ts +0 -118
  362. package/src/narration/pacing.ts +0 -211
  363. package/src/narration/script.ts +0 -239
  364. package/src/narration/session.ts +0 -100
  365. package/src/narration/sidecar.ts +0 -187
  366. package/src/narration/syllables.ts +0 -85
  367. package/src/narration/trace.ts +0 -50
  368. package/src/narration/types.ts +0 -299
  369. package/src/narration/vad.ts +0 -131
  370. package/src/ngeohash.d.ts +0 -11
  371. package/src/random/SeededRandom.ts +0 -127
  372. package/src/random/index.ts +0 -1
  373. package/src/recommend/index.ts +0 -16
  374. package/src/recommend/numberHighlight.ts +0 -25
  375. package/src/recommend/templates.ts +0 -393
  376. package/src/schemas/BlockTemplates.ts +0 -1046
  377. package/src/schemas/CustomTemplates.ts +0 -126
  378. package/src/schemas/Doc.ts +0 -1073
  379. package/src/schemas/ImageEditDoc.ts +0 -102
  380. package/src/schemas/LayoutStrategy.ts +0 -178
  381. package/src/schemas/Media.ts +0 -179
  382. package/src/schemas/MediaProvider.ts +0 -70
  383. package/src/schemas/PageStyle.ts +0 -213
  384. package/src/schemas/Theme.ts +0 -413
  385. package/src/schemas/Transitions.ts +0 -224
  386. package/src/schemas/Types.ts +0 -15
  387. package/src/schemas/Viewport.ts +0 -91
  388. package/src/schemas/colorUtils.ts +0 -219
  389. package/src/schemas/fontStacks.ts +0 -339
  390. package/src/schemas/index.ts +0 -31
  391. package/src/schemas/pageStyleDefaults.ts +0 -204
  392. package/src/schemas/themeCompile.ts +0 -244
  393. package/src/schemas/themeConstants.ts +0 -2
  394. package/src/schemas/themeLibrary.ts +0 -60
  395. package/src/schemas/themeValidator.ts +0 -609
  396. package/src/schemas/themes/bold.json +0 -77
  397. package/src/schemas/themes/cinematic.json +0 -143
  398. package/src/schemas/themes/documentary.json +0 -125
  399. package/src/schemas/themes/gezellig.json +0 -123
  400. package/src/schemas/themes/index.ts +0 -53
  401. package/src/schemas/themes/magazine.json +0 -126
  402. package/src/schemas/themes/minimalist.json +0 -74
  403. package/src/schemas/themes/morning-light.json +0 -117
  404. package/src/schemas/themes/standard-dark.json +0 -109
  405. package/src/schemas/themes/standard.json +0 -98
  406. package/src/schemas/themes/tech-dark.json +0 -143
  407. package/src/schemas/themes/warm-earth.json +0 -74
  408. package/src/spatial/Geohash.ts +0 -196
  409. package/src/spatial/Haversine.ts +0 -59
  410. package/src/spatial/index.ts +0 -2
  411. package/src/storage/ContentContainer.ts +0 -220
  412. package/src/storage/LocalForageAdapter.ts +0 -103
  413. package/src/storage/LocalStorageAdapter.ts +0 -57
  414. package/src/storage/MediaProviderFromContainer.ts +0 -92
  415. package/src/storage/MemoryStorageAdapter.ts +0 -37
  416. package/src/storage/ScopedContentContainer.ts +0 -143
  417. package/src/storage/Storage.ts +0 -28
  418. package/src/storage/index.ts +0 -9
  419. package/src/timing/index.ts +0 -17
  420. package/src/timing/narrationTiming.ts +0 -220
  421. package/src/timing/readingTime.ts +0 -94
  422. package/src/transform/applyTransform.ts +0 -122
  423. package/src/transform/blockAnalyzer.ts +0 -181
  424. package/src/transform/index.ts +0 -23
  425. package/src/transform/registry.ts +0 -217
  426. package/src/transform/styles/dataDriven.ts +0 -18
  427. package/src/transform/styles/documentary.ts +0 -18
  428. package/src/transform/styles/index.ts +0 -5
  429. package/src/transform/styles/magazine.ts +0 -19
  430. package/src/transform/styles/minimal.ts +0 -18
  431. package/src/transform/styles/narrative.ts +0 -19
  432. package/src/transform/templateSelector.ts +0 -389
  433. package/src/transform/timingAllocator.ts +0 -257
  434. package/src/transform/types.ts +0 -158
  435. package/src/versions/DocumentVersionManager.ts +0 -70
  436. package/src/versions/gitignore.ts +0 -34
  437. package/src/versions/index.ts +0 -56
  438. package/src/versions/operations.ts +0 -144
  439. package/src/versions/paths.ts +0 -51
  440. package/src/versions/snapshotStore.ts +0 -202
  441. package/src/versions/timestamp.ts +0 -48
  442. package/src/versions/types.ts +0 -93
@@ -1,1073 +0,0 @@
1
- /**
2
- * Doc Schema
3
- *
4
- * Defines the JSON format for AI-scriptable visual docs that accompany
5
- * audio narration. A Doc describes a sequence of animated blocks
6
- * with text overlays, images, and transitions synchronized to audio.
7
- *
8
- * The format is designed to be:
9
- * 1. AI-generatable - Claude can create scripts from article content
10
- * 2. Browser-renderable - SVG + CSS animations (ES2015 compatible)
11
- * 3. Video-exportable - Frame-by-frame capture via Playwright
12
- *
13
- * Timing: Blocks are timed to match narration audio segments. Each article
14
- * has 3-6 MP3 files (intro + sections), and blocks are grouped by segment.
15
- */
16
-
17
- import type { Transition } from './Transitions.js';
18
- export type { Transition, TransitionType, TransitionDirection } from './Transitions.js';
19
-
20
- // ============================================
21
- // Core Types
22
- // ============================================
23
-
24
- /**
25
- * A directed connection from one block to another.
26
- *
27
- * Populated from a heading's Pandoc-style `{connectsTo=…}` attribute
28
- * (e.g. `## Step 1 {#step1 connectsTo=foo:flow,bar}`). Each item is
29
- * `target` or `target:type`. Used by diagram-style layouts that draw
30
- * edges between blocks.
31
- */
32
- export interface BlockConnection {
33
- /** Target block id (matches another block's `id`). */
34
- target: string;
35
- /** Optional connection type/label (e.g., "flow", "requires"). */
36
- type?: string;
37
- }
38
-
39
- /**
40
- * Configuration for the Start/resting block shown before playback begins.
41
- */
42
- export interface StartBlockConfig {
43
- /** Hero image path (relative to article media). When omitted, a theme-driven background is used. */
44
- heroSrc?: string;
45
- /** Alt text for the hero image */
46
- heroAlt?: string;
47
- /** Title to display over the hero */
48
- title: string;
49
- /** Optional subtitle */
50
- subtitle?: string;
51
- /** Ambient motion for the hero image */
52
- ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';
53
- /** Photo credit / artist name for the hero image */
54
- heroCredit?: string;
55
- /** License identifier for the hero image */
56
- heroLicense?: string;
57
- }
58
-
59
- /**
60
- * A structural problem detected while converting or validating a document.
61
- *
62
- * Diagnostics ride on `Doc.diagnostics` so any consumer — the editor, the
63
- * CLI `validate` command, or an agent re-parsing its own output — gets the
64
- * same feedback without watching the console. Conversion never throws for
65
- * content problems; it degrades gracefully and records a diagnostic.
66
- */
67
- export interface DocDiagnostic {
68
- /** `error` = the author's intent could not be honored (e.g. unparseable
69
- * data fence); `warning` = something looks wrong but rendering proceeds
70
- * with a fallback (e.g. unknown template name); `info` = nothing is
71
- * broken, but the author may want to know (e.g. a redundant annotation). */
72
- severity: 'error' | 'warning' | 'info';
73
- /** Stable machine-readable code (e.g. `unknown-template`, `duplicate-id`,
74
- * `unresolved-connection`, `data-fence-parse`, `missing-asset`). */
75
- code: string;
76
- /** Human-readable description, including a suggestion when one exists. */
77
- message: string;
78
- /** Id of the block the problem belongs to, when attributable. */
79
- blockId?: string;
80
- /** 1-based line number in the markdown source, when known. */
81
- line?: number;
82
- }
83
-
84
- /**
85
- * A complete visual doc for an article.
86
- */
87
- export interface Doc {
88
- /** Article ID this doc belongs to */
89
- articleId: string;
90
-
91
- /** Total duration in seconds (sum of all audio segments) */
92
- duration: number;
93
-
94
- /** Ordered list of blocks */
95
- blocks: Block[];
96
-
97
- /** Audio track configuration */
98
- audio: AudioTrack;
99
-
100
- /** Caption track for closed captions (generated by postprocess-doc) */
101
- captions?: CaptionTrack;
102
-
103
- /**
104
- * Start/resting block shown before playback begins.
105
- * Displays hero image with title - acts as a "poster" for the doc.
106
- * The player shows this until the user starts playback.
107
- */
108
- startBlock?: StartBlockConfig;
109
-
110
- /**
111
- * Persistent layers rendered on every block (behind and/or on top of content).
112
- * Used for consistent branding overlays, background gradients, etc.
113
- */
114
- persistentLayers?: import('./BlockTemplates.js').PersistentLayerConfig;
115
-
116
- /**
117
- * Optional theme identifier. Resolved at render time via `resolveTheme()`.
118
- * When omitted, the renderer uses the default theme ('documentary').
119
- */
120
- themeId?: string;
121
-
122
- /** Optional metadata */
123
- meta?: {
124
- generatedAt?: string;
125
- generatedBy?: string;
126
- version?: number;
127
- };
128
-
129
- /**
130
- * YAML frontmatter from the source markdown.
131
- * Carries rendering hints like `document-render-as` and custom metadata.
132
- */
133
- frontmatter?: Record<string, unknown>;
134
-
135
- /**
136
- * User-defined block templates inlined into this doc.
137
- *
138
- * Populated from the markdown frontmatter key
139
- * `squisq-custom-templates`. The template-expansion pipeline
140
- * (`expandDocBlocks` in `doc/templates/index.ts`) merges these into
141
- * the registry before walking blocks, so a heading annotated
142
- * `{[myhero]}` resolves against a doc-defined template named `myhero`.
143
- *
144
- * Library templates (stored in localStorage on the editor side) are
145
- * NOT auto-loaded here — applying a library template to a block
146
- * copies its definition into this list so the doc remains
147
- * self-sufficient for SSR and export.
148
- */
149
- customTemplates?: import('./CustomTemplates.js').CustomTemplateDefinition[];
150
-
151
- /**
152
- * User-defined themes inlined into this doc.
153
- *
154
- * The theme analog of {@link Doc.customTemplates}. Populated from the
155
- * markdown frontmatter key `squisq-custom-themes`. Exactly one is active
156
- * at a time — selected by id via `squisq-theme` / {@link Doc.themeId},
157
- * the doc-level counterpart of a block's `{[name]}` template annotation —
158
- * but the payload is a list so a doc can carry a small catalog and stay
159
- * self-sufficient for SSR / export. `resolveThemeForDoc(doc, id)` resolves
160
- * against this list first (pure, doc-scoped) before built-ins, mirroring
161
- * how `buildRegistry` resolves custom templates.
162
- */
163
- customThemes?: import('./Theme.js').Theme[];
164
-
165
- /**
166
- * Structural problems found while building this doc (unknown templates,
167
- * unparseable data fences, duplicate ids, unresolved connections, …).
168
- * Populated by `markdownToDoc()`; extended by `validateMarkdownDoc()`.
169
- * Absent when the document is clean.
170
- */
171
- diagnostics?: DocDiagnostic[];
172
-
173
- /**
174
- * Document-spanning timed media (e.g. a full-length narration MP3/MP4),
175
- * authored as a media annotation in the preamble (before the first
176
- * heading) with `anchor=document`. Each clip is timed from the document
177
- * start and may play across every block. See `resolveMediaSchedule`.
178
- */
179
- documentMedia?: import('./Media.js').MediaClip[];
180
- }
181
-
182
- /**
183
- * A single block in the doc.
184
- *
185
- * Blocks can be flat (audio-synced timeline) or nested (markdown-driven hierarchy).
186
- * When derived from markdown, a block corresponds to a heading section:
187
- * - `sourceHeading` references the original MarkdownHeading node
188
- * - `contents` holds the body markdown between this heading and the next
189
- * - `children` holds sub-heading blocks (e.g., H2s under an H1)
190
- *
191
- * Four adjacent fields carry template information — do not confuse them:
192
- * - `template` — the *resolved* template id this block renders with.
193
- * - `templateOverrides` — raw `{[…]}` inline params (always strings).
194
- * - `templateData` — structured inputs from a data fence / GFM table
195
- * (parsed types, not strings).
196
- * - `sourceAnnotation.template` — the raw *requested* template name for a
197
- * standalone-annotation block (before alias resolution).
198
- * Merge order at render time: template defaults → `templateData` →
199
- * `templateOverrides`.
200
- */
201
- export interface Block {
202
- /** Unique identifier for this block.
203
- * Defaults to a slug derived from the heading text. May be overridden by
204
- * a Pandoc-style `{#custom-id}` attribute on the heading. */
205
- id: string;
206
-
207
- /** When this block appears (seconds from start).
208
- * Overridden by a heading attribute `startTime=…` when present. */
209
- startTime: number;
210
-
211
- /** How long this block is visible (seconds).
212
- * Overridden by a heading attribute `duration=…` when present. */
213
- duration: number;
214
-
215
- /** Which audio segment this block belongs to (0-indexed) */
216
- audioSegment: number;
217
-
218
- /**
219
- * Transform provenance: the source block id this block was derived
220
- * from (see `BaseTemplateBlock.sourceBlockId`). Present on blocks a
221
- * transform produced; lets a persisted transformed Doc keep its typed
222
- * link back to the source content.
223
- */
224
- sourceBlockId?: string;
225
- /** All source block ids when this block summarizes several. */
226
- sourceBlockIds?: string[];
227
- /** Char offset of the extraction inside the source block's plain text. */
228
- sourceCharOffset?: number;
229
-
230
- /**
231
- * Pre-computed visual layers, rendered back-to-front.
232
- *
233
- * Optional — template-derived blocks typically omit this and compute
234
- * layers on demand via `materializeBlockLayers()` from `@bendyline/squisq/doc`.
235
- * Raw blocks (e.g., hand-crafted by AI) may provide layers directly.
236
- */
237
- layers?: Layer[];
238
-
239
- /** Entry transition from previous block */
240
- transition?: Transition;
241
-
242
- /** Resolved template id this block renders with (see the quartet note above). */
243
- template?: string;
244
-
245
- /**
246
- * True when `template` was chosen by content-aware auto-picking
247
- * (`markdownToDoc`'s `autoTemplates`) rather than authored. Ephemeral:
248
- * `docToMarkdown` does not materialize auto-picked templates as heading
249
- * annotations, keeping the markdown round-trip lossless.
250
- */
251
- autoTemplate?: boolean;
252
-
253
- /**
254
- * True when this block was produced from a *standalone* `{[templateName …]}`
255
- * annotation paragraph in another block's body (rather than from a heading).
256
- * Such blocks have no `sourceHeading`; `docToMarkdown` re-emits their
257
- * annotation as a synthesized paragraph before their `contents` so the
258
- * markdown round-trips. See `annotationBlocks.ts`.
259
- *
260
- * Presence-marker: only ever `true` (never `false`). Test with
261
- * `block.standaloneAnnotation` presence, not as a boolean toggle.
262
- */
263
- standaloneAnnotation?: true;
264
-
265
- /**
266
- * The annotation a standalone block was built from — the raw (un-resolved)
267
- * template name and its params, in author order. Round-tripped by
268
- * `docToMarkdown` (via `serializeAnnotation`) and read by validation as the
269
- * raw requested template name (symmetric with
270
- * `sourceHeading.templateAnnotation`). Present only when
271
- * `standaloneAnnotation` is true.
272
- */
273
- sourceAnnotation?: { template?: string; params?: Record<string, string> };
274
-
275
- /**
276
- * Display title for template rendering.
277
- * Extracted from the sourceHeading when the block is created by markdownToDoc().
278
- * Templates like sectionHeader and titleBlock read this for their title layer.
279
- */
280
- title?: string;
281
-
282
- // ── Markdown-driven hierarchy (optional) ──
283
-
284
- /**
285
- * Nested sub-blocks (heading hierarchy).
286
- * When a doc is derived from markdown, sub-headings within this
287
- * heading's section become child blocks. For example, H2 blocks
288
- * under an H1 block appear here.
289
- */
290
- children?: Block[];
291
-
292
- /**
293
- * Markdown body content for this block's section.
294
- * Contains the block-level markdown nodes (paragraphs, lists, code,
295
- * blockquotes, etc.) that appear between this heading and the next
296
- * heading or sub-heading. Empty for pure structural blocks.
297
- */
298
- contents?: import('../markdown/types.js').MarkdownBlockNode[];
299
-
300
- /**
301
- * Reference to the MarkdownHeading node that created this block.
302
- * Present when the block was derived from markdown via markdownToDoc().
303
- * Enables round-tripping back to markdown and provides heading depth.
304
- * Absent for the preamble block (content before the first heading).
305
- */
306
- sourceHeading?: import('../markdown/types.js').MarkdownHeading;
307
-
308
- /**
309
- * Template overrides extracted from a heading's `{[templateName key=value]}`
310
- * annotation. Only carries template-specific params (e.g. `colorScheme=blue`).
311
- * Block-level metadata lives in `x` / `y` / `connectsTo` / `metadata` and is
312
- * sourced from the Pandoc-style `{#id .class key=value}` attribute block instead.
313
- */
314
- templateOverrides?: Record<string, string>;
315
-
316
- /**
317
- * Structured template inputs sourced from the block's body content:
318
- * a ```json data / ```yaml data fence under the heading, or — for the
319
- * `dataTable` template — the first GFM table in the section. Unlike
320
- * `templateOverrides` (always strings), values here keep their parsed
321
- * types (arrays, numbers, nested objects). Merge order at render time:
322
- * template defaults → `templateData` → `templateOverrides`.
323
- */
324
- templateData?: Record<string, unknown>;
325
-
326
- // ── Block-level metadata from Pandoc-style `{#id .class key=value}` ──
327
-
328
- /**
329
- * X coordinate for diagram-style positioning (in author-defined units).
330
- * Sourced from a heading attribute `x=…`.
331
- */
332
- x?: number;
333
-
334
- /**
335
- * Y coordinate for diagram-style positioning (in author-defined units).
336
- * Sourced from a heading attribute `y=…`.
337
- */
338
- y?: number;
339
-
340
- /**
341
- * Outgoing connections to other blocks, by id. Sourced from a heading
342
- * attribute `connectsTo=target1,target2:type,target3`.
343
- */
344
- connectsTo?: BlockConnection[];
345
-
346
- /**
347
- * CSS-style class tokens from a heading's Pandoc attribute (e.g. `{.important .v2}`).
348
- * Parsed and stored; downstream consumers may use them for styling or filtering.
349
- */
350
- classes?: string[];
351
-
352
- /**
353
- * Free-form metadata for heading attribute keys outside the typed registry
354
- * (anything that isn't `x` / `y` / `connectsTo` / `startTime` / `duration`).
355
- * Values are raw strings exactly as authored.
356
- */
357
- metadata?: Record<string, string>;
358
-
359
- /**
360
- * Timed media clips attached to this block, authored as body-level
361
- * `{[audio …]}` / `{[video …]}` annotations. Each clip is timed relative
362
- * to this block's `startTime` (via `startAt`) and optionally spills past
363
- * the block's end. See `MediaClip` / `resolveMediaSchedule`.
364
- */
365
- media?: import('./Media.js').MediaClip[];
366
- }
367
-
368
- // ============================================
369
- // Layer Types
370
- // ============================================
371
-
372
- /**
373
- * A visual element within a block.
374
- * Layers are composited back-to-front (first layer is background).
375
- */
376
- export type Layer =
377
- | ImageLayer
378
- | TextLayer
379
- | ShapeLayer
380
- | PathLayer
381
- | MapLayer
382
- | VideoLayer
383
- | TableLayer
384
- | TreeLayer
385
- | MermaidLayer;
386
-
387
- interface BaseLayer {
388
- /** Unique identifier for this layer */
389
- id: string;
390
-
391
- /** Position and size */
392
- position: Position;
393
-
394
- /** Animation to apply */
395
- animation?: Animation;
396
- }
397
-
398
- /**
399
- * Photographic treatment applied to an image layer — a theme-level "grade"
400
- * so the same photo looks native in every theme. Rendered as CSS filter
401
- * functions, which behave identically in the browser player and headless
402
- * frame capture (video/still export).
403
- */
404
- export interface ImageTreatment {
405
- /**
406
- * mono: desaturate toward archival black & white.
407
- * duotone: single-hue tint (hue taken from `color`).
408
- * warm / cool: gentle temperature grade.
409
- */
410
- type: 'none' | 'mono' | 'duotone' | 'warm' | 'cool';
411
- /** Blend strength 0..1. Default 0.6. */
412
- strength?: number;
413
- /** Duotone tint color (themes default this to their primary). */
414
- color?: string;
415
- }
416
-
417
- /**
418
- * Image layer - displays an image with optional Ken Burns effect.
419
- */
420
- export interface ImageLayer extends BaseLayer {
421
- type: 'image';
422
- content: {
423
- /** Path to image file (relative to article media dir) */
424
- src: string;
425
- /** Alt text for accessibility */
426
- alt: string;
427
- /** How to fit image in bounds */
428
- fit?: 'cover' | 'contain' | 'fill';
429
- /** Photo credit / artist name */
430
- credit?: string;
431
- /** License identifier (e.g., 'CC BY-SA 4.0') */
432
- license?: string;
433
- /** Theme-derived photographic grade (see ImageTreatment). */
434
- treatment?: ImageTreatment;
435
- /** Gaussian blur radius in px (background/atmosphere imagery). */
436
- blur?: number;
437
- };
438
- }
439
-
440
- /**
441
- * Text layer - displays text with styling.
442
- */
443
- export interface TextLayer extends BaseLayer {
444
- type: 'text';
445
- content: {
446
- /**
447
- * Plain text (supports \n for line breaks). Source of truth for plain
448
- * consumers — PDF/markdown export, search, accessibility — and the SVG
449
- * `<text>` fallback. When `html` is set, this is its plain-text
450
- * projection and must be kept in sync.
451
- */
452
- text: string;
453
- /**
454
- * Optional sanitized **inline** HTML for rich formatting (bold/italic/
455
- * links, and — for layout textboxes — headings/lists). When present the
456
- * renderer draws it via `<foreignObject>` instead of SVG `<text>`. Treated
457
- * as untrusted and re-sanitized at render time. See `RichTextLayer` in
458
- * `@bendyline/squisq-react`.
459
- */
460
- html?: string;
461
- /** Text styling */
462
- style: TextStyle;
463
- };
464
- }
465
-
466
- /**
467
- * A two-stop linear gradient fill, shared by shape/path fills and text
468
- * backgrounds. When present it overrides the solid `fill` color.
469
- *
470
- * `angle` is in degrees: 0 = top→bottom, 90 = left→right, increasing
471
- * clockwise. Defaults to 0. Rendered as an SVG `<linearGradient>` in
472
- * objectBoundingBox units so it scales with the layer's box.
473
- */
474
- export interface LinearGradient {
475
- from: string;
476
- to: string;
477
- angle?: number;
478
- }
479
-
480
- /** Border line style, mapped to an SVG stroke-dasharray by the renderer. */
481
- export type BorderStyle = 'solid' | 'dashed' | 'dotted';
482
-
483
- /**
484
- * Shape layer - simple geometric shapes for visual accents.
485
- */
486
- /**
487
- * Repeating SVG pattern fill for a shape (dots, grid, diagonal lines).
488
- * Rendered as a native `<pattern>` def — fully vector and export-safe.
489
- */
490
- export interface ShapePattern {
491
- kind: 'dots' | 'grid' | 'diagonal';
492
- /** Pattern ink color. */
493
- color: string;
494
- /** Tile size in px (default 24). */
495
- size?: number;
496
- /** Pattern opacity 0–1 (default 1; tint via a translucent color or this). */
497
- opacity?: number;
498
- }
499
-
500
- /**
501
- * Procedural filter applied to a shape. `noise` renders static film grain
502
- * via SVG feTurbulence — deliberately not animated so frame capture and
503
- * the live player agree.
504
- */
505
- export interface ShapeFilter {
506
- type: 'noise';
507
- /** feTurbulence base frequency (default 0.8 — fine grain). */
508
- baseFrequency?: number;
509
- /** Grain opacity 0–1 (default 0.05). */
510
- opacity?: number;
511
- }
512
-
513
- export interface ShapeLayer extends BaseLayer {
514
- type: 'shape';
515
- content: {
516
- /** Shape type */
517
- shape: 'rect' | 'circle' | 'line';
518
- /** Fill color (CSS color or 'none') */
519
- fill?: string;
520
- /** Fill opacity 0–1 (applies to solid and gradient fills). */
521
- fillOpacity?: number;
522
- /** Gradient fill; overrides `fill` when set. */
523
- gradient?: LinearGradient;
524
- /** Repeating pattern fill; overrides `fill`/`gradient` when set. */
525
- pattern?: ShapePattern;
526
- /** Procedural filter (film grain). */
527
- filter?: ShapeFilter;
528
- /** Stroke color */
529
- stroke?: string;
530
- /** Stroke width in pixels */
531
- strokeWidth?: number;
532
- /** Border line style (solid/dashed/dotted). Default solid. */
533
- borderStyle?: BorderStyle;
534
- /** Corner radius for rect */
535
- borderRadius?: number;
536
- };
537
- }
538
-
539
- /**
540
- * End-of-line marker style for a path/connector endpoint.
541
- * `arrow` is a filled triangle (the classic arrowhead); `open` is a stroked
542
- * V; `diamond`/`circle`/`square` are filled glyphs; `none` draws nothing.
543
- */
544
- export type MarkerStyle = 'none' | 'arrow' | 'open' | 'diamond' | 'circle' | 'square';
545
-
546
- /**
547
- * Path layer - renders an SVG `<path>` for arbitrary curves, connectors,
548
- * arrows, or filled regions. Used by the diagram template for edges
549
- * between nodes, the drawing template for non-rect/circle/line shapes, and
550
- * available to any template that needs a custom geometry.
551
- *
552
- * The `position` field carries the layer's bounding box (so animations
553
- * and clipping work the same as for other layers), but the actual
554
- * geometry is encoded in the `d` attribute using absolute SVG path
555
- * coordinates relative to the block viewport.
556
- */
557
- export interface PathLayer extends BaseLayer {
558
- type: 'path';
559
- content: {
560
- /** SVG path `d` attribute (e.g. "M 10 10 L 90 90"). Absolute viewBox coords. */
561
- d: string;
562
- /**
563
- * Named shape kind (e.g. `'diamond'`, `'star'`, `'arrow-right'`) for
564
- * path layers that represent one of Squisq's standard shapes. When
565
- * set, the renderer re-derives `d` from the layer's `position` box
566
- * (resolved against the viewport) instead of using the stored `d` —
567
- * so the shape moves, resizes, and adapts to any aspect ratio like
568
- * the native rect/circle/line layers do. Plain paths (connectors,
569
- * freehand) leave this unset and keep their absolute `d`.
570
- */
571
- shapeKind?: string;
572
- /** Stroke color (default: theme text color). */
573
- stroke?: string;
574
- /** Stroke width in pixels (default: 2). */
575
- strokeWidth?: number;
576
- /** Optional fill color (default: 'none' — pure connectors). */
577
- fill?: string;
578
- /** Fill opacity 0–1 (applies to solid and gradient fills). */
579
- fillOpacity?: number;
580
- /** Gradient fill; overrides `fill` when set. */
581
- gradient?: LinearGradient;
582
- /**
583
- * Border line style (solid/dashed/dotted). A convenience over
584
- * `dasharray` for named shapes; when set the renderer derives the
585
- * dash pattern from it (scaled by stroke width).
586
- */
587
- borderStyle?: BorderStyle;
588
- /** Optional stroke dash pattern (SVG `stroke-dasharray` syntax). */
589
- dasharray?: string;
590
- /** Marker at the path start. */
591
- startMarker?: MarkerStyle;
592
- /** Marker at the path end. */
593
- endMarker?: MarkerStyle;
594
- };
595
- }
596
-
597
- /**
598
- * Map layer - displays a geographic map with optional markers.
599
- *
600
- * Maps are rendered as composite tile images from free tile providers.
601
- * Supported styles use open-source/free tiles requiring attribution.
602
- */
603
- export interface MapLayer extends BaseLayer {
604
- type: 'map';
605
- content: {
606
- /** Center coordinates for the map */
607
- center: {
608
- lat: number;
609
- lng: number;
610
- };
611
- /** Zoom level (0-18, typically 8-14 for doc blocks) */
612
- zoom: number;
613
- /** Map tile style */
614
- style: MapTileStyle;
615
- /** Optional markers to display on the map */
616
- markers?: MapMarker[];
617
- /** Pre-rendered static image path (for video export reliability) */
618
- staticSrc?: string;
619
- /** Show attribution text (default: true) */
620
- showAttribution?: boolean;
621
- };
622
- }
623
-
624
- /**
625
- * Video layer - displays a short video clip, always muted (narration provides audio).
626
- *
627
- * Rendered via an HTML5 <video> element inside <foreignObject>, similar to how
628
- * ImageLayer uses <img> for Ken Burns effects. clipStart/clipEnd define the window
629
- * within the source video to play. During Playwright frame capture (seekTo mode),
630
- * the video is seeked programmatically rather than playing in real time.
631
- */
632
- export interface VideoLayer extends BaseLayer {
633
- type: 'video';
634
- content: {
635
- /** Path to video file (relative to article media dir) */
636
- src: string;
637
- /** Path to poster frame (shown before video loads / during seek) */
638
- posterSrc?: string;
639
- /** Alt text for accessibility */
640
- alt: string;
641
- /** How to fit video in bounds */
642
- fit?: 'cover' | 'contain' | 'fill';
643
- /** Start time within the source video (seconds) */
644
- clipStart: number;
645
- /** End time within the source video (seconds) */
646
- clipEnd: number;
647
- /** Total source video duration (for validation) */
648
- sourceDuration?: number;
649
- /**
650
- * Seconds into the owning block before this video begins playing
651
- * (the block-relative `startAt`). Default 0 — plays from block start.
652
- */
653
- startAt?: number;
654
- /**
655
- * When true, the video keeps playing past the block's end (the
656
- * playback scheduler re-homes it to the player level). Default false.
657
- */
658
- spillover?: boolean;
659
- /** Video credit / artist name */
660
- credit?: string;
661
- /** License identifier (e.g., 'CC BY-SA 4.0') */
662
- license?: string;
663
- };
664
- }
665
-
666
- /**
667
- * Table layer - renders a data table with themed styling.
668
- * Uses foreignObject inside SVG for HTML-based table layout.
669
- */
670
- export interface TableLayer extends BaseLayer {
671
- type: 'table';
672
- content: {
673
- /** Header cell values */
674
- headers: string[];
675
- /** Data rows (array of cell value arrays) */
676
- rows: string[][];
677
- /** Per-column alignment */
678
- align?: (('left' | 'right' | 'center') | null)[];
679
- /** Visual styling */
680
- style: TableLayerStyle;
681
- };
682
- }
683
-
684
- /**
685
- * Styling options for a TableLayer.
686
- */
687
- export interface TableLayerStyle {
688
- /** Header row background color */
689
- headerBackground: string;
690
- /** Header row text color */
691
- headerColor: string;
692
- /** Body cell background color */
693
- cellBackground: string;
694
- /** Body cell text color */
695
- cellColor: string;
696
- /** Border/divider color */
697
- borderColor: string;
698
- /** Font size in pixels */
699
- fontSize: number;
700
- /** Font family */
701
- fontFamily?: string;
702
- /** Header font family (falls back to fontFamily) */
703
- headerFontFamily?: string;
704
- /** Corner radius for the table container */
705
- borderRadius?: number;
706
- }
707
-
708
- /**
709
- * One node in a `TreeLayer` — a JSON-serializable hierarchy item (mirrors
710
- * the treeview codec's `TreeItem`). Rendered as an indented filesystem-style
711
- * row with a folder/file icon and connector rails.
712
- */
713
- export interface TreeLayerItem {
714
- id: string;
715
- label: string;
716
- /** True renders a folder (container) icon; else a file (leaf) icon. */
717
- isDir?: boolean;
718
- /** Trailing comment shown muted after the label. */
719
- comment?: string;
720
- children: TreeLayerItem[];
721
- }
722
-
723
- /**
724
- * A hierarchical treeview rendered as interactive HTML inside a
725
- * `<foreignObject>` (like `TableLayer`): folder/file icons, connector
726
- * rails, and collapse chevrons. Interactive (collapse/expand) in the live
727
- * React player; captured fully-expanded and static in frame/PDF export.
728
- */
729
- export interface TreeLayer extends BaseLayer {
730
- type: 'tree';
731
- content: {
732
- items: TreeLayerItem[];
733
- style: TreeLayerStyle;
734
- };
735
- }
736
-
737
- /** Styling options for a TreeLayer. */
738
- export interface TreeLayerStyle {
739
- /** Leaf (file) row text color. */
740
- rowColor: string;
741
- /** Container (folder) row text color. */
742
- dirColor: string;
743
- /** Connector rail / branch color. */
744
- connectorColor: string;
745
- /** Icon color. */
746
- iconColor: string;
747
- /** Muted comment color. */
748
- commentColor: string;
749
- /** Font size in pixels. */
750
- fontSize: number;
751
- /** Row label font family. */
752
- fontFamily?: string;
753
- /** Monospace font for the connector rails. */
754
- monoFontFamily?: string;
755
- /** Indent step per depth level, in pixels. */
756
- indentPx: number;
757
- /** FontAwesome icon token for containers (default `folder`). */
758
- folderIcon?: string;
759
- /** FontAwesome icon token for leaves (default `file`). */
760
- fileIcon?: string;
761
- }
762
-
763
- /**
764
- * Mermaid diagram layer — renders an authored `mermaid` code fence through
765
- * the official Mermaid runtime while keeping the fence source authoritative.
766
- * Like video/table/tree layers, the browser renderer hosts the diagram in an
767
- * SVG `<foreignObject>` so it participates in slide layout and frame capture.
768
- */
769
- export interface MermaidLayer extends BaseLayer {
770
- type: 'mermaid';
771
- content: {
772
- /** Complete Mermaid source, excluding the Markdown fence delimiters. */
773
- source: string;
774
- /** Theme-derived panel color behind the generated SVG. */
775
- background?: string;
776
- /** Theme-derived foreground used by loading/error states. */
777
- foreground?: string;
778
- /** Inner panel padding in pixels. */
779
- padding?: number;
780
- };
781
- }
782
-
783
- /**
784
- * Available map tile styles from free/open-source providers.
785
- */
786
- export type MapTileStyle =
787
- | 'terrain' // OpenTopoMap - topographic/terrain (default)
788
- | 'satellite' // ESRI World Imagery
789
- | 'road' // OpenStreetMap standard
790
- | 'toner' // Stadia Toner (high contrast B&W)
791
- | 'watercolor'; // Stadia Watercolor (artistic)
792
-
793
- /**
794
- * A marker to display on the map.
795
- */
796
- export interface MapMarker {
797
- /** Marker latitude */
798
- lat: number;
799
- /** Marker longitude */
800
- lng: number;
801
- /** Optional label text */
802
- label?: string;
803
- /** Marker color (CSS color, default: #ef4444) */
804
- color?: string;
805
- /** Marker icon type */
806
- icon?: 'pin' | 'circle' | 'star';
807
- }
808
-
809
- // ============================================
810
- // Position & Styling
811
- // ============================================
812
-
813
- /**
814
- * Position and dimensions for a layer.
815
- * Values can be pixels (number) or percentages (string like "50%").
816
- */
817
- export interface Position {
818
- /** X position (pixels or percentage) */
819
- x: number | string;
820
- /** Y position (pixels or percentage) */
821
- y: number | string;
822
- /** Width (pixels or percentage) */
823
- width?: number | string;
824
- /** Height (pixels or percentage) */
825
- height?: number | string;
826
- /** Anchor point for positioning */
827
- anchor?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
828
- }
829
-
830
- /**
831
- * Text styling options.
832
- */
833
- export interface TextStyle {
834
- /** Font size in pixels */
835
- fontSize: number;
836
- /** Font family (defaults to system sans-serif) */
837
- fontFamily?: string;
838
- /** Font weight */
839
- fontWeight?: 'normal' | 'bold';
840
- /** Font style. Also the inherited baseline for rich `content.html`. */
841
- fontStyle?: 'normal' | 'italic';
842
- /** Text color (CSS color) */
843
- color: string;
844
- /** Horizontal text alignment within the layer's position box. */
845
- textAlign?: 'left' | 'center' | 'right';
846
- /**
847
- * Vertical alignment of the text within the layer's position box.
848
- * Requires a `position.height` to have an effect. When omitted, the
849
- * vertical baseline is derived from `position.anchor` (legacy behavior).
850
- */
851
- verticalAlign?: 'top' | 'middle' | 'bottom';
852
- /** Line height multiplier */
853
- lineHeight?: number;
854
- /** Add drop shadow for readability over images */
855
- shadow?: boolean;
856
- /** Background color for text box */
857
- background?: string;
858
- /** Background opacity 0–1 (applies to solid and gradient backgrounds). */
859
- backgroundOpacity?: number;
860
- /** Gradient background; overrides `background` when set. */
861
- backgroundGradient?: LinearGradient;
862
- /** Border (stroke) color for the text box. */
863
- borderColor?: string;
864
- /** Border width in pixels. A border renders when > 0 and a color is set. */
865
- borderWidth?: number;
866
- /** Border line style (solid/dashed/dotted). Default solid. */
867
- borderStyle?: BorderStyle;
868
- /** Padding around text (pixels) */
869
- padding?: number;
870
- /** Maximum number of lines before truncation (adds "..." to last line) */
871
- maxLines?: number;
872
- }
873
-
874
- // ============================================
875
- // Animation & Transitions
876
- // ============================================
877
-
878
- /**
879
- * Animation to apply to a layer.
880
- */
881
- export interface Animation {
882
- /** Animation type */
883
- type: AnimationType;
884
- /** Duration in seconds (defaults to layer's block duration) */
885
- duration?: number;
886
- /** Delay before animation starts (seconds) */
887
- delay?: number;
888
- /** CSS easing function */
889
- easing?: string;
890
- /** For Ken Burns: zoom direction */
891
- direction?: 'in' | 'out';
892
- /** For pan animations: pan direction */
893
- panDirection?: 'left' | 'right' | 'up' | 'down';
894
- }
895
-
896
- /**
897
- * Available animation types.
898
- */
899
- export type AnimationType =
900
- | 'none'
901
- | 'fadeIn'
902
- | 'fadeOut'
903
- | 'slowZoom' // Slow zoom with optional pan
904
- | 'zoomIn'
905
- | 'zoomOut'
906
- | 'panLeft'
907
- | 'panRight'
908
- | 'typewriter'; // Text appears letter by letter
909
-
910
- // ============================================
911
- // Audio Configuration
912
- // ============================================
913
-
914
- /**
915
- * Audio track configuration.
916
- * Articles have multiple MP3 segments (intro + sections).
917
- */
918
- export interface AudioTrack {
919
- /** Audio segments in playback order */
920
- segments: AudioSegment[];
921
- }
922
-
923
- // ============================================
924
- // Captions
925
- // ============================================
926
-
927
- /**
928
- * A single word with precise timing, used for word-level highlighting
929
- * in social-style captions. Populated from TTS timing data when available.
930
- */
931
- export interface CaptionWord {
932
- /** The word text */
933
- text: string;
934
- /** Start time in seconds (relative to doc start) */
935
- startTime: number;
936
- /** End time in seconds */
937
- endTime: number;
938
- }
939
-
940
- /**
941
- * A single caption phrase to display during playback.
942
- */
943
- export interface CaptionPhrase {
944
- /** The text to display */
945
- text: string;
946
- /** Start time in seconds (relative to doc start) */
947
- startTime: number;
948
- /** End time in seconds */
949
- endTime: number;
950
- /** Which audio segment this caption belongs to (0-indexed) */
951
- audioSegment: number;
952
- /**
953
- * Optional per-word timing from TTS timing data.
954
- * When present, enables precise word-level highlighting in social
955
- * caption style. When absent, word timing is interpolated evenly
956
- * across the phrase duration.
957
- */
958
- words?: CaptionWord[];
959
- }
960
-
961
- /**
962
- * Caption track for a doc.
963
- */
964
- export interface CaptionTrack {
965
- /** Caption phrases in chronological order */
966
- phrases: CaptionPhrase[];
967
- /** When the captions were generated. Optional so that conversion stays
968
- * deterministic — `markdownToDoc()` only sets it when the caller
969
- * supplies a timestamp via `captionsGeneratedAt`. */
970
- generatedAt?: string;
971
- /** Algorithm version for regeneration detection */
972
- version: number;
973
- }
974
-
975
- /**
976
- * A single audio segment (one MP3 file).
977
- */
978
- export interface AudioSegment {
979
- /** Path to MP3 file (relative to article media dir) */
980
- src: string;
981
- /** Segment name (e.g., "intro", "history") */
982
- name: string;
983
- /** Duration in seconds */
984
- duration: number;
985
- /** Start time in overall timeline (calculated) */
986
- startTime: number;
987
- }
988
-
989
- // ============================================
990
- // Audio Timing Data (from TTS)
991
- // ============================================
992
-
993
- /**
994
- * A single word-level timing bookmark from TTS synthesis.
995
- * Used for precise audio-to-content mapping and word-level caption sync.
996
- */
997
- export interface AudioBookmark {
998
- /** Unique identifier (e.g., "word-0", "word-1") */
999
- id: string;
1000
- /** Timestamp in seconds from audio start */
1001
- time: number;
1002
- /** Character offset in the source text */
1003
- charOffset: number;
1004
- /** The word text at this position */
1005
- textFragment?: string;
1006
- }
1007
-
1008
- /**
1009
- * Timing data for an audio segment, typically from a `.timing.json` file
1010
- * generated alongside TTS audio. Contains the source text and per-word
1011
- * timing bookmarks for precise content matching and caption sync.
1012
- */
1013
- export interface AudioTimingData {
1014
- /** The normalized plain text that was synthesized */
1015
- sourceText: string;
1016
- /** Word-level timing bookmarks */
1017
- bookmarks: AudioBookmark[];
1018
- /** Total audio duration in seconds */
1019
- duration: number;
1020
- }
1021
-
1022
- // ============================================
1023
- // Helper Functions
1024
- // ============================================
1025
-
1026
- /**
1027
- * Calculate total duration from audio segments.
1028
- */
1029
- export function calculateDuration(audio: AudioTrack): number {
1030
- return audio.segments.reduce((sum, seg) => sum + seg.duration, 0);
1031
- }
1032
-
1033
- /**
1034
- * Find which audio segment is playing at a given time.
1035
- */
1036
- export function getSegmentAtTime(audio: AudioTrack, time: number): number {
1037
- let elapsed = 0;
1038
- for (let i = 0; i < audio.segments.length; i++) {
1039
- elapsed += audio.segments[i].duration;
1040
- if (time < elapsed) return i;
1041
- }
1042
- return audio.segments.length - 1;
1043
- }
1044
-
1045
- /**
1046
- * Find which block should be visible at a given time.
1047
- */
1048
- export function getBlockAtTime(blocks: Block[], time: number): Block | null {
1049
- for (let i = blocks.length - 1; i >= 0; i--) {
1050
- const block = blocks[i];
1051
- if (time >= block.startTime && time < block.startTime + block.duration) {
1052
- return block;
1053
- }
1054
- }
1055
- return blocks[0] || null;
1056
- }
1057
-
1058
- /**
1059
- * Find the caption phrase that should be displayed at a given time.
1060
- */
1061
- export function getCaptionAtTime(
1062
- captions: CaptionTrack | undefined,
1063
- time: number,
1064
- ): CaptionPhrase | null {
1065
- if (!captions || !captions.phrases.length) return null;
1066
-
1067
- for (const phrase of captions.phrases) {
1068
- if (time >= phrase.startTime && time < phrase.endTime) {
1069
- return phrase;
1070
- }
1071
- }
1072
- return null;
1073
- }