@bendyline/squisq 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/{Doc-DBadkoP4.d.ts → Doc-CRPQCkHn.d.ts} +35 -3
  2. package/dist/{ImageEditDoc-Cq2a3c30.d.ts → ImageEditDoc-MbvJM1HE.d.ts} +1 -1
  3. package/dist/{annotationCoercion-CPHEggo3.d.ts → annotationCoercion-Ckqpu33y.d.ts} +1 -1
  4. package/dist/{chunk-HXMV7WQB.js → chunk-64I44JAP.js} +1 -1
  5. package/dist/{chunk-KIAEJDZB.js → chunk-EH4S7HXE.js} +193 -3
  6. package/dist/{chunk-7YEZFHLS.js → chunk-O7HLQ22N.js} +11 -0
  7. package/dist/chunk-T3B4WJBR.js +167 -0
  8. package/dist/{chunk-NBKAXPSX.js → chunk-TMOHAFYE.js} +1 -0
  9. package/dist/{chunk-6MVWWZHL.js → chunk-UBFT2CDQ.js} +117 -16
  10. package/dist/{chunk-FCG3BIZN.js → chunk-UNVHAK3A.js} +5 -1
  11. package/dist/{chunk-HEYR3TPL.js → chunk-ZWID3HM5.js} +107 -2
  12. package/dist/{chunk-W2GIFNLN.js → chunk-ZYCSRDSX.js} +374 -2
  13. package/dist/doc/index.d.ts +125 -8
  14. package/dist/doc/index.js +12 -4
  15. package/dist/fence/index.d.ts +2 -2
  16. package/dist/generate/index.d.ts +2 -2
  17. package/dist/imageEdit/index.d.ts +4 -4
  18. package/dist/index.d.ts +11 -9
  19. package/dist/index.js +58 -8
  20. package/dist/jsonForm/index.d.ts +2 -2
  21. package/dist/markdown/index.d.ts +3 -3
  22. package/dist/markdown/index.js +3 -3
  23. package/dist/{materializePageSection-Rss5thAj.d.ts → materializePageSection-BeUPHeCl.d.ts} +2 -2
  24. package/dist/narration/index.d.ts +109 -4
  25. package/dist/narration/index.js +11 -3
  26. package/dist/proof/index.d.ts +179 -0
  27. package/dist/proof/index.js +32 -0
  28. package/dist/recommend/index.d.ts +1 -1
  29. package/dist/schemas/index.d.ts +5 -5
  30. package/dist/storage/index.js +1 -1
  31. package/dist/table/index.d.ts +123 -0
  32. package/dist/table/index.js +298 -0
  33. package/dist/{themeLibrary-8BQMY2HV.d.ts → themeLibrary-BG3jr6mT.d.ts} +1 -1
  34. package/dist/transform/index.d.ts +3 -3
  35. package/dist/{types-CcrDFdWH.d.ts → types-Be6sBUBx.d.ts} +28 -2
  36. package/dist/versions/index.d.ts +15 -1
  37. package/dist/versions/index.js +5 -1
  38. package/dist/viewState-lTZS-hP_.d.ts +91 -0
  39. package/package.json +11 -1
@@ -6,7 +6,7 @@ import {
6
6
  quoteAttrValue,
7
7
  splitKeyValueToken,
8
8
  tokenizeAttrTokens
9
- } from "./chunk-NBKAXPSX.js";
9
+ } from "./chunk-TMOHAFYE.js";
10
10
  import {
11
11
  resolveIcon
12
12
  } from "./chunk-7N4G32LG.js";
@@ -259,7 +259,72 @@ function convertInlineChildren(children, parseHtml, applyIconSplit = true) {
259
259
  if (node) result.push(node);
260
260
  }
261
261
  const mentioned = coalesceMentions(result);
262
- return applyIconSplit ? splitInlineIcons(mentioned) : mentioned;
262
+ const repaired = recombineDirectiveTokens(mentioned);
263
+ const split = applyIconSplit ? splitInlineIcons(repaired) : repaired;
264
+ return foldPairedInlineHtml(split);
265
+ }
266
+ var PAIRED_INLINE_HTML = /* @__PURE__ */ new Map([
267
+ ["sup", "superscript"],
268
+ ["sub", "subscript"]
269
+ ]);
270
+ function bareOpenTag(rawHtml) {
271
+ const m = /^<([a-zA-Z][a-zA-Z0-9]*)\s*>$/.exec(rawHtml);
272
+ return m ? m[1].toLowerCase() : null;
273
+ }
274
+ function bareCloseTag(rawHtml) {
275
+ const m = /^<\/([a-zA-Z][a-zA-Z0-9]*)\s*>$/.exec(rawHtml);
276
+ return m ? m[1].toLowerCase() : null;
277
+ }
278
+ function foldPairedInlineHtml(nodes) {
279
+ if (!nodes.some((n) => n.type === "htmlInline")) return nodes;
280
+ const root = [];
281
+ const stack = [];
282
+ const top = () => stack[stack.length - 1]?.children ?? root;
283
+ for (const node of nodes) {
284
+ if (node.type !== "htmlInline") {
285
+ top().push(node);
286
+ continue;
287
+ }
288
+ const open = bareOpenTag(node.rawHtml);
289
+ const foldType = open ? PAIRED_INLINE_HTML.get(open) : void 0;
290
+ if (open && foldType) {
291
+ stack.push({ tag: open, type: foldType, open: node, children: [] });
292
+ continue;
293
+ }
294
+ const close = bareCloseTag(node.rawHtml);
295
+ let closeIndex = -1;
296
+ if (close) {
297
+ for (let i = stack.length - 1; i >= 0; i--) {
298
+ if (stack[i].tag === close) {
299
+ closeIndex = i;
300
+ break;
301
+ }
302
+ }
303
+ }
304
+ if (close && closeIndex >= 0) {
305
+ while (stack.length - 1 > closeIndex) {
306
+ const orphan = stack.pop();
307
+ top().push(orphan.open, ...orphan.children);
308
+ }
309
+ const frame = stack.pop();
310
+ top().push({
311
+ type: frame.type,
312
+ children: frame.children,
313
+ ...spanPosition(frame.open, node)
314
+ });
315
+ continue;
316
+ }
317
+ top().push(node);
318
+ }
319
+ while (stack.length > 0) {
320
+ const orphan = stack.pop();
321
+ top().push(orphan.open, ...orphan.children);
322
+ }
323
+ return root;
324
+ }
325
+ function spanPosition(open, close) {
326
+ if (!open.position || !close.position) return {};
327
+ return { position: { start: open.position.start, end: close.position.end } };
263
328
  }
264
329
  function splitInlineIcons(nodes) {
265
330
  const recombined = recombineDirectiveTokens(nodes);
@@ -277,24 +342,38 @@ function recombineDirectiveTokens(nodes) {
277
342
  const out = [];
278
343
  for (let i = 0; i < nodes.length; i++) {
279
344
  const cur = nodes[i];
280
- const next = nodes[i + 1];
281
- const after = nodes[i + 2];
282
- if (cur?.type === "text" && next?.type === "textDirective" && after?.type === "text" && /\{\[[a-zA-Z0-9_-]+$/.test(cur.value) && /^\]\}/.test(after.value)) {
283
- const directive = next;
284
- const directiveName = directive.name ?? "";
285
- const merged = {
286
- type: "text",
287
- value: cur.value + ":" + directiveName + after.value,
288
- ...cur.position ? { position: cur.position } : {}
289
- };
290
- out.push(merged);
291
- i += 2;
292
- continue;
345
+ if (cur?.type === "text") {
346
+ let value = cur.value;
347
+ let j = i;
348
+ while (hasUnclosedAnnotationSpan(value) && nodes[j + 1]?.type === "textDirective") {
349
+ const directive = nodes[j + 1];
350
+ value += ":" + (directive.name ?? "");
351
+ j += 1;
352
+ const following = nodes[j + 1];
353
+ if (following?.type === "text") {
354
+ value += following.value;
355
+ j += 1;
356
+ }
357
+ }
358
+ if (j !== i) {
359
+ out.push({
360
+ type: "text",
361
+ value,
362
+ ...cur.position ? { position: cur.position } : {}
363
+ });
364
+ i = j;
365
+ continue;
366
+ }
293
367
  }
294
368
  out.push(cur);
295
369
  }
296
370
  return out;
297
371
  }
372
+ function hasUnclosedAnnotationSpan(text) {
373
+ const open = text.lastIndexOf("{[");
374
+ if (open === -1) return false;
375
+ return !text.includes("]}", open);
376
+ }
298
377
  var ICON_TOKEN_RE = /\{\[([a-zA-Z0-9_:-]+)\]\}/g;
299
378
  function splitTextOnIcons(value, position) {
300
379
  if (!value) return [];
@@ -825,7 +904,12 @@ function tableCellToMdast(cell) {
825
904
  function inlineChildrenToMdast(nodes) {
826
905
  const out = [];
827
906
  for (const n of nodes) {
828
- if (n.type === "mention") {
907
+ if (n.type === "superscript" || n.type === "subscript") {
908
+ const tag = n.type === "superscript" ? "sup" : "sub";
909
+ out.push({ type: "html", value: `<${tag}>`, ...mdastPosField(n.position) });
910
+ out.push(...inlineChildrenToMdast(n.children));
911
+ out.push({ type: "html", value: `</${tag}>` });
912
+ } else if (n.type === "mention") {
829
913
  out.push({ type: "text", value: "@" });
830
914
  out.push({
831
915
  type: "link",
@@ -944,6 +1028,13 @@ function inlineToMdast(node) {
944
1028
  children: [{ type: "text", value: node.displayName }],
945
1029
  ...mdastPosField(node.position)
946
1030
  };
1031
+ case "superscript":
1032
+ case "subscript":
1033
+ return {
1034
+ type: "text",
1035
+ value: inlineNodesToPlainText(node.children),
1036
+ ...mdastPosField(node.position)
1037
+ };
947
1038
  case "inlineIcon":
948
1039
  return {
949
1040
  type: "text",
@@ -954,6 +1045,16 @@ function inlineToMdast(node) {
954
1045
  return { type: "text", value: "" };
955
1046
  }
956
1047
  }
1048
+ function inlineNodesToPlainText(nodes) {
1049
+ let out = "";
1050
+ for (const node of nodes) {
1051
+ if ("value" in node && typeof node.value === "string") out += node.value;
1052
+ else if ("children" in node && Array.isArray(node.children)) {
1053
+ out += inlineNodesToPlainText(node.children);
1054
+ }
1055
+ }
1056
+ return out;
1057
+ }
957
1058
  function escapeHtmlText(value) {
958
1059
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
959
1060
  }
@@ -230,7 +230,11 @@ var EXTENSION_MIME_MAP = {
230
230
  ".ogg": "audio/ogg",
231
231
  ".css": "text/css",
232
232
  ".html": "text/html",
233
- ".js": "application/javascript"
233
+ ".js": "application/javascript",
234
+ ".csv": "text/csv",
235
+ ".tsv": "text/tab-separated-values",
236
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
237
+ ".parquet": "application/vnd.apache.parquet"
234
238
  };
235
239
  function guessMimeType(path) {
236
240
  const dot = path.lastIndexOf(".");
@@ -1,7 +1,9 @@
1
1
  import {
2
+ buildNarrationScript,
2
3
  expectedSyllablesAt,
4
+ flattenRenderableBlocks,
3
5
  wordPosAtExpectedSyllables
4
- } from "./chunk-W2GIFNLN.js";
6
+ } from "./chunk-ZYCSRDSX.js";
5
7
 
6
8
  // src/narration/types.ts
7
9
  var DEFAULT_FEATURE_CONFIG = Object.freeze({
@@ -872,6 +874,105 @@ function proportionalAlignment(script, effectiveDuration, takeDuration, c, detec
872
874
  return { words, blocks, detectedSyllables, cost: 0 };
873
875
  }
874
876
 
877
+ // src/narration/advanceTiming.ts
878
+ var EMPTY_ADVANCE_LOG = Object.freeze([]);
879
+ function recordSlideShown(log, blockId, atMs) {
880
+ if (!blockId || !Number.isFinite(atMs)) return log;
881
+ for (const entry of log) {
882
+ if (entry.blockId === blockId) return log;
883
+ }
884
+ const floor = log.length > 0 ? log[log.length - 1].atMs : 0;
885
+ return [...log, { blockId, atMs: Math.max(atMs, floor, 0) }];
886
+ }
887
+ function clampDuration(durationSec) {
888
+ return Number.isFinite(durationSec) && durationSec >= 0 ? durationSec : 0;
889
+ }
890
+ function firstShownSeconds(advances, knownIds, duration) {
891
+ const shown = /* @__PURE__ */ new Map();
892
+ let cursor = 0;
893
+ for (const advance of advances) {
894
+ if (!knownIds.has(advance.blockId) || shown.has(advance.blockId)) continue;
895
+ const raw = Number.isFinite(advance.atMs) ? advance.atMs / 1e3 : cursor;
896
+ const t = Math.min(duration, Math.max(cursor, raw));
897
+ shown.set(advance.blockId, t);
898
+ cursor = t;
899
+ }
900
+ const first = shown.keys().next();
901
+ if (!first.done) shown.set(first.value, 0);
902
+ return shown;
903
+ }
904
+ function buildAdvanceTimingJson(doc, advances, durationSec, options) {
905
+ const duration = clampDuration(durationSec);
906
+ const flat = flattenRenderableBlocks(doc.blocks);
907
+ const script = buildNarrationScript(doc, options?.script);
908
+ const scriptById = new Map(script.blocks.map((range) => [range.blockId, range]));
909
+ const shown = firstShownSeconds(advances, new Set(flat.map((block) => block.id)), duration);
910
+ const starts = new Array(flat.length);
911
+ let boundary = duration;
912
+ for (let i = flat.length - 1; i >= 0; i--) {
913
+ const at = shown.get(flat[i].id);
914
+ if (at !== void 0) {
915
+ starts[i] = at;
916
+ boundary = at;
917
+ } else {
918
+ starts[i] = boundary;
919
+ }
920
+ }
921
+ const blocks = [];
922
+ let charCursor = 0;
923
+ for (let i = 0; i < flat.length; i++) {
924
+ const block = flat[i];
925
+ const range = scriptById.get(block.id);
926
+ const charStart = range ? range.charStart : charCursor;
927
+ const charEnd = range ? range.charEnd : charCursor;
928
+ charCursor = charEnd;
929
+ const startSec = starts[i];
930
+ const rawEnd = i + 1 < flat.length ? starts[i + 1] : duration;
931
+ blocks.push({
932
+ blockId: block.id,
933
+ ...block.title ? { heading: block.title } : {},
934
+ blockIndex: i,
935
+ charStart,
936
+ charEnd,
937
+ startSec,
938
+ endSec: Math.max(startSec, Math.min(rawEnd, duration))
939
+ });
940
+ }
941
+ return {
942
+ version: 3,
943
+ sourceText: script.sourceText,
944
+ duration,
945
+ // No word-level timings exist on this path — the presenter gave us block
946
+ // boundaries, not speech. Bookmarks are documented as per-WORD, so filling
947
+ // them with block starts would misreport what was measured.
948
+ bookmarks: [],
949
+ blocks,
950
+ // `cameraOffsetSec` is deliberately omitted: a dual take already encodes
951
+ // its skew in the camera clip's `startAt`/`clipStart` attributes, and a
952
+ // second copy here invites a double correction.
953
+ generator: {
954
+ name: options?.generatorName ?? "squisq-recorder",
955
+ method: "presenter-advance"
956
+ }
957
+ };
958
+ }
959
+ function advanceCoverage(doc, advances) {
960
+ const flat = flattenRenderableBlocks(doc.blocks);
961
+ const seen = new Set(advances.map((advance) => advance.blockId));
962
+ const unshownHeadings = [];
963
+ let shown = 0;
964
+ for (const block of flat) {
965
+ if (seen.has(block.id)) shown++;
966
+ else unshownHeadings.push(block.title || block.id);
967
+ }
968
+ return {
969
+ total: flat.length,
970
+ shown,
971
+ unshown: flat.length - shown,
972
+ unshownHeadings
973
+ };
974
+ }
975
+
875
976
  export {
876
977
  DEFAULT_FEATURE_CONFIG,
877
978
  DEFAULT_VAD_CONFIG,
@@ -896,5 +997,9 @@ export {
896
997
  reanchorSession,
897
998
  traceWordPosAt,
898
999
  downsampleTrace,
899
- alignNarration
1000
+ alignNarration,
1001
+ EMPTY_ADVANCE_LOG,
1002
+ recordSlideShown,
1003
+ buildAdvanceTimingJson,
1004
+ advanceCoverage
900
1005
  };