@bendyline/squisq 2.3.3 → 2.4.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 (38) hide show
  1. package/dist/{Doc-BrgZC7SE.d.ts → Doc-CSW6K2UF.d.ts} +222 -9
  2. package/dist/{ImageEditDoc-rum0Xb9P.d.ts → ImageEditDoc-x9yoTb4l.d.ts} +1 -1
  3. package/dist/{chunk-GQNH7PLN.js → chunk-2HY2ZA7U.js} +1470 -77
  4. package/dist/{chunk-G3JOS25T.js → chunk-7TJJA2RI.js} +46 -15
  5. package/dist/{chunk-RS5AP3J4.js → chunk-AE3IUKMM.js} +1 -1
  6. package/dist/{chunk-IZLKI3IL.js → chunk-AQF5ZYDI.js} +76 -16
  7. package/dist/{chunk-QWCFK5FN.js → chunk-CUYHFOFL.js} +5 -1
  8. package/dist/{chunk-2VCNTDNZ.js → chunk-D6YTLQCL.js} +71 -0
  9. package/dist/{chunk-32R2RZAO.js → chunk-DAMIRKTO.js} +1 -1
  10. package/dist/{chunk-ABP4LAJS.js → chunk-EMXYZLRH.js} +1 -1
  11. package/dist/{chunk-2ZWIXGAC.js → chunk-GAZKTT4R.js} +28 -4
  12. package/dist/{chunk-SPTY4C6F.js → chunk-GODLNXO4.js} +45 -3
  13. package/dist/chunk-JUAC2QWP.js +983 -0
  14. package/dist/{chunk-BCCXTMN5.js → chunk-O7JILDEF.js} +7 -0
  15. package/dist/{chunk-C33GTPUZ.js → chunk-SBAX4ZPO.js} +438 -0
  16. package/dist/doc/index.d.ts +113 -6
  17. package/dist/doc/index.js +14 -11
  18. package/dist/generate/index.d.ts +1 -1
  19. package/dist/imageEdit/index.d.ts +3 -3
  20. package/dist/index.d.ts +7 -7
  21. package/dist/index.js +41 -17
  22. package/dist/jsonForm/index.d.ts +1 -1
  23. package/dist/jsonForm/index.js +4 -4
  24. package/dist/markdown/index.d.ts +118 -1
  25. package/dist/markdown/index.js +22 -6
  26. package/dist/{materializePageSection-CrZWYnXM.d.ts → materializePageSection-_rrDuOYU.d.ts} +2 -2
  27. package/dist/narration/index.d.ts +1 -1
  28. package/dist/narration/index.js +6 -6
  29. package/dist/recommend/index.js +2 -2
  30. package/dist/schemas/index.d.ts +32 -5
  31. package/dist/schemas/index.js +9 -3
  32. package/dist/storage/index.d.ts +2 -3
  33. package/dist/{themeLibrary-DJt89gyP.d.ts → themeLibrary-DlJzXsin.d.ts} +1 -1
  34. package/dist/timing/index.d.ts +1 -2
  35. package/dist/transform/index.d.ts +2 -2
  36. package/dist/transform/index.js +2 -2
  37. package/package.json +2 -2
  38. package/dist/chunk-UA5DTYAY.js +0 -400
@@ -1,18 +1,19 @@
1
1
  import {
2
2
  coerceAnnotationValues,
3
+ isReservedAnnotationToken,
3
4
  matchTrailingPandocAttr,
4
5
  matchTrailingTemplateAnnotation,
5
6
  quoteAttrValue,
6
7
  splitKeyValueToken,
7
8
  tokenizeAttrTokens
8
- } from "./chunk-2VCNTDNZ.js";
9
+ } from "./chunk-D6YTLQCL.js";
9
10
  import {
10
11
  resolveIcon
11
12
  } from "./chunk-7N4G32LG.js";
12
13
  import {
13
14
  parseFrontmatter,
14
15
  parseHtmlToNodes
15
- } from "./chunk-BCCXTMN5.js";
16
+ } from "./chunk-O7JILDEF.js";
16
17
 
17
18
  // src/markdown/convert.ts
18
19
  function convertPosition(pos) {
@@ -58,25 +59,54 @@ function extractText(node) {
58
59
  return "";
59
60
  }
60
61
  function extractTemplateAnnotation(children) {
62
+ const trail = [];
61
63
  for (let i = children.length - 1; i >= 0; i--) {
62
64
  const child = children[i];
63
65
  if (child.type === "text") {
64
- const match = matchTrailingTemplateAnnotation(child.value);
65
- if (match) {
66
- const inner = match.inner.trim();
67
- const annotation = parseAnnotationTokens(inner);
68
- const stripped = child.value.slice(0, match.index).replace(/\s+$/, "");
69
- if (stripped) {
70
- child.value = stripped;
71
- } else {
72
- children.splice(i, 1);
73
- }
74
- return annotation;
75
- }
76
- break;
66
+ trail.unshift({ value: child.value, index: i });
67
+ continue;
68
+ }
69
+ const autolink = literalAutolinkText(child);
70
+ if (autolink != null) {
71
+ trail.unshift({ value: autolink, index: i });
72
+ continue;
77
73
  }
78
74
  break;
79
75
  }
76
+ if (trail.length === 0) return null;
77
+ const joined = trail.map((part) => part.value).join("");
78
+ const match = matchTrailingTemplateAnnotation(joined);
79
+ if (!match) return null;
80
+ const annotation = parseAnnotationTokens(match.inner.trim());
81
+ let scannedLength = 0;
82
+ for (const part of trail) {
83
+ if (scannedLength + part.value.length <= match.index) {
84
+ scannedLength += part.value.length;
85
+ continue;
86
+ }
87
+ const boundaryNode = children[part.index];
88
+ const keepLength = match.index - scannedLength;
89
+ if (boundaryNode.type === "text" && keepLength > 0) {
90
+ const stripped = boundaryNode.value.slice(0, keepLength).replace(/\s+$/, "");
91
+ if (stripped) {
92
+ boundaryNode.value = stripped;
93
+ children.splice(part.index + 1);
94
+ } else {
95
+ children.splice(part.index);
96
+ }
97
+ } else {
98
+ children.splice(part.index);
99
+ }
100
+ return annotation;
101
+ }
102
+ children.splice(trail[0].index);
103
+ return annotation;
104
+ }
105
+ function literalAutolinkText(node) {
106
+ if (node.type !== "link" || node.title != null) return null;
107
+ const label = extractInlineText(node.children);
108
+ if (label === node.url) return label;
109
+ if (/^www\./i.test(label) && node.url === `http://${label}`) return label;
80
110
  return null;
81
111
  }
82
112
  function parseAnnotationTokens(inner) {
@@ -274,6 +304,7 @@ function splitTextOnIcons(value, position) {
274
304
  const out = [];
275
305
  while ((match = ICON_TOKEN_RE.exec(value)) !== null) {
276
306
  const token = match[1];
307
+ if (isReservedAnnotationToken(token)) continue;
277
308
  const icon = resolveIcon(token);
278
309
  if (!icon) continue;
279
310
  if (match.index > lastIndex) {
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  extractPlainText,
12
12
  getChildren
13
- } from "./chunk-BCCXTMN5.js";
13
+ } from "./chunk-O7JILDEF.js";
14
14
  import {
15
15
  estimateTimeFromText
16
16
  } from "./chunk-67L6WRJN.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SHAPE_NAMES,
3
- TEMPLATE_ALIASES,
3
+ buildChartData,
4
4
  buildNarrationScript,
5
5
  coerceTemplateParams,
6
6
  deriveTemplateInputs,
@@ -10,7 +10,6 @@ import {
10
10
  flattenRenderableBlocks,
11
11
  getBlockBodyText,
12
12
  getPinnedBlockMeta,
13
- isContainerTemplate,
14
13
  isDataFence,
15
14
  isShapeName,
16
15
  lintTemplateParams,
@@ -21,11 +20,10 @@ import {
21
20
  parseNarrationTimingJson,
22
21
  parseStandaloneAnnotation,
23
22
  readCustomThemesFromFrontmatter,
24
- resolveTemplateName,
25
23
  templateRegistry,
26
24
  writeCustomTemplatesToFrontmatter,
27
25
  writeCustomThemesToFrontmatter
28
- } from "./chunk-GQNH7PLN.js";
26
+ } from "./chunk-2HY2ZA7U.js";
29
27
  import {
30
28
  ASCII_TREE_VOCAB,
31
29
  ASCII_VOCAB,
@@ -41,11 +39,11 @@ import {
41
39
  toCells,
42
40
  toGrid,
43
41
  traceBoxes
44
- } from "./chunk-QWCFK5FN.js";
42
+ } from "./chunk-CUYHFOFL.js";
45
43
  import {
46
44
  defaultPageStyle,
47
45
  resolveMediaSchedule
48
- } from "./chunk-2ZWIXGAC.js";
46
+ } from "./chunk-GAZKTT4R.js";
49
47
  import {
50
48
  DEFAULT_THEME,
51
49
  FRONTMATTER_CUSTOM_TEMPLATES_KEY,
@@ -53,24 +51,28 @@ import {
53
51
  hexHueDegrees,
54
52
  resolveFontFamily,
55
53
  resolveTheme
56
- } from "./chunk-C33GTPUZ.js";
54
+ } from "./chunk-SBAX4ZPO.js";
57
55
  import {
58
56
  VIEWPORT_PRESETS,
59
57
  isTemplateBlock
60
58
  } from "./chunk-BAOV476U.js";
61
59
  import {
62
60
  parseMarkdown
63
- } from "./chunk-G3JOS25T.js";
61
+ } from "./chunk-7TJJA2RI.js";
64
62
  import {
65
63
  KNOWN_BLOCK_META_KEYS,
64
+ TEMPLATE_ALIASES,
66
65
  coerceAnnotationValues,
66
+ isContainerTemplate,
67
+ resolveTemplateName,
67
68
  serializeAnnotation
68
- } from "./chunk-2VCNTDNZ.js";
69
+ } from "./chunk-D6YTLQCL.js";
69
70
  import {
70
71
  extractPlainText,
71
72
  getChildren,
73
+ parseHtmlToNodes,
72
74
  readFrontmatterThemeId
73
- } from "./chunk-BCCXTMN5.js";
75
+ } from "./chunk-O7JILDEF.js";
74
76
  import {
75
77
  estimateTimeFromText
76
78
  } from "./chunk-67L6WRJN.js";
@@ -354,15 +356,21 @@ function docToMarkdown(doc, options = {}) {
354
356
  children.push(synthesizeMediaParagraph(clip));
355
357
  }
356
358
  function emitBlock(block) {
359
+ const promoted = block.promotedBodyAnnotation;
360
+ const promotedUnedited = promoted !== void 0 && !isPromotedBodyEdited(block, promoted);
357
361
  if (block.sourceHeading) {
358
- const heading = ensureAnnotation(block, block.sourceHeading, defaultTemplate);
359
- children.push(heading);
362
+ if (promotedUnedited) {
363
+ children.push(block.sourceHeading);
364
+ } else {
365
+ const heading = ensureAnnotation(block, block.sourceHeading, defaultTemplate);
366
+ children.push(heading);
367
+ }
360
368
  } else if (block.standaloneAnnotation) {
361
369
  children.push(synthesizeAnnotationParagraph(block));
362
370
  }
363
371
  const clips = [...block.media ?? [], ...docMediaByBlock.get(block.id) ?? []];
372
+ const contents = [...block.contents ?? []];
364
373
  if (clips.length > 0) {
365
- const contents = [...block.contents ?? []];
366
374
  const anchored = clips.filter((clip) => clip.origin).sort((a, b) => a.origin.index - b.origin.index);
367
375
  for (const clip of anchored) {
368
376
  contents.splice(
@@ -374,10 +382,11 @@ function docToMarkdown(doc, options = {}) {
374
382
  for (const clip of clips.filter((c) => !c.origin).reverse()) {
375
383
  contents.unshift(synthesizeMediaParagraph(clip));
376
384
  }
377
- children.push(...contents);
378
- } else if (block.contents) {
379
- children.push(...block.contents);
380
385
  }
386
+ if (promotedUnedited) {
387
+ reinsertPromotedBodyAnnotation(contents, promoted);
388
+ }
389
+ children.push(...contents);
381
390
  if (block.children) {
382
391
  for (const child of block.children) {
383
392
  emitBlock(child);
@@ -414,11 +423,49 @@ function synthesizeAnnotationParagraph(block) {
414
423
  const text = serializeAnnotation(block.sourceAnnotation?.template, block.templateOverrides);
415
424
  return { type: "paragraph", children: [{ type: "text", value: text }] };
416
425
  }
426
+ function isPromotedBodyEdited(block, p) {
427
+ const templateSame = resolveTemplateName(block.template ?? "") === resolveTemplateName(p.template);
428
+ const paramsSame = paramsEqual(block.templateOverrides ?? {}, p.params ?? {});
429
+ return !(templateSame && paramsSame);
430
+ }
431
+ function reinsertPromotedBodyAnnotation(contents, p) {
432
+ if (p.origin.kind === "paragraph") {
433
+ contents.push({ type: "paragraph", children: [{ type: "text", value: p.origin.raw }] });
434
+ return;
435
+ }
436
+ const last = contents[contents.length - 1];
437
+ if (last && last.type === "paragraph") {
438
+ const children = last.children ?? [];
439
+ const lastChild = children[children.length - 1];
440
+ if (lastChild && lastChild.type === "text") {
441
+ const cloned = [...children];
442
+ cloned[cloned.length - 1] = { ...lastChild, value: lastChild.value + p.origin.suffix };
443
+ contents[contents.length - 1] = { ...last, children: cloned };
444
+ return;
445
+ }
446
+ }
447
+ contents.push({
448
+ type: "paragraph",
449
+ children: [{ type: "text", value: p.origin.suffix.replace(/^\s+/, "") }]
450
+ });
451
+ }
417
452
  function synthesizeMediaParagraph(clip) {
453
+ if (clip.origin?.format === "html" && clip.origin.raw) {
454
+ return {
455
+ type: "htmlBlock",
456
+ rawHtml: clip.origin.raw,
457
+ htmlChildren: parseHtmlToNodes(clip.origin.raw)
458
+ };
459
+ }
418
460
  if (clip.origin?.raw) {
419
461
  return { type: "paragraph", children: [{ type: "text", value: clip.origin.raw }] };
420
462
  }
421
463
  const params = { src: clip.src };
464
+ if (clip.placement) params.placement = clip.placement;
465
+ if (clip.pipSize) params.pipSize = clip.pipSize;
466
+ if (clip.pipShape) params.pipShape = clip.pipShape;
467
+ if (clip.pipPosition) params.pipPosition = clip.pipPosition;
468
+ if (clip.lockToBlock != null) params.lockToBlock = String(clip.lockToBlock);
422
469
  if (clip.anchor === "document") params.anchor = "document";
423
470
  if (clip.startAt) params.startAt = String(clip.startAt);
424
471
  if (clip.clipStart != null) params.clipStart = String(clip.clipStart);
@@ -903,6 +950,12 @@ var dataTable = (input) => {
903
950
  colorScheme: d.colorScheme
904
951
  };
905
952
  };
953
+ var chartExtractor = (input, ctx) => {
954
+ const chart = input;
955
+ const chartable = Array.isArray(chart.headers) && Array.isArray(chart.rows) && buildChartData({ headers: chart.headers, rows: chart.rows }, chart) !== null;
956
+ if (chartable) return canvasDraft("chart", ctx, input);
957
+ return content(input, ctx);
958
+ };
906
959
  var diagram = (input, ctx) => canvasDraft("diagram", ctx, input);
907
960
  var tree = (input, ctx) => canvasDraft("tree", ctx, input);
908
961
  var timeline = (input, ctx) => canvasDraft("timeline", ctx, input);
@@ -931,6 +984,13 @@ var sectionExtractors = {
931
984
  videoWithCaption,
932
985
  videoPullQuote,
933
986
  dataTable,
987
+ barChart: chartExtractor,
988
+ columnChart: chartExtractor,
989
+ pieChart: chartExtractor,
990
+ donutChart: chartExtractor,
991
+ lineChart: chartExtractor,
992
+ areaChart: chartExtractor,
993
+ scatterChart: chartExtractor,
934
994
  diagram,
935
995
  tree,
936
996
  timeline,
@@ -2,7 +2,7 @@ import {
2
2
  extractPlainText,
3
3
  findNodesByType,
4
4
  walkMarkdownTree
5
- } from "./chunk-BCCXTMN5.js";
5
+ } from "./chunk-O7JILDEF.js";
6
6
 
7
7
  // src/doc/asciiDiagram/chars.ts
8
8
  function toCells(s) {
@@ -2435,6 +2435,10 @@ function recommendedNamesForProfile(profile) {
2435
2435
  anyContentSignal = true;
2436
2436
  names.add("dataTable");
2437
2437
  names.add("comparisonBar");
2438
+ names.add("columnChart");
2439
+ names.add("barChart");
2440
+ names.add("lineChart");
2441
+ names.add("pieChart");
2438
2442
  }
2439
2443
  if (profile.hasDate) {
2440
2444
  anyContentSignal = true;
@@ -5,6 +5,71 @@ import {
5
5
  normalizeTransitionType
6
6
  } from "./chunk-4VOD55SX.js";
7
7
 
8
+ // src/doc/templates/templateNames.ts
9
+ var TEMPLATE_ALIASES = Object.freeze({
10
+ titleBlock: "title",
11
+ quoteBlock: "quote",
12
+ mapBlock: "map",
13
+ listBlock: "list",
14
+ diagramBlock: "diagram",
15
+ diagramNode: "diagram"
16
+ });
17
+ function resolveTemplateName(name) {
18
+ return TEMPLATE_ALIASES[name] ?? name;
19
+ }
20
+ var TABLE_FED_TEMPLATES = /* @__PURE__ */ new Set([
21
+ "dataTable",
22
+ "barChart",
23
+ "columnChart",
24
+ "pieChart",
25
+ "donutChart",
26
+ "lineChart",
27
+ "areaChart",
28
+ "scatterChart"
29
+ ]);
30
+ var CONTAINER_TEMPLATES = /* @__PURE__ */ new Set(["diagram", "drawing", "layout"]);
31
+ function isContainerTemplate(name) {
32
+ return !!name && CONTAINER_TEMPLATES.has(resolveTemplateName(name));
33
+ }
34
+ var TEMPLATE_TOKEN_NAMES = /* @__PURE__ */ new Set([
35
+ "title",
36
+ "sectionHeader",
37
+ "content",
38
+ "statHighlight",
39
+ "quote",
40
+ "factCard",
41
+ "twoColumn",
42
+ "dateEvent",
43
+ "imageWithCaption",
44
+ "leftFeature",
45
+ "rightFeature",
46
+ "map",
47
+ "fullBleedQuote",
48
+ "list",
49
+ "photoGrid",
50
+ "definitionCard",
51
+ "comparisonBar",
52
+ "pullQuote",
53
+ "videoWithCaption",
54
+ "videoPullQuote",
55
+ "dataTable",
56
+ "barChart",
57
+ "columnChart",
58
+ "pieChart",
59
+ "donutChart",
60
+ "lineChart",
61
+ "areaChart",
62
+ "scatterChart",
63
+ "diagram",
64
+ "tree",
65
+ "timeline",
66
+ "layout",
67
+ "drawing"
68
+ ]);
69
+ function isReservedAnnotationToken(token) {
70
+ return TEMPLATE_TOKEN_NAMES.has(resolveTemplateName(token));
71
+ }
72
+
8
73
  // src/markdown/sanitize.ts
9
74
  var SAFE_LINK_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "mailto", "tel"]);
10
75
  var SAFE_MEDIA_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "blob"]);
@@ -518,6 +583,12 @@ function serializeAnnotation(template, params) {
518
583
  }
519
584
 
520
585
  export {
586
+ TEMPLATE_ALIASES,
587
+ resolveTemplateName,
588
+ TABLE_FED_TEMPLATES,
589
+ CONTAINER_TEMPLATES,
590
+ isContainerTemplate,
591
+ isReservedAnnotationToken,
521
592
  sanitizeUrl,
522
593
  sanitizeHtmlNodes,
523
594
  KNOWN_BLOCK_META_KEYS,
@@ -2,7 +2,7 @@ import {
2
2
  DEFAULT_THEME,
3
3
  applySurface,
4
4
  resolveFontFamily
5
- } from "./chunk-C33GTPUZ.js";
5
+ } from "./chunk-SBAX4ZPO.js";
6
6
 
7
7
  // src/jsonForm/chooseControl.ts
8
8
  var ENUM_SEGMENTED_LIMIT = 4;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  expectedSyllablesAt,
3
3
  wordPosAtExpectedSyllables
4
- } from "./chunk-GQNH7PLN.js";
4
+ } from "./chunk-2HY2ZA7U.js";
5
5
 
6
6
  // src/narration/types.ts
7
7
  var DEFAULT_FEATURE_CONFIG = Object.freeze({
@@ -10,6 +10,13 @@ function clipLength(clip) {
10
10
  if (clip.clipEnd == null) return null;
11
11
  return Math.max(0, clip.clipEnd - (clip.clipStart ?? 0));
12
12
  }
13
+ function intrinsicPlayedLength(clip, opts) {
14
+ if (clip.clipEnd != null || clip.lockToBlock === true) return null;
15
+ const intrinsic = opts?.intrinsicDuration?.(clip);
16
+ if (intrinsic == null || !Number.isFinite(intrinsic) || intrinsic <= 0) return null;
17
+ const played = intrinsic - (clip.clipStart ?? 0);
18
+ return played > 0 ? played : null;
19
+ }
13
20
  function baseTimelineEnd(doc) {
14
21
  const blockEnd = flatten(doc.blocks).reduce(
15
22
  (max, b) => Math.max(max, b.startTime + b.duration),
@@ -17,7 +24,7 @@ function baseTimelineEnd(doc) {
17
24
  );
18
25
  return Math.max(doc.duration ?? 0, blockEnd);
19
26
  }
20
- function resolveMediaSchedule(doc) {
27
+ function resolveMediaSchedule(doc, opts) {
21
28
  const out = [];
22
29
  const docEnd = baseTimelineEnd(doc);
23
30
  for (const block of flatten(doc.blocks)) {
@@ -31,10 +38,17 @@ function resolveMediaSchedule(doc) {
31
38
  } else {
32
39
  end = len != null ? Math.min(start + len, blockEnd) : blockEnd;
33
40
  }
41
+ const natLen = intrinsicPlayedLength(clip, opts);
42
+ if (natLen != null) end = Math.min(end, start + natLen);
34
43
  out.push({
35
44
  id: clip.id,
36
45
  src: clip.src,
37
46
  kind: clip.kind,
47
+ ...clip.placement ? { placement: clip.placement } : {},
48
+ ...clip.pipSize ? { pipSize: clip.pipSize } : {},
49
+ ...clip.pipShape ? { pipShape: clip.pipShape } : {},
50
+ ...clip.pipPosition ? { pipPosition: clip.pipPosition } : {},
51
+ ...clip.lockToBlock != null ? { lockToBlock: clip.lockToBlock } : {},
38
52
  absoluteStart: start,
39
53
  absoluteEnd: Math.max(start, end),
40
54
  sourceIn: clip.clipStart ?? 0,
@@ -47,11 +61,18 @@ function resolveMediaSchedule(doc) {
47
61
  for (const clip of doc.documentMedia ?? []) {
48
62
  const start = clip.startAt;
49
63
  const len = clipLength(clip);
50
- const end = len != null ? start + len : docEnd;
64
+ let end = len != null ? start + len : docEnd;
65
+ const natLen = intrinsicPlayedLength(clip, opts);
66
+ if (natLen != null) end = Math.min(end, start + natLen);
51
67
  out.push({
52
68
  id: clip.id,
53
69
  src: clip.src,
54
70
  kind: clip.kind,
71
+ ...clip.placement ? { placement: clip.placement } : {},
72
+ ...clip.pipSize ? { pipSize: clip.pipSize } : {},
73
+ ...clip.pipShape ? { pipShape: clip.pipShape } : {},
74
+ ...clip.pipPosition ? { pipPosition: clip.pipPosition } : {},
75
+ ...clip.lockToBlock != null ? { lockToBlock: clip.lockToBlock } : {},
55
76
  absoluteStart: start,
56
77
  absoluteEnd: Math.max(start, end),
57
78
  sourceIn: clip.clipStart ?? 0,
@@ -61,9 +82,12 @@ function resolveMediaSchedule(doc) {
61
82
  }
62
83
  return out;
63
84
  }
64
- function getDocPlaybackDuration(doc) {
85
+ function getDocPlaybackDuration(doc, opts) {
65
86
  const base = baseTimelineEnd(doc);
66
- const mediaEnd = resolveMediaSchedule(doc).reduce((max, c) => Math.max(max, c.absoluteEnd), 0);
87
+ const mediaEnd = resolveMediaSchedule(doc, opts).reduce(
88
+ (max, c) => Math.max(max, c.absoluteEnd),
89
+ 0
90
+ );
67
91
  return Math.max(base, mediaEnd);
68
92
  }
69
93
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defaultPageStyle
3
- } from "./chunk-2ZWIXGAC.js";
3
+ } from "./chunk-GAZKTT4R.js";
4
4
  import {
5
5
  FONT_FALLBACKS,
6
6
  THEME_SCHEMA_VERSION,
@@ -13,8 +13,9 @@ import {
13
13
  oklchSetChroma,
14
14
  pickContrastingText,
15
15
  relativeLuminance,
16
- resolveFontFamily
17
- } from "./chunk-C33GTPUZ.js";
16
+ resolveFontFamily,
17
+ withAlpha
18
+ } from "./chunk-SBAX4ZPO.js";
18
19
 
19
20
  // src/schemas/Doc.ts
20
21
  function calculateDuration(audio) {
@@ -47,6 +48,46 @@ function getCaptionAtTime(captions, time) {
47
48
  return null;
48
49
  }
49
50
 
51
+ // src/schemas/pipStyle.ts
52
+ var DEFAULT_SHADOW = "0 0.75em 2em rgba(0, 0, 0, 0.34)";
53
+ var DERIVED_BORDER_WIDTH = "max(1px, 0.12vw)";
54
+ function cssLength(value) {
55
+ return typeof value === "number" ? `${value}px` : value;
56
+ }
57
+ function resolveRadius(theme) {
58
+ const explicit = theme.style.pip?.cornerRadius;
59
+ if (explicit != null) {
60
+ if (typeof explicit === "number") return explicit <= 0 ? "0" : `${explicit}px`;
61
+ return explicit;
62
+ }
63
+ const br = theme.style.borderRadius ?? 0;
64
+ if (br <= 0) return "0";
65
+ return `${Math.min(28, Math.max(6, Math.round(br)))}%`;
66
+ }
67
+ function resolveBorder(theme) {
68
+ const border = theme.style.pip?.border;
69
+ if (border === "none") return "none";
70
+ if (border && typeof border === "object") {
71
+ const width = border.width == null ? DERIVED_BORDER_WIDTH : cssLength(border.width);
72
+ const color = border.color ?? withAlpha(theme.colors.text, 0.35);
73
+ return `${width} solid ${color}`;
74
+ }
75
+ return `${DERIVED_BORDER_WIDTH} solid ${withAlpha(theme.colors.text, 0.35)}`;
76
+ }
77
+ function resolveShadow(theme) {
78
+ const shadow = theme.style.pip?.shadow;
79
+ if (shadow === false || shadow === "none") return "none";
80
+ if (typeof shadow === "string") return shadow;
81
+ return DEFAULT_SHADOW;
82
+ }
83
+ function pipStyleVars(theme) {
84
+ return {
85
+ "--squisq-pip-radius": resolveRadius(theme),
86
+ "--squisq-pip-border": resolveBorder(theme),
87
+ "--squisq-pip-shadow": resolveShadow(theme)
88
+ };
89
+ }
90
+
50
91
  // src/schemas/themeCompile.ts
51
92
  var STARTER_BODY_FONT = { stackId: "system-sans" };
52
93
  var STARTER_TITLE_FONT = { stackId: "system-serif" };
@@ -308,6 +349,7 @@ export {
308
349
  getSegmentAtTime,
309
350
  getBlockAtTime,
310
351
  getCaptionAtTime,
352
+ pipStyleVars,
311
353
  STARTER_THEME,
312
354
  deriveColorPalette,
313
355
  accentToColorScheme,