@bendyline/squisq 2.1.0 → 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-DynJleo-.d.ts → Doc-BubIpWsp.d.ts} +1 -1
- package/dist/{ImageEditDoc-Ca4Tr9uN.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-VWCJ2WXC.js → chunk-2ZWIXGAC.js} +0 -1
- package/dist/{chunk-VYFRI7R6.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-JI77MGAK.js → chunk-7ARJZYQY.js} +159 -120
- 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-JHZWYRSW.js → chunk-C33GTPUZ.js} +11 -4
- package/dist/{chunk-QUUPYOSP.js → chunk-CB45YGAM.js} +2 -3
- package/dist/{chunk-XNLB57UD.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-OTKVFVL6.js → chunk-I2O6W7DX.js} +116 -44
- 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-ILWDXLUK.js → chunk-RS5AP3J4.js} +49 -10
- 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 +27 -12
- package/dist/doc/index.js +16 -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 +11 -11
- package/dist/index.js +60 -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-DDzubQXo.d.ts → materializePageSection-wSLA2A1g.d.ts} +2 -2
- 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 +5 -5
- package/dist/schemas/index.js +5 -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-B72m0W1y.d.ts → themeLibrary-DU9mUmVl.d.ts} +1 -1
- package/dist/timing/index.js +3 -4
- package/dist/transform/index.d.ts +3 -3
- 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-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-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-FVTQSNR7.js.map +0 -1
- package/dist/chunk-GZY66SDN.js.map +0 -1
- package/dist/chunk-ILWDXLUK.js.map +0 -1
- package/dist/chunk-JHZWYRSW.js.map +0 -1
- package/dist/chunk-JI77MGAK.js.map +0 -1
- package/dist/chunk-JOQYPRDZ.js.map +0 -1
- package/dist/chunk-OTKVFVL6.js.map +0 -1
- package/dist/chunk-PGGGKYWG.js +0 -1
- package/dist/chunk-PGGGKYWG.js.map +0 -1
- package/dist/chunk-Q7LROV2H.js.map +0 -1
- package/dist/chunk-QE7TWGVT.js.map +0 -1
- package/dist/chunk-QUUPYOSP.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-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-VWCJ2WXC.js.map +0 -1
- package/dist/chunk-VYFRI7R6.js.map +0 -1
- package/dist/chunk-XNLB57UD.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 -167
- package/src/__tests__/materializePageSections.test.ts +0 -404
- 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__/pageStyle.test.ts +0 -258
- 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 -173
- 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 -161
- package/src/doc/markdownToDoc.ts +0 -1054
- package/src/doc/materializeBlockLayers.ts +0 -465
- package/src/doc/mediaAnnotations.ts +0 -120
- package/src/doc/page/PageSection.ts +0 -174
- package/src/doc/page/materializePageSection.ts +0 -616
- package/src/doc/page/resolvePageBlock.ts +0 -108
- package/src/doc/page/sectionExtractors.ts +0 -466
- package/src/doc/pageCss.ts +0 -628
- 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 -424
- 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 -1073
- 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/PageStyle.ts +0 -213
- package/src/schemas/Theme.ts +0 -413
- 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 -31
- package/src/schemas/pageStyleDefaults.ts +0 -204
- package/src/schemas/themeCompile.ts +0 -244
- package/src/schemas/themeConstants.ts +0 -2
- package/src/schemas/themeLibrary.ts +0 -60
- package/src/schemas/themeValidator.ts +0 -609
- package/src/schemas/themes/bold.json +0 -77
- package/src/schemas/themes/cinematic.json +0 -143
- package/src/schemas/themes/documentary.json +0 -125
- package/src/schemas/themes/gezellig.json +0 -123
- package/src/schemas/themes/index.ts +0 -53
- package/src/schemas/themes/magazine.json +0 -126
- package/src/schemas/themes/minimalist.json +0 -74
- package/src/schemas/themes/morning-light.json +0 -117
- package/src/schemas/themes/standard-dark.json +0 -109
- package/src/schemas/themes/standard.json +0 -98
- package/src/schemas/themes/tech-dark.json +0 -143
- package/src/schemas/themes/warm-earth.json +0 -74
- 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 -217
- package/src/transform/styles/dataDriven.ts +0 -18
- package/src/transform/styles/documentary.ts +0 -18
- package/src/transform/styles/index.ts +0 -5
- package/src/transform/styles/magazine.ts +0 -19
- package/src/transform/styles/minimal.ts +0 -18
- package/src/transform/styles/narrative.ts +0 -19
- package/src/transform/templateSelector.ts +0 -389
- package/src/transform/timingAllocator.ts +0 -257
- package/src/transform/types.ts +0 -158
- 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,263 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Two Column Template
|
|
3
|
-
*
|
|
4
|
-
* Side-by-side comparison of two items.
|
|
5
|
-
* Each column has a label and optional sublabel.
|
|
6
|
-
* Adapts font sizes and positioning for different viewports.
|
|
7
|
-
*
|
|
8
|
-
* Portrait mode: Stacks columns vertically (top/bottom) instead of side-by-side.
|
|
9
|
-
*
|
|
10
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
14
|
-
import type { TwoColumnInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
15
|
-
import {
|
|
16
|
-
resolveColorScheme,
|
|
17
|
-
getThemeFont,
|
|
18
|
-
themedEntrance,
|
|
19
|
-
themedFontSize,
|
|
20
|
-
themedSurfaceGradient,
|
|
21
|
-
} from '../utils/themeUtils.js';
|
|
22
|
-
import { withAlpha } from '../../schemas/colorUtils.js';
|
|
23
|
-
import { getTwoColumnPositions } from '../../schemas/LayoutStrategy.js';
|
|
24
|
-
|
|
25
|
-
export function twoColumn(input: TwoColumnInput, context: TemplateContext): Layer[] {
|
|
26
|
-
const { left, right, header, leftColor = 'green', rightColor = 'blue' } = input;
|
|
27
|
-
|
|
28
|
-
// Guard: required fields may be absent when generated from sparse markdown
|
|
29
|
-
if (!left?.label || !right?.label) return [];
|
|
30
|
-
|
|
31
|
-
const { theme, layout, orientation } = context;
|
|
32
|
-
const leftColors = resolveColorScheme(context, leftColor);
|
|
33
|
-
const rightColors = resolveColorScheme(context, rightColor);
|
|
34
|
-
|
|
35
|
-
// Get column positions based on orientation
|
|
36
|
-
const positions = getTwoColumnPositions(orientation);
|
|
37
|
-
const isStacked = layout.stackColumns;
|
|
38
|
-
|
|
39
|
-
// Column width ~42% for side-by-side, ~85% for stacked
|
|
40
|
-
const columnWidth = isStacked ? '85%' : '42%';
|
|
41
|
-
|
|
42
|
-
// Calculate font sizes based on viewport. The header is the block's
|
|
43
|
-
// title, so it sits a step ABOVE the column labels in the hierarchy —
|
|
44
|
-
// it used to render smaller and dimmer than the labels, which read as
|
|
45
|
-
// an inverted hierarchy.
|
|
46
|
-
const headerFontSize = themedFontSize(36, context, true);
|
|
47
|
-
const labelFontSize = themedFontSize(44, context, true);
|
|
48
|
-
const sublabelFontSize = themedFontSize(22, context, false);
|
|
49
|
-
|
|
50
|
-
// Panels drop below the header band so the title never overlaps them.
|
|
51
|
-
const panelTop = header && !isStacked ? 22 : 15;
|
|
52
|
-
const panelHeight = header && !isStacked ? 64 : 70;
|
|
53
|
-
|
|
54
|
-
const layers: Layer[] = [
|
|
55
|
-
// Background — subtle gradient to add depth
|
|
56
|
-
{
|
|
57
|
-
type: 'shape',
|
|
58
|
-
id: 'bg',
|
|
59
|
-
content: {
|
|
60
|
-
shape: 'rect',
|
|
61
|
-
fill: themedSurfaceGradient(context, 135),
|
|
62
|
-
},
|
|
63
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
64
|
-
},
|
|
65
|
-
];
|
|
66
|
-
|
|
67
|
-
if (!isStacked) {
|
|
68
|
-
// Column background panels — tinted from the theme text color so
|
|
69
|
-
// they stay visible on light and dark surfaces alike.
|
|
70
|
-
const panelFill = withAlpha(theme.colors.text, 0.05);
|
|
71
|
-
layers.push({
|
|
72
|
-
type: 'shape',
|
|
73
|
-
id: 'left-panel',
|
|
74
|
-
content: {
|
|
75
|
-
shape: 'rect',
|
|
76
|
-
fill: panelFill,
|
|
77
|
-
borderRadius: 12,
|
|
78
|
-
},
|
|
79
|
-
position: { x: '3%', y: `${panelTop}%`, width: '44%', height: `${panelHeight}%` },
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
layers.push({
|
|
83
|
-
type: 'shape',
|
|
84
|
-
id: 'right-panel',
|
|
85
|
-
content: {
|
|
86
|
-
shape: 'rect',
|
|
87
|
-
fill: panelFill,
|
|
88
|
-
borderRadius: 12,
|
|
89
|
-
},
|
|
90
|
-
position: { x: '53%', y: `${panelTop}%`, width: '44%', height: `${panelHeight}%` },
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Header position adjusts based on layout — always clear of the panels.
|
|
95
|
-
const headerY = isStacked ? '8%' : '12%';
|
|
96
|
-
|
|
97
|
-
// Add header if provided
|
|
98
|
-
if (header) {
|
|
99
|
-
layers.push({
|
|
100
|
-
type: 'text',
|
|
101
|
-
id: 'header',
|
|
102
|
-
content: {
|
|
103
|
-
text: header,
|
|
104
|
-
style: {
|
|
105
|
-
fontSize: headerFontSize,
|
|
106
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
107
|
-
fontWeight: 'bold',
|
|
108
|
-
color: theme.colors.text,
|
|
109
|
-
textAlign: 'center',
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
position: { x: '50%', y: headerY, anchor: 'center' },
|
|
113
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 0.8 }),
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Calculate Y positions based on layout mode and header presence
|
|
118
|
-
let leftY: string;
|
|
119
|
-
let leftSublabelY: string;
|
|
120
|
-
let rightY: string;
|
|
121
|
-
let rightSublabelY: string;
|
|
122
|
-
|
|
123
|
-
if (isStacked) {
|
|
124
|
-
// Portrait: stacked vertically
|
|
125
|
-
leftY = header ? '30%' : '25%';
|
|
126
|
-
leftSublabelY = header ? '40%' : '35%';
|
|
127
|
-
rightY = header ? '60%' : '55%';
|
|
128
|
-
rightSublabelY = header ? '70%' : '65%';
|
|
129
|
-
} else {
|
|
130
|
-
// Landscape/square: side by side — vertically centered in the panels.
|
|
131
|
-
const panelCenter = panelTop + panelHeight / 2;
|
|
132
|
-
leftY = `${panelCenter - 4}%`;
|
|
133
|
-
leftSublabelY = `${panelCenter + 7}%`;
|
|
134
|
-
rightY = `${panelCenter - 4}%`;
|
|
135
|
-
rightSublabelY = `${panelCenter + 7}%`;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Left column (or top in portrait)
|
|
139
|
-
layers.push({
|
|
140
|
-
type: 'text',
|
|
141
|
-
id: 'left-label',
|
|
142
|
-
content: {
|
|
143
|
-
text: left.label,
|
|
144
|
-
style: {
|
|
145
|
-
fontSize: labelFontSize,
|
|
146
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
147
|
-
fontWeight: 'bold',
|
|
148
|
-
color: leftColors.text,
|
|
149
|
-
textAlign: 'center',
|
|
150
|
-
lineHeight: 1.3,
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
position: {
|
|
154
|
-
x: positions.left.x,
|
|
155
|
-
y: leftY,
|
|
156
|
-
anchor: 'center',
|
|
157
|
-
width: columnWidth,
|
|
158
|
-
},
|
|
159
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 1 }),
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
if (left.sublabel) {
|
|
163
|
-
layers.push({
|
|
164
|
-
type: 'text',
|
|
165
|
-
id: 'left-sublabel',
|
|
166
|
-
content: {
|
|
167
|
-
text: left.sublabel,
|
|
168
|
-
style: {
|
|
169
|
-
fontSize: sublabelFontSize,
|
|
170
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
171
|
-
color: theme.colors.textMuted,
|
|
172
|
-
textAlign: 'center',
|
|
173
|
-
lineHeight: 1.4,
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
position: {
|
|
177
|
-
x: positions.left.x,
|
|
178
|
-
y: leftSublabelY,
|
|
179
|
-
anchor: 'center',
|
|
180
|
-
width: columnWidth,
|
|
181
|
-
},
|
|
182
|
-
animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 },
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Visual connector between columns — sized to fit inside the gutter
|
|
187
|
-
// between the panels (a 120px glyph used to cross both panel edges),
|
|
188
|
-
// tinted from the theme text color so it shows on any surface.
|
|
189
|
-
const connectorFontSize = themedFontSize(64, context, true);
|
|
190
|
-
const connectorY = isStacked ? '48%' : `${panelTop + panelHeight / 2}%`;
|
|
191
|
-
const connectorSymbol = isStacked ? '\u2193' : '\u2192'; // ↓ for stacked, → for side-by-side
|
|
192
|
-
|
|
193
|
-
layers.push({
|
|
194
|
-
type: 'text',
|
|
195
|
-
id: 'connector',
|
|
196
|
-
content: {
|
|
197
|
-
text: connectorSymbol,
|
|
198
|
-
style: {
|
|
199
|
-
fontSize: connectorFontSize,
|
|
200
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
201
|
-
fontWeight: 'bold',
|
|
202
|
-
color: withAlpha(theme.colors.text, 0.45),
|
|
203
|
-
textAlign: 'center',
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
position: {
|
|
207
|
-
x: '50%',
|
|
208
|
-
y: connectorY,
|
|
209
|
-
anchor: 'center',
|
|
210
|
-
},
|
|
211
|
-
animation: { type: 'fadeIn', duration: 0.6, delay: 0.4 },
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// Right column (or bottom in portrait)
|
|
215
|
-
layers.push({
|
|
216
|
-
type: 'text',
|
|
217
|
-
id: 'right-label',
|
|
218
|
-
content: {
|
|
219
|
-
text: right.label,
|
|
220
|
-
style: {
|
|
221
|
-
fontSize: labelFontSize,
|
|
222
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
223
|
-
fontWeight: 'bold',
|
|
224
|
-
color: rightColors.text,
|
|
225
|
-
textAlign: 'center',
|
|
226
|
-
lineHeight: 1.3,
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
position: {
|
|
230
|
-
x: positions.right.x,
|
|
231
|
-
y: rightY,
|
|
232
|
-
anchor: 'center',
|
|
233
|
-
width: columnWidth,
|
|
234
|
-
},
|
|
235
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 1, delay: 0.5 }),
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
if (right.sublabel) {
|
|
239
|
-
layers.push({
|
|
240
|
-
type: 'text',
|
|
241
|
-
id: 'right-sublabel',
|
|
242
|
-
content: {
|
|
243
|
-
text: right.sublabel,
|
|
244
|
-
style: {
|
|
245
|
-
fontSize: sublabelFontSize,
|
|
246
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
247
|
-
color: theme.colors.textMuted,
|
|
248
|
-
textAlign: 'center',
|
|
249
|
-
lineHeight: 1.4,
|
|
250
|
-
},
|
|
251
|
-
},
|
|
252
|
-
position: {
|
|
253
|
-
x: positions.right.x,
|
|
254
|
-
y: rightSublabelY,
|
|
255
|
-
anchor: 'center',
|
|
256
|
-
width: columnWidth,
|
|
257
|
-
},
|
|
258
|
-
animation: { type: 'fadeIn', duration: 0.8, delay: 0.8 },
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return layers;
|
|
263
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Video Pull Quote Template
|
|
3
|
-
*
|
|
4
|
-
* Quote text over a video clip background with dark overlay.
|
|
5
|
-
* Cinematic alternative to pullQuote when a video clip is available.
|
|
6
|
-
* Combines the visual dynamism of live video with the text focus of quoteBlock.
|
|
7
|
-
*
|
|
8
|
-
* The video plays muted — narration audio is the only sound track.
|
|
9
|
-
*
|
|
10
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
11
|
-
*
|
|
12
|
-
* Related Files:
|
|
13
|
-
* - shared/story/templates/pullQuote.ts — image-based equivalent
|
|
14
|
-
* - schemas/StoryScript.ts — VideoLayer type
|
|
15
|
-
* - site/src/components/story/layers/VideoLayer.tsx — rendering component
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
19
|
-
import type { VideoPullQuoteInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
20
|
-
import { getThemeFont, themedEntrance, themedFontSize } from '../utils/themeUtils.js';
|
|
21
|
-
import { estimateTextHeight } from './captionUtils.js';
|
|
22
|
-
|
|
23
|
-
export function videoPullQuote(input: VideoPullQuoteInput, context: TemplateContext): Layer[] {
|
|
24
|
-
const { text, attribution, backgroundVideo } = input;
|
|
25
|
-
const { viewport } = context;
|
|
26
|
-
|
|
27
|
-
// Guard: backgroundVideo is required
|
|
28
|
-
if (!backgroundVideo?.src) return [];
|
|
29
|
-
|
|
30
|
-
const quoteFontSize = themedFontSize(52, context, true);
|
|
31
|
-
const attrFontSize = themedFontSize(26, context, false);
|
|
32
|
-
const decoFontSize = themedFontSize(200, context, true);
|
|
33
|
-
const quoteLineHeight = 1.4;
|
|
34
|
-
const quoteYPct = attribution ? 45 : 50;
|
|
35
|
-
|
|
36
|
-
const layers: Layer[] = [
|
|
37
|
-
// Full-bleed background video clip
|
|
38
|
-
{
|
|
39
|
-
type: 'video',
|
|
40
|
-
id: 'bg-video',
|
|
41
|
-
content: {
|
|
42
|
-
src: backgroundVideo.src,
|
|
43
|
-
posterSrc: backgroundVideo.posterSrc,
|
|
44
|
-
alt: backgroundVideo.alt,
|
|
45
|
-
fit: 'cover',
|
|
46
|
-
clipStart: backgroundVideo.clipStart,
|
|
47
|
-
clipEnd: backgroundVideo.clipEnd,
|
|
48
|
-
credit: backgroundVideo.credit,
|
|
49
|
-
license: backgroundVideo.license,
|
|
50
|
-
},
|
|
51
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
// Dark overlay for text readability
|
|
55
|
-
{
|
|
56
|
-
type: 'shape',
|
|
57
|
-
id: 'overlay',
|
|
58
|
-
content: {
|
|
59
|
-
shape: 'rect',
|
|
60
|
-
fill: 'rgba(0, 0, 0, 0.55)',
|
|
61
|
-
},
|
|
62
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
// Decorative quotation mark
|
|
66
|
-
{
|
|
67
|
-
type: 'text',
|
|
68
|
-
id: 'deco-quote',
|
|
69
|
-
content: {
|
|
70
|
-
text: '\u201C',
|
|
71
|
-
style: {
|
|
72
|
-
fontSize: decoFontSize,
|
|
73
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
74
|
-
color: 'rgba(255, 255, 255, 0.08)',
|
|
75
|
-
textAlign: 'center',
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
position: {
|
|
79
|
-
x: '50%',
|
|
80
|
-
y: '20%',
|
|
81
|
-
anchor: 'center',
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
// Quote text
|
|
86
|
-
{
|
|
87
|
-
type: 'text',
|
|
88
|
-
id: 'quote-text',
|
|
89
|
-
content: {
|
|
90
|
-
text,
|
|
91
|
-
style: {
|
|
92
|
-
fontSize: quoteFontSize,
|
|
93
|
-
fontFamily: getThemeFont(context, 'title'),
|
|
94
|
-
color: '#ffffff',
|
|
95
|
-
textAlign: 'center',
|
|
96
|
-
lineHeight: quoteLineHeight,
|
|
97
|
-
shadow: true,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
position: {
|
|
101
|
-
x: '50%',
|
|
102
|
-
y: `${quoteYPct}%`,
|
|
103
|
-
anchor: 'center',
|
|
104
|
-
width: '72%',
|
|
105
|
-
},
|
|
106
|
-
animation: themedEntrance(context, 'text', { type: 'fadeIn', duration: 2 }),
|
|
107
|
-
},
|
|
108
|
-
];
|
|
109
|
-
|
|
110
|
-
// Attribution \u2014 hangs just below the quote's estimated bottom edge so
|
|
111
|
-
// the two read as one lockup instead of stranding near the bottom.
|
|
112
|
-
if (attribution) {
|
|
113
|
-
const quoteWidthPx = 0.72 * viewport.width;
|
|
114
|
-
const quoteHeightPx = estimateTextHeight(text, quoteFontSize, quoteWidthPx, quoteLineHeight);
|
|
115
|
-
const attrYPct = Math.min(
|
|
116
|
-
82,
|
|
117
|
-
quoteYPct + ((quoteHeightPx / 2 + quoteFontSize * 1.7) / viewport.height) * 100,
|
|
118
|
-
);
|
|
119
|
-
layers.push({
|
|
120
|
-
type: 'text',
|
|
121
|
-
id: 'attribution',
|
|
122
|
-
content: {
|
|
123
|
-
text: `\u2014 ${attribution}`,
|
|
124
|
-
style: {
|
|
125
|
-
fontSize: attrFontSize,
|
|
126
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
127
|
-
color: 'rgba(255, 255, 255, 0.85)',
|
|
128
|
-
textAlign: 'center',
|
|
129
|
-
shadow: true,
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
position: {
|
|
133
|
-
x: '50%',
|
|
134
|
-
y: `${attrYPct}%`,
|
|
135
|
-
anchor: 'center',
|
|
136
|
-
},
|
|
137
|
-
animation: { type: 'fadeIn', duration: 1, delay: 1.5 },
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return layers;
|
|
142
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Video With Caption Template
|
|
3
|
-
*
|
|
4
|
-
* Full-screen background video clip with text overlay. Mirrors the structure of
|
|
5
|
-
* imageWithCaption but uses a VideoLayer instead of an ImageLayer. The video
|
|
6
|
-
* plays muted — narration audio is the only sound track.
|
|
7
|
-
*
|
|
8
|
-
* Adapts caption positioning and font sizes for different viewports.
|
|
9
|
-
*
|
|
10
|
-
* This is shared code used by both site and efb-app doc renderers.
|
|
11
|
-
*
|
|
12
|
-
* Related Files:
|
|
13
|
-
* - shared/story/templates/imageWithCaption.ts — image equivalent
|
|
14
|
-
* - schemas/StoryScript.ts — VideoLayer type
|
|
15
|
-
* - site/src/components/story/layers/VideoLayer.tsx — rendering component
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import type { Layer } from '../../schemas/Doc.js';
|
|
19
|
-
import type { VideoWithCaptionInput, TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
20
|
-
import { getThemeFont, shouldUseShadow, themedFontSize } from '../utils/themeUtils.js';
|
|
21
|
-
import { withAlpha } from '../../schemas/colorUtils.js';
|
|
22
|
-
import { cleanCaption } from './captionUtils.js';
|
|
23
|
-
|
|
24
|
-
export function videoWithCaption(input: VideoWithCaptionInput, context: TemplateContext): Layer[] {
|
|
25
|
-
const {
|
|
26
|
-
videoSrc,
|
|
27
|
-
posterSrc,
|
|
28
|
-
videoAlt,
|
|
29
|
-
clipStart,
|
|
30
|
-
clipEnd,
|
|
31
|
-
sourceDuration,
|
|
32
|
-
caption: rawCaption,
|
|
33
|
-
captionPosition = 'bottom',
|
|
34
|
-
videoCredit,
|
|
35
|
-
videoLicense,
|
|
36
|
-
} = input;
|
|
37
|
-
const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;
|
|
38
|
-
const { theme } = context;
|
|
39
|
-
|
|
40
|
-
const captionFontSize = themedFontSize(30, context, false);
|
|
41
|
-
const creditFontSize = themedFontSize(16, context, false);
|
|
42
|
-
|
|
43
|
-
const layers: Layer[] = [
|
|
44
|
-
// Background video clip
|
|
45
|
-
{
|
|
46
|
-
type: 'video',
|
|
47
|
-
id: 'bg-video',
|
|
48
|
-
content: {
|
|
49
|
-
src: videoSrc,
|
|
50
|
-
posterSrc,
|
|
51
|
-
alt: videoAlt,
|
|
52
|
-
fit: 'cover',
|
|
53
|
-
clipStart,
|
|
54
|
-
clipEnd,
|
|
55
|
-
sourceDuration,
|
|
56
|
-
credit: videoCredit,
|
|
57
|
-
license: videoLicense,
|
|
58
|
-
},
|
|
59
|
-
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
// Caption text with a compact translucent band. Long archival captions are
|
|
64
|
-
// clamped so they don't collide with player controls or cover the frame.
|
|
65
|
-
if (caption) {
|
|
66
|
-
const bg = theme.colors.background;
|
|
67
|
-
const captionBgY =
|
|
68
|
-
captionPosition === 'top' ? '7%' : captionPosition === 'center' ? '42%' : '68%';
|
|
69
|
-
const captionY =
|
|
70
|
-
captionPosition === 'top' ? '13%' : captionPosition === 'center' ? '48%' : '74%';
|
|
71
|
-
|
|
72
|
-
layers.push({
|
|
73
|
-
type: 'shape',
|
|
74
|
-
id: 'caption-gradient',
|
|
75
|
-
content: {
|
|
76
|
-
shape: 'rect',
|
|
77
|
-
fill: `linear-gradient(90deg, ${withAlpha(bg, 0)}, ${withAlpha(bg, 0.78)} 16%, ${withAlpha(bg, 0.78)} 84%, ${withAlpha(bg, 0)})`,
|
|
78
|
-
},
|
|
79
|
-
position: {
|
|
80
|
-
x: 0,
|
|
81
|
-
y: captionBgY,
|
|
82
|
-
width: '100%',
|
|
83
|
-
height: '16%',
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
layers.push({
|
|
88
|
-
type: 'text',
|
|
89
|
-
id: 'caption',
|
|
90
|
-
content: {
|
|
91
|
-
text: caption,
|
|
92
|
-
style: {
|
|
93
|
-
fontSize: captionFontSize,
|
|
94
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
95
|
-
color: theme.colors.text,
|
|
96
|
-
textAlign: 'center',
|
|
97
|
-
shadow: shouldUseShadow(context),
|
|
98
|
-
lineHeight: 1.18,
|
|
99
|
-
maxLines: 2,
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
position: {
|
|
103
|
-
x: '50%',
|
|
104
|
-
y: captionY,
|
|
105
|
-
anchor: 'center',
|
|
106
|
-
width: '78%',
|
|
107
|
-
},
|
|
108
|
-
animation: { type: 'fadeIn', duration: 1.5, delay: 0.5 },
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Small credit text in bottom-right corner
|
|
113
|
-
if (videoCredit) {
|
|
114
|
-
layers.push({
|
|
115
|
-
type: 'text',
|
|
116
|
-
id: 'credit',
|
|
117
|
-
content: {
|
|
118
|
-
text: videoCredit,
|
|
119
|
-
style: {
|
|
120
|
-
fontSize: creditFontSize,
|
|
121
|
-
fontFamily: getThemeFont(context, 'body'),
|
|
122
|
-
color: withAlpha(theme.colors.text, 0.65),
|
|
123
|
-
textAlign: 'right',
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
position: {
|
|
127
|
-
x: '96%',
|
|
128
|
-
y: '96%',
|
|
129
|
-
anchor: 'bottom-right',
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return layers;
|
|
135
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Character classification + render vocabularies for ASCII tree art.
|
|
3
|
-
*
|
|
4
|
-
* The parser accepts a superset (Unicode light/heavy/rounded branches plus
|
|
5
|
-
* ASCII `|-- ` / `` `-- `` / `+-- `); the renderer emits one `TreeVocab`.
|
|
6
|
-
* Internal to the treeview module.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/** Vertical rail glyphs (an ancestor line continuing downward). */
|
|
10
|
-
const RAIL_CHARS = new Set(['│', '┃', '╎', '╏', '║', '|']);
|
|
11
|
-
/** Branch-tee glyphs (a node that has a following sibling). */
|
|
12
|
-
const BRANCH_TEE = new Set(['├', '┣', '┠', '┝', '╠', '╞']);
|
|
13
|
-
/** Branch-elbow glyphs (the last child). */
|
|
14
|
-
const BRANCH_ELBOW = new Set(['└', '┗', '╰', '╚', '╘']);
|
|
15
|
-
/** Horizontal dash glyphs used in a branch arm. */
|
|
16
|
-
const DASH_CHARS = new Set(['─', '━', '═', '-']);
|
|
17
|
-
|
|
18
|
-
export function isRailChar(ch: string): boolean {
|
|
19
|
-
return RAIL_CHARS.has(ch);
|
|
20
|
-
}
|
|
21
|
-
export function isBranchTee(ch: string): boolean {
|
|
22
|
-
return BRANCH_TEE.has(ch);
|
|
23
|
-
}
|
|
24
|
-
export function isBranchElbow(ch: string): boolean {
|
|
25
|
-
return BRANCH_ELBOW.has(ch);
|
|
26
|
-
}
|
|
27
|
-
export function isUnicodeBranch(ch: string): boolean {
|
|
28
|
-
return BRANCH_TEE.has(ch) || BRANCH_ELBOW.has(ch);
|
|
29
|
-
}
|
|
30
|
-
export function isDashChar(ch: string): boolean {
|
|
31
|
-
return DASH_CHARS.has(ch);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Structural glyphs used for the style vote. */
|
|
35
|
-
export function isUnicodeTreeChar(ch: string): boolean {
|
|
36
|
-
return (
|
|
37
|
-
BRANCH_TEE.has(ch) ||
|
|
38
|
-
BRANCH_ELBOW.has(ch) ||
|
|
39
|
-
ch === '│' ||
|
|
40
|
-
ch === '┃' ||
|
|
41
|
-
ch === '─' ||
|
|
42
|
-
ch === '━'
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
export function isAsciiTreeChar(ch: string): boolean {
|
|
46
|
-
return ch === '|' || ch === '`' || ch === '+' || ch === '-';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface TreeVocab {
|
|
50
|
-
/** Branch to a node that has a later sibling (`├── `). */
|
|
51
|
-
tee: string;
|
|
52
|
-
/** Branch to the last child (`└── `). */
|
|
53
|
-
elbow: string;
|
|
54
|
-
/** Ancestor rail column (`│ `). */
|
|
55
|
-
rail: string;
|
|
56
|
-
/** Ended-ancestor gap column (` `). */
|
|
57
|
-
gap: string;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const UNICODE_TREE_VOCAB: TreeVocab = {
|
|
61
|
-
tee: '├── ',
|
|
62
|
-
elbow: '└── ',
|
|
63
|
-
rail: '│ ',
|
|
64
|
-
gap: ' ',
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export const ASCII_TREE_VOCAB: TreeVocab = {
|
|
68
|
-
tee: '|-- ',
|
|
69
|
-
elbow: '`-- ',
|
|
70
|
-
rail: '| ',
|
|
71
|
-
gap: ' ',
|
|
72
|
-
};
|