@bendyline/squisq 2.11.17 → 2.11.18
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/dist/{Doc-CXx1WL8G.d.ts → Doc-B6TYHYGc.d.ts} +14 -0
- package/dist/{ImageEditDoc-BVLXI-Zd.d.ts → ImageEditDoc-CN_3Ysj5.d.ts} +1 -1
- package/dist/chunk-3XEABCT3.js +114 -0
- package/dist/{chunk-L7IIFWWW.js → chunk-7IGKCHDP.js} +243 -3
- package/dist/{chunk-54RU7TBZ.js → chunk-J4ACZBO4.js} +18 -3
- package/dist/{chunk-KNC4ZBQC.js → chunk-NM747LUO.js} +825 -294
- package/dist/{chunk-MY46W5O5.js → chunk-RYO4QW6R.js} +2 -4
- package/dist/doc/index.d.ts +5 -22
- package/dist/doc/index.js +5 -3
- package/dist/fence/index.d.ts +1 -1
- package/dist/generate/index.d.ts +1 -1
- package/dist/imageEdit/index.d.ts +3 -3
- package/dist/index.d.ts +5 -5
- package/dist/index.js +58 -28
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/{materializePageSection-BX1uOAlN.d.ts → materializePageSection-IYXU3tDN.d.ts} +1 -1
- package/dist/mediaEdit/index.d.ts +2 -2
- package/dist/narration/index.d.ts +1 -1
- package/dist/narration/index.js +7 -6
- package/dist/schemas/index.d.ts +4 -4
- package/dist/{themeLibrary-Bnq_x-db.d.ts → themeLibrary-_46saKYO.d.ts} +1 -1
- package/dist/timing/index.d.ts +1 -1
- package/dist/transform/index.d.ts +84 -4
- package/dist/transform/index.js +35 -5
- package/package.json +1 -1
- package/dist/chunk-PNXBDMNS.js +0 -337
package/dist/transform/index.js
CHANGED
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_TRANSFORM_STYLE_ID,
|
|
3
|
+
DYNAMIC_PRESENTATION_STYLE,
|
|
4
|
+
PRESENTATION_HINTS_KEY,
|
|
5
|
+
PRESENTATION_KEY,
|
|
6
|
+
PRESENTATION_LAYOUTS,
|
|
7
|
+
PRESENTATION_LIMITS,
|
|
3
8
|
allocateTiming,
|
|
4
9
|
analyzeBlocks,
|
|
10
|
+
applySavedPresentation,
|
|
5
11
|
applyTransform,
|
|
12
|
+
compilePresentationPlan,
|
|
13
|
+
createPresentationPlan,
|
|
6
14
|
createTransformStyleRegistry,
|
|
15
|
+
defaultPresentationHints,
|
|
7
16
|
extractDocImages,
|
|
8
17
|
getTransformStyleIds,
|
|
9
18
|
getTransformStyleSummaries,
|
|
19
|
+
parsePresentationHints,
|
|
20
|
+
parsePresentationPlan,
|
|
21
|
+
presentationSections,
|
|
10
22
|
resolveTransformStyle,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
serializePresentationHints,
|
|
24
|
+
serializePresentationPlan,
|
|
25
|
+
transformNarratedSegment,
|
|
26
|
+
usesDynamicPresentation
|
|
27
|
+
} from "../chunk-NM747LUO.js";
|
|
28
|
+
import "../chunk-7IGKCHDP.js";
|
|
15
29
|
import "../chunk-A5QJJZ5S.js";
|
|
30
|
+
import "../chunk-SVN7T6BK.js";
|
|
16
31
|
import "../chunk-PUS54YU6.js";
|
|
17
32
|
import "../chunk-PFH3WV6J.js";
|
|
18
33
|
import "../chunk-L7QZORLB.js";
|
|
@@ -25,13 +40,28 @@ import "../chunk-GHOPHGOK.js";
|
|
|
25
40
|
import "../chunk-XRW6P7IF.js";
|
|
26
41
|
export {
|
|
27
42
|
DEFAULT_TRANSFORM_STYLE_ID,
|
|
43
|
+
DYNAMIC_PRESENTATION_STYLE,
|
|
44
|
+
PRESENTATION_HINTS_KEY,
|
|
45
|
+
PRESENTATION_KEY,
|
|
46
|
+
PRESENTATION_LAYOUTS,
|
|
47
|
+
PRESENTATION_LIMITS,
|
|
28
48
|
allocateTiming,
|
|
29
49
|
analyzeBlocks,
|
|
50
|
+
applySavedPresentation,
|
|
30
51
|
applyTransform,
|
|
52
|
+
compilePresentationPlan,
|
|
53
|
+
createPresentationPlan,
|
|
31
54
|
createTransformStyleRegistry,
|
|
55
|
+
defaultPresentationHints,
|
|
32
56
|
extractDocImages,
|
|
33
57
|
getTransformStyleIds,
|
|
34
58
|
getTransformStyleSummaries,
|
|
59
|
+
parsePresentationHints,
|
|
60
|
+
parsePresentationPlan,
|
|
61
|
+
presentationSections,
|
|
35
62
|
resolveTransformStyle,
|
|
36
|
-
|
|
63
|
+
serializePresentationHints,
|
|
64
|
+
serializePresentationPlan,
|
|
65
|
+
transformNarratedSegment,
|
|
66
|
+
usesDynamicPresentation
|
|
37
67
|
};
|
package/package.json
CHANGED
package/dist/chunk-PNXBDMNS.js
DELETED
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
flattenRenderableBlocks,
|
|
3
|
-
getBlockBodyText
|
|
4
|
-
} from "./chunk-L7IIFWWW.js";
|
|
5
|
-
import {
|
|
6
|
-
estimateSpokenWordCount
|
|
7
|
-
} from "./chunk-GHOPHGOK.js";
|
|
8
|
-
|
|
9
|
-
// src/narration/syllables.ts
|
|
10
|
-
var BOUNDARY_PUNCT = /^[.,!?;:'"()[\]{}]+|[.,!?;:'"()[\]{}]+$/g;
|
|
11
|
-
var SYLLABLES_PER_SPOKEN_WORD = 1.4;
|
|
12
|
-
function estimateSyllables(token) {
|
|
13
|
-
const stripped = token.replace(BOUNDARY_PUNCT, "");
|
|
14
|
-
if (!stripped) return 1;
|
|
15
|
-
if (/^[-+]?[\d.,]+$/.test(stripped)) {
|
|
16
|
-
const num = parseFloat(stripped.replace(/,/g, ""));
|
|
17
|
-
if (!Number.isNaN(num) && Number.isFinite(num)) {
|
|
18
|
-
return Math.max(1, Math.round(estimateSpokenWordCount(stripped) * SYLLABLES_PER_SPOKEN_WORD));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (/^[A-Z]{2,5}$/.test(stripped) && !/[AEIOUY]/.test(stripped)) {
|
|
22
|
-
return stripped.length;
|
|
23
|
-
}
|
|
24
|
-
const parts = stripped.toLowerCase().split(/[^a-z']+/).filter((p) => p.length > 0);
|
|
25
|
-
if (parts.length === 0) return 1;
|
|
26
|
-
let total = 0;
|
|
27
|
-
for (const part of parts) {
|
|
28
|
-
total += countAlphaSyllables(part.replace(/'/g, ""));
|
|
29
|
-
}
|
|
30
|
-
return Math.max(1, total);
|
|
31
|
-
}
|
|
32
|
-
function countAlphaSyllables(word) {
|
|
33
|
-
if (!word) return 0;
|
|
34
|
-
const groups = word.match(/[aeiouy]+/g);
|
|
35
|
-
let count = groups ? groups.length : 0;
|
|
36
|
-
if (count === 0) return 1;
|
|
37
|
-
if (count > 1 && /[^aeiouy]e$/.test(word)) {
|
|
38
|
-
count -= 1;
|
|
39
|
-
}
|
|
40
|
-
if (count > 1 && /[^aeiouy]ed$/.test(word) && !/[td]ed$/.test(word)) {
|
|
41
|
-
count -= 1;
|
|
42
|
-
}
|
|
43
|
-
if (count > 1 && /[^aeiouy]es$/.test(word) && !/(?:[sxz]|[cs]h)es$/.test(word)) {
|
|
44
|
-
count -= 1;
|
|
45
|
-
}
|
|
46
|
-
if (/[^aeiouy]le$/.test(word)) {
|
|
47
|
-
count += 1;
|
|
48
|
-
}
|
|
49
|
-
return Math.max(1, count);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// src/narration/script.ts
|
|
53
|
-
function blockSpokenText(block, includeTitles) {
|
|
54
|
-
const title = includeTitles && block.title ? block.title.trim() : "";
|
|
55
|
-
const body = getBlockBodyText(block);
|
|
56
|
-
if (title && body) return `${title}
|
|
57
|
-
${body}`;
|
|
58
|
-
return title || body;
|
|
59
|
-
}
|
|
60
|
-
function buildNarrationScript(doc, options) {
|
|
61
|
-
const includeTitles = options?.includeTitles ?? true;
|
|
62
|
-
const separator = options?.blockSeparator ?? "\n\n";
|
|
63
|
-
const pieces = [];
|
|
64
|
-
for (const block of flattenRenderableBlocks(doc.blocks)) {
|
|
65
|
-
const text = blockSpokenText(block, includeTitles);
|
|
66
|
-
if (!text) continue;
|
|
67
|
-
pieces.push({
|
|
68
|
-
blockId: block.id,
|
|
69
|
-
heading: block.title || void 0,
|
|
70
|
-
text
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
let sourceText = "";
|
|
74
|
-
const blocks = [];
|
|
75
|
-
for (let i = 0; i < pieces.length; i++) {
|
|
76
|
-
if (i > 0) sourceText += separator;
|
|
77
|
-
const charStart = sourceText.length;
|
|
78
|
-
sourceText += pieces[i].text;
|
|
79
|
-
blocks.push({
|
|
80
|
-
blockId: pieces[i].blockId,
|
|
81
|
-
...pieces[i].heading !== void 0 ? { heading: pieces[i].heading } : {},
|
|
82
|
-
tokenStart: 0,
|
|
83
|
-
tokenEnd: 0,
|
|
84
|
-
charStart,
|
|
85
|
-
charEnd: sourceText.length
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
const tokens = [];
|
|
89
|
-
const tokenRe = /\S+/g;
|
|
90
|
-
let blockIndex = 0;
|
|
91
|
-
let match;
|
|
92
|
-
while ((match = tokenRe.exec(sourceText)) !== null) {
|
|
93
|
-
const charOffset = match.index;
|
|
94
|
-
const charEnd = charOffset + match[0].length;
|
|
95
|
-
while (blockIndex < blocks.length - 1 && charOffset >= blocks[blockIndex].charEnd) {
|
|
96
|
-
blockIndex++;
|
|
97
|
-
}
|
|
98
|
-
const spoken = hasSpokenContent(match[0]);
|
|
99
|
-
tokens.push({
|
|
100
|
-
text: match[0],
|
|
101
|
-
charOffset,
|
|
102
|
-
charEnd,
|
|
103
|
-
blockId: blocks[blockIndex]?.blockId ?? "",
|
|
104
|
-
blockIndex,
|
|
105
|
-
syllables: spoken ? estimateSyllables(match[0]) : 0,
|
|
106
|
-
spokenWordEquiv: spoken ? estimateSpokenWordCount(stripBoundaryPunct(match[0])) : 0,
|
|
107
|
-
pauseAfter: 0,
|
|
108
|
-
spoken
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
for (const range of blocks) {
|
|
112
|
-
range.tokenStart = tokens.length;
|
|
113
|
-
range.tokenEnd = 0;
|
|
114
|
-
}
|
|
115
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
116
|
-
const range = blocks[tokens[i].blockIndex];
|
|
117
|
-
if (range) {
|
|
118
|
-
if (i < range.tokenStart) range.tokenStart = i;
|
|
119
|
-
range.tokenEnd = i + 1;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
for (const range of blocks) {
|
|
123
|
-
if (range.tokenStart > range.tokenEnd) {
|
|
124
|
-
range.tokenStart = range.tokenEnd;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
128
|
-
const token = tokens[i];
|
|
129
|
-
const next = tokens[i + 1];
|
|
130
|
-
if (!next || next.blockIndex !== token.blockIndex) {
|
|
131
|
-
token.pauseAfter = 3;
|
|
132
|
-
} else if (sourceText.slice(token.charEnd, next.charOffset).includes("\n")) {
|
|
133
|
-
token.pauseAfter = 2;
|
|
134
|
-
} else if (endsWithClausePunctuation(token.text)) {
|
|
135
|
-
token.pauseAfter = 1;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
const cumulativeSyllables = new Array(tokens.length + 1);
|
|
139
|
-
cumulativeSyllables[0] = 0;
|
|
140
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
141
|
-
cumulativeSyllables[i + 1] = cumulativeSyllables[i] + tokens[i].syllables;
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
sourceText,
|
|
145
|
-
tokens,
|
|
146
|
-
blocks,
|
|
147
|
-
totalSyllables: cumulativeSyllables[tokens.length],
|
|
148
|
-
cumulativeSyllables
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
var TRAILING_CLOSERS = /["')\]}»”’]+$/;
|
|
152
|
-
function hasSpokenContent(token) {
|
|
153
|
-
return /[\p{L}\p{N}]/u.test(token);
|
|
154
|
-
}
|
|
155
|
-
function stripBoundaryPunct(token) {
|
|
156
|
-
return token.replace(/^[.,!?;:'"()[\]{}]+|[.,!?;:'"()[\]{}]+$/g, "");
|
|
157
|
-
}
|
|
158
|
-
function endsWithClausePunctuation(token) {
|
|
159
|
-
const bare = token.replace(TRAILING_CLOSERS, "");
|
|
160
|
-
const last = bare.charAt(bare.length - 1);
|
|
161
|
-
if (!last) return false;
|
|
162
|
-
if (last === ",") {
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
return last === "." || last === ";" || last === ":" || last === "!" || last === "?";
|
|
166
|
-
}
|
|
167
|
-
function clamp(value, min, max) {
|
|
168
|
-
return value < min ? min : value > max ? max : value;
|
|
169
|
-
}
|
|
170
|
-
function expectedSyllablesAt(script, wordPos) {
|
|
171
|
-
const n = script.tokens.length;
|
|
172
|
-
if (n === 0) return 0;
|
|
173
|
-
const pos = clamp(wordPos, 0, n);
|
|
174
|
-
const idx = Math.floor(pos);
|
|
175
|
-
if (idx >= n) return script.totalSyllables;
|
|
176
|
-
return script.cumulativeSyllables[idx] + (pos - idx) * script.tokens[idx].syllables;
|
|
177
|
-
}
|
|
178
|
-
function wordPosAtExpectedSyllables(script, syllables) {
|
|
179
|
-
const n = script.tokens.length;
|
|
180
|
-
if (n === 0) return 0;
|
|
181
|
-
const target = clamp(syllables, 0, script.totalSyllables);
|
|
182
|
-
let lo = 0;
|
|
183
|
-
let hi = n;
|
|
184
|
-
while (lo < hi) {
|
|
185
|
-
const mid = lo + hi + 1 >> 1;
|
|
186
|
-
if (script.cumulativeSyllables[mid] <= target) lo = mid;
|
|
187
|
-
else hi = mid - 1;
|
|
188
|
-
}
|
|
189
|
-
if (lo >= n) return n;
|
|
190
|
-
const within = target - script.cumulativeSyllables[lo];
|
|
191
|
-
const sylls = script.tokens[lo].syllables;
|
|
192
|
-
return lo + (sylls > 0 ? within / sylls : 0);
|
|
193
|
-
}
|
|
194
|
-
function wordIndexAtChar(script, charOffset) {
|
|
195
|
-
const tokens = script.tokens;
|
|
196
|
-
if (tokens.length === 0) return 0;
|
|
197
|
-
let lo = 0;
|
|
198
|
-
let hi = tokens.length - 1;
|
|
199
|
-
while (lo < hi) {
|
|
200
|
-
const mid = lo + hi >> 1;
|
|
201
|
-
if (tokens[mid].charEnd <= charOffset) lo = mid + 1;
|
|
202
|
-
else hi = mid;
|
|
203
|
-
}
|
|
204
|
-
return lo;
|
|
205
|
-
}
|
|
206
|
-
function wordIndexAtTime(words, tSec) {
|
|
207
|
-
if (words.length === 0) return 0;
|
|
208
|
-
let lo = 0;
|
|
209
|
-
let hi = words.length - 1;
|
|
210
|
-
while (lo < hi) {
|
|
211
|
-
const mid = lo + hi + 1 >> 1;
|
|
212
|
-
if (words[mid].tSec <= tSec) lo = mid;
|
|
213
|
-
else hi = mid - 1;
|
|
214
|
-
}
|
|
215
|
-
return words[lo].tSec <= tSec ? lo : 0;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// src/narration/sidecar.ts
|
|
219
|
-
function resolveNarrationTimingGenerator(options) {
|
|
220
|
-
const baseWpm = options?.generator?.baseWpm ?? options?.baseWpm;
|
|
221
|
-
return {
|
|
222
|
-
name: options?.generator?.name ?? "squisq-teleprompter",
|
|
223
|
-
method: options?.generator?.method ?? "dsp-align",
|
|
224
|
-
...baseWpm !== void 0 ? { baseWpm } : {}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
function buildNarrationTimingJson(script, alignment, durationSec, options) {
|
|
228
|
-
const bookmarks = alignment.words.map((word) => {
|
|
229
|
-
const token = script.tokens[word.tokenIndex];
|
|
230
|
-
return {
|
|
231
|
-
id: `word-${word.tokenIndex}`,
|
|
232
|
-
time: word.tSec,
|
|
233
|
-
charOffset: token?.charOffset ?? 0,
|
|
234
|
-
textFragment: token?.text ?? ""
|
|
235
|
-
};
|
|
236
|
-
});
|
|
237
|
-
const blocks = alignment.blocks.map((range) => ({
|
|
238
|
-
...range.blockId ? { blockId: range.blockId } : {},
|
|
239
|
-
...range.heading !== void 0 ? { heading: range.heading } : {},
|
|
240
|
-
blockIndex: range.blockIndex,
|
|
241
|
-
charStart: range.charStart,
|
|
242
|
-
charEnd: range.charEnd,
|
|
243
|
-
startSec: range.startSec,
|
|
244
|
-
endSec: range.endSec
|
|
245
|
-
}));
|
|
246
|
-
return {
|
|
247
|
-
version: 3,
|
|
248
|
-
sourceText: script.sourceText,
|
|
249
|
-
duration: Number.isFinite(durationSec) && durationSec >= 0 ? durationSec : 0,
|
|
250
|
-
bookmarks,
|
|
251
|
-
blocks,
|
|
252
|
-
// Write only what `parseNarrationTimingJson` will read back, so the codec
|
|
253
|
-
// is a round-trip pair. A non-finite value would serialize to `null`
|
|
254
|
-
// (JSON has no NaN) and be dropped on parse anyway — omitting it here
|
|
255
|
-
// keeps the emitted sidecar honest rather than carrying a dead field.
|
|
256
|
-
...finiteNumber(options?.cameraOffsetSec) ? { cameraOffsetSec: options.cameraOffsetSec } : {},
|
|
257
|
-
generator: resolveNarrationTimingGenerator(options)
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
function finiteNonNegative(value) {
|
|
261
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
262
|
-
}
|
|
263
|
-
function finiteNumber(value) {
|
|
264
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
265
|
-
}
|
|
266
|
-
function parseNarrationTimingJson(data) {
|
|
267
|
-
try {
|
|
268
|
-
const text = typeof data === "string" ? data : new TextDecoder().decode(data instanceof Uint8Array ? data : new Uint8Array(data));
|
|
269
|
-
const parsed = JSON.parse(text);
|
|
270
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
271
|
-
const raw = parsed;
|
|
272
|
-
if (typeof raw.sourceText !== "string" || !finiteNonNegative(raw.duration)) return null;
|
|
273
|
-
const bookmarks = Array.isArray(raw.bookmarks) ? raw.bookmarks.flatMap((b) => {
|
|
274
|
-
if (typeof b !== "object" || b === null) return [];
|
|
275
|
-
const bookmark = b;
|
|
276
|
-
if (!finiteNonNegative(bookmark.time) || !finiteNonNegative(bookmark.charOffset)) {
|
|
277
|
-
return [];
|
|
278
|
-
}
|
|
279
|
-
return [
|
|
280
|
-
{
|
|
281
|
-
id: typeof bookmark.id === "string" ? bookmark.id : `bookmark-${bookmark.charOffset}`,
|
|
282
|
-
time: bookmark.time,
|
|
283
|
-
charOffset: bookmark.charOffset,
|
|
284
|
-
...typeof bookmark.textFragment === "string" ? { textFragment: bookmark.textFragment } : {}
|
|
285
|
-
}
|
|
286
|
-
];
|
|
287
|
-
}) : [];
|
|
288
|
-
let blocks = Array.isArray(raw.blocks) ? raw.blocks.flatMap((b) => {
|
|
289
|
-
if (typeof b !== "object" || b === null) return [];
|
|
290
|
-
const block = b;
|
|
291
|
-
if (!finiteNonNegative(block.startSec) || !finiteNonNegative(block.endSec) || !finiteNonNegative(block.charStart) || !finiteNonNegative(block.charEnd)) {
|
|
292
|
-
return [];
|
|
293
|
-
}
|
|
294
|
-
return [
|
|
295
|
-
{
|
|
296
|
-
...typeof block.blockId === "string" ? { blockId: block.blockId } : {},
|
|
297
|
-
...typeof block.heading === "string" ? { heading: block.heading } : {},
|
|
298
|
-
blockIndex: finiteNonNegative(block.blockIndex) ? block.blockIndex : 0,
|
|
299
|
-
charStart: block.charStart,
|
|
300
|
-
charEnd: block.charEnd,
|
|
301
|
-
startSec: block.startSec,
|
|
302
|
-
endSec: Math.max(block.startSec, block.endSec)
|
|
303
|
-
}
|
|
304
|
-
];
|
|
305
|
-
}) : [];
|
|
306
|
-
blocks = blocks.sort((a, b) => a.startSec - b.startSec);
|
|
307
|
-
let cursor = 0;
|
|
308
|
-
for (const block of blocks) {
|
|
309
|
-
if (block.startSec < cursor) block.startSec = cursor;
|
|
310
|
-
if (block.endSec < block.startSec) block.endSec = block.startSec;
|
|
311
|
-
cursor = block.startSec;
|
|
312
|
-
}
|
|
313
|
-
return {
|
|
314
|
-
version: 3,
|
|
315
|
-
sourceText: raw.sourceText,
|
|
316
|
-
duration: raw.duration,
|
|
317
|
-
bookmarks,
|
|
318
|
-
blocks,
|
|
319
|
-
...finiteNumber(raw.cameraOffsetSec) ? { cameraOffsetSec: raw.cameraOffsetSec } : {},
|
|
320
|
-
...typeof raw.generator === "object" && raw.generator !== null ? { generator: raw.generator } : {}
|
|
321
|
-
};
|
|
322
|
-
} catch {
|
|
323
|
-
return null;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
export {
|
|
328
|
-
estimateSyllables,
|
|
329
|
-
buildNarrationScript,
|
|
330
|
-
expectedSyllablesAt,
|
|
331
|
-
wordPosAtExpectedSyllables,
|
|
332
|
-
wordIndexAtChar,
|
|
333
|
-
wordIndexAtTime,
|
|
334
|
-
resolveNarrationTimingGenerator,
|
|
335
|
-
buildNarrationTimingJson,
|
|
336
|
-
parseNarrationTimingJson
|
|
337
|
-
};
|