@bendyline/squisq 0.1.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.
Files changed (102) hide show
  1. package/dist/Types-sh2VRxfo.d.ts +15 -0
  2. package/dist/chunk-7UDSRZKG.js +103 -0
  3. package/dist/chunk-7UDSRZKG.js.map +1 -0
  4. package/dist/chunk-O5HCIUAD.js +577 -0
  5. package/dist/chunk-O5HCIUAD.js.map +1 -0
  6. package/dist/chunk-PJ7AODIM.js +3040 -0
  7. package/dist/chunk-PJ7AODIM.js.map +1 -0
  8. package/dist/chunk-QWVRN6I4.js +81 -0
  9. package/dist/chunk-QWVRN6I4.js.map +1 -0
  10. package/dist/chunk-S4F2RY37.js +92 -0
  11. package/dist/chunk-S4F2RY37.js.map +1 -0
  12. package/dist/chunk-URU6QMLY.js +888 -0
  13. package/dist/chunk-URU6QMLY.js.map +1 -0
  14. package/dist/chunk-VJN7UB2Z.js +145 -0
  15. package/dist/chunk-VJN7UB2Z.js.map +1 -0
  16. package/dist/doc/index.d.ts +3 -0
  17. package/dist/doc/index.js +126 -0
  18. package/dist/doc/index.js.map +1 -0
  19. package/dist/index.d.ts +8 -0
  20. package/dist/index.js +217 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/markdown/index.d.ts +237 -0
  23. package/dist/markdown/index.js +33 -0
  24. package/dist/markdown/index.js.map +1 -0
  25. package/dist/schemas/index.d.ts +70 -0
  26. package/dist/schemas/index.js +61 -0
  27. package/dist/schemas/index.js.map +1 -0
  28. package/dist/spatial/index.d.ts +111 -0
  29. package/dist/spatial/index.js +25 -0
  30. package/dist/spatial/index.js.map +1 -0
  31. package/dist/storage/index.d.ts +91 -0
  32. package/dist/storage/index.js +11 -0
  33. package/dist/storage/index.js.map +1 -0
  34. package/dist/story/index.d.ts +691 -0
  35. package/dist/story/index.js +126 -0
  36. package/dist/story/index.js.map +1 -0
  37. package/dist/themeLibrary-DySHPcgj.d.ts +1352 -0
  38. package/dist/types-DHiv_Pnm.d.ts +496 -0
  39. package/package.json +91 -0
  40. package/src/__tests__/animationUtils.test.ts +77 -0
  41. package/src/__tests__/geohash.test.ts +109 -0
  42. package/src/__tests__/getLayers.test.ts +200 -0
  43. package/src/__tests__/haversine.test.ts +63 -0
  44. package/src/__tests__/localForageAdapter.test.ts +155 -0
  45. package/src/__tests__/markdown.test.ts +806 -0
  46. package/src/__tests__/markdownToDoc.test.ts +374 -0
  47. package/src/__tests__/storage.test.ts +60 -0
  48. package/src/__tests__/templates.test.ts +247 -0
  49. package/src/doc/docToMarkdown.ts +98 -0
  50. package/src/doc/getLayers.ts +152 -0
  51. package/src/doc/index.ts +8 -0
  52. package/src/doc/markdownToDoc.ts +277 -0
  53. package/src/doc/templates/accentImage.ts +338 -0
  54. package/src/doc/templates/captionUtils.ts +33 -0
  55. package/src/doc/templates/comparisonBar.ts +140 -0
  56. package/src/doc/templates/coverBlock.ts +156 -0
  57. package/src/doc/templates/dateEvent.ts +122 -0
  58. package/src/doc/templates/definitionCard.ts +129 -0
  59. package/src/doc/templates/factCard.ts +114 -0
  60. package/src/doc/templates/fullBleedQuote.ts +59 -0
  61. package/src/doc/templates/imageWithCaption.ts +167 -0
  62. package/src/doc/templates/index.ts +571 -0
  63. package/src/doc/templates/listBlock.ts +101 -0
  64. package/src/doc/templates/mapBlock.ts +132 -0
  65. package/src/doc/templates/persistentLayers.ts +522 -0
  66. package/src/doc/templates/photoGrid.ts +199 -0
  67. package/src/doc/templates/pullQuote.ts +119 -0
  68. package/src/doc/templates/quoteBlock.ts +112 -0
  69. package/src/doc/templates/sectionHeader.ts +105 -0
  70. package/src/doc/templates/statHighlight.ts +113 -0
  71. package/src/doc/templates/titleBlock.ts +100 -0
  72. package/src/doc/templates/twoColumn.ts +239 -0
  73. package/src/doc/templates/videoPullQuote.ts +128 -0
  74. package/src/doc/templates/videoWithCaption.ts +126 -0
  75. package/src/doc/utils/animationUtils.ts +135 -0
  76. package/src/doc/utils/themeUtils.ts +139 -0
  77. package/src/index.ts +5 -0
  78. package/src/markdown/convert.ts +897 -0
  79. package/src/markdown/htmlParse.ts +212 -0
  80. package/src/markdown/index.ts +110 -0
  81. package/src/markdown/parse.ts +103 -0
  82. package/src/markdown/stringify.ts +122 -0
  83. package/src/markdown/types.ts +605 -0
  84. package/src/markdown/utils.ts +165 -0
  85. package/src/ngeohash.d.ts +11 -0
  86. package/src/schemas/BlockTemplates.ts +706 -0
  87. package/src/schemas/Doc.ts +565 -0
  88. package/src/schemas/LayoutStrategy.ts +178 -0
  89. package/src/schemas/MediaProvider.ts +70 -0
  90. package/src/schemas/Theme.ts +235 -0
  91. package/src/schemas/Types.ts +15 -0
  92. package/src/schemas/Viewport.ts +91 -0
  93. package/src/schemas/index.ts +14 -0
  94. package/src/schemas/themeLibrary.ts +492 -0
  95. package/src/spatial/Geohash.ts +168 -0
  96. package/src/spatial/Haversine.ts +59 -0
  97. package/src/spatial/index.ts +2 -0
  98. package/src/storage/LocalForageAdapter.ts +103 -0
  99. package/src/storage/LocalStorageAdapter.ts +57 -0
  100. package/src/storage/MemoryStorageAdapter.ts +37 -0
  101. package/src/storage/Storage.ts +28 -0
  102. package/src/storage/index.ts +5 -0
@@ -0,0 +1,691 @@
1
+ import { z as PersistentLayer, L as Layer, E as PersistentLayerConfig, a9 as TitleBlockInput, $ as TemplateContext, U as SectionHeaderInput, Y as StatHighlightInput, S as QuoteBlockInput, F as FactCardInput, ad as TwoColumnInput, m as DateEventInput, t as ImageWithCaptionInput, M as MapBlockInput, X as StartBlockConfig, r as FullBleedQuoteInput, v as ListBlockInput, N as PhotoGridInput, o as DefinitionCardInput, h as ComparisonBarInput, R as PullQuoteInput, ah as VideoWithCaptionInput, ag as VideoPullQuoteInput, A as AccentImage, a as AccentPosition, a4 as Theme, ai as ViewportConfig, q as DocBlock, B as Block, _ as TemplateBlock, a1 as TemplateRegistry, b as Animation, c as AnimationType, ac as TransitionType, a6 as ThemeColorScheme, p as Doc } from '../themeLibrary-DySHPcgj.js';
2
+ export { j as DEFAULT_THEME, u as LayoutHints, T as RenderStyle, a5 as ThemeColorPalette, a7 as ThemeStyle, a8 as ThemeTypography, ae as VIEWPORT_PRESETS, aj as ViewportOrientation, ak as ViewportPreset, an as createTemplateContext, aq as getAvailableThemes, at as getLayoutHints, aw as getThemeSummaries, ax as getTwoColumnPositions, ay as getViewport, az as getViewportOrientation, aB as isTemplateBlock, aD as resolveTheme, aE as scaledFontSize } from '../themeLibrary-DySHPcgj.js';
3
+ import { p as MarkdownHeading, l as MarkdownDocument } from '../types-DHiv_Pnm.js';
4
+
5
+ /**
6
+ * Persistent Layers Expansion
7
+ *
8
+ * Expands persistent layer templates (solid backgrounds, gradients, overlays)
9
+ * into raw Layer arrays. These layers are injected into each block based on
10
+ * per-block flags (useBottomLayer, useTopLayer).
11
+ *
12
+ * This is shared code used by both site and efb-app doc renderers.
13
+ *
14
+ * Related Files:
15
+ * - schemas/BlockTemplates.ts - PersistentLayerConfig types
16
+ */
17
+
18
+ /**
19
+ * Expand all persistent layers in a config to raw Layer arrays.
20
+ */
21
+ declare function expandPersistentLayers(layers: PersistentLayer[] | undefined): Layer[];
22
+ /** Legacy style preset names. Prefer using `Theme.persistentLayers` directly. */
23
+ type DocStylePreset = 'minimal' | 'documentary' | 'branded' | 'cinematic' | 'clean';
24
+ /**
25
+ * Get a PersistentLayerConfig from a style preset.
26
+ *
27
+ * @param preset - Style preset name
28
+ * @param articleTitle - Article title for title caption
29
+ * @param heroSrc - Optional hero image for cinematic style
30
+ */
31
+ declare function getDocStyleConfig(preset: DocStylePreset, articleTitle: string, heroSrc?: string, subtitle?: string): PersistentLayerConfig;
32
+
33
+ /**
34
+ * Title Block Template
35
+ *
36
+ * Large title with optional subtitle for doc intros.
37
+ * Centered text with fade-in animations.
38
+ * Adapts font sizes and positioning for different viewports.
39
+ *
40
+ * This is shared code used by both site and efb-app doc renderers.
41
+ */
42
+
43
+ declare function titleBlock(input: TitleBlockInput, context: TemplateContext): Layer[];
44
+
45
+ /**
46
+ * Section Header Template
47
+ *
48
+ * Section title card with optional background image.
49
+ * Used to introduce new sections of a story.
50
+ * When an image is provided, displays like a title slide with the image as background.
51
+ * Without an image, falls back to a colored background.
52
+ *
53
+ * This is shared code used by both site and efb-app doc renderers.
54
+ */
55
+
56
+ declare function sectionHeader(input: SectionHeaderInput, context: TemplateContext): Layer[];
57
+
58
+ /**
59
+ * Stat Highlight Template
60
+ *
61
+ * Large statistic/number with description and optional detail.
62
+ * Great for emphasizing key data points.
63
+ * Adapts font sizes and positioning for different viewports.
64
+ *
65
+ * Supports optional accent images that appear as tasteful side/bottom strips.
66
+ *
67
+ * This is shared code used by both site and efb-app doc renderers.
68
+ */
69
+
70
+ declare function statHighlight(input: StatHighlightInput, context: TemplateContext): Layer[];
71
+
72
+ /**
73
+ * Quote Block Template
74
+ *
75
+ * Large centered quote with optional attribution.
76
+ * Good for impactful statements or descriptions.
77
+ * Adapts font sizes and positioning for different viewports.
78
+ *
79
+ * Supports optional accent images that appear as tasteful side/bottom strips.
80
+ *
81
+ * This is shared code used by both site and efb-app doc renderers.
82
+ */
83
+
84
+ declare function quoteBlock(input: QuoteBlockInput, context: TemplateContext): Layer[];
85
+
86
+ /**
87
+ * Fact Card Template
88
+ *
89
+ * Key fact with explanation and optional source.
90
+ * Useful for presenting important information clearly.
91
+ * Adapts font sizes and positioning for different viewports.
92
+ *
93
+ * Supports optional accent images that appear as tasteful side/bottom strips.
94
+ *
95
+ * This is shared code used by both site and efb-app doc renderers.
96
+ */
97
+
98
+ declare function factCard(input: FactCardInput, context: TemplateContext): Layer[];
99
+
100
+ /**
101
+ * Two Column Template
102
+ *
103
+ * Side-by-side comparison of two items.
104
+ * Each column has a label and optional sublabel.
105
+ * Adapts font sizes and positioning for different viewports.
106
+ *
107
+ * Portrait mode: Stacks columns vertically (top/bottom) instead of side-by-side.
108
+ *
109
+ * This is shared code used by both site and efb-app doc renderers.
110
+ */
111
+
112
+ declare function twoColumn(input: TwoColumnInput, context: TemplateContext): Layer[];
113
+
114
+ /**
115
+ * Date Event Template
116
+ *
117
+ * Timeline-style slide with prominent date and description.
118
+ * Supports different moods: neutral, somber, celebratory.
119
+ * Adapts font sizes and positioning for different viewports.
120
+ *
121
+ * Supports optional accent images that appear as tasteful side/bottom strips.
122
+ *
123
+ * This is shared code used by both site and efb-app doc renderers.
124
+ */
125
+
126
+ declare function dateEvent(input: DateEventInput, context: TemplateContext): Layer[];
127
+
128
+ /**
129
+ * Image With Caption Template
130
+ *
131
+ * Full-screen background image with text overlay.
132
+ * Supports Ken Burns animation effects (zoom, pan).
133
+ * Adapts caption positioning and font sizes for different viewports.
134
+ *
135
+ * This is shared code used by both site and efb-app doc renderers.
136
+ */
137
+
138
+ declare function imageWithCaption(input: ImageWithCaptionInput, context: TemplateContext): Layer[];
139
+
140
+ /**
141
+ * Map Block Template
142
+ *
143
+ * Full-screen geographic map with optional title and caption overlays.
144
+ * Great for establishing geographic context at the start of a doc
145
+ * or when discussing location-specific content.
146
+ * Adapts font sizes and positioning for different viewports.
147
+ *
148
+ * Map tiles are fetched from free/open-source providers.
149
+ * See docs/MAP_TILES.md for available styles and attribution requirements.
150
+ *
151
+ * This is shared code used by both site and efb-app doc renderers.
152
+ */
153
+
154
+ declare function mapBlock(input: MapBlockInput, context: TemplateContext): Layer[];
155
+
156
+ /**
157
+ * Cover Block Template
158
+ *
159
+ * Full-screen hero image with title overlay, shown before playback starts.
160
+ * This is the "poster for the doc, displaying the
161
+ * article's hero image with elegant title treatment.
162
+ *
163
+ * Features:
164
+ * - Full-screen hero image with Ken Burns ambient motion
165
+ * - Gradient overlay for text readability
166
+ * - Large centered title with optional subtitle
167
+ * - No animation delays (shown at rest, not during playback)
168
+ *
169
+ * This is shared code used by both site and efb-app doc renderers.
170
+ */
171
+
172
+ /**
173
+ * Input for coverBlock template - matches StartBlockConfig
174
+ */
175
+ interface CoverBlockInput {
176
+ /** Path to hero image */
177
+ heroSrc: string;
178
+ /** Alt text for the hero image */
179
+ heroAlt?: string;
180
+ /** Title to display over the hero */
181
+ title: string;
182
+ /** Optional subtitle */
183
+ subtitle?: string;
184
+ /** Ambient motion for the hero image */
185
+ ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';
186
+ /** Photo credit / artist name */
187
+ heroCredit?: string;
188
+ /** License identifier */
189
+ heroLicense?: string;
190
+ }
191
+ /**
192
+ * Generate cover block layers from StartBlockConfig.
193
+ */
194
+ declare function coverBlock(input: CoverBlockInput, context: TemplateContext): Layer[];
195
+ /**
196
+ * Expand a StartBlockConfig into a renderable Block.
197
+ * This is used by the player to render the cover block at rest.
198
+ */
199
+ declare function expandCoverBlock(config: StartBlockConfig, context: TemplateContext): Layer[];
200
+
201
+ /**
202
+ * Full Bleed Quote Template
203
+ *
204
+ * Short dramatic text filling the viewport like a movie title card.
205
+ * Designed for punchy text under 60 characters. Uses massive font
206
+ * centered on a dark vignette background.
207
+ *
208
+ * This is shared code used by both site and efb-app doc renderers.
209
+ */
210
+
211
+ declare function fullBleedQuote(input: FullBleedQuoteInput, context: TemplateContext): Layer[];
212
+
213
+ /**
214
+ * List Block Template
215
+ *
216
+ * Displays 3-5 items in a numbered vertical list with staggered animations.
217
+ * Good for enumerations like "things to see", "key features", or "tips".
218
+ * Supports optional accent images.
219
+ *
220
+ * This is shared code used by both site and efb-app doc renderers.
221
+ */
222
+
223
+ declare function listBlock(input: ListBlockInput, context: TemplateContext): Layer[];
224
+
225
+ /**
226
+ * Photo Grid Template
227
+ *
228
+ * Displays 2-4 images in a tiled layout for visual variety.
229
+ * Layout adapts based on image count and viewport orientation:
230
+ *
231
+ * Landscape:
232
+ * - 2 images: side-by-side 50/50
233
+ * - 3 images: one large left (60%) + two stacked right
234
+ * - 4 images: 2x2 grid
235
+ *
236
+ * Portrait (9:16): images stack horizontally (top/bottom) instead of
237
+ * side-by-side, giving each image full width on narrow screens.
238
+ *
239
+ * This is shared code used by both site and efb-app doc renderers.
240
+ */
241
+
242
+ declare function photoGrid(input: PhotoGridInput, context: TemplateContext): Layer[];
243
+
244
+ /**
245
+ * Definition Card Template
246
+ *
247
+ * Dictionary-style slide with a large term and its definition.
248
+ * Good for explaining local words, place names, or cultural concepts.
249
+ * Supports optional accent images.
250
+ *
251
+ * This is shared code used by both site and efb-app doc renderers.
252
+ */
253
+
254
+ declare function definitionCard(input: DefinitionCardInput, context: TemplateContext): Layer[];
255
+
256
+ /**
257
+ * Comparison Bar Template
258
+ *
259
+ * Two horizontal bars showing relative numeric values side by side.
260
+ * Bar widths are proportional to the values for immediate visual comparison.
261
+ * Good for population, distance, or measurement comparisons.
262
+ *
263
+ * This is shared code used by both site and efb-app doc renderers.
264
+ */
265
+
266
+ declare function comparisonBar(input: ComparisonBarInput, context: TemplateContext): Layer[];
267
+
268
+ /**
269
+ * Pull Quote Template
270
+ *
271
+ * Quote text over a full-bleed background image with dark overlay.
272
+ * Cinematic alternative to quoteBlock when a high-quality image is available.
273
+ * Combines the visual impact of imageWithCaption with the text focus of quoteBlock.
274
+ *
275
+ * This is shared code used by both site and efb-app doc renderers.
276
+ */
277
+
278
+ declare function pullQuote(input: PullQuoteInput, context: TemplateContext): Layer[];
279
+
280
+ /**
281
+ * Video With Caption Template
282
+ *
283
+ * Full-screen background video clip with text overlay. Mirrors the structure of
284
+ * imageWithCaption but uses a VideoLayer instead of an ImageLayer. The video
285
+ * plays muted — narration audio is the only sound track.
286
+ *
287
+ * Adapts caption positioning and font sizes for different viewports.
288
+ *
289
+ * This is shared code used by both site and efb-app doc renderers.
290
+ *
291
+ * Related Files:
292
+ * - shared/story/templates/imageWithCaption.ts — image equivalent
293
+ * - schemas/StoryScript.ts — VideoLayer type
294
+ * - site/src/components/story/layers/VideoLayer.tsx — rendering component
295
+ */
296
+
297
+ declare function videoWithCaption(input: VideoWithCaptionInput, context: TemplateContext): Layer[];
298
+
299
+ /**
300
+ * Video Pull Quote Template
301
+ *
302
+ * Quote text over a video clip background with dark overlay.
303
+ * Cinematic alternative to pullQuote when a video clip is available.
304
+ * Combines the visual dynamism of live video with the text focus of quoteBlock.
305
+ *
306
+ * The video plays muted — narration audio is the only sound track.
307
+ *
308
+ * This is shared code used by both site and efb-app doc renderers.
309
+ *
310
+ * Related Files:
311
+ * - shared/story/templates/pullQuote.ts — image-based equivalent
312
+ * - schemas/StoryScript.ts — VideoLayer type
313
+ * - site/src/components/story/layers/VideoLayer.tsx — rendering component
314
+ */
315
+
316
+ declare function videoPullQuote(input: VideoPullQuoteInput, context: TemplateContext): Layer[];
317
+
318
+ /**
319
+ * Accent Image Utility
320
+ *
321
+ * Creates image layers and layout adjustments for accent images on text-based slides.
322
+ * Accent images are tasteful additions that complement text without overwhelming it.
323
+ *
324
+ * Layout patterns:
325
+ * - left-strip: 35% width vertical strip on left, text area shifted to right 65%
326
+ * - right-strip: 35% width vertical strip on right, text area shifted to left 65%
327
+ * - bottom-strip: 35% height horizontal strip at bottom, text area in upper 65%
328
+ * - corner-inset: Small 25% corner image with gradient vignette
329
+ *
330
+ * This is shared code used by both site and efb-app doc renderers.
331
+ */
332
+
333
+ /**
334
+ * Layout adjustments when an accent image is present.
335
+ * Templates use these values to reposition their text content.
336
+ */
337
+ interface AccentLayout {
338
+ /** X offset for text center (e.g., '64%' for left-strip) */
339
+ textCenterX: string;
340
+ /** Width available for text content */
341
+ textWidth: string;
342
+ /** Y offset adjustment for vertical positioning */
343
+ textYAdjust: number;
344
+ /** Whether to adjust Y positions (for bottom-strip) */
345
+ adjustY: boolean;
346
+ }
347
+ /**
348
+ * Default layout when no accent image is present.
349
+ */
350
+ declare const DEFAULT_LAYOUT: AccentLayout;
351
+ /**
352
+ * Get layout adjustments based on accent position.
353
+ */
354
+ declare function getAccentLayout(position: AccentPosition): AccentLayout;
355
+ /**
356
+ * Create layers for an accent image.
357
+ * Returns the image layer and any overlay/gradient layers needed.
358
+ */
359
+ declare function createAccentLayers(accent: AccentImage, slideId: string): Layer[];
360
+ /**
361
+ * Adjust a Y position value based on accent layout.
362
+ * Used by templates to shift content when bottom-strip is present.
363
+ */
364
+ declare function adjustY(originalY: string | number, layout: AccentLayout): string;
365
+
366
+ /**
367
+ * Block Template Registry
368
+ *
369
+ * Central registry of all block templates. Provides functions to:
370
+ * - Look up templates by name
371
+ * - Expand template blocks into full Layer arrays
372
+ * - Convert a template-based doc script into a renderable format
373
+ *
374
+ * Supports multiple viewport configurations for different aspect ratios.
375
+ *
376
+ * This is shared code used by both site and efb-app doc renderers.
377
+ */
378
+
379
+ /**
380
+ * Registry mapping template names to their implementation functions.
381
+ * Note: coverBlock is not in the registry as it's used directly for start blocks,
382
+ * not as a regular template in the block sequence.
383
+ */
384
+ declare const templateRegistry: TemplateRegistry;
385
+ /**
386
+ * Expand a template block into a full Block with layers.
387
+ */
388
+ declare function expandTemplateBlock(templateBlock: TemplateBlock, context: TemplateContext): Block;
389
+ /**
390
+ * Audio segment timing info for aligning blocks with audio.
391
+ */
392
+ interface AudioSegmentTiming {
393
+ /** Start time of this segment in the overall timeline */
394
+ startTime: number;
395
+ /** Duration of this segment */
396
+ duration: number;
397
+ }
398
+ /**
399
+ * Options for expanding doc blocks.
400
+ */
401
+ interface ExpandDocBlocksOptions {
402
+ /** Theme for template rendering (defaults to DEFAULT_THEME) */
403
+ theme?: Theme;
404
+ /** Viewport configuration (defaults to 16:9 landscape) */
405
+ viewport?: ViewportConfig;
406
+ /** Persistent layers for visual consistency across blocks */
407
+ persistentLayers?: PersistentLayerConfig;
408
+ /**
409
+ * Audio segment timing information.
410
+ * When provided, blocks are timed relative to their audio segment's start time,
411
+ * ensuring proper synchronization with audio playback.
412
+ */
413
+ audioSegments?: AudioSegmentTiming[];
414
+ }
415
+ /**
416
+ * Expand all template blocks in a doc, calculating start times.
417
+ * Injects persistent layers (bottom/top) based on per-block flags.
418
+ *
419
+ * When audioSegments is provided, blocks are timed relative to their audio segment's
420
+ * start time, ensuring blocks appear when their audio is playing. Blocks within each
421
+ * segment are distributed proportionally across the segment duration.
422
+ *
423
+ * @param blocks - Array of template or raw blocks
424
+ * @param options - Expansion options including theme, viewport, and persistent layers
425
+ */
426
+ declare function expandDocBlocks(blocks: DocBlock[], options?: ExpandDocBlocksOptions): Block[];
427
+ /**
428
+ * Get list of available template names.
429
+ */
430
+ declare function getAvailableTemplates(): string[];
431
+ /**
432
+ * Check if a template exists.
433
+ */
434
+ declare function hasTemplate(name: string): boolean;
435
+
436
+ /**
437
+ * Animation Utilities
438
+ *
439
+ * Helper functions for mapping Doc animations to CSS classes and styles.
440
+ * Generates the appropriate animation class names and CSS custom properties
441
+ * for duration, delay, and easing.
442
+ *
443
+ * This is shared code used by both site and efb-app doc renderers.
444
+ */
445
+
446
+ interface AnimationResult {
447
+ /** CSS class name to apply */
448
+ className: string;
449
+ /** Inline styles for CSS custom properties */
450
+ style: Record<string, string>;
451
+ }
452
+ /**
453
+ * Get CSS class and styles for an animation.
454
+ */
455
+ declare function getAnimationStyle(animation: Animation | undefined, _currentTime?: number): AnimationResult;
456
+ /**
457
+ * Get default duration for an animation type.
458
+ */
459
+ declare function getDefaultAnimationDuration(type: AnimationType): number;
460
+ /**
461
+ * Get transition class for slide entry/exit.
462
+ */
463
+ declare function getTransitionClass(type: TransitionType, entering: boolean): string;
464
+ /**
465
+ * Calculate animation progress (0-1) based on current time.
466
+ */
467
+ declare function getAnimationProgress(animation: Animation, currentTime: number, slideDuration: number): number;
468
+
469
+ /**
470
+ * Theme Utilities
471
+ *
472
+ * Template-facing helpers that read from the Theme object on the
473
+ * TemplateContext. Templates call these instead of hard-coding style
474
+ * decisions, so the same template code adapts to any theme.
475
+ */
476
+
477
+ /**
478
+ * Resolve a named color scheme from the theme, with a safe fallback.
479
+ * Templates call this instead of `COLOR_SCHEMES[name]`.
480
+ */
481
+ declare function resolveColorScheme(context: TemplateContext, name: string | undefined): ThemeColorScheme;
482
+ /**
483
+ * Calculate a theme-aware scaled font size.
484
+ * Applies the theme's typography scale multipliers on top of the
485
+ * viewport-based font scale from LayoutStrategy.
486
+ *
487
+ * @param basePx Base font size designed for 1920×1080
488
+ * @param context Template context (includes fontScale, layout, theme)
489
+ * @param isTitle Whether this is title text (uses titleScale) or body (bodyScale)
490
+ */
491
+ declare function themedFontSize(basePx: number, context: TemplateContext, isTitle?: boolean): number;
492
+ /**
493
+ * Scale an animation duration by the theme's animationSpeed multiplier.
494
+ * A speed of 1.0 returns the base duration unchanged.
495
+ */
496
+ declare function scaleAnimationDuration(baseDuration: number, context: TemplateContext): number;
497
+ /**
498
+ * Get the theme's default animation type for a layer kind.
499
+ * Returns `undefined` when the theme doesn't specify one (template picks its own).
500
+ */
501
+ declare function getDefaultAnimation(context: TemplateContext, layerType: 'text' | 'image'): AnimationType | undefined;
502
+ /**
503
+ * Whether the theme defaults to text shadows.
504
+ * Templates should consult this when choosing `shadow: true/false`.
505
+ */
506
+ declare function shouldUseShadow(context: TemplateContext): boolean;
507
+ /**
508
+ * Get the theme's overlay opacity for image-backed blocks.
509
+ */
510
+ declare function getOverlayOpacity(context: TemplateContext): number;
511
+ /**
512
+ * Read a per-template hint from the theme's renderStyle.
513
+ * Returns `fallback` when the hint isn't defined.
514
+ *
515
+ * @example
516
+ * ```ts
517
+ * const entrance = getTemplateHint(context, 'statHighlight', 'entrance', 'subtle');
518
+ * ```
519
+ */
520
+ declare function getTemplateHint<T extends string | number | boolean>(context: TemplateContext, templateName: string, key: string, fallback: T): T;
521
+
522
+ /**
523
+ * Markdown → Doc Conversion
524
+ *
525
+ * Converts a MarkdownDocument into a hierarchical Doc whose Block tree
526
+ * mirrors the heading structure of the markdown. Every heading (H1–H6)
527
+ * becomes a Block; body content between headings populates `contents`;
528
+ * sub-headings nest as `children`.
529
+ *
530
+ * This enables using BlockTemplates to supply alternate visualizations
531
+ * for each section of a markdown document.
532
+ *
533
+ * @example
534
+ * ```ts
535
+ * import { parseMarkdown } from '@bendyline/squisq/markdown';
536
+ * import { markdownToDoc } from '@bendyline/squisq/doc';
537
+ *
538
+ * const md = parseMarkdown('# Intro\n\nHello world\n\n## Details\n\nMore text');
539
+ * const doc = markdownToDoc(md);
540
+ * // doc.blocks[0].sourceHeading.depth === 1 ("# Intro")
541
+ * // doc.blocks[0].contents → [paragraph("Hello world")]
542
+ * // doc.blocks[0].children[0].sourceHeading.depth === 2 ("## Details")
543
+ * ```
544
+ */
545
+
546
+ /**
547
+ * Options for markdownToDoc().
548
+ */
549
+ interface MarkdownToDocOptions {
550
+ /** Article ID for the generated Doc. Default: 'markdown-doc' */
551
+ articleId?: string;
552
+ /** Default template name for heading blocks. Default: 'sectionHeader' */
553
+ defaultTemplate?: string;
554
+ /** Default duration per block in seconds. Default: 5 */
555
+ defaultDuration?: number;
556
+ /** Custom ID generator. Receives the heading node and its index. */
557
+ generateId?: (heading: MarkdownHeading, index: number) => string;
558
+ }
559
+ /**
560
+ * Convert a MarkdownDocument into a Doc with a heading-driven Block hierarchy.
561
+ *
562
+ * **Algorithm:**
563
+ * 1. Walk the document's top-level children sequentially
564
+ * 2. Each MarkdownHeading starts a new block at its depth level
565
+ * 3. Non-heading nodes accumulate as `contents` on the current block
566
+ * 4. Sub-headings (deeper depth) nest as `children` of the current block
567
+ * 5. Same-level or shallower headings close the current block and start a sibling/ancestor
568
+ * 6. Content before the first heading goes into a "preamble" block with no sourceHeading
569
+ *
570
+ * @param markdownDoc - A parsed MarkdownDocument
571
+ * @param options - Conversion options
572
+ * @returns A Doc whose blocks mirror the markdown heading structure
573
+ */
574
+ declare function markdownToDoc(markdownDoc: MarkdownDocument, options?: MarkdownToDocOptions): Doc;
575
+ /**
576
+ * Flatten a nested block tree into a depth-first ordered array.
577
+ * Useful for calculating sequential timing or iterating all blocks.
578
+ */
579
+ declare function flattenBlocks(blocks: Block[]): Block[];
580
+ /**
581
+ * Count the total number of blocks in a nested tree (including children at all levels).
582
+ */
583
+ declare function countBlocks(blocks: Block[]): number;
584
+ /**
585
+ * Get the heading depth for a block. Returns 0 for preamble blocks (no heading).
586
+ */
587
+ declare function getBlockDepth(block: Block): number;
588
+
589
+ /**
590
+ * Doc → Markdown Conversion
591
+ *
592
+ * Converts a Doc with a heading-driven Block hierarchy back into a
593
+ * MarkdownDocument. This is the reverse of markdownToDoc() and enables
594
+ * round-tripping: edit a Doc's block tree, then serialize back to markdown.
595
+ *
596
+ * **Algorithm:**
597
+ * Walk the block tree depth-first. For each block:
598
+ * 1. If it has a `sourceHeading`, emit that heading node
599
+ * 2. Emit all nodes in `contents`
600
+ * 3. Recurse into `children`
601
+ *
602
+ * @example
603
+ * ```ts
604
+ * import { markdownToDoc, docToMarkdown } from '@bendyline/squisq/doc';
605
+ * import { parseMarkdown, stringifyMarkdown } from '@bendyline/squisq/markdown';
606
+ *
607
+ * const md = '# Hello\n\nWorld\n';
608
+ * const doc = markdownToDoc(parseMarkdown(md));
609
+ * const roundTripped = stringifyMarkdown(docToMarkdown(doc));
610
+ * ```
611
+ */
612
+
613
+ /**
614
+ * Convert a Doc with heading-driven blocks back to a MarkdownDocument.
615
+ *
616
+ * Walks the block tree depth-first, emitting heading nodes and contents
617
+ * in document order. Blocks without a `sourceHeading` (preamble blocks)
618
+ * emit only their contents.
619
+ *
620
+ * If a block has a `template` or `templateOverrides` that aren't already
621
+ * reflected in the heading's `templateAnnotation`, the annotation is
622
+ * injected so the round-trip preserves template assignments.
623
+ *
624
+ * @param doc - A Doc whose blocks may have `sourceHeading`, `contents`, and `children`
625
+ * @returns A MarkdownDocument that can be stringified back to markdown
626
+ */
627
+ declare function docToMarkdown(doc: Doc): MarkdownDocument;
628
+
629
+ /**
630
+ * getLayers — Compute visual layers for a block on demand.
631
+ *
632
+ * This is the preferred way to obtain renderable layers for a block.
633
+ * Instead of storing pre-computed layers on the Block object, call
634
+ * `getLayers(block, context)` to derive them from the block's template
635
+ * name, content, and the current render context (theme, viewport, etc.).
636
+ *
637
+ * For raw blocks that already carry a `layers` array, those layers are
638
+ * returned directly (with optional persistent layer injection).
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * import { getLayers } from '@bendyline/squisq/doc';
643
+ *
644
+ * const layers = getLayers(block, {
645
+ * theme: DEFAULT_THEME,
646
+ * viewport: VIEWPORT_PRESETS.landscape,
647
+ * blockIndex: 0,
648
+ * totalBlocks: 10,
649
+ * });
650
+ * ```
651
+ */
652
+
653
+ /**
654
+ * Context needed to compute layers for a block.
655
+ *
656
+ * Captures the visual rendering parameters: theme colors, viewport
657
+ * configuration, persistent layers, and the block's position within
658
+ * the doc (for template functions that vary output by index).
659
+ */
660
+ interface RenderContext {
661
+ /** Theme for template rendering. Defaults to DEFAULT_THEME (documentary). */
662
+ theme?: Theme;
663
+ /** Target viewport configuration. Defaults to 16:9 landscape. */
664
+ viewport?: ViewportConfig;
665
+ /** Persistent layers injected behind and/or on top of all block content. */
666
+ persistentLayers?: PersistentLayerConfig;
667
+ /** 0-based index of this block in the sequence. Defaults to 0. */
668
+ blockIndex?: number;
669
+ /** Total number of blocks in the doc. Defaults to 1. */
670
+ totalBlocks?: number;
671
+ }
672
+ /**
673
+ * Compute the visual layers for a block.
674
+ *
675
+ * Resolution order:
676
+ * 1. If the block already has a non-empty `layers` array, use it (raw block).
677
+ * 2. If the block has a `template` name that exists in the registry,
678
+ * call the template function to generate layers.
679
+ * 3. Otherwise return an empty array.
680
+ *
681
+ * Persistent layers (bottom/top) from the render context are injected
682
+ * around the result unless the block opts out via `useBottomLayer: false`
683
+ * or `useTopLayer: false`.
684
+ *
685
+ * @param block A Block or TemplateBlock to render.
686
+ * @param context Render context (theme, viewport, persistent layers, position).
687
+ * @returns The computed Layer[] for the block, ready for BlockRenderer.
688
+ */
689
+ declare function getLayers(block: DocBlock, context?: RenderContext): Layer[];
690
+
691
+ export { type AccentLayout, type AudioSegmentTiming, type CoverBlockInput, DEFAULT_LAYOUT, DocBlock, type DocStylePreset, type ExpandDocBlocksOptions, type MarkdownToDocOptions, PersistentLayerConfig, type RenderContext, TemplateBlock, TemplateContext, Theme, ThemeColorScheme, ViewportConfig, adjustY, comparisonBar, countBlocks, coverBlock, createAccentLayers, dateEvent, definitionCard, docToMarkdown, expandCoverBlock, expandDocBlocks, expandPersistentLayers, expandTemplateBlock, factCard, flattenBlocks, fullBleedQuote, getAccentLayout, getAnimationProgress, getAnimationStyle, getAvailableTemplates, getBlockDepth, getDefaultAnimation, getDefaultAnimationDuration, getDocStyleConfig, getLayers, getOverlayOpacity, getTemplateHint, getTransitionClass, hasTemplate, imageWithCaption, listBlock, mapBlock, markdownToDoc, photoGrid, pullQuote, quoteBlock, resolveColorScheme, scaleAnimationDuration, sectionHeader, shouldUseShadow, statHighlight, templateRegistry, themedFontSize, titleBlock, twoColumn, videoPullQuote, videoWithCaption };