@bendyline/squisq 1.5.2 → 2.0.1
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/README.md +63 -10
- package/dist/{Doc-BBVGq1_9.d.ts → Doc-ylqWKDc_.d.ts} +248 -37
- package/dist/{ImageEditDoc-FuyGtt6o.d.ts → ImageEditDoc-D828IXJ1.d.ts} +1 -1
- package/dist/annotationCoercion-Dr_DY9Hx.d.ts +86 -0
- package/dist/{chunk-T5UK6YOB.js → chunk-2PWOO4ZE.js} +60 -17
- package/dist/chunk-2PWOO4ZE.js.map +1 -0
- package/dist/{chunk-VWUFZ6ZG.js → chunk-3E5F2XMR.js} +2 -29
- package/dist/chunk-3E5F2XMR.js.map +1 -0
- package/dist/chunk-4X3JQXNM.js +35 -0
- package/dist/chunk-4X3JQXNM.js.map +1 -0
- package/dist/{chunk-P3K7NLHF.js → chunk-5DKBFXPY.js} +31 -121
- package/dist/chunk-5DKBFXPY.js.map +1 -0
- package/dist/{chunk-DLXZMS5K.js → chunk-5J4HKRJF.js} +51 -3
- package/dist/chunk-5J4HKRJF.js.map +1 -0
- package/dist/chunk-5UYI3RJB.js +2503 -0
- package/dist/chunk-5UYI3RJB.js.map +1 -0
- package/dist/{chunk-BEQODJWV.js → chunk-66QO7XFB.js} +11 -291
- package/dist/chunk-66QO7XFB.js.map +1 -0
- package/dist/{chunk-HWVFJAAH.js → chunk-AMIR72JP.js} +28 -10
- package/dist/chunk-AMIR72JP.js.map +1 -0
- package/dist/chunk-CY2R2VPR.js +884 -0
- package/dist/chunk-CY2R2VPR.js.map +1 -0
- package/dist/chunk-FVJUUTEM.js +74 -0
- package/dist/chunk-FVJUUTEM.js.map +1 -0
- package/dist/{chunk-Q3ROPT5H.js → chunk-GZY66SDN.js} +1 -1
- package/dist/{chunk-Q3ROPT5H.js.map → chunk-GZY66SDN.js.map} +1 -1
- package/dist/chunk-JOQYPRDZ.js +127 -0
- package/dist/chunk-JOQYPRDZ.js.map +1 -0
- package/dist/{chunk-A4O7GIWE.js → chunk-MMPBOUK7.js} +10 -73
- package/dist/chunk-MMPBOUK7.js.map +1 -0
- package/dist/{chunk-LDQ2HJIX.js → chunk-PXLVXTLW.js} +252 -54
- package/dist/chunk-PXLVXTLW.js.map +1 -0
- package/dist/{chunk-TQWLI6S2.js → chunk-Q7LROV2H.js} +4 -2
- package/dist/{chunk-TQWLI6S2.js.map → chunk-Q7LROV2H.js.map} +1 -1
- package/dist/{chunk-GPLTCSXO.js → chunk-R2GC6RLD.js} +7 -7
- package/dist/chunk-R2GC6RLD.js.map +1 -0
- package/dist/chunk-R2YZTCLO.js +292 -0
- package/dist/chunk-R2YZTCLO.js.map +1 -0
- package/dist/chunk-S7A5D7ZJ.js +174 -0
- package/dist/chunk-S7A5D7ZJ.js.map +1 -0
- package/dist/chunk-TFJVXUHH.js +2358 -0
- package/dist/chunk-TFJVXUHH.js.map +1 -0
- package/dist/{chunk-LTN6I7QW.js → chunk-TUWMK62B.js} +55 -4
- package/dist/chunk-TUWMK62B.js.map +1 -0
- package/dist/{chunk-IMSCRLLV.js → chunk-VR7UPJ7C.js} +35 -25
- package/dist/chunk-VR7UPJ7C.js.map +1 -0
- package/dist/{chunk-KKNUBQ6Y.js → chunk-W4O2TX5I.js} +157 -92
- package/dist/chunk-W4O2TX5I.js.map +1 -0
- package/dist/{chunk-5TYS5V3G.js → chunk-X6DUONGT.js} +4204 -3560
- package/dist/chunk-X6DUONGT.js.map +1 -0
- package/dist/doc/index.d.ts +2334 -5
- package/dist/doc/index.js +127 -33
- package/dist/generate/index.d.ts +7 -2
- package/dist/generate/index.js +1 -1
- package/dist/imageEdit/index.d.ts +9 -6
- package/dist/imageEdit/index.js +3 -3
- package/dist/index.d.ts +12 -10
- package/dist/index.js +246 -80
- package/dist/jsonForm/index.d.ts +7 -3
- package/dist/jsonForm/index.js +9 -4
- package/dist/markdown/index.d.ts +6 -70
- package/dist/markdown/index.js +13 -9
- package/dist/narration/index.d.ts +618 -0
- package/dist/narration/index.js +82 -0
- package/dist/recommend/index.d.ts +15 -1
- package/dist/recommend/index.js +2 -2
- package/dist/schemas/index.d.ts +28 -6
- package/dist/schemas/index.js +15 -13
- package/dist/spatial/index.d.ts +0 -1
- package/dist/spatial/index.js +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/{themeLibrary-CehcJhzz.d.ts → themeLibrary-RjVgLpUi.d.ts} +10 -11
- package/dist/timing/index.js +5 -3
- package/dist/transform/index.d.ts +35 -24
- package/dist/transform/index.js +9 -10
- package/dist/{types-DlAZ7MW4.d.ts → types-BwMPl2CB.d.ts} +1 -1
- package/dist/{types-D98li1gV.d.ts → types-C4kiRn_k.d.ts} +3 -1
- package/dist/versions/index.d.ts +2 -1
- package/dist/versions/index.js +2 -2
- package/package.json +6 -6
- package/src/__tests__/applyNarrationTiming.test.ts +190 -0
- package/src/__tests__/applyRenderStyle.test.ts +3 -3
- package/src/__tests__/asciiDiagramBattle.test.ts +246 -0
- package/src/__tests__/asciiDiagramDetect.test.ts +162 -0
- package/src/__tests__/asciiDiagramMapping.test.ts +38 -0
- package/src/__tests__/asciiDiagramParse.test.ts +233 -0
- package/src/__tests__/asciiDiagramPipeline.test.ts +273 -0
- package/src/__tests__/asciiDiagramRender.test.ts +162 -0
- package/src/__tests__/asciiDiagramRepair.test.ts +84 -0
- package/src/__tests__/asciiTimelineDetect.test.ts +157 -0
- package/src/__tests__/asciiTimelineParse.test.ts +205 -0
- package/src/__tests__/asciiTimelinePipeline.test.ts +349 -0
- package/src/__tests__/asciiTimelineRender.test.ts +376 -0
- package/src/__tests__/attrTokens.test.ts +5 -0
- package/src/__tests__/contentContainer.test.ts +43 -0
- package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -15
- package/src/__tests__/customThemesFrontmatter.test.ts +1 -0
- package/src/__tests__/dataTable.test.ts +25 -15
- package/src/__tests__/diagramBlock.test.ts +3 -3
- package/src/__tests__/diagramText.test.ts +26 -0
- package/src/__tests__/docToMarkdownMedia.test.ts +83 -0
- package/src/__tests__/drawingBlock.test.ts +3 -3
- package/src/__tests__/fixtures/asciiDiagramBattle.ts +512 -0
- package/src/__tests__/fixtures/asciiDiagrams.ts +287 -0
- package/src/__tests__/fixtures/asciiTimelines.ts +35 -0
- package/src/__tests__/fixtures/treeviewFixtures.ts +243 -0
- package/src/__tests__/getLayers.test.ts +32 -18
- package/src/__tests__/getLayersFallback.test.ts +8 -8
- package/src/__tests__/imageEditVersions.test.ts +2 -0
- package/src/__tests__/jsonForm.pointer.test.ts +47 -1
- package/src/__tests__/layoutBlock.test.ts +3 -3
- package/src/__tests__/majorApiTypes.test.ts +18 -0
- package/src/__tests__/markdown.test.ts +54 -4
- package/src/__tests__/markdownSanitize.test.ts +7 -5
- package/src/__tests__/matchFontFamily.test.ts +114 -0
- package/src/__tests__/materializeBlockLayers.test.ts +135 -0
- package/src/__tests__/materializeTestUtils.ts +17 -0
- package/src/__tests__/narrationAlign.test.ts +150 -0
- package/src/__tests__/narrationFeatures.test.ts +71 -0
- package/src/__tests__/narrationNuclei.test.ts +45 -0
- package/src/__tests__/narrationPacing.test.ts +189 -0
- package/src/__tests__/narrationScript.test.ts +149 -0
- package/src/__tests__/narrationSessionRepro.test.ts +62 -0
- package/src/__tests__/narrationSidecar.test.ts +88 -0
- package/src/__tests__/narrationSyllables.test.ts +65 -0
- package/src/__tests__/narrationTestSignals.ts +167 -0
- package/src/__tests__/narrationVad.test.ts +66 -0
- package/src/__tests__/resolveDocTheme.test.ts +16 -2
- package/src/__tests__/rootExports.test.ts +18 -0
- package/src/__tests__/scopedContentContainer.test.ts +20 -0
- package/src/__tests__/shapeGeometry.test.ts +12 -0
- package/src/__tests__/templateAnnotationParse.test.ts +10 -0
- package/src/__tests__/templateInputs.test.ts +69 -0
- package/src/__tests__/templateMetadata.test.ts +2 -1
- package/src/__tests__/templates.test.ts +143 -17
- package/src/__tests__/themeCompile.test.ts +49 -22
- package/src/__tests__/transformProvenance.test.ts +160 -0
- package/src/__tests__/transformV2.test.ts +40 -14
- package/src/__tests__/treeviewBattle.test.ts +76 -0
- package/src/__tests__/treeviewDetect.test.ts +168 -0
- package/src/__tests__/treeviewParse.test.ts +118 -0
- package/src/__tests__/treeviewPipeline.test.ts +183 -0
- package/src/__tests__/treeviewRender.test.ts +91 -0
- package/src/__tests__/versions.test.ts +44 -0
- package/src/doc/applyNarrationTiming.ts +244 -0
- package/src/doc/asciiDiagram/chars.ts +210 -0
- package/src/doc/asciiDiagram/detect.ts +175 -0
- package/src/doc/asciiDiagram/index.ts +38 -0
- package/src/doc/asciiDiagram/mapping.ts +225 -0
- package/src/doc/asciiDiagram/parse.ts +1095 -0
- package/src/doc/asciiDiagram/render.ts +963 -0
- package/src/doc/asciiDiagram/repair.ts +400 -0
- package/src/doc/asciiDiagram/types.ts +65 -0
- package/src/doc/asciiTimeline/detect.ts +138 -0
- package/src/doc/asciiTimeline/index.ts +26 -0
- package/src/doc/asciiTimeline/mapping.ts +43 -0
- package/src/doc/asciiTimeline/parse.ts +870 -0
- package/src/doc/asciiTimeline/render.ts +427 -0
- package/src/doc/asciiTimeline/types.ts +73 -0
- package/src/doc/asciiTimeline/wrappedFlow.ts +427 -0
- package/src/doc/audioMapping.ts +60 -46
- package/src/doc/customTemplatesFrontmatter.ts +0 -41
- package/src/doc/docToMarkdown.ts +70 -2
- package/src/doc/index.ts +76 -4
- package/src/doc/markdownToDoc.ts +138 -2
- package/src/doc/materializeBlockLayers.ts +304 -0
- package/src/doc/mediaAnnotations.ts +20 -0
- package/src/doc/resolveDocTheme.ts +8 -7
- package/src/doc/templateInputs.ts +185 -2
- package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +22 -8
- package/src/doc/templates/__tests__/listBlock.test.ts +64 -0
- package/src/doc/templates/diagramBlock.ts +237 -38
- package/src/doc/templates/fallbackBlock.ts +1 -1
- package/src/doc/templates/index.ts +134 -279
- package/src/doc/templates/inputDescriptors.ts +20 -1
- package/src/doc/templates/listBlock.ts +88 -30
- package/src/doc/templates/metadata.ts +10 -0
- package/src/doc/templates/persistentLayers.ts +12 -126
- package/src/doc/templates/registry.ts +88 -0
- package/src/doc/templates/templateNames.ts +22 -0
- package/src/doc/templates/timelineBlock.ts +613 -0
- package/src/doc/templates/treeBlock.ts +131 -0
- package/src/doc/treeview/chars.ts +72 -0
- package/src/doc/treeview/detect.ts +145 -0
- package/src/doc/treeview/index.ts +30 -0
- package/src/doc/treeview/mapping.ts +95 -0
- package/src/doc/treeview/parse.ts +201 -0
- package/src/doc/treeview/render.ts +41 -0
- package/src/doc/treeview/types.ts +43 -0
- package/src/doc/utils/applyRenderStyle.ts +2 -9
- package/src/doc/utils/diagramText.ts +78 -0
- package/src/doc/utils/shapeGeometry.ts +67 -5
- package/src/doc/validate.ts +1 -1
- package/src/generate/templateMapper.ts +7 -0
- package/src/imageEdit/export.ts +6 -5
- package/src/imageEdit/versionPaths.ts +13 -26
- package/src/imageEdit/versions.ts +21 -100
- package/src/index.ts +1 -0
- package/src/internal/immutable.ts +58 -0
- package/src/jsonForm/index.ts +9 -1
- package/src/jsonForm/pointer.ts +68 -23
- package/src/markdown/attrTokens.ts +7 -5
- package/src/markdown/index.ts +1 -0
- package/src/markdown/stringify.ts +4 -9
- package/src/markdown/utils.ts +36 -14
- package/src/narration/align.ts +514 -0
- package/src/narration/features.ts +231 -0
- package/src/narration/index.ts +86 -0
- package/src/narration/nuclei.ts +118 -0
- package/src/narration/pacing.ts +211 -0
- package/src/narration/script.ts +239 -0
- package/src/narration/session.ts +100 -0
- package/src/narration/sidecar.ts +187 -0
- package/src/narration/syllables.ts +85 -0
- package/src/narration/trace.ts +50 -0
- package/src/narration/types.ts +299 -0
- package/src/narration/vad.ts +131 -0
- package/src/recommend/numberHighlight.ts +25 -0
- package/src/recommend/templates.ts +108 -12
- package/src/schemas/BlockTemplates.ts +156 -7
- package/src/schemas/Doc.ts +72 -9
- package/src/schemas/Media.ts +12 -2
- package/src/schemas/Theme.ts +45 -25
- package/src/schemas/Viewport.ts +2 -2
- package/src/schemas/fontStacks.ts +79 -0
- package/src/schemas/themeCompile.ts +15 -0
- package/src/schemas/themeConstants.ts +2 -0
- package/src/schemas/themeLibrary.ts +25 -19
- package/src/schemas/themeValidator.ts +1 -1
- package/src/schemas/themes/gezellig.json +1 -1
- package/src/spatial/Geohash.ts +0 -3
- package/src/storage/ContentContainer.ts +17 -9
- package/src/storage/ScopedContentContainer.ts +45 -15
- package/src/transform/applyTransform.ts +5 -5
- package/src/transform/index.ts +3 -1
- package/src/transform/registry.ts +169 -49
- package/src/transform/templateSelector.ts +21 -2
- package/src/transform/timingAllocator.ts +152 -21
- package/src/transform/types.ts +14 -1
- package/src/versions/gitignore.ts +34 -0
- package/src/versions/index.ts +2 -0
- package/src/versions/operations.ts +18 -104
- package/src/versions/paths.ts +13 -28
- package/src/versions/snapshotStore.ts +202 -0
- package/src/versions/types.ts +3 -1
- package/dist/chunk-5TYS5V3G.js.map +0 -1
- package/dist/chunk-A4O7GIWE.js.map +0 -1
- package/dist/chunk-BEQODJWV.js.map +0 -1
- package/dist/chunk-DLXZMS5K.js.map +0 -1
- package/dist/chunk-GPLTCSXO.js.map +0 -1
- package/dist/chunk-HWVFJAAH.js.map +0 -1
- package/dist/chunk-IMSCRLLV.js.map +0 -1
- package/dist/chunk-JELIRVDP.js +0 -24
- package/dist/chunk-JELIRVDP.js.map +0 -1
- package/dist/chunk-KKNUBQ6Y.js.map +0 -1
- package/dist/chunk-LDQ2HJIX.js.map +0 -1
- package/dist/chunk-LTN6I7QW.js.map +0 -1
- package/dist/chunk-P3K7NLHF.js.map +0 -1
- package/dist/chunk-T5UK6YOB.js.map +0 -1
- package/dist/chunk-UY7KGQ5R.js +0 -192
- package/dist/chunk-UY7KGQ5R.js.map +0 -1
- package/dist/chunk-VLJJHDAC.js +0 -218
- package/dist/chunk-VLJJHDAC.js.map +0 -1
- package/dist/chunk-VWUFZ6ZG.js.map +0 -1
- package/dist/story/index.d.ts +0 -1801
- package/dist/story/index.js +0 -279
- package/src/doc/getLayers.ts +0 -195
- /package/dist/{story → narration}/index.js.map +0 -0
|
@@ -11,56 +11,33 @@
|
|
|
11
11
|
* This is shared code used by both site and efb-app doc renderers.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type { Block
|
|
14
|
+
import type { Block } from '../../schemas/Doc.js';
|
|
15
15
|
import type {
|
|
16
16
|
TemplateBlock,
|
|
17
|
-
TemplateContext,
|
|
18
|
-
TemplateRegistry,
|
|
19
17
|
DocBlock,
|
|
20
18
|
PersistentLayerConfig,
|
|
21
19
|
} from '../../schemas/BlockTemplates.js';
|
|
22
20
|
import type { Theme } from '../../schemas/Theme.js';
|
|
23
21
|
import type { CustomTemplateDefinition } from '../../schemas/CustomTemplates.js';
|
|
24
|
-
import { isTemplateBlock
|
|
22
|
+
import { isTemplateBlock } from '../../schemas/BlockTemplates.js';
|
|
25
23
|
import { DEFAULT_THEME as defaultTheme } from '../../schemas/themeLibrary.js';
|
|
26
|
-
import { expandPersistentLayers
|
|
27
|
-
import { applyRenderStyleToLayers } from '../utils/applyRenderStyle.js';
|
|
24
|
+
import { expandPersistentLayers } from './persistentLayers.js';
|
|
28
25
|
import { resolveBlockTransition } from '../../schemas/Transitions.js';
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
// imports `resolveTemplateName` from this module in return; the cycle is benign
|
|
32
|
-
// because every cross-reference lives inside a function body, not module init.
|
|
33
|
-
import { coerceTemplateParams } from './inputDescriptors.js';
|
|
26
|
+
import { resolveTemplateName } from './templateNames.js';
|
|
27
|
+
import { cloneData } from '../../internal/immutable.js';
|
|
34
28
|
import type { ViewportConfig } from '../../schemas/Viewport.js';
|
|
35
29
|
import { VIEWPORT_PRESETS } from '../../schemas/Viewport.js';
|
|
30
|
+
import { buildRegistry, templateRegistry, type RuntimeTemplateRegistry } from './registry.js';
|
|
31
|
+
import {
|
|
32
|
+
materializeBlockLayersWithRuntime,
|
|
33
|
+
type ExpandedPersistentLayerSet,
|
|
34
|
+
type LayerMaterializationDiagnostic,
|
|
35
|
+
type LayerMaterializationFailureMode,
|
|
36
|
+
} from '../materializeBlockLayers.js';
|
|
36
37
|
|
|
37
38
|
export { TEMPLATE_METADATA } from './metadata.js';
|
|
38
39
|
export type { TemplateMetadata } from './metadata.js';
|
|
39
40
|
|
|
40
|
-
// Import all template functions
|
|
41
|
-
import { titleBlock } from './titleBlock.js';
|
|
42
|
-
import { sectionHeader } from './sectionHeader.js';
|
|
43
|
-
import { statHighlight } from './statHighlight.js';
|
|
44
|
-
import { quoteBlock } from './quoteBlock.js';
|
|
45
|
-
import { factCard } from './factCard.js';
|
|
46
|
-
import { twoColumn } from './twoColumn.js';
|
|
47
|
-
import { dateEvent } from './dateEvent.js';
|
|
48
|
-
import { imageWithCaption } from './imageWithCaption.js';
|
|
49
|
-
import { leftFeature, rightFeature } from './featureBlock.js';
|
|
50
|
-
import { mapBlock } from './mapBlock.js';
|
|
51
|
-
import { fullBleedQuote } from './fullBleedQuote.js';
|
|
52
|
-
import { listBlock } from './listBlock.js';
|
|
53
|
-
import { photoGrid } from './photoGrid.js';
|
|
54
|
-
import { definitionCard } from './definitionCard.js';
|
|
55
|
-
import { comparisonBar } from './comparisonBar.js';
|
|
56
|
-
import { pullQuote } from './pullQuote.js';
|
|
57
|
-
import { videoWithCaption } from './videoWithCaption.js';
|
|
58
|
-
import { videoPullQuote } from './videoPullQuote.js';
|
|
59
|
-
import { dataTable } from './dataTable.js';
|
|
60
|
-
import { diagramBlock } from './diagramBlock.js';
|
|
61
|
-
import { drawingBlock } from './drawingBlock.js';
|
|
62
|
-
import { layoutBlock } from './layoutBlock.js';
|
|
63
|
-
|
|
64
41
|
/**
|
|
65
42
|
* Registry mapping template ids (the strings that appear in
|
|
66
43
|
* `{[name]}` markdown annotations) to their implementation functions.
|
|
@@ -68,61 +45,29 @@ import { layoutBlock } from './layoutBlock.js';
|
|
|
68
45
|
* Some implementation functions keep historical "Block" suffixes
|
|
69
46
|
* (`titleBlock`, `quoteBlock`, `mapBlock`, `listBlock`) for source
|
|
70
47
|
* readability — the registry surfaces them under the cleaner short
|
|
71
|
-
* ids (`title`, `quote`, `map`, `list`).
|
|
72
|
-
*
|
|
73
|
-
* rename.
|
|
48
|
+
* ids (`title`, `quote`, `map`, `list`). Internal aliases keep legacy
|
|
49
|
+
* document names readable without expanding the public API surface.
|
|
74
50
|
*
|
|
75
51
|
* Note: coverBlock is not in the registry as it's used directly for
|
|
76
52
|
* start blocks, not as a regular template in the block sequence.
|
|
77
53
|
*/
|
|
78
|
-
export
|
|
79
|
-
|
|
80
|
-
sectionHeader,
|
|
81
|
-
statHighlight,
|
|
82
|
-
quote: quoteBlock,
|
|
83
|
-
factCard,
|
|
84
|
-
twoColumn,
|
|
85
|
-
dateEvent,
|
|
86
|
-
imageWithCaption,
|
|
87
|
-
leftFeature,
|
|
88
|
-
rightFeature,
|
|
89
|
-
map: mapBlock,
|
|
90
|
-
fullBleedQuote,
|
|
91
|
-
list: listBlock,
|
|
92
|
-
photoGrid,
|
|
93
|
-
definitionCard,
|
|
94
|
-
comparisonBar,
|
|
95
|
-
pullQuote,
|
|
96
|
-
videoWithCaption,
|
|
97
|
-
videoPullQuote,
|
|
98
|
-
dataTable,
|
|
99
|
-
diagram: diagramBlock,
|
|
100
|
-
layout: layoutBlock,
|
|
101
|
-
drawing: drawingBlock,
|
|
102
|
-
};
|
|
54
|
+
export { buildRegistry, templateRegistry } from './registry.js';
|
|
55
|
+
export type { RuntimeTemplateRegistry } from './registry.js';
|
|
103
56
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
quoteBlock: 'quote',
|
|
113
|
-
mapBlock: 'map',
|
|
114
|
-
listBlock: 'list',
|
|
115
|
-
diagramBlock: 'diagram',
|
|
116
|
-
diagramNode: 'diagram',
|
|
117
|
-
};
|
|
57
|
+
export { materializeBlockLayers } from '../materializeBlockLayers.js';
|
|
58
|
+
export type {
|
|
59
|
+
BlockLayerMaterialization,
|
|
60
|
+
LayerMaterializationDiagnostic,
|
|
61
|
+
LayerMaterializationFailureMode,
|
|
62
|
+
LayerMaterializationSource,
|
|
63
|
+
MaterializeBlockLayersOptions,
|
|
64
|
+
} from '../materializeBlockLayers.js';
|
|
118
65
|
|
|
119
66
|
/**
|
|
120
|
-
* Resolve a template id through
|
|
121
|
-
* input unchanged when no alias is registered.
|
|
67
|
+
* Resolve a template id through the internal compatibility table. Returns
|
|
68
|
+
* the input unchanged when no alias is registered.
|
|
122
69
|
*/
|
|
123
|
-
export
|
|
124
|
-
return TEMPLATE_ALIASES[name] ?? name;
|
|
125
|
-
}
|
|
70
|
+
export { resolveTemplateName } from './templateNames.js';
|
|
126
71
|
|
|
127
72
|
/**
|
|
128
73
|
* Container templates render their parent block by consuming the block's
|
|
@@ -132,114 +77,10 @@ export function resolveTemplateName(name: string): string {
|
|
|
132
77
|
* render paths use {@link isContainerTemplate} to skip descending into
|
|
133
78
|
* them (see `flattenRenderableBlocks`).
|
|
134
79
|
*/
|
|
135
|
-
export
|
|
80
|
+
export { CONTAINER_TEMPLATES } from './templateNames.js';
|
|
136
81
|
|
|
137
82
|
/** True when `name` (or its alias) is a children-consuming container template. */
|
|
138
|
-
export
|
|
139
|
-
if (!name) return false;
|
|
140
|
-
return CONTAINER_TEMPLATES.has(resolveTemplateName(name));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Merge user-defined custom templates onto the built-in registry.
|
|
145
|
-
* Built-in names take precedence on collision — a user can't shadow
|
|
146
|
-
* `title` or `diagram` from a custom definition. Returns a frozen view
|
|
147
|
-
* so callers don't accidentally mutate the global registry.
|
|
148
|
-
*/
|
|
149
|
-
export type RuntimeTemplateRegistry = Record<
|
|
150
|
-
string,
|
|
151
|
-
(input: TemplateBlock, ctx: TemplateContext) => Layer[]
|
|
152
|
-
>;
|
|
153
|
-
|
|
154
|
-
export function buildRegistry(
|
|
155
|
-
custom?: readonly CustomTemplateDefinition[],
|
|
156
|
-
): RuntimeTemplateRegistry {
|
|
157
|
-
// The exported `templateRegistry` is a discriminated-union mapped type;
|
|
158
|
-
// we cast through `unknown` because each entry's `input` type is the
|
|
159
|
-
// template-specific variant, not the broad `TemplateBlock` union.
|
|
160
|
-
// The runtime contract — "given any TemplateBlock that resolves to a
|
|
161
|
-
// registered name, the function returns Layer[]" — holds because the
|
|
162
|
-
// expansion path looks up by `template` string before calling.
|
|
163
|
-
const merged: RuntimeTemplateRegistry = {
|
|
164
|
-
...(templateRegistry as unknown as RuntimeTemplateRegistry),
|
|
165
|
-
};
|
|
166
|
-
if (custom) {
|
|
167
|
-
for (const def of custom) {
|
|
168
|
-
if (merged[def.name]) continue; // built-in wins
|
|
169
|
-
merged[def.name] = makeCustomTemplateFn(def) as unknown as RuntimeTemplateRegistry[string];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return merged;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Expand a template block into a full Block with layers.
|
|
177
|
-
*
|
|
178
|
-
* `registry` lets callers swap in a registry that includes user-defined
|
|
179
|
-
* custom templates. Defaults to the built-in registry when omitted.
|
|
180
|
-
*/
|
|
181
|
-
export function expandTemplateBlock(
|
|
182
|
-
templateBlock: TemplateBlock,
|
|
183
|
-
context: TemplateContext,
|
|
184
|
-
registry: RuntimeTemplateRegistry = templateRegistry as unknown as RuntimeTemplateRegistry,
|
|
185
|
-
): Block {
|
|
186
|
-
const resolved = resolveTemplateName(templateBlock.template);
|
|
187
|
-
const templateFn = registry[resolved];
|
|
188
|
-
|
|
189
|
-
if (!templateFn) {
|
|
190
|
-
console.warn(`Unknown template: ${templateBlock.template}`);
|
|
191
|
-
// Return block with no layers
|
|
192
|
-
return {
|
|
193
|
-
id: templateBlock.id,
|
|
194
|
-
startTime: 0,
|
|
195
|
-
duration: templateBlock.duration,
|
|
196
|
-
audioSegment: templateBlock.audioSegment,
|
|
197
|
-
transition: templateBlock.transition,
|
|
198
|
-
template: templateBlock.template, // Preserve for debugging
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Effective template input: the block's own fields, then structured
|
|
203
|
-
// body data (```json data fences / derived auto-template inputs), then
|
|
204
|
-
// `{[…]}` string overrides — the same merge order getLayers uses. Inline
|
|
205
|
-
// overrides are coerced to their typed shape (e.g. `center="47.6,-122.3"` →
|
|
206
|
-
// `{lat,lng}`); `templateOverrides` itself stays raw for round-tripping.
|
|
207
|
-
const { templateData, templateOverrides } = templateBlock as Block;
|
|
208
|
-
const input =
|
|
209
|
-
templateData || templateOverrides
|
|
210
|
-
? ({
|
|
211
|
-
...templateBlock,
|
|
212
|
-
...templateData,
|
|
213
|
-
...coerceTemplateParams(templateBlock.template, templateOverrides ?? {}).input,
|
|
214
|
-
} as TemplateBlock)
|
|
215
|
-
: templateBlock;
|
|
216
|
-
|
|
217
|
-
// Generate layers from template with error handling
|
|
218
|
-
let layers: Layer[];
|
|
219
|
-
try {
|
|
220
|
-
layers = templateFn(input, context);
|
|
221
|
-
if (!Array.isArray(layers)) {
|
|
222
|
-
console.error(
|
|
223
|
-
`Template ${templateBlock.template} did not return an array, got:`,
|
|
224
|
-
typeof layers,
|
|
225
|
-
);
|
|
226
|
-
layers = [];
|
|
227
|
-
}
|
|
228
|
-
} catch (err: unknown) {
|
|
229
|
-
console.error(`Error expanding template ${templateBlock.template}:`, err);
|
|
230
|
-
layers = [];
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
id: templateBlock.id,
|
|
235
|
-
startTime: 0, // Will be calculated later
|
|
236
|
-
duration: templateBlock.duration,
|
|
237
|
-
audioSegment: templateBlock.audioSegment,
|
|
238
|
-
...(layers.length > 0 ? { layers } : {}),
|
|
239
|
-
transition: templateBlock.transition,
|
|
240
|
-
template: templateBlock.template, // Preserve for debugging
|
|
241
|
-
};
|
|
242
|
-
}
|
|
83
|
+
export { isContainerTemplate } from './templateNames.js';
|
|
243
84
|
|
|
244
85
|
/**
|
|
245
86
|
* Audio segment timing info for aligning blocks with audio.
|
|
@@ -260,7 +101,7 @@ export interface ExpandDocBlocksOptions {
|
|
|
260
101
|
/** Viewport configuration (defaults to 16:9 landscape) */
|
|
261
102
|
viewport?: ViewportConfig;
|
|
262
103
|
/** Persistent layers for visual consistency across blocks */
|
|
263
|
-
persistentLayers?: PersistentLayerConfig;
|
|
104
|
+
persistentLayers?: PersistentLayerConfig | false;
|
|
264
105
|
/**
|
|
265
106
|
* Audio segment timing information.
|
|
266
107
|
* When provided, blocks are timed relative to their audio segment's start time,
|
|
@@ -273,6 +114,14 @@ export interface ExpandDocBlocksOptions {
|
|
|
273
114
|
* `Doc.customTemplates`. Built-in names take precedence on collision.
|
|
274
115
|
*/
|
|
275
116
|
customTemplates?: readonly CustomTemplateDefinition[];
|
|
117
|
+
/** Failed templates render a visible fallback by default. */
|
|
118
|
+
failureMode?: LayerMaterializationFailureMode;
|
|
119
|
+
/** Receives structured template failures without hidden console output. */
|
|
120
|
+
onDiagnostic?: (
|
|
121
|
+
diagnostic: LayerMaterializationDiagnostic,
|
|
122
|
+
block: DocBlock,
|
|
123
|
+
blockIndex: number,
|
|
124
|
+
) => void;
|
|
276
125
|
}
|
|
277
126
|
|
|
278
127
|
/**
|
|
@@ -287,38 +136,57 @@ export interface ExpandDocBlocksOptions {
|
|
|
287
136
|
* @param options - Expansion options including theme, viewport, and persistent layers
|
|
288
137
|
*/
|
|
289
138
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
* and fill the theme's default transition (never on block 0, never over an
|
|
293
|
-
* authored transition). Shared by every expansion path in this module.
|
|
139
|
+
* Materialize one block through the canonical layer contract, then add its
|
|
140
|
+
* timeline envelope and resolved transition.
|
|
294
141
|
*/
|
|
295
|
-
function
|
|
296
|
-
expandedBlock: Block,
|
|
142
|
+
function materializeScheduledBlock(
|
|
297
143
|
sourceBlock: DocBlock,
|
|
298
144
|
blockIndex: number,
|
|
145
|
+
totalBlocks: number,
|
|
299
146
|
theme: Theme,
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
147
|
+
viewport: ViewportConfig,
|
|
148
|
+
persistentLayers: PersistentLayerConfig | undefined,
|
|
149
|
+
expandedPersistentLayers: ExpandedPersistentLayerSet | undefined,
|
|
150
|
+
registry: RuntimeTemplateRegistry,
|
|
151
|
+
failureMode: LayerMaterializationFailureMode,
|
|
152
|
+
onDiagnostic?: ExpandDocBlocksOptions['onDiagnostic'],
|
|
153
|
+
): Block {
|
|
154
|
+
const materialized = materializeBlockLayersWithRuntime(
|
|
155
|
+
sourceBlock,
|
|
156
|
+
{
|
|
157
|
+
theme,
|
|
158
|
+
viewport,
|
|
159
|
+
persistentLayers: persistentLayers ?? false,
|
|
160
|
+
blockIndex,
|
|
161
|
+
totalBlocks,
|
|
162
|
+
failureMode,
|
|
163
|
+
},
|
|
164
|
+
{ registry, expandedPersistentLayers },
|
|
165
|
+
);
|
|
166
|
+
if (materialized.diagnostic) {
|
|
167
|
+
onDiagnostic?.(materialized.diagnostic, sourceBlock, blockIndex);
|
|
307
168
|
}
|
|
308
169
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
170
|
+
const expandedBlock: Block = isTemplateBlock(sourceBlock)
|
|
171
|
+
? {
|
|
172
|
+
id: sourceBlock.id,
|
|
173
|
+
startTime: 0,
|
|
174
|
+
duration: sourceBlock.duration,
|
|
175
|
+
audioSegment: sourceBlock.audioSegment,
|
|
176
|
+
...(materialized.layers.length > 0 ? { layers: materialized.layers } : {}),
|
|
177
|
+
transition: sourceBlock.transition,
|
|
178
|
+
template: sourceBlock.template,
|
|
179
|
+
}
|
|
180
|
+
: {
|
|
181
|
+
...cloneData(sourceBlock as Block),
|
|
182
|
+
...(materialized.layers.length > 0 ? { layers: materialized.layers } : {}),
|
|
183
|
+
};
|
|
317
184
|
|
|
318
185
|
const transition = resolveBlockTransition(expandedBlock, theme, blockIndex);
|
|
319
186
|
if (transition !== expandedBlock.transition) {
|
|
320
187
|
expandedBlock.transition = transition;
|
|
321
188
|
}
|
|
189
|
+
return expandedBlock;
|
|
322
190
|
}
|
|
323
191
|
|
|
324
192
|
export function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOptions = {}): Block[] {
|
|
@@ -326,49 +194,46 @@ export function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOpti
|
|
|
326
194
|
|
|
327
195
|
const theme = opts.theme ?? defaultTheme;
|
|
328
196
|
const viewport = opts.viewport ?? VIEWPORT_PRESETS.landscape;
|
|
329
|
-
const {
|
|
197
|
+
const {
|
|
198
|
+
persistentLayers,
|
|
199
|
+
audioSegments,
|
|
200
|
+
customTemplates,
|
|
201
|
+
failureMode = 'fallback',
|
|
202
|
+
onDiagnostic,
|
|
203
|
+
} = opts;
|
|
330
204
|
const totalBlocks = blocks.length;
|
|
331
|
-
// Merge user-defined templates
|
|
332
|
-
// call; passed into every `expandTemplateBlock` invocation below.
|
|
205
|
+
// Merge user-defined templates once, then share the immutable runtime view.
|
|
333
206
|
const registry: RuntimeTemplateRegistry =
|
|
334
207
|
customTemplates && customTemplates.length > 0
|
|
335
208
|
? buildRegistry(customTemplates)
|
|
336
209
|
: (templateRegistry as unknown as RuntimeTemplateRegistry);
|
|
337
210
|
|
|
338
|
-
//
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
211
|
+
// Callers that pass no config inherit the theme's atmosphere.
|
|
212
|
+
const effectivePersistentLayers =
|
|
213
|
+
persistentLayers === false ? undefined : (persistentLayers ?? theme.persistentLayers);
|
|
214
|
+
const expandedPersistentLayers = effectivePersistentLayers
|
|
215
|
+
? {
|
|
216
|
+
bottomLayers: expandPersistentLayers(effectivePersistentLayers.bottomLayers, theme),
|
|
217
|
+
topLayers: expandPersistentLayers(effectivePersistentLayers.topLayers, theme),
|
|
218
|
+
}
|
|
219
|
+
: undefined;
|
|
344
220
|
|
|
345
221
|
// If no audio segments provided, use simple cumulative timing
|
|
346
222
|
if (!audioSegments || audioSegments.length === 0) {
|
|
347
223
|
let currentTime = 0;
|
|
348
224
|
return blocks.map((block, index) => {
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
customTemplates &&
|
|
362
|
-
customTemplates.some((c) => c.name === block.template)
|
|
363
|
-
) {
|
|
364
|
-
context.block = block as Block;
|
|
365
|
-
}
|
|
366
|
-
const expandedBlock = isTemplateBlock(block)
|
|
367
|
-
? expandTemplateBlock(block, context, registry)
|
|
368
|
-
: (block as Block);
|
|
369
|
-
|
|
370
|
-
finalizeExpandedBlock(expandedBlock, block, index, theme, bottomLayers, topLayers);
|
|
371
|
-
|
|
225
|
+
const expandedBlock = materializeScheduledBlock(
|
|
226
|
+
block,
|
|
227
|
+
index,
|
|
228
|
+
totalBlocks,
|
|
229
|
+
theme,
|
|
230
|
+
viewport,
|
|
231
|
+
effectivePersistentLayers,
|
|
232
|
+
expandedPersistentLayers,
|
|
233
|
+
registry,
|
|
234
|
+
failureMode,
|
|
235
|
+
onDiagnostic,
|
|
236
|
+
);
|
|
372
237
|
expandedBlock.startTime = currentTime;
|
|
373
238
|
currentTime += expandedBlock.duration;
|
|
374
239
|
return expandedBlock;
|
|
@@ -394,23 +259,18 @@ export function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOpti
|
|
|
394
259
|
// No audio segment info - use simple sequential timing within the segment
|
|
395
260
|
let offsetTime = 0;
|
|
396
261
|
for (const { block, originalIndex } of segmentBlocks) {
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
const expandedBlock = isTemplateBlock(block)
|
|
410
|
-
? expandTemplateBlock(block, context, registry)
|
|
411
|
-
: (block as Block);
|
|
412
|
-
|
|
413
|
-
finalizeExpandedBlock(expandedBlock, block, originalIndex, theme, bottomLayers, topLayers);
|
|
262
|
+
const expandedBlock = materializeScheduledBlock(
|
|
263
|
+
block,
|
|
264
|
+
originalIndex,
|
|
265
|
+
totalBlocks,
|
|
266
|
+
theme,
|
|
267
|
+
viewport,
|
|
268
|
+
effectivePersistentLayers,
|
|
269
|
+
expandedPersistentLayers,
|
|
270
|
+
registry,
|
|
271
|
+
failureMode,
|
|
272
|
+
onDiagnostic,
|
|
273
|
+
);
|
|
414
274
|
|
|
415
275
|
expandedBlock.startTime = offsetTime;
|
|
416
276
|
offsetTime += expandedBlock.duration;
|
|
@@ -462,23 +322,18 @@ export function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOpti
|
|
|
462
322
|
const expandedInfos: ExpandedSlideInfo[] = [];
|
|
463
323
|
|
|
464
324
|
for (const { block, originalIndex } of segmentBlocks) {
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const expandedBlock = isTemplateBlock(block)
|
|
478
|
-
? expandTemplateBlock(block, context, registry)
|
|
479
|
-
: (block as Block);
|
|
480
|
-
|
|
481
|
-
finalizeExpandedBlock(expandedBlock, block, originalIndex, theme, bottomLayers, topLayers);
|
|
325
|
+
const expandedBlock = materializeScheduledBlock(
|
|
326
|
+
block,
|
|
327
|
+
originalIndex,
|
|
328
|
+
totalBlocks,
|
|
329
|
+
theme,
|
|
330
|
+
viewport,
|
|
331
|
+
effectivePersistentLayers,
|
|
332
|
+
expandedPersistentLayers,
|
|
333
|
+
registry,
|
|
334
|
+
failureMode,
|
|
335
|
+
onDiagnostic,
|
|
336
|
+
);
|
|
482
337
|
|
|
483
338
|
const templateBlock = block as TemplateBlock;
|
|
484
339
|
expandedInfos.push({
|
|
@@ -656,7 +511,7 @@ export function expandDocBlocks(blocks: DocBlock[], options: ExpandDocBlocksOpti
|
|
|
656
511
|
duration: partDuration,
|
|
657
512
|
audioSegment: block.audioSegment,
|
|
658
513
|
layers: (block.layers ?? []).map((layer) => ({
|
|
659
|
-
...layer,
|
|
514
|
+
...cloneData(layer),
|
|
660
515
|
id: `${layer.id}-split-${p}`,
|
|
661
516
|
})),
|
|
662
517
|
transition: { type: 'dissolve', duration: 1.0 },
|
|
@@ -716,7 +571,6 @@ export type {
|
|
|
716
571
|
ThemeStyle,
|
|
717
572
|
RenderStyle,
|
|
718
573
|
} from '../../schemas/Theme.js';
|
|
719
|
-
export type { DocStylePreset } from './persistentLayers.js';
|
|
720
574
|
// Re-export timing types (AudioSegmentTiming and ExpandDocBlocksOptions are already exported above)
|
|
721
575
|
export { VIEWPORT_PRESETS, getViewport, getViewportOrientation } from '../../schemas/Viewport.js';
|
|
722
576
|
export type {
|
|
@@ -728,7 +582,6 @@ export { getLayoutHints, getTwoColumnPositions } from '../../schemas/LayoutStrat
|
|
|
728
582
|
export type { LayoutHints } from '../../schemas/LayoutStrategy.js';
|
|
729
583
|
export {
|
|
730
584
|
expandPersistentLayers,
|
|
731
|
-
getDocStyleConfig,
|
|
732
585
|
getPersistentLayersFromTheme,
|
|
733
586
|
resolvePersistentLayers,
|
|
734
587
|
wrapWithPersistentLayers,
|
|
@@ -757,6 +610,8 @@ export { videoWithCaption } from './videoWithCaption.js';
|
|
|
757
610
|
export { videoPullQuote } from './videoPullQuote.js';
|
|
758
611
|
export { dataTable } from './dataTable.js';
|
|
759
612
|
export { diagramBlock } from './diagramBlock.js';
|
|
613
|
+
export { treeBlock } from './treeBlock.js';
|
|
614
|
+
export { timelineBlock } from './timelineBlock.js';
|
|
760
615
|
export { computeDiagramLayout } from './diagramLayout.js';
|
|
761
616
|
export type {
|
|
762
617
|
DiagramLayout,
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
import { KNOWN_BLOCK_META_KEYS, parseNumber } from '../../markdown/annotationCoercion.js';
|
|
34
|
-
import { resolveTemplateName } from './
|
|
34
|
+
import { resolveTemplateName } from './templateNames.js';
|
|
35
35
|
import { nearestName } from '../utils/nearest.js';
|
|
36
36
|
|
|
37
37
|
// ============================================
|
|
@@ -220,6 +220,25 @@ export const TEMPLATE_INPUT_DESCRIPTORS: Readonly<
|
|
|
220
220
|
{ key: 'align', description: 'Per-column alignment (supply via a data fence)' },
|
|
221
221
|
{ key: 'colorScheme', description: 'Header color scheme', valueHint: COLOR_SCHEME_HINT },
|
|
222
222
|
],
|
|
223
|
+
tree: [
|
|
224
|
+
{ key: 'title', description: 'Optional title above the tree' },
|
|
225
|
+
{ key: 'colorScheme', description: 'Folder-row color scheme', valueHint: COLOR_SCHEME_HINT },
|
|
226
|
+
// `items` is a nested structure derived from the tree fence, not an
|
|
227
|
+
// inline string — declared so it isn't flagged as unknown.
|
|
228
|
+
{ key: 'items', description: 'Tree items (derived from the tree fence)' },
|
|
229
|
+
],
|
|
230
|
+
timeline: [
|
|
231
|
+
{ key: 'title', description: 'Optional title above the timeline' },
|
|
232
|
+
{
|
|
233
|
+
key: 'colorScheme',
|
|
234
|
+
description: 'Track and marker color scheme',
|
|
235
|
+
valueHint: COLOR_SCHEME_HINT,
|
|
236
|
+
},
|
|
237
|
+
// Tracks/events and branch links are nested structures derived from the
|
|
238
|
+
// timeline source, not values that can be expressed as one inline string.
|
|
239
|
+
{ key: 'tracks', description: 'Timeline tracks and events (supply via template data)' },
|
|
240
|
+
{ key: 'links', description: 'Branch links between event ids (supply via template data)' },
|
|
241
|
+
],
|
|
223
242
|
videoWithCaption: [
|
|
224
243
|
{ key: 'videoSrc', description: 'Path to the video file', required: true },
|
|
225
244
|
{ key: 'posterSrc', description: 'Poster frame path' },
|