@bendyline/squisq 2.0.1 → 2.2.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.
- package/LICENSE +21 -0
- package/NOTICE.md +24 -0
- package/dist/{ContentContainer-BXUlIf18.d.ts → ContentContainer-B2w9sUoL.d.ts} +15 -0
- package/dist/{Doc-ylqWKDc_.d.ts → Doc-BubIpWsp.d.ts} +160 -3
- package/dist/{ImageEditDoc-D828IXJ1.d.ts → ImageEditDoc-CGxk5CHc.d.ts} +1 -1
- package/dist/{annotationCoercion-Dr_DY9Hx.d.ts → annotationCoercion-PtRQhk5V.d.ts} +1 -1
- package/dist/chunk-2L55443L.js +0 -0
- package/dist/chunk-2ZWIXGAC.js +214 -0
- package/dist/{chunk-2PWOO4ZE.js → chunk-32R2RZAO.js} +72 -3
- package/dist/chunk-3IGPAPQ7.js +645 -0
- package/dist/{chunk-QE7TWGVT.js → chunk-4VOD55SX.js} +0 -1
- package/dist/{chunk-3E5F2XMR.js → chunk-67L6WRJN.js} +0 -1
- package/dist/{chunk-5DKBFXPY.js → chunk-6ECMNUIP.js} +26 -18
- package/dist/{chunk-X6DUONGT.js → chunk-7ARJZYQY.js} +280 -128
- package/dist/{chunk-DBS6RIFL.js → chunk-7N4G32LG.js} +0 -1
- package/dist/{chunk-JOQYPRDZ.js → chunk-7YEZFHLS.js} +10 -8
- package/dist/{chunk-2UQOHYE2.js → chunk-7ZAAICW4.js} +0 -1
- package/dist/{chunk-66QO7XFB.js → chunk-ACZOVWX3.js} +117 -7
- package/dist/{chunk-5J4HKRJF.js → chunk-BAOV476U.js} +0 -1
- package/dist/chunk-BCCXTMN5.js +699 -0
- package/dist/{chunk-W4O2TX5I.js → chunk-C33GTPUZ.js} +579 -4
- package/dist/{chunk-MMPBOUK7.js → chunk-CB45YGAM.js} +7 -2
- package/dist/{chunk-CY2R2VPR.js → chunk-DYPMOPIW.js} +18 -2
- package/dist/{chunk-VR7UPJ7C.js → chunk-FCG3BIZN.js} +12 -1
- package/dist/{chunk-5UYI3RJB.js → chunk-FDYDYL77.js} +54 -40
- package/dist/{chunk-TFJVXUHH.js → chunk-I2O6W7DX.js} +1513 -79
- package/dist/{chunk-Q7LROV2H.js → chunk-NKNMGIIN.js} +0 -1
- package/dist/chunk-OPO5K4DZ.js +241 -0
- package/dist/{chunk-TUWMK62B.js → chunk-PUS54YU6.js} +45 -2
- package/dist/chunk-QKPXHDLR.js +0 -0
- package/dist/{chunk-GZY66SDN.js → chunk-R3KTTOMS.js} +0 -1
- package/dist/{chunk-PXLVXTLW.js → chunk-RS5AP3J4.js} +72 -15
- package/dist/chunk-WV5ARNDA.js +0 -0
- package/dist/{chunk-4X3JQXNM.js → chunk-XOFT65EX.js} +1 -2
- package/dist/{chunk-FVTQSNR7.js → chunk-XRW6P7IF.js} +13 -5
- package/dist/chunk-XWNNA3KE.js +0 -0
- package/dist/chunk-YZNGMV3G.js +0 -0
- package/dist/{chunk-R2YZTCLO.js → chunk-ZQKZSJAX.js} +1 -2
- package/dist/doc/index.d.ts +166 -12
- package/dist/doc/index.js +36 -17
- package/dist/generate/index.d.ts +2 -2
- package/dist/generate/index.js +2 -3
- package/dist/icons/index.js +3 -4
- package/dist/icons/inlineIconMarker.js +1 -2
- package/dist/imageEdit/index.d.ts +48 -17
- package/dist/imageEdit/index.js +3 -4
- package/dist/index.d.ts +13 -12
- package/dist/index.js +118 -33
- package/dist/jsonForm/index.d.ts +10 -3
- package/dist/jsonForm/index.js +8 -7
- package/dist/markdown/index.d.ts +75 -11
- package/dist/markdown/index.js +32 -7
- package/dist/materializePageSection-wSLA2A1g.d.ts +223 -0
- package/dist/narration/index.d.ts +16 -3
- package/dist/narration/index.js +13 -14
- package/dist/random/index.d.ts +11 -2
- package/dist/random/index.js +2 -3
- package/dist/recommend/index.d.ts +1 -1
- package/dist/recommend/index.js +3 -4
- package/dist/schemas/index.d.ts +31 -6
- package/dist/schemas/index.js +43 -6
- package/dist/spatial/index.d.ts +2 -1
- package/dist/spatial/index.js +1 -2
- package/dist/storage/index.d.ts +4 -2
- package/dist/storage/index.js +1 -2
- package/dist/{themeLibrary-RjVgLpUi.d.ts → themeLibrary-DU9mUmVl.d.ts} +1 -1
- package/dist/timing/index.js +3 -4
- package/dist/transform/index.d.ts +9 -10
- package/dist/transform/index.js +6 -7
- package/dist/{types-C4kiRn_k.d.ts → types-8QjefM9J.d.ts} +38 -2
- package/dist/{types-BwMPl2CB.d.ts → types-CUNc9biN.d.ts} +24 -1
- package/dist/versions/index.d.ts +14 -11
- package/dist/versions/index.js +2 -3
- package/package.json +4 -2
- package/dist/chunk-2PWOO4ZE.js.map +0 -1
- package/dist/chunk-2UQOHYE2.js.map +0 -1
- package/dist/chunk-3E5F2XMR.js.map +0 -1
- package/dist/chunk-4X3JQXNM.js.map +0 -1
- package/dist/chunk-5DKBFXPY.js.map +0 -1
- package/dist/chunk-5J4HKRJF.js.map +0 -1
- package/dist/chunk-5UYI3RJB.js.map +0 -1
- package/dist/chunk-66QO7XFB.js.map +0 -1
- package/dist/chunk-AMIR72JP.js +0 -380
- package/dist/chunk-AMIR72JP.js.map +0 -1
- package/dist/chunk-CY2R2VPR.js.map +0 -1
- package/dist/chunk-DBS6RIFL.js.map +0 -1
- package/dist/chunk-DNJKBAI7.js +0 -1
- package/dist/chunk-DNJKBAI7.js.map +0 -1
- package/dist/chunk-ET53IIEP.js +0 -1
- package/dist/chunk-ET53IIEP.js.map +0 -1
- package/dist/chunk-FVJUUTEM.js +0 -74
- package/dist/chunk-FVJUUTEM.js.map +0 -1
- package/dist/chunk-FVTQSNR7.js.map +0 -1
- package/dist/chunk-GZY66SDN.js.map +0 -1
- package/dist/chunk-JOQYPRDZ.js.map +0 -1
- package/dist/chunk-MMPBOUK7.js.map +0 -1
- package/dist/chunk-PGGGKYWG.js +0 -1
- package/dist/chunk-PGGGKYWG.js.map +0 -1
- package/dist/chunk-PXLVXTLW.js.map +0 -1
- package/dist/chunk-Q7LROV2H.js.map +0 -1
- package/dist/chunk-QE7TWGVT.js.map +0 -1
- package/dist/chunk-R2GC6RLD.js +0 -344
- package/dist/chunk-R2GC6RLD.js.map +0 -1
- package/dist/chunk-R2YZTCLO.js.map +0 -1
- package/dist/chunk-S7A5D7ZJ.js +0 -174
- package/dist/chunk-S7A5D7ZJ.js.map +0 -1
- package/dist/chunk-TFJVXUHH.js.map +0 -1
- package/dist/chunk-TUWMK62B.js.map +0 -1
- package/dist/chunk-V543AI2F.js +0 -1
- package/dist/chunk-V543AI2F.js.map +0 -1
- package/dist/chunk-VR7UPJ7C.js.map +0 -1
- package/dist/chunk-W4O2TX5I.js.map +0 -1
- package/dist/chunk-X6DUONGT.js.map +0 -1
- package/dist/chunk-ZLQKNOZQ.js +0 -1
- package/dist/chunk-ZLQKNOZQ.js.map +0 -1
- package/dist/doc/index.js.map +0 -1
- package/dist/generate/index.js.map +0 -1
- package/dist/icons/index.js.map +0 -1
- package/dist/icons/inlineIconMarker.js.map +0 -1
- package/dist/imageEdit/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jsonForm/index.js.map +0 -1
- package/dist/markdown/index.js.map +0 -1
- package/dist/narration/index.js.map +0 -1
- package/dist/random/index.js.map +0 -1
- package/dist/recommend/index.js.map +0 -1
- package/dist/schemas/index.js.map +0 -1
- package/dist/spatial/index.js.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/timing/index.js.map +0 -1
- package/dist/transform/index.js.map +0 -1
- package/dist/versions/index.js.map +0 -1
- package/src/__tests__/animationUtils.test.ts +0 -117
- package/src/__tests__/annotationCoercion.test.ts +0 -243
- package/src/__tests__/applyNarrationTiming.test.ts +0 -190
- package/src/__tests__/applyRenderStyle.test.ts +0 -146
- package/src/__tests__/asciiDiagramBattle.test.ts +0 -246
- package/src/__tests__/asciiDiagramDetect.test.ts +0 -162
- package/src/__tests__/asciiDiagramMapping.test.ts +0 -38
- package/src/__tests__/asciiDiagramParse.test.ts +0 -233
- package/src/__tests__/asciiDiagramPipeline.test.ts +0 -273
- package/src/__tests__/asciiDiagramRender.test.ts +0 -162
- package/src/__tests__/asciiDiagramRepair.test.ts +0 -84
- package/src/__tests__/asciiTimelineDetect.test.ts +0 -157
- package/src/__tests__/asciiTimelineParse.test.ts +0 -205
- package/src/__tests__/asciiTimelinePipeline.test.ts +0 -349
- package/src/__tests__/asciiTimelineRender.test.ts +0 -376
- package/src/__tests__/atmosphereLayers.test.ts +0 -108
- package/src/__tests__/attrTokens.test.ts +0 -167
- package/src/__tests__/colorUtils.test.ts +0 -112
- package/src/__tests__/contentContainer.test.ts +0 -325
- package/src/__tests__/contentExtractor.test.ts +0 -243
- package/src/__tests__/coverBlock.test.ts +0 -310
- package/src/__tests__/customTemplateSample.test.ts +0 -144
- package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -221
- package/src/__tests__/customThemesFrontmatter.test.ts +0 -146
- package/src/__tests__/dataTable.test.ts +0 -145
- package/src/__tests__/diagramBlock.test.ts +0 -122
- package/src/__tests__/diagramLayout.test.ts +0 -134
- package/src/__tests__/diagramText.test.ts +0 -26
- package/src/__tests__/docToMarkdownMedia.test.ts +0 -83
- package/src/__tests__/drawing.test.ts +0 -109
- package/src/__tests__/drawingBlock.test.ts +0 -124
- package/src/__tests__/drawingLayout.test.ts +0 -171
- package/src/__tests__/fixtures/asciiDiagramBattle.ts +0 -512
- package/src/__tests__/fixtures/asciiDiagrams.ts +0 -287
- package/src/__tests__/fixtures/asciiTimelines.ts +0 -35
- package/src/__tests__/fixtures/treeviewFixtures.ts +0 -243
- package/src/__tests__/geohash.test.ts +0 -110
- package/src/__tests__/getLayers.test.ts +0 -243
- package/src/__tests__/getLayersFallback.test.ts +0 -103
- package/src/__tests__/haversine.test.ts +0 -63
- package/src/__tests__/iconResolve.test.ts +0 -122
- package/src/__tests__/imageEditExportSvg.test.ts +0 -70
- package/src/__tests__/imageEditState.test.ts +0 -74
- package/src/__tests__/imageEditVersions.test.ts +0 -243
- package/src/__tests__/inferDocumentTitle.test.ts +0 -50
- package/src/__tests__/inlineIconMarker.test.ts +0 -36
- package/src/__tests__/inputDescriptors.test.ts +0 -162
- package/src/__tests__/jsonForm.chooseControl.test.ts +0 -86
- package/src/__tests__/jsonForm.evaluateWhen.test.ts +0 -59
- package/src/__tests__/jsonForm.inferSchema.test.ts +0 -25
- package/src/__tests__/jsonForm.pointer.test.ts +0 -149
- package/src/__tests__/jsonForm.tokens.test.ts +0 -84
- package/src/__tests__/layoutBlock.test.ts +0 -83
- package/src/__tests__/layoutLayout.test.ts +0 -169
- package/src/__tests__/localForageAdapter.test.ts +0 -155
- package/src/__tests__/majorApiTypes.test.ts +0 -18
- package/src/__tests__/markdown.test.ts +0 -1009
- package/src/__tests__/markdownIcons.test.ts +0 -104
- package/src/__tests__/markdownSanitize.test.ts +0 -81
- package/src/__tests__/markdownToDoc.test.ts +0 -957
- package/src/__tests__/matchFontFamily.test.ts +0 -114
- package/src/__tests__/materializeBlockLayers.test.ts +0 -135
- package/src/__tests__/materializeTestUtils.ts +0 -17
- package/src/__tests__/mediaAnnotations.test.ts +0 -91
- package/src/__tests__/mediaSchedule.test.ts +0 -118
- package/src/__tests__/narrationAlign.test.ts +0 -150
- package/src/__tests__/narrationFeatures.test.ts +0 -71
- package/src/__tests__/narrationNuclei.test.ts +0 -45
- package/src/__tests__/narrationPacing.test.ts +0 -189
- package/src/__tests__/narrationScript.test.ts +0 -149
- package/src/__tests__/narrationSessionRepro.test.ts +0 -62
- package/src/__tests__/narrationSidecar.test.ts +0 -88
- package/src/__tests__/narrationSyllables.test.ts +0 -65
- package/src/__tests__/narrationTestSignals.ts +0 -167
- package/src/__tests__/narrationVad.test.ts +0 -66
- package/src/__tests__/pandocAttrParse.test.ts +0 -187
- package/src/__tests__/recommendTemplates.test.ts +0 -183
- package/src/__tests__/resolveDocTheme.test.ts +0 -69
- package/src/__tests__/rootExports.test.ts +0 -61
- package/src/__tests__/scopedContentContainer.test.ts +0 -109
- package/src/__tests__/seededRandom.test.ts +0 -142
- package/src/__tests__/shapeGeometry.test.ts +0 -138
- package/src/__tests__/shapeVocabulary.test.ts +0 -133
- package/src/__tests__/storage.test.ts +0 -60
- package/src/__tests__/structuredData.test.ts +0 -249
- package/src/__tests__/surface.test.ts +0 -68
- package/src/__tests__/templateAnnotationParse.test.ts +0 -160
- package/src/__tests__/templateInputs.test.ts +0 -69
- package/src/__tests__/templateMetadata.test.ts +0 -32
- package/src/__tests__/templates.test.ts +0 -710
- package/src/__tests__/themeCompile.test.ts +0 -225
- package/src/__tests__/themeValidator.test.ts +0 -131
- package/src/__tests__/timing.test.ts +0 -167
- package/src/__tests__/transformProvenance.test.ts +0 -160
- package/src/__tests__/transformV2.test.ts +0 -163
- package/src/__tests__/transitionNormalize.test.ts +0 -61
- package/src/__tests__/treeviewBattle.test.ts +0 -76
- package/src/__tests__/treeviewDetect.test.ts +0 -168
- package/src/__tests__/treeviewParse.test.ts +0 -118
- package/src/__tests__/treeviewPipeline.test.ts +0 -183
- package/src/__tests__/treeviewRender.test.ts +0 -91
- package/src/__tests__/validateDoc.test.ts +0 -260
- package/src/__tests__/versions.test.ts +0 -459
- package/src/doc/annotationBlocks.ts +0 -117
- package/src/doc/applyNarrationTiming.ts +0 -244
- package/src/doc/asciiDiagram/chars.ts +0 -210
- package/src/doc/asciiDiagram/detect.ts +0 -175
- package/src/doc/asciiDiagram/index.ts +0 -38
- package/src/doc/asciiDiagram/mapping.ts +0 -225
- package/src/doc/asciiDiagram/parse.ts +0 -1095
- package/src/doc/asciiDiagram/render.ts +0 -963
- package/src/doc/asciiDiagram/repair.ts +0 -400
- package/src/doc/asciiDiagram/types.ts +0 -65
- package/src/doc/asciiTimeline/detect.ts +0 -138
- package/src/doc/asciiTimeline/index.ts +0 -26
- package/src/doc/asciiTimeline/mapping.ts +0 -43
- package/src/doc/asciiTimeline/parse.ts +0 -870
- package/src/doc/asciiTimeline/render.ts +0 -427
- package/src/doc/asciiTimeline/types.ts +0 -73
- package/src/doc/asciiTimeline/wrappedFlow.ts +0 -427
- package/src/doc/audioMapping.ts +0 -442
- package/src/doc/customTemplatesFrontmatter.ts +0 -273
- package/src/doc/customThemesFrontmatter.ts +0 -95
- package/src/doc/docToMarkdown.ts +0 -284
- package/src/doc/index.ts +0 -127
- package/src/doc/markdownToDoc.ts +0 -1054
- package/src/doc/materializeBlockLayers.ts +0 -304
- package/src/doc/mediaAnnotations.ts +0 -120
- package/src/doc/resolveDocTheme.ts +0 -56
- package/src/doc/standaloneAnnotation.ts +0 -58
- package/src/doc/structuredData.ts +0 -301
- package/src/doc/templateInputs.ts +0 -423
- package/src/doc/templates/__tests__/customTemplate.test.ts +0 -170
- package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +0 -124
- package/src/doc/templates/__tests__/listBlock.test.ts +0 -64
- package/src/doc/templates/accentImage.ts +0 -362
- package/src/doc/templates/captionUtils.ts +0 -56
- package/src/doc/templates/comparisonBar.ts +0 -173
- package/src/doc/templates/coverBlock.ts +0 -255
- package/src/doc/templates/customTemplate.ts +0 -51
- package/src/doc/templates/dataTable.ts +0 -102
- package/src/doc/templates/dateEvent.ts +0 -147
- package/src/doc/templates/definitionCard.ts +0 -140
- package/src/doc/templates/diagramBlock.ts +0 -403
- package/src/doc/templates/diagramLayout.ts +0 -159
- package/src/doc/templates/drawingBlock.ts +0 -325
- package/src/doc/templates/drawingLayout.ts +0 -539
- package/src/doc/templates/factCard.ts +0 -146
- package/src/doc/templates/fallbackBlock.ts +0 -123
- package/src/doc/templates/featureBlock.ts +0 -209
- package/src/doc/templates/fullBleedQuote.ts +0 -83
- package/src/doc/templates/imageWithCaption.ts +0 -186
- package/src/doc/templates/index.ts +0 -642
- package/src/doc/templates/inputDescriptors.ts +0 -451
- package/src/doc/templates/layoutBlock.ts +0 -43
- package/src/doc/templates/layoutLayout.ts +0 -243
- package/src/doc/templates/listBlock.ts +0 -207
- package/src/doc/templates/mapBlock.ts +0 -138
- package/src/doc/templates/metadata.ts +0 -130
- package/src/doc/templates/persistentLayers.ts +0 -526
- package/src/doc/templates/photoGrid.ts +0 -190
- package/src/doc/templates/pullQuote.ts +0 -141
- package/src/doc/templates/quoteBlock.ts +0 -141
- package/src/doc/templates/registry.ts +0 -88
- package/src/doc/templates/sectionHeader.ts +0 -120
- package/src/doc/templates/statHighlight.ts +0 -146
- package/src/doc/templates/templateNames.ts +0 -22
- package/src/doc/templates/timelineBlock.ts +0 -613
- package/src/doc/templates/titleBlock.ts +0 -150
- package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +0 -487
- package/src/doc/templates/tokens/resolveTokens.ts +0 -453
- package/src/doc/templates/treeBlock.ts +0 -131
- package/src/doc/templates/twoColumn.ts +0 -263
- package/src/doc/templates/videoPullQuote.ts +0 -142
- package/src/doc/templates/videoWithCaption.ts +0 -135
- package/src/doc/treeview/chars.ts +0 -72
- package/src/doc/treeview/detect.ts +0 -145
- package/src/doc/treeview/index.ts +0 -30
- package/src/doc/treeview/mapping.ts +0 -95
- package/src/doc/treeview/parse.ts +0 -201
- package/src/doc/treeview/render.ts +0 -41
- package/src/doc/treeview/types.ts +0 -43
- package/src/doc/utils/animationUtils.ts +0 -399
- package/src/doc/utils/applyRenderStyle.ts +0 -106
- package/src/doc/utils/diagramText.ts +0 -78
- package/src/doc/utils/imageTreatment.ts +0 -70
- package/src/doc/utils/nearest.ts +0 -59
- package/src/doc/utils/shapeGeometry.ts +0 -614
- package/src/doc/utils/themeUtils.ts +0 -243
- package/src/doc/validate.ts +0 -575
- package/src/generate/contentExtractor.ts +0 -921
- package/src/generate/index.ts +0 -18
- package/src/generate/templateMapper.ts +0 -177
- package/src/icons/iconData.ts +0 -31
- package/src/icons/index.ts +0 -26
- package/src/icons/inlineIconMarker.ts +0 -73
- package/src/icons/resolve.ts +0 -139
- package/src/imageEdit/ImageEditVersionManager.ts +0 -73
- package/src/imageEdit/export.ts +0 -410
- package/src/imageEdit/index.ts +0 -72
- package/src/imageEdit/persistence.ts +0 -113
- package/src/imageEdit/state.ts +0 -112
- package/src/imageEdit/versionPaths.ts +0 -44
- package/src/imageEdit/versions.ts +0 -152
- package/src/index.ts +0 -15
- package/src/internal/immutable.ts +0 -58
- package/src/jsonForm/chooseControl.ts +0 -88
- package/src/jsonForm/evaluateWhen.ts +0 -59
- package/src/jsonForm/index.ts +0 -32
- package/src/jsonForm/inferSchema.ts +0 -25
- package/src/jsonForm/pointer.ts +0 -154
- package/src/jsonForm/tokens.ts +0 -78
- package/src/jsonForm/types.ts +0 -167
- package/src/markdown/annotationCoercion.ts +0 -295
- package/src/markdown/attrTokens.ts +0 -243
- package/src/markdown/convert.ts +0 -1353
- package/src/markdown/htmlParse.ts +0 -212
- package/src/markdown/index.ts +0 -152
- package/src/markdown/parse.ts +0 -103
- package/src/markdown/sanitize.ts +0 -318
- package/src/markdown/stringify.ts +0 -207
- package/src/markdown/types.ts +0 -710
- package/src/markdown/utils.ts +0 -459
- package/src/narration/align.ts +0 -514
- package/src/narration/features.ts +0 -231
- package/src/narration/index.ts +0 -86
- package/src/narration/nuclei.ts +0 -118
- package/src/narration/pacing.ts +0 -211
- package/src/narration/script.ts +0 -239
- package/src/narration/session.ts +0 -100
- package/src/narration/sidecar.ts +0 -187
- package/src/narration/syllables.ts +0 -85
- package/src/narration/trace.ts +0 -50
- package/src/narration/types.ts +0 -299
- package/src/narration/vad.ts +0 -131
- package/src/ngeohash.d.ts +0 -11
- package/src/random/SeededRandom.ts +0 -127
- package/src/random/index.ts +0 -1
- package/src/recommend/index.ts +0 -16
- package/src/recommend/numberHighlight.ts +0 -25
- package/src/recommend/templates.ts +0 -393
- package/src/schemas/BlockTemplates.ts +0 -1046
- package/src/schemas/CustomTemplates.ts +0 -126
- package/src/schemas/Doc.ts +0 -1052
- package/src/schemas/ImageEditDoc.ts +0 -102
- package/src/schemas/LayoutStrategy.ts +0 -178
- package/src/schemas/Media.ts +0 -179
- package/src/schemas/MediaProvider.ts +0 -70
- package/src/schemas/Theme.ts +0 -406
- package/src/schemas/Transitions.ts +0 -224
- package/src/schemas/Types.ts +0 -15
- package/src/schemas/Viewport.ts +0 -91
- package/src/schemas/colorUtils.ts +0 -219
- package/src/schemas/fontStacks.ts +0 -339
- package/src/schemas/index.ts +0 -29
- package/src/schemas/themeCompile.ts +0 -237
- package/src/schemas/themeConstants.ts +0 -2
- package/src/schemas/themeLibrary.ts +0 -60
- package/src/schemas/themeValidator.ts +0 -426
- package/src/schemas/themes/bold.json +0 -48
- package/src/schemas/themes/cinematic.json +0 -111
- package/src/schemas/themes/documentary.json +0 -96
- package/src/schemas/themes/gezellig.json +0 -93
- package/src/schemas/themes/index.ts +0 -53
- package/src/schemas/themes/magazine.json +0 -89
- package/src/schemas/themes/minimalist.json +0 -45
- package/src/schemas/themes/morning-light.json +0 -85
- package/src/schemas/themes/standard-dark.json +0 -85
- package/src/schemas/themes/standard.json +0 -74
- package/src/schemas/themes/tech-dark.json +0 -101
- package/src/schemas/themes/warm-earth.json +0 -50
- package/src/spatial/Geohash.ts +0 -196
- package/src/spatial/Haversine.ts +0 -59
- package/src/spatial/index.ts +0 -2
- package/src/storage/ContentContainer.ts +0 -220
- package/src/storage/LocalForageAdapter.ts +0 -103
- package/src/storage/LocalStorageAdapter.ts +0 -57
- package/src/storage/MediaProviderFromContainer.ts +0 -92
- package/src/storage/MemoryStorageAdapter.ts +0 -37
- package/src/storage/ScopedContentContainer.ts +0 -143
- package/src/storage/Storage.ts +0 -28
- package/src/storage/index.ts +0 -9
- package/src/timing/index.ts +0 -17
- package/src/timing/narrationTiming.ts +0 -220
- package/src/timing/readingTime.ts +0 -94
- package/src/transform/applyTransform.ts +0 -122
- package/src/transform/blockAnalyzer.ts +0 -181
- package/src/transform/index.ts +0 -23
- package/src/transform/registry.ts +0 -198
- package/src/transform/styles/dataDriven.ts +0 -17
- package/src/transform/styles/documentary.ts +0 -17
- package/src/transform/styles/index.ts +0 -5
- package/src/transform/styles/magazine.ts +0 -18
- package/src/transform/styles/minimal.ts +0 -17
- package/src/transform/styles/narrative.ts +0 -18
- package/src/transform/templateSelector.ts +0 -389
- package/src/transform/timingAllocator.ts +0 -257
- package/src/transform/types.ts +0 -151
- package/src/versions/DocumentVersionManager.ts +0 -70
- package/src/versions/gitignore.ts +0 -34
- package/src/versions/index.ts +0 -56
- package/src/versions/operations.ts +0 -144
- package/src/versions/paths.ts +0 -51
- package/src/versions/snapshotStore.ts +0 -202
- package/src/versions/timestamp.ts +0 -48
- package/src/versions/types.ts +0 -93
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical, framework-free UI metadata for every built-in block template.
|
|
3
|
-
*
|
|
4
|
-
* This is the single source of truth for the human-readable label and the
|
|
5
|
-
* one-sentence description of each template id in {@link templateRegistry}.
|
|
6
|
-
* The editor's `TemplatePicker` renders its gallery from this map (joining
|
|
7
|
-
* each id with a locally-defined SVG icon, which can't live in this
|
|
8
|
-
* framework-free package), so a template only has to be added here and to
|
|
9
|
-
* `templateRegistry` for it to surface in the editor.
|
|
10
|
-
*
|
|
11
|
-
* `templateMetadata.test.ts` asserts this map and `templateRegistry` stay
|
|
12
|
-
* exactly 1:1 — adding a template to one without the other fails the build.
|
|
13
|
-
*
|
|
14
|
-
* Order matters: pickers iterate this object's insertion order, so it doubles
|
|
15
|
-
* as the canonical gallery order.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
export interface TemplateMetadata {
|
|
19
|
-
/** Human-readable label shown in pickers (e.g. "Image with Caption"). */
|
|
20
|
-
label: string;
|
|
21
|
-
/** One-sentence description of when to reach for this template. */
|
|
22
|
-
description: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const TEMPLATE_METADATA: Record<string, TemplateMetadata> = {
|
|
26
|
-
title: {
|
|
27
|
-
label: 'Title',
|
|
28
|
-
description: 'A bold opening slide with large title text, perfect for covers and chapters.',
|
|
29
|
-
},
|
|
30
|
-
sectionHeader: {
|
|
31
|
-
label: 'Section Header',
|
|
32
|
-
description: 'A clean section break with a prominent title and optional subtitle.',
|
|
33
|
-
},
|
|
34
|
-
statHighlight: {
|
|
35
|
-
label: 'Stat Highlight',
|
|
36
|
-
description: 'Showcases a single key number or metric with supporting context.',
|
|
37
|
-
},
|
|
38
|
-
quote: {
|
|
39
|
-
label: 'Quote',
|
|
40
|
-
description: 'Displays a stylized pull quote with decorative marks and attribution.',
|
|
41
|
-
},
|
|
42
|
-
factCard: {
|
|
43
|
-
label: 'Fact Card',
|
|
44
|
-
description: 'Presents a focused fact or insight with a labeled header and body text.',
|
|
45
|
-
},
|
|
46
|
-
twoColumn: {
|
|
47
|
-
label: 'Two Column',
|
|
48
|
-
description: 'Divides the slide into two equal side-by-side content columns.',
|
|
49
|
-
},
|
|
50
|
-
dateEvent: {
|
|
51
|
-
label: 'Date Event',
|
|
52
|
-
description: 'Highlights a date-based event or milestone with a prominent date display.',
|
|
53
|
-
},
|
|
54
|
-
imageWithCaption: {
|
|
55
|
-
label: 'Image with Caption',
|
|
56
|
-
description: 'Displays a full-bleed image with an optional caption below.',
|
|
57
|
-
},
|
|
58
|
-
leftFeature: {
|
|
59
|
-
label: 'Left Feature',
|
|
60
|
-
description: 'Image on the left, title and body text stacked on the right.',
|
|
61
|
-
},
|
|
62
|
-
rightFeature: {
|
|
63
|
-
label: 'Right Feature',
|
|
64
|
-
description: 'Image on the right, title and body text stacked on the left.',
|
|
65
|
-
},
|
|
66
|
-
map: {
|
|
67
|
-
label: 'Map',
|
|
68
|
-
description: 'Embeds an interactive map centered on a geographic location.',
|
|
69
|
-
},
|
|
70
|
-
fullBleedQuote: {
|
|
71
|
-
label: 'Full Bleed Quote',
|
|
72
|
-
description: 'A full-width quote that spans the entire slide for maximum impact.',
|
|
73
|
-
},
|
|
74
|
-
list: {
|
|
75
|
-
label: 'List',
|
|
76
|
-
description: 'Renders a bulleted or numbered list in a clean, card-style layout.',
|
|
77
|
-
},
|
|
78
|
-
photoGrid: {
|
|
79
|
-
label: 'Photo Grid',
|
|
80
|
-
description: 'Arranges multiple photos in a 2×2 or 3×3 mosaic grid.',
|
|
81
|
-
},
|
|
82
|
-
definitionCard: {
|
|
83
|
-
label: 'Definition Card',
|
|
84
|
-
description: 'Shows a term and its definition in a structured, dictionary-style card.',
|
|
85
|
-
},
|
|
86
|
-
comparisonBar: {
|
|
87
|
-
label: 'Comparison Bar',
|
|
88
|
-
description: 'Visualizes two or more values side-by-side with labeled horizontal bars.',
|
|
89
|
-
},
|
|
90
|
-
pullQuote: {
|
|
91
|
-
label: 'Pull Quote',
|
|
92
|
-
description: 'A stylized pull quote with large decorative marks and centered text.',
|
|
93
|
-
},
|
|
94
|
-
videoWithCaption: {
|
|
95
|
-
label: 'Video with Caption',
|
|
96
|
-
description: 'Embeds a video player with an optional caption below.',
|
|
97
|
-
},
|
|
98
|
-
videoPullQuote: {
|
|
99
|
-
label: 'Video Pull Quote',
|
|
100
|
-
description: 'Combines a video panel with a highlighted pull quote side-by-side.',
|
|
101
|
-
},
|
|
102
|
-
dataTable: {
|
|
103
|
-
label: 'Data Table',
|
|
104
|
-
description: 'Renders tabular data in a clean, styled table with a header row.',
|
|
105
|
-
},
|
|
106
|
-
diagram: {
|
|
107
|
-
label: 'Diagram',
|
|
108
|
-
description:
|
|
109
|
-
'Renders sub-headings as connected nodes — edit visually as a node-and-edge diagram.',
|
|
110
|
-
},
|
|
111
|
-
tree: {
|
|
112
|
-
label: 'Tree',
|
|
113
|
-
description:
|
|
114
|
-
'Renders an ASCII file-tree / outline fence as a filesystem-style treeview — edit as an outline.',
|
|
115
|
-
},
|
|
116
|
-
timeline: {
|
|
117
|
-
label: 'Timeline',
|
|
118
|
-
description:
|
|
119
|
-
'Plots events across one or more horizontal tracks with callouts and optional branching links.',
|
|
120
|
-
},
|
|
121
|
-
layout: {
|
|
122
|
-
label: 'Layout',
|
|
123
|
-
description:
|
|
124
|
-
"Free-form 2D canvas — drag layers into place. Use for one-off block layouts that don't fit a template.",
|
|
125
|
-
},
|
|
126
|
-
drawing: {
|
|
127
|
-
label: 'Drawing',
|
|
128
|
-
description: 'Free-form sketches — draw shapes, paths, and text directly on a 2D surface.',
|
|
129
|
-
},
|
|
130
|
-
};
|
|
@@ -1,526 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Persistent Layers Expansion
|
|
3
|
-
*
|
|
4
|
-
* Expands persistent layer templates (solid backgrounds, gradients, overlays)
|
|
5
|
-
* into raw Layer arrays. These layers are injected into each block based on
|
|
6
|
-
* per-block flags (useBottomLayer, useTopLayer).
|
|
7
|
-
*
|
|
8
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
9
|
-
*
|
|
10
|
-
* Related Files:
|
|
11
|
-
* - schemas/BlockTemplates.ts - PersistentLayerConfig types
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
15
|
-
import type {
|
|
16
|
-
PersistentLayer,
|
|
17
|
-
PersistentLayerTemplate,
|
|
18
|
-
PersistentLayerConfig,
|
|
19
|
-
SolidBackgroundConfig,
|
|
20
|
-
GradientBackgroundConfig,
|
|
21
|
-
ImageBackgroundConfig,
|
|
22
|
-
PatternBackgroundConfig,
|
|
23
|
-
VignetteConfig,
|
|
24
|
-
AmbientGradientConfig,
|
|
25
|
-
TitleCaptionConfig,
|
|
26
|
-
CornerBrandingConfig,
|
|
27
|
-
ProgressIndicatorConfig,
|
|
28
|
-
} from '../../schemas/BlockTemplates.js';
|
|
29
|
-
import type { Theme } from '../../schemas/Theme.js';
|
|
30
|
-
import { cloneData } from '../../internal/immutable.js';
|
|
31
|
-
import { isPersistentLayerTemplate } from '../../schemas/BlockTemplates.js';
|
|
32
|
-
import { oklchDarken, withAlpha } from '../../schemas/colorUtils.js';
|
|
33
|
-
|
|
34
|
-
// ============================================
|
|
35
|
-
// Gradient Presets
|
|
36
|
-
// ============================================
|
|
37
|
-
|
|
38
|
-
const GRADIENT_PRESETS: Record<string, string> = {
|
|
39
|
-
'dark-vignette':
|
|
40
|
-
'radial-gradient(ellipse at center, rgba(26,32,44,0.8) 0%, rgba(0,0,0,0.95) 100%)',
|
|
41
|
-
'radial-dark': 'radial-gradient(ellipse at center, #1a202c 0%, #000000 100%)',
|
|
42
|
-
// Warm presets deepen within their own hue — ending in the shared navy
|
|
43
|
-
// made warm themes drift cold halfway down the frame.
|
|
44
|
-
'warm-sunset': 'linear-gradient(135deg, rgba(124,58,48,0.9) 0%, rgba(46,20,16,0.95) 100%)',
|
|
45
|
-
'cool-blue': 'linear-gradient(135deg, rgba(26,54,93,0.9) 0%, rgba(26,32,44,0.95) 100%)',
|
|
46
|
-
'earth-tones': 'linear-gradient(135deg, rgba(68,51,34,0.9) 0%, rgba(30,22,15,0.95) 100%)',
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// ============================================
|
|
50
|
-
// Background Layer Expansion
|
|
51
|
-
// ============================================
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Expand a solid background config to a Layer.
|
|
55
|
-
*/
|
|
56
|
-
function expandSolidBackground(config: SolidBackgroundConfig): Layer {
|
|
57
|
-
return {
|
|
58
|
-
type: 'shape',
|
|
59
|
-
id: 'persistent-bg-solid',
|
|
60
|
-
content: {
|
|
61
|
-
shape: 'rect',
|
|
62
|
-
fill: config.color,
|
|
63
|
-
},
|
|
64
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Expand a gradient background config to a Layer.
|
|
70
|
-
*/
|
|
71
|
-
function expandGradientBackground(config: GradientBackgroundConfig): Layer {
|
|
72
|
-
const gradient = config.gradient ?? GRADIENT_PRESETS[config.preset ?? 'dark-vignette'];
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
type: 'shape',
|
|
76
|
-
id: 'persistent-bg-gradient',
|
|
77
|
-
content: {
|
|
78
|
-
shape: 'rect',
|
|
79
|
-
fill: gradient,
|
|
80
|
-
},
|
|
81
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Expand an image background config to Layers.
|
|
87
|
-
* Returns multiple layers: base image + dark overlay for readability.
|
|
88
|
-
*/
|
|
89
|
-
function expandImageBackground(config: ImageBackgroundConfig): Layer[] {
|
|
90
|
-
const layers: Layer[] = [];
|
|
91
|
-
const opacity = config.opacity ?? 0.4;
|
|
92
|
-
|
|
93
|
-
// Base image layer. `blur` softens the photo into an atmosphere layer
|
|
94
|
-
// (the ImageLayer renderer over-scans blurred images so soft edges never
|
|
95
|
-
// reveal the frame).
|
|
96
|
-
const imageLayer: Layer = {
|
|
97
|
-
type: 'image',
|
|
98
|
-
id: 'persistent-bg-image',
|
|
99
|
-
content: {
|
|
100
|
-
src: config.src,
|
|
101
|
-
alt: 'Background',
|
|
102
|
-
fit: 'cover',
|
|
103
|
-
...(config.blur != null && config.blur > 0 ? { blur: config.blur } : {}),
|
|
104
|
-
},
|
|
105
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
106
|
-
animation: config.ambientMotion
|
|
107
|
-
? {
|
|
108
|
-
type: config.ambientMotion,
|
|
109
|
-
duration: 30, // Long ambient motion
|
|
110
|
-
}
|
|
111
|
-
: undefined,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
layers.push(imageLayer);
|
|
115
|
-
|
|
116
|
-
// Add dark overlay for text readability
|
|
117
|
-
layers.push({
|
|
118
|
-
type: 'shape',
|
|
119
|
-
id: 'persistent-bg-overlay',
|
|
120
|
-
content: {
|
|
121
|
-
shape: 'rect',
|
|
122
|
-
fill: `rgba(0,0,0,${0.5 + (1 - opacity) * 0.3})`,
|
|
123
|
-
},
|
|
124
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
return layers;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Expand a pattern background config to a Layer.
|
|
132
|
-
*/
|
|
133
|
-
function expandPatternBackground(config: PatternBackgroundConfig): Layer {
|
|
134
|
-
// 'noise' is film grain: a full-bleed rect whose paint is replaced by a
|
|
135
|
-
// static feTurbulence field clipped to the rect (see ShapeFilter).
|
|
136
|
-
if (config.pattern === 'noise') {
|
|
137
|
-
return {
|
|
138
|
-
type: 'shape',
|
|
139
|
-
id: 'persistent-grain',
|
|
140
|
-
content: {
|
|
141
|
-
shape: 'rect',
|
|
142
|
-
fill: '#000000',
|
|
143
|
-
filter: { type: 'noise', opacity: config.opacity ?? 0.05 },
|
|
144
|
-
},
|
|
145
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// dots / grid / diagonal render as native SVG <pattern> fills.
|
|
150
|
-
const opacity = config.opacity ?? 0.06;
|
|
151
|
-
return {
|
|
152
|
-
type: 'shape',
|
|
153
|
-
id: 'persistent-bg-pattern',
|
|
154
|
-
content: {
|
|
155
|
-
shape: 'rect',
|
|
156
|
-
pattern: {
|
|
157
|
-
kind: config.pattern,
|
|
158
|
-
color: config.color ?? '#ffffff',
|
|
159
|
-
size: Math.round(24 * (config.scale ?? 1)),
|
|
160
|
-
opacity,
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Expand a vignette config: transparent center darkening toward the frame
|
|
169
|
-
* edges. Rides the CSS-gradient rect path in the renderer.
|
|
170
|
-
*/
|
|
171
|
-
function expandVignette(config: VignetteConfig): Layer {
|
|
172
|
-
const strength = Math.max(0, Math.min(1, config.strength ?? 0.3));
|
|
173
|
-
const color = config.color ?? '#000000';
|
|
174
|
-
const edge = withAlpha(color, strength);
|
|
175
|
-
const clear = withAlpha(color, 0);
|
|
176
|
-
return {
|
|
177
|
-
type: 'shape',
|
|
178
|
-
id: 'persistent-vignette',
|
|
179
|
-
content: {
|
|
180
|
-
shape: 'rect',
|
|
181
|
-
fill: `radial-gradient(ellipse at center, ${clear} 55%, ${edge} 100%)`,
|
|
182
|
-
},
|
|
183
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Expand an ambient drifting gradient: an oversized surface gradient with
|
|
189
|
-
* a very slow Ken Burns loop. Deterministic (no randomness).
|
|
190
|
-
*/
|
|
191
|
-
function expandAmbientGradient(config: AmbientGradientConfig, theme?: Theme): Layer {
|
|
192
|
-
const from = config.from ?? theme?.colors.backgroundLight ?? '#1a202c';
|
|
193
|
-
const to = config.to ?? (theme ? oklchDarken(theme.colors.background, 0.04) : '#0f141d');
|
|
194
|
-
return {
|
|
195
|
-
type: 'shape',
|
|
196
|
-
id: 'persistent-ambient-gradient',
|
|
197
|
-
content: {
|
|
198
|
-
shape: 'rect',
|
|
199
|
-
fill: `linear-gradient(150deg, ${from} 0%, ${to} 100%)`,
|
|
200
|
-
},
|
|
201
|
-
// Oversized so the slow pan never reveals the frame edge.
|
|
202
|
-
position: { x: '-5%', y: '-5%', width: '110%', height: '110%' },
|
|
203
|
-
animation: { type: 'slowZoom', panDirection: 'left', duration: config.duration ?? 40 },
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// ============================================
|
|
208
|
-
// Overlay Layer Expansion
|
|
209
|
-
// ============================================
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Expand a title caption config to Layers.
|
|
213
|
-
*/
|
|
214
|
-
function expandTitleCaption(config: TitleCaptionConfig): Layer[] {
|
|
215
|
-
const layers: Layer[] = [];
|
|
216
|
-
const fontSize = config.fontSize ?? 18;
|
|
217
|
-
const hasSubtitle = !!config.subtitle;
|
|
218
|
-
|
|
219
|
-
// Position calculations
|
|
220
|
-
const isBottom = config.position.includes('bottom');
|
|
221
|
-
const isLeft = config.position.includes('left');
|
|
222
|
-
|
|
223
|
-
// Even padding around the pill (3% from edges)
|
|
224
|
-
const pad = 3; // percent
|
|
225
|
-
|
|
226
|
-
// Pill dimensions — taller when subtitle present
|
|
227
|
-
const pillHeight = hasSubtitle ? '15%' : '7%';
|
|
228
|
-
// Position above player controls
|
|
229
|
-
const bgYPos = isBottom ? (hasSubtitle ? '78%' : '84%') : '2%';
|
|
230
|
-
const bgXPos = isLeft ? `${pad}%` : '68%';
|
|
231
|
-
|
|
232
|
-
// Thumbnail sizing — use different width/height to appear square in 16:9 viewport
|
|
233
|
-
// In 16:9, 6% of width ≈ 10.7% of height in pixels, so use ~6%w x 10%h for visual square
|
|
234
|
-
const thumbW = hasSubtitle ? '6%' : '5%';
|
|
235
|
-
const thumbH = hasSubtitle ? '10%' : '5%';
|
|
236
|
-
const thumbPad = 1.5; // padding inside pill around thumbnail (percent)
|
|
237
|
-
|
|
238
|
-
// Text X offset: after thumbnail + padding, or just pill padding
|
|
239
|
-
const textX =
|
|
240
|
-
config.showThumbnail && isLeft
|
|
241
|
-
? `${pad + thumbPad + 6 + thumbPad}%` // pill edge + thumb padding + thumb width + gap
|
|
242
|
-
: `${pad + thumbPad}%`;
|
|
243
|
-
// Text area width: pill width minus thumbnail area minus padding
|
|
244
|
-
const textWidth = config.showThumbnail
|
|
245
|
-
? '19%' // narrower when thumbnail takes space
|
|
246
|
-
: '24%';
|
|
247
|
-
|
|
248
|
-
// Title Y: top of text area inside pill
|
|
249
|
-
const titleYPos = isBottom ? (hasSubtitle ? '80%' : '86%') : '4%';
|
|
250
|
-
|
|
251
|
-
// Background pill for readability
|
|
252
|
-
layers.push({
|
|
253
|
-
type: 'shape',
|
|
254
|
-
id: 'persistent-caption-bg',
|
|
255
|
-
content: {
|
|
256
|
-
shape: 'rect',
|
|
257
|
-
fill: 'rgba(0,0,0,0.6)',
|
|
258
|
-
borderRadius: 8,
|
|
259
|
-
},
|
|
260
|
-
position: {
|
|
261
|
-
x: bgXPos,
|
|
262
|
-
y: bgYPos,
|
|
263
|
-
width: config.showThumbnail ? '30%' : '28%',
|
|
264
|
-
height: pillHeight,
|
|
265
|
-
},
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
// Thumbnail if configured
|
|
269
|
-
if (config.showThumbnail && config.thumbnailSrc) {
|
|
270
|
-
const thumbX = isLeft ? `${pad + thumbPad}%` : '93%';
|
|
271
|
-
// Center thumbnail vertically in pill
|
|
272
|
-
const thumbY = isBottom ? (hasSubtitle ? `${78 + thumbPad}%` : '85%') : '3%';
|
|
273
|
-
|
|
274
|
-
layers.push({
|
|
275
|
-
type: 'image',
|
|
276
|
-
id: 'persistent-caption-thumb',
|
|
277
|
-
content: {
|
|
278
|
-
src: config.thumbnailSrc,
|
|
279
|
-
alt: 'Article thumbnail',
|
|
280
|
-
fit: 'cover',
|
|
281
|
-
},
|
|
282
|
-
position: {
|
|
283
|
-
x: thumbX,
|
|
284
|
-
y: thumbY,
|
|
285
|
-
width: thumbW,
|
|
286
|
-
height: thumbH,
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Title text — single line, cropped with ellipsis
|
|
292
|
-
layers.push({
|
|
293
|
-
type: 'text',
|
|
294
|
-
id: 'persistent-caption-title',
|
|
295
|
-
content: {
|
|
296
|
-
text: config.title,
|
|
297
|
-
style: {
|
|
298
|
-
fontSize,
|
|
299
|
-
fontWeight: 'bold',
|
|
300
|
-
color: 'rgba(255,255,255,0.9)',
|
|
301
|
-
textAlign: isLeft ? 'left' : 'right',
|
|
302
|
-
maxLines: 1,
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
position: {
|
|
306
|
-
x: textX,
|
|
307
|
-
y: titleYPos,
|
|
308
|
-
width: textWidth,
|
|
309
|
-
},
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// Subtitle text (e.g., short URL)
|
|
313
|
-
if (hasSubtitle) {
|
|
314
|
-
const subtitleYPos = isBottom ? '85.5%' : '8%';
|
|
315
|
-
|
|
316
|
-
layers.push({
|
|
317
|
-
type: 'text',
|
|
318
|
-
id: 'persistent-caption-subtitle',
|
|
319
|
-
content: {
|
|
320
|
-
text: config.subtitle!,
|
|
321
|
-
style: {
|
|
322
|
-
fontSize: 18,
|
|
323
|
-
fontWeight: 'normal',
|
|
324
|
-
color: 'rgba(255,255,255,0.55)',
|
|
325
|
-
textAlign: isLeft ? 'left' : 'right',
|
|
326
|
-
},
|
|
327
|
-
},
|
|
328
|
-
position: {
|
|
329
|
-
x: textX,
|
|
330
|
-
y: subtitleYPos,
|
|
331
|
-
width: textWidth,
|
|
332
|
-
},
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
return layers;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Expand a corner branding config to a Layer.
|
|
341
|
-
*/
|
|
342
|
-
function expandCornerBranding(config: CornerBrandingConfig): Layer {
|
|
343
|
-
const isBottom = config.position.includes('bottom');
|
|
344
|
-
const isLeft = config.position.includes('left');
|
|
345
|
-
|
|
346
|
-
const xPos = isLeft ? '3%' : '90%';
|
|
347
|
-
const yPos = isBottom ? '94%' : '3%';
|
|
348
|
-
|
|
349
|
-
if (config.isImage) {
|
|
350
|
-
return {
|
|
351
|
-
type: 'image',
|
|
352
|
-
id: 'persistent-branding',
|
|
353
|
-
content: {
|
|
354
|
-
src: config.content,
|
|
355
|
-
alt: 'Branding',
|
|
356
|
-
fit: 'contain',
|
|
357
|
-
},
|
|
358
|
-
position: {
|
|
359
|
-
x: xPos,
|
|
360
|
-
y: yPos,
|
|
361
|
-
width: '8%',
|
|
362
|
-
height: '4%',
|
|
363
|
-
},
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return {
|
|
368
|
-
type: 'text',
|
|
369
|
-
id: 'persistent-branding',
|
|
370
|
-
content: {
|
|
371
|
-
text: config.content,
|
|
372
|
-
style: {
|
|
373
|
-
fontSize: 14,
|
|
374
|
-
fontWeight: 'normal',
|
|
375
|
-
color: 'rgba(255,255,255,0.6)',
|
|
376
|
-
},
|
|
377
|
-
},
|
|
378
|
-
position: {
|
|
379
|
-
x: xPos,
|
|
380
|
-
y: yPos,
|
|
381
|
-
},
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Expand a progress indicator config to a Layer.
|
|
387
|
-
* Note: Progress requires block context, returns placeholder bar.
|
|
388
|
-
*/
|
|
389
|
-
function expandProgressIndicator(config: ProgressIndicatorConfig): Layer {
|
|
390
|
-
const color = config.color ?? 'rgba(255,255,255,0.3)';
|
|
391
|
-
const y = config.position === 'top' ? '1%' : '98%';
|
|
392
|
-
|
|
393
|
-
// Simple bar style - actual progress would need to be set per-block
|
|
394
|
-
return {
|
|
395
|
-
type: 'shape',
|
|
396
|
-
id: 'persistent-progress',
|
|
397
|
-
content: {
|
|
398
|
-
shape: 'rect',
|
|
399
|
-
fill: color,
|
|
400
|
-
borderRadius: 2,
|
|
401
|
-
},
|
|
402
|
-
position: {
|
|
403
|
-
x: '5%',
|
|
404
|
-
y,
|
|
405
|
-
width: '90%',
|
|
406
|
-
height: '0.5%',
|
|
407
|
-
},
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// ============================================
|
|
412
|
-
// Main Expansion Function
|
|
413
|
-
// ============================================
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Expand a single persistent layer (template or raw) to raw Layer(s).
|
|
417
|
-
*/
|
|
418
|
-
export function expandPersistentLayer(layer: PersistentLayer, theme?: Theme): Layer[] {
|
|
419
|
-
// If already a raw Layer, return an owned copy.
|
|
420
|
-
if (!isPersistentLayerTemplate(layer)) {
|
|
421
|
-
return [cloneData(layer as Layer)];
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
const template = layer as PersistentLayerTemplate;
|
|
425
|
-
const config = template.config;
|
|
426
|
-
|
|
427
|
-
switch (config.type) {
|
|
428
|
-
case 'solidBackground':
|
|
429
|
-
return [expandSolidBackground(config)];
|
|
430
|
-
case 'gradientBackground':
|
|
431
|
-
return [expandGradientBackground(config)];
|
|
432
|
-
case 'imageBackground':
|
|
433
|
-
return expandImageBackground(config);
|
|
434
|
-
case 'patternBackground':
|
|
435
|
-
return [expandPatternBackground(config)];
|
|
436
|
-
case 'vignette':
|
|
437
|
-
return [expandVignette(config)];
|
|
438
|
-
case 'ambientGradient':
|
|
439
|
-
return [expandAmbientGradient(config, theme)];
|
|
440
|
-
case 'titleCaption':
|
|
441
|
-
return expandTitleCaption(config);
|
|
442
|
-
case 'cornerBranding':
|
|
443
|
-
return [expandCornerBranding(config)];
|
|
444
|
-
case 'progressIndicator':
|
|
445
|
-
return [expandProgressIndicator(config)];
|
|
446
|
-
default:
|
|
447
|
-
console.warn('Unknown persistent layer template:', (config as Record<string, unknown>).type);
|
|
448
|
-
return [];
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Expand all persistent layers in a config to raw Layer arrays.
|
|
454
|
-
*/
|
|
455
|
-
export function expandPersistentLayers(
|
|
456
|
-
layers: PersistentLayer[] | undefined,
|
|
457
|
-
theme?: Theme,
|
|
458
|
-
): Layer[] {
|
|
459
|
-
if (!layers || layers.length === 0) {
|
|
460
|
-
return [];
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Use reduce+concat instead of flatMap for Coherent GT compatibility (ES2017)
|
|
464
|
-
return layers.reduce<Layer[]>(
|
|
465
|
-
(acc, layer) => acc.concat(expandPersistentLayer(layer, theme)),
|
|
466
|
-
[],
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Get persistent layers from a Theme. Returns the theme's baked-in
|
|
472
|
-
* persistentLayers config, or an empty config when the theme has none.
|
|
473
|
-
*/
|
|
474
|
-
export function getPersistentLayersFromTheme(theme: Theme): PersistentLayerConfig {
|
|
475
|
-
return theme.persistentLayers ?? {};
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Resolve the effective persistent-layer config for a doc: the doc's own
|
|
480
|
-
* config wins **wholesale** when present; only docs with no persistent
|
|
481
|
-
* layers inherit the theme's.
|
|
482
|
-
*
|
|
483
|
-
* Doc-wins-wholesale (rather than merging) protects pre-baked documents
|
|
484
|
-
* that carry their own background/branding layers — merging a theme's
|
|
485
|
-
* atmosphere on top of those would double up backgrounds and stack
|
|
486
|
-
* overlays the doc author never saw.
|
|
487
|
-
*/
|
|
488
|
-
export function resolvePersistentLayers(
|
|
489
|
-
doc: { persistentLayers?: PersistentLayerConfig },
|
|
490
|
-
theme: Theme,
|
|
491
|
-
): PersistentLayerConfig | undefined {
|
|
492
|
-
const docConfig = doc.persistentLayers;
|
|
493
|
-
const hasDocLayers =
|
|
494
|
-
!!docConfig &&
|
|
495
|
-
((docConfig.bottomLayers?.length ?? 0) > 0 || (docConfig.topLayers?.length ?? 0) > 0);
|
|
496
|
-
if (hasDocLayers) return docConfig;
|
|
497
|
-
const themeConfig = theme.persistentLayers;
|
|
498
|
-
const hasThemeLayers =
|
|
499
|
-
!!themeConfig &&
|
|
500
|
-
((themeConfig.bottomLayers?.length ?? 0) > 0 || (themeConfig.topLayers?.length ?? 0) > 0);
|
|
501
|
-
return hasThemeLayers ? themeConfig : docConfig;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Compose a block's layers between pre-expanded persistent bottom/top
|
|
506
|
-
* layers, honoring the per-block `useBottomLayer` / `useTopLayer` opt-outs.
|
|
507
|
-
* Shared persistent-layer primitive used by `materializeBlockLayers`.
|
|
508
|
-
*/
|
|
509
|
-
export function wrapWithPersistentLayers(
|
|
510
|
-
layers: Layer[],
|
|
511
|
-
block: { useBottomLayer?: boolean; useTopLayer?: boolean },
|
|
512
|
-
bottomLayers: Layer[],
|
|
513
|
-
topLayers: Layer[],
|
|
514
|
-
): Layer[] {
|
|
515
|
-
if (bottomLayers.length === 0 && topLayers.length === 0) return layers;
|
|
516
|
-
const useBottom = block.useBottomLayer !== false;
|
|
517
|
-
const useTop = block.useTopLayer !== false;
|
|
518
|
-
// Each expanded block owns its persistent layers. This prevents a renderer
|
|
519
|
-
// (or a later timing/style pass) from mutating the caller's config or a
|
|
520
|
-
// sibling block through a shared layer reference.
|
|
521
|
-
return [
|
|
522
|
-
...(useBottom ? bottomLayers.map((layer) => cloneData(layer)) : []),
|
|
523
|
-
...layers,
|
|
524
|
-
...(useTop ? topLayers.map((layer) => cloneData(layer)) : []),
|
|
525
|
-
];
|
|
526
|
-
}
|