@cueframe/kernel 0.2.53 → 0.2.54
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/_members/composition/ops/compositionOps.shared.d.ts +1 -0
- package/dist/_members/composition/validators/composition.d.ts +80 -0
- package/dist/_members/composition/validators/render.d.ts +40 -0
- package/dist/_members/composition-ops/index.d.ts +15 -0
- package/dist/_members/core/render/compositionAudioAndDepth.d.ts +2 -1
- package/dist/_members/primitives/lib/text/spec.d.ts +1 -0
- package/dist/authoring/build-tools.js +5 -5
- package/dist/authoring/context.js +4 -4
- package/dist/authoring/tools.js +4 -4
- package/dist/authoring.js +6 -6
- package/dist/{chunk-P3DYA5NA.js → chunk-C3ARYFN6.js} +4 -4
- package/dist/{chunk-D2EG7J7X.js → chunk-DFB7UFZD.js} +1 -1
- package/dist/{chunk-ZIPGDGBR.js → chunk-FYMXVYWS.js} +1 -1
- package/dist/{chunk-LPUQTBKU.js → chunk-GZMKTLO3.js} +11 -1
- package/dist/{chunk-5E4YP44R.js → chunk-Q2FWFTDZ.js} +1 -1
- package/dist/{chunk-CJMUTCJW.js → chunk-QCGT3M7M.js} +1 -1
- package/dist/{chunk-4DM63RTI.js → chunk-QCJUGKRC.js} +4 -4
- package/dist/{chunk-VTM7NEJC.js → chunk-SIGKJOSF.js} +3 -3
- package/dist/{chunk-TPKPU4PE.js → chunk-T7WKIMTB.js} +8 -7
- package/dist/{chunk-46DGDPXR.js → chunk-V6GL37RZ.js} +98 -7
- package/dist/{chunk-UFNIB3JL.js → chunk-VKZTGD5Z.js} +11 -1
- package/dist/{chunk-ZFW35DLG.js → chunk-VYSBZUXZ.js} +1 -1
- package/dist/{chunk-7AUHC2X7.js → chunk-ZDE5S3DE.js} +1 -1
- package/dist/composition/graphics-plan.js +1 -1
- package/dist/composition/ops.js +3 -3
- package/dist/composition/validators.js +2 -2
- package/dist/composition-ops.js +5 -5
- package/dist/composition.js +2 -2
- package/dist/{context-UAS5WJRB.js → context-I7SPXR2Z.js} +4 -4
- package/dist/core/render.js +1 -1
- package/dist/core.js +1 -1
- package/dist/mcp/adapter.js +2 -2
- package/dist/mcp/core.js +1 -1
- package/dist/mcp/scene-shot.js +2 -2
- package/dist/mcp/server.js +9 -9
- package/dist/mcp.js +9 -9
- package/dist/primitives/captions.js +115 -46
- package/dist/primitives/lib/text/marker.js +1 -1
- package/dist/render-harness.js +1 -1
- package/package.json +11 -11
package/dist/composition/ops.js
CHANGED
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
selectMediaClipAt,
|
|
21
21
|
selectSceneMarkers,
|
|
22
22
|
selectTracksByKind
|
|
23
|
-
} from "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
23
|
+
} from "../chunk-T7WKIMTB.js";
|
|
24
|
+
import "../chunk-QCGT3M7M.js";
|
|
25
|
+
import "../chunk-VKZTGD5Z.js";
|
|
26
26
|
import "../chunk-WPZKOVYF.js";
|
|
27
27
|
import "../chunk-B7J5UUUV.js";
|
|
28
28
|
import "../chunk-KYRDKK2D.js";
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
WebhookDeliveryStatus,
|
|
49
49
|
WebhookDestination,
|
|
50
50
|
YoutubeDestination
|
|
51
|
-
} from "../chunk-
|
|
51
|
+
} from "../chunk-QCGT3M7M.js";
|
|
52
52
|
import {
|
|
53
53
|
ANIMATABLE_PARAMS,
|
|
54
54
|
ANIMATABLE_VALUE,
|
|
@@ -93,7 +93,7 @@ import {
|
|
|
93
93
|
captionVisibilityIssues,
|
|
94
94
|
captionWords,
|
|
95
95
|
captionsAreBehindSubject
|
|
96
|
-
} from "../chunk-
|
|
96
|
+
} from "../chunk-VKZTGD5Z.js";
|
|
97
97
|
import {
|
|
98
98
|
AUTHORED_GRAPHIC_KINDS
|
|
99
99
|
} from "../chunk-WPZKOVYF.js";
|
package/dist/composition-ops.js
CHANGED
|
@@ -20,16 +20,16 @@ import {
|
|
|
20
20
|
replaceRegion,
|
|
21
21
|
resolveClipKind,
|
|
22
22
|
wrapWithOpRecorder
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-SIGKJOSF.js";
|
|
24
|
+
import "./chunk-GZMKTLO3.js";
|
|
25
25
|
import "./chunk-QH3YI3ND.js";
|
|
26
26
|
import "./chunk-JPMVNMF3.js";
|
|
27
27
|
import "./chunk-IMIUHG2E.js";
|
|
28
28
|
import "./chunk-VZ7TYX6Z.js";
|
|
29
29
|
import "./chunk-T56BK7NS.js";
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-T7WKIMTB.js";
|
|
31
|
+
import "./chunk-QCGT3M7M.js";
|
|
32
|
+
import "./chunk-VKZTGD5Z.js";
|
|
33
33
|
import "./chunk-WPZKOVYF.js";
|
|
34
34
|
import "./chunk-B7J5UUUV.js";
|
|
35
35
|
import "./chunk-KYRDKK2D.js";
|
package/dist/composition.js
CHANGED
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
WebhookDeliveryStatus,
|
|
74
74
|
WebhookDestination,
|
|
75
75
|
YoutubeDestination
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-QCGT3M7M.js";
|
|
77
77
|
import {
|
|
78
78
|
ANIMATABLE_PARAMS,
|
|
79
79
|
ANIMATABLE_VALUE,
|
|
@@ -118,7 +118,7 @@ import {
|
|
|
118
118
|
captionVisibilityIssues,
|
|
119
119
|
captionWords,
|
|
120
120
|
captionsAreBehindSubject
|
|
121
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-VKZTGD5Z.js";
|
|
122
122
|
import {
|
|
123
123
|
AUTHORED_GRAPHIC_KINDS
|
|
124
124
|
} from "./chunk-WPZKOVYF.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildDirectorContext
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-FYMXVYWS.js";
|
|
4
|
+
import "./chunk-T7WKIMTB.js";
|
|
5
|
+
import "./chunk-QCGT3M7M.js";
|
|
6
|
+
import "./chunk-VKZTGD5Z.js";
|
|
7
7
|
import "./chunk-WPZKOVYF.js";
|
|
8
8
|
import "./chunk-B7J5UUUV.js";
|
|
9
9
|
import "./chunk-KYRDKK2D.js";
|
package/dist/core/render.js
CHANGED
package/dist/core.js
CHANGED
package/dist/mcp/adapter.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
querySchemaShape,
|
|
3
3
|
serializeQuery,
|
|
4
4
|
waitForJob
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-VYSBZUXZ.js";
|
|
6
6
|
import {
|
|
7
7
|
CURATED_TOOLS
|
|
8
8
|
} from "../chunk-4WBSXHQA.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
opById,
|
|
17
17
|
safeParse,
|
|
18
18
|
sniffImageMediaType
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-V6GL37RZ.js";
|
|
20
20
|
import "../chunk-2ESYSVXG.js";
|
|
21
21
|
|
|
22
22
|
// ../mcp/src/adapter.ts
|
package/dist/mcp/core.js
CHANGED
package/dist/mcp/scene-shot.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
SCENE_SHOT_RULES,
|
|
6
6
|
sceneBrandTokens,
|
|
7
7
|
sceneShotContract
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-ZDE5S3DE.js";
|
|
9
|
+
import "../chunk-V6GL37RZ.js";
|
|
10
10
|
import "../chunk-2ESYSVXG.js";
|
|
11
11
|
export {
|
|
12
12
|
SCENE_SHOT_LIMITS,
|
package/dist/mcp/server.js
CHANGED
|
@@ -8,21 +8,21 @@ import {
|
|
|
8
8
|
registerRawTools,
|
|
9
9
|
registerSkillPrompts,
|
|
10
10
|
titleCase
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
11
|
+
} from "../chunk-C3ARYFN6.js";
|
|
12
|
+
import "../chunk-ZDE5S3DE.js";
|
|
13
|
+
import "../chunk-VYSBZUXZ.js";
|
|
14
14
|
import "../chunk-4WBSXHQA.js";
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-V6GL37RZ.js";
|
|
16
|
+
import "../chunk-SIGKJOSF.js";
|
|
17
|
+
import "../chunk-GZMKTLO3.js";
|
|
18
18
|
import "../chunk-QH3YI3ND.js";
|
|
19
19
|
import "../chunk-JPMVNMF3.js";
|
|
20
20
|
import "../chunk-IMIUHG2E.js";
|
|
21
21
|
import "../chunk-VZ7TYX6Z.js";
|
|
22
22
|
import "../chunk-T56BK7NS.js";
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-T7WKIMTB.js";
|
|
24
|
+
import "../chunk-QCGT3M7M.js";
|
|
25
|
+
import "../chunk-VKZTGD5Z.js";
|
|
26
26
|
import "../chunk-WPZKOVYF.js";
|
|
27
27
|
import "../chunk-B7J5UUUV.js";
|
|
28
28
|
import "../chunk-KYRDKK2D.js";
|
package/dist/mcp.js
CHANGED
|
@@ -8,21 +8,21 @@ import {
|
|
|
8
8
|
buildServer,
|
|
9
9
|
registerCuratedTools,
|
|
10
10
|
registerRawTools
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-C3ARYFN6.js";
|
|
12
|
+
import "./chunk-ZDE5S3DE.js";
|
|
13
|
+
import "./chunk-VYSBZUXZ.js";
|
|
14
14
|
import "./chunk-4WBSXHQA.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-V6GL37RZ.js";
|
|
16
|
+
import "./chunk-SIGKJOSF.js";
|
|
17
|
+
import "./chunk-GZMKTLO3.js";
|
|
18
18
|
import "./chunk-QH3YI3ND.js";
|
|
19
19
|
import "./chunk-JPMVNMF3.js";
|
|
20
20
|
import "./chunk-IMIUHG2E.js";
|
|
21
21
|
import "./chunk-VZ7TYX6Z.js";
|
|
22
22
|
import "./chunk-T56BK7NS.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-T7WKIMTB.js";
|
|
24
|
+
import "./chunk-QCGT3M7M.js";
|
|
25
|
+
import "./chunk-VKZTGD5Z.js";
|
|
26
26
|
import "./chunk-WPZKOVYF.js";
|
|
27
27
|
import "./chunk-B7J5UUUV.js";
|
|
28
28
|
import "./chunk-KYRDKK2D.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Marker
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-DFB7UFZD.js";
|
|
4
4
|
import {
|
|
5
5
|
fillStyle
|
|
6
6
|
} from "../chunk-XLIPPLG3.js";
|
|
@@ -154,15 +154,16 @@ function plateStyleFor(kind, backgroundColor) {
|
|
|
154
154
|
}
|
|
155
155
|
var COMBINE_TOKENS_MS = 1500;
|
|
156
156
|
var CAPTION_LINGER_MS = 600;
|
|
157
|
-
function
|
|
157
|
+
function measuredTextBox(maxWidth, maxLines, gapPx) {
|
|
158
158
|
const lineWidths = [0];
|
|
159
159
|
return {
|
|
160
160
|
add: (word) => {
|
|
161
161
|
const widthOf = (text) => measureText({ ...word, text }).width;
|
|
162
162
|
const current = lineWidths.length - 1;
|
|
163
163
|
const width = widthOf(lineWidths[current] === 0 ? word.text.trimStart() : word.text);
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
const nextWidth = lineWidths[current] + (lineWidths[current] ? gapPx : 0) + width;
|
|
165
|
+
if (Math.ceil(nextWidth) < maxWidth) {
|
|
166
|
+
lineWidths[current] = nextWidth;
|
|
166
167
|
return { exceedsBox: false, newLine: false };
|
|
167
168
|
}
|
|
168
169
|
const firstWidth = widthOf(word.text.trimStart());
|
|
@@ -174,10 +175,11 @@ function italicAwareTextBox(maxWidth, maxLines) {
|
|
|
174
175
|
}
|
|
175
176
|
};
|
|
176
177
|
}
|
|
177
|
-
function tokenBox(maxWidth, maxLines, emphasis) {
|
|
178
|
-
|
|
178
|
+
function tokenBox(maxWidth, maxLines, fontSize, letterSpacing, wordGapEm, textTransform, emphasis) {
|
|
179
|
+
const needsMeasured = emphasis?.emphasisFontStyle === "italic" || letterSpacing !== 0 || (emphasis?.emphasisLetterSpacing ?? 0) !== 0 || wordGapEm !== void 0 || textTransform !== void 0 && textTransform !== "none" || emphasis?.emphasisTextTransform !== void 0 && emphasis.emphasisTextTransform !== "none";
|
|
180
|
+
return needsMeasured ? measuredTextBox(maxWidth, maxLines, fontSize * (wordGapEm ?? 0.35)) : fillTextBox({ maxBoxWidth: maxWidth, maxLines });
|
|
179
181
|
}
|
|
180
|
-
function addTokenToBox(box, token, fontFamily, fontSize, fontWeight, emphasis) {
|
|
182
|
+
function addTokenToBox(box, token, fontFamily, fontSize, fontWeight, letterSpacing, textTransform, emphasis) {
|
|
181
183
|
const isEmp = emphasis?.emphasisSet.has(token.fromMs) ?? false;
|
|
182
184
|
const tokenSize = isEmp ? Math.round(fontSize * (emphasis?.emphasisScale ?? 1.2)) : fontSize;
|
|
183
185
|
const tokenWeight = emphasis && isEmp ? emphasis.emphasisFontWeight : fontWeight;
|
|
@@ -187,22 +189,24 @@ function addTokenToBox(box, token, fontFamily, fontSize, fontWeight, emphasis) {
|
|
|
187
189
|
fontFamily: tokenFamily,
|
|
188
190
|
fontSize: tokenSize,
|
|
189
191
|
fontWeight: String(tokenWeight),
|
|
192
|
+
...(isEmp ? emphasis?.emphasisLetterSpacing : letterSpacing) ? { letterSpacing: `${isEmp ? emphasis?.emphasisLetterSpacing : letterSpacing}px` } : {},
|
|
193
|
+
...isEmp ? { textTransform: emphasis?.emphasisTextTransform } : { textTransform },
|
|
190
194
|
...isEmp && emphasis?.emphasisFontStyle === "italic" ? { additionalStyles: { fontStyle: "italic" } } : {}
|
|
191
195
|
});
|
|
192
196
|
}
|
|
193
|
-
function makeBoxFactory(maxWidth, maxLines, fontFamily, fontSize, fontWeight, emphasis) {
|
|
197
|
+
function makeBoxFactory(maxWidth, maxLines, fontFamily, fontSize, fontWeight, letterSpacing, wordGapEm, textTransform, emphasis) {
|
|
194
198
|
return () => {
|
|
195
|
-
const box = tokenBox(maxWidth, maxLines, emphasis);
|
|
199
|
+
const box = tokenBox(maxWidth, maxLines, fontSize, letterSpacing, wordGapEm, textTransform, emphasis);
|
|
196
200
|
return {
|
|
197
|
-
add: (token) => !addTokenToBox(box, token, fontFamily, fontSize, fontWeight, emphasis).exceedsBox
|
|
201
|
+
add: (token) => !addTokenToBox(box, token, fontFamily, fontSize, fontWeight, letterSpacing, textTransform, emphasis).exceedsBox
|
|
198
202
|
};
|
|
199
203
|
};
|
|
200
204
|
}
|
|
201
|
-
function layoutTokensIntoLines(tokens, maxWidth, maxLines, fontFamily, fontSize, fontWeight, emphasis) {
|
|
202
|
-
const box = tokenBox(maxWidth, maxLines, emphasis);
|
|
205
|
+
function layoutTokensIntoLines(tokens, maxWidth, maxLines, fontFamily, fontSize, fontWeight, letterSpacing, wordGapEm, textTransform, emphasis) {
|
|
206
|
+
const box = tokenBox(maxWidth, maxLines, fontSize, letterSpacing, wordGapEm, textTransform, emphasis);
|
|
203
207
|
const lines = [[]];
|
|
204
208
|
for (const token of tokens) {
|
|
205
|
-
const result = addTokenToBox(box, token, fontFamily, fontSize, fontWeight, emphasis);
|
|
209
|
+
const result = addTokenToBox(box, token, fontFamily, fontSize, fontWeight, letterSpacing, textTransform, emphasis);
|
|
206
210
|
if (result.newLine) {
|
|
207
211
|
lines.push([token]);
|
|
208
212
|
} else {
|
|
@@ -211,8 +215,10 @@ function layoutTokensIntoLines(tokens, maxWidth, maxLines, fontFamily, fontSize,
|
|
|
211
215
|
}
|
|
212
216
|
return lines.filter((line) => line.length > 0);
|
|
213
217
|
}
|
|
214
|
-
function layoutFitError(label) {
|
|
215
|
-
|
|
218
|
+
function layoutFitError(label, detail) {
|
|
219
|
+
const error = new Error(`Caption layout${label ? ` ${label}` : " word range"} does not fit one page in its region${detail ? ` (${detail})` : ""}; enlarge the region or split the range`);
|
|
220
|
+
error.name = "CaptionLayoutFitError";
|
|
221
|
+
return error;
|
|
216
222
|
}
|
|
217
223
|
function tokenRuns(tokens, emphasisSet, emphasisPlate) {
|
|
218
224
|
const runs = [];
|
|
@@ -224,34 +230,38 @@ function tokenRuns(tokens, emphasisSet, emphasisPlate) {
|
|
|
224
230
|
}
|
|
225
231
|
return runs;
|
|
226
232
|
}
|
|
233
|
+
function measureVisualRun(run, fontSize, style, faces) {
|
|
234
|
+
const plate = style.emphasisPlate ?? false;
|
|
235
|
+
const emph = run.emph;
|
|
236
|
+
const text = emph && plate ? run.tokens.map((token) => token.text.trim()).join(" ") : plate ? run.tokens[0].text.trim() : run.tokens[0].text;
|
|
237
|
+
const size = emph ? Math.round(fontSize * (style.emphasisScale ?? 1.08)) : fontSize;
|
|
238
|
+
const transform = emph ? style.emphasisTextTransform ?? style.textTransform : style.textTransform;
|
|
239
|
+
const letterSpacing = emph ? style.emphasisLetterSpacing ?? style.letterSpacing : style.letterSpacing;
|
|
240
|
+
return measureText({
|
|
241
|
+
text,
|
|
242
|
+
fontFamily: emph ? faces.emphasis.stack : faces.base.stack,
|
|
243
|
+
fontSize: size,
|
|
244
|
+
fontWeight: String(emph ? faces.emphasis.weight : faces.base.weight),
|
|
245
|
+
...transform ? { textTransform: transform } : {},
|
|
246
|
+
...letterSpacing !== void 0 ? { letterSpacing: `${letterSpacing}px` } : {},
|
|
247
|
+
...emph && faces.emphasis.style === "italic" ? { additionalStyles: { fontStyle: "italic" } } : {}
|
|
248
|
+
}).width + (emph && plate ? 2 * Math.round(size * (style.emphasisPlatePadX ?? 0.16)) : 0);
|
|
249
|
+
}
|
|
227
250
|
function layoutAuthoredTokensIntoLines(tokens, maxWidth, maxLines, fontSize, style, emphasisSet, faces, label) {
|
|
228
251
|
const lines = [[]];
|
|
229
252
|
let lineWidth = 0;
|
|
230
253
|
const plate = style.emphasisPlate ?? false;
|
|
231
|
-
const runGap = fontSize * 0.35;
|
|
254
|
+
const runGap = fontSize * (style.wordGapEm ?? 0.35);
|
|
232
255
|
for (const run of tokenRuns(tokens, emphasisSet, plate)) {
|
|
233
|
-
const
|
|
234
|
-
const text = emph && plate ? run.tokens.map((token) => token.text.trim()).join(" ") : plate ? run.tokens[0].text.trim() : run.tokens[0].text;
|
|
235
|
-
const size = emph ? Math.round(fontSize * (style.emphasisScale ?? 1.08)) : fontSize;
|
|
236
|
-
const transform = emph ? style.emphasisTextTransform ?? style.textTransform : style.textTransform;
|
|
237
|
-
const letterSpacing = emph ? style.emphasisLetterSpacing : void 0;
|
|
238
|
-
const width = measureText({
|
|
239
|
-
text,
|
|
240
|
-
fontFamily: emph ? faces.emphasis.stack : faces.base.stack,
|
|
241
|
-
fontSize: size,
|
|
242
|
-
fontWeight: String(emph ? faces.emphasis.weight : faces.base.weight),
|
|
243
|
-
...transform ? { textTransform: transform } : {},
|
|
244
|
-
...letterSpacing ? { letterSpacing: `${letterSpacing}px` } : {},
|
|
245
|
-
...emph && faces.emphasis.style === "italic" ? { additionalStyles: { fontStyle: "italic" } } : {}
|
|
246
|
-
}).width + (emph && plate ? 2 * Math.round(size * (style.emphasisPlatePadX ?? 0.16)) : 0);
|
|
256
|
+
const width = measureVisualRun(run, fontSize, style, faces);
|
|
247
257
|
if (Math.ceil(width) > maxWidth) {
|
|
248
|
-
throw layoutFitError(label);
|
|
258
|
+
throw layoutFitError(label, `run needs ${Math.ceil(width)}px, box has ${Math.floor(maxWidth)}px`);
|
|
249
259
|
}
|
|
250
260
|
const current = lines[lines.length - 1];
|
|
251
261
|
const nextWidth = lineWidth + (current.length ? runGap : 0) + width;
|
|
252
262
|
if (Math.ceil(nextWidth) > maxWidth) {
|
|
253
263
|
if (lines.length >= maxLines) {
|
|
254
|
-
throw layoutFitError(label);
|
|
264
|
+
throw layoutFitError(label, `needs ${lines.length + 1} lines, box allows ${maxLines}`);
|
|
255
265
|
}
|
|
256
266
|
lines.push([...run.tokens]);
|
|
257
267
|
lineWidth = width;
|
|
@@ -287,7 +297,8 @@ function Captions({
|
|
|
287
297
|
const emphasisFontFamily = faces.emphasis.stack;
|
|
288
298
|
const emphasisFontWeight = faces.emphasis.weight;
|
|
289
299
|
const emphasisTextTransform = style.emphasisTextTransform ?? style.textTransform;
|
|
290
|
-
const
|
|
300
|
+
const letterSpacing = style.letterSpacing ?? 0;
|
|
301
|
+
const emphasisLetterSpacing = style.emphasisLetterSpacing ?? letterSpacing;
|
|
291
302
|
const emphasisFontStyle = faces.emphasis.style;
|
|
292
303
|
const entrance = style.entrance ?? "none";
|
|
293
304
|
const entranceFrames = Math.max(1, Math.round((style.entranceMs ?? 160) / 1e3 * fps));
|
|
@@ -301,18 +312,25 @@ function Captions({
|
|
|
301
312
|
const plateRadius = style.emphasisPlateRadius ?? 6;
|
|
302
313
|
const platePadX = style.emphasisPlatePadX ?? 0.16;
|
|
303
314
|
const platePadY = style.emphasisPlatePadY ?? 0.04;
|
|
315
|
+
const plateReveal = style.emphasisPlateReveal ?? false;
|
|
304
316
|
const annotationColor = style.annotationColor ?? VIOLET;
|
|
317
|
+
const annotationStrokeWidth = style.annotationStrokeWidth ?? 4;
|
|
305
318
|
const maxWidthPercent = style.maxWidthPercent ?? 80;
|
|
306
319
|
const plateStyle = plateStyleFor(style.plate ?? "glass", style.backgroundColor);
|
|
307
320
|
const fontSize = Math.round(height * (style.fontSize / 100));
|
|
321
|
+
const wordGapPx = fontSize * (style.wordGapEm ?? 0.35);
|
|
322
|
+
const lineGapPx = fontSize * (style.lineGapEm ?? 0.25);
|
|
308
323
|
const authoredRegion = userStyle?.region;
|
|
309
324
|
const regionWidth = authoredRegion ? width * authoredRegion.w : width;
|
|
310
325
|
const maxTextWidth = authoredRegion ? Math.min(width * (maxWidthPercent / 100), regionWidth - fontSize * 1.6) : width * (maxWidthPercent / 100);
|
|
311
326
|
const availableHeight = authoredRegion ? height * authoredRegion.h - fontSize * 0.8 : Infinity;
|
|
312
327
|
const lineHeight = fontSize * Math.max(1, emphasisScale) * 1.2;
|
|
313
|
-
const maxLines = authoredRegion ? Math.min(3, Math.floor((availableHeight +
|
|
328
|
+
const maxLines = authoredRegion ? Math.min(3, Math.floor((availableHeight + lineGapPx) / (lineHeight + lineGapPx))) : 3;
|
|
314
329
|
if (authoredRegion && (maxTextWidth <= 0 || maxLines < 1)) {
|
|
315
|
-
if (singlePageRequired) throw layoutFitError(
|
|
330
|
+
if (singlePageRequired) throw layoutFitError(
|
|
331
|
+
layoutLabel,
|
|
332
|
+
maxTextWidth <= 0 ? `box has ${Math.floor(maxTextWidth)}px text width` : "box allows no complete line"
|
|
333
|
+
);
|
|
316
334
|
throw new Error("Caption style.region is too small for one caption line at the authored font size");
|
|
317
335
|
}
|
|
318
336
|
const { emphasisStartMs, annotateKind } = useMemo(() => {
|
|
@@ -325,12 +343,38 @@ function Captions({
|
|
|
325
343
|
return { emphasisStartMs: emph, annotateKind: ann };
|
|
326
344
|
}, [segments]);
|
|
327
345
|
const emphasisLayout = useMemo(
|
|
328
|
-
() => emphasisStartMs.size > 0 ? {
|
|
329
|
-
|
|
346
|
+
() => emphasisStartMs.size > 0 ? {
|
|
347
|
+
emphasisSet: emphasisStartMs,
|
|
348
|
+
emphasisScale,
|
|
349
|
+
emphasisFontFamily,
|
|
350
|
+
emphasisFontWeight,
|
|
351
|
+
emphasisFontStyle,
|
|
352
|
+
emphasisLetterSpacing,
|
|
353
|
+
emphasisTextTransform
|
|
354
|
+
} : void 0,
|
|
355
|
+
[
|
|
356
|
+
emphasisStartMs,
|
|
357
|
+
emphasisScale,
|
|
358
|
+
emphasisFontFamily,
|
|
359
|
+
emphasisFontWeight,
|
|
360
|
+
emphasisFontStyle,
|
|
361
|
+
emphasisLetterSpacing,
|
|
362
|
+
emphasisTextTransform
|
|
363
|
+
]
|
|
330
364
|
);
|
|
331
365
|
const pages = useMemo(
|
|
332
366
|
() => {
|
|
333
|
-
const makeBox = makeBoxFactory(
|
|
367
|
+
const makeBox = makeBoxFactory(
|
|
368
|
+
maxTextWidth,
|
|
369
|
+
maxLines,
|
|
370
|
+
style.fontFamily,
|
|
371
|
+
fontSize,
|
|
372
|
+
style.fontWeight,
|
|
373
|
+
letterSpacing,
|
|
374
|
+
style.wordGapEm,
|
|
375
|
+
style.textTransform,
|
|
376
|
+
emphasisLayout
|
|
377
|
+
);
|
|
334
378
|
const paginated = paginateCaptionSegments(segments, {
|
|
335
379
|
combineMs: singlePageRequired ? Number.MAX_SAFE_INTEGER : COMBINE_TOKENS_MS,
|
|
336
380
|
makeBox: singlePageRequired ? () => ({ add: () => true }) : makeBox,
|
|
@@ -357,7 +401,20 @@ function Captions({
|
|
|
357
401
|
}
|
|
358
402
|
return paginated;
|
|
359
403
|
},
|
|
360
|
-
[
|
|
404
|
+
[
|
|
405
|
+
segments,
|
|
406
|
+
maxTextWidth,
|
|
407
|
+
maxLines,
|
|
408
|
+
fontSize,
|
|
409
|
+
style,
|
|
410
|
+
emphasisStartMs,
|
|
411
|
+
faces,
|
|
412
|
+
emphasisLayout,
|
|
413
|
+
letterSpacing,
|
|
414
|
+
holdUntilMs,
|
|
415
|
+
singlePageRequired,
|
|
416
|
+
layoutLabel
|
|
417
|
+
]
|
|
361
418
|
);
|
|
362
419
|
if (pages.length === 0) return null;
|
|
363
420
|
const currentTimeMs = frame / fps * 1e3;
|
|
@@ -398,6 +455,9 @@ function Captions({
|
|
|
398
455
|
style.fontFamily,
|
|
399
456
|
fontSize,
|
|
400
457
|
style.fontWeight,
|
|
458
|
+
letterSpacing,
|
|
459
|
+
style.wordGapEm,
|
|
460
|
+
style.textTransform,
|
|
401
461
|
emphasisLayout
|
|
402
462
|
);
|
|
403
463
|
const wrapperStyle = resolveCaptionPlacement(userStyle?.position, region, authoredRegion);
|
|
@@ -413,7 +473,7 @@ function Captions({
|
|
|
413
473
|
display: "flex",
|
|
414
474
|
flexDirection: "column",
|
|
415
475
|
alignItems: authoredRegion ? "flex-start" : "center",
|
|
416
|
-
gap: `${
|
|
476
|
+
gap: `${lineGapPx}px`,
|
|
417
477
|
padding: `${fontSize * 0.4}px ${fontSize * 0.8}px`,
|
|
418
478
|
borderRadius: fontSize * 0.5,
|
|
419
479
|
...plateStyle,
|
|
@@ -451,7 +511,7 @@ function Captions({
|
|
|
451
511
|
};
|
|
452
512
|
return lines.map((line, lineIdx) => {
|
|
453
513
|
const segs = tokenRuns(line, emphasisStartMs, emphasisPlate);
|
|
454
|
-
return /* @__PURE__ */ React.createElement("div", { key: lineIdx, style: { display: "flex", justifyContent: authoredRegion ? "flex-start" : "center", alignItems: "baseline", gap: `${
|
|
514
|
+
return /* @__PURE__ */ React.createElement("div", { key: lineIdx, style: { display: "flex", justifyContent: authoredRegion ? "flex-start" : "center", alignItems: "baseline", gap: `${wordGapPx}px` } }, segs.map((seg, si) => {
|
|
455
515
|
const first = seg.tokens[0];
|
|
456
516
|
const entered = entranceOf(first, seg.emph);
|
|
457
517
|
const opacity = syncWordVisibility && currentTimeMs < first.fromMs ? 0 : entered.opacity;
|
|
@@ -469,7 +529,16 @@ function Captions({
|
|
|
469
529
|
const bg = idx % 2 === 0 ? plateColor : plateAltColor;
|
|
470
530
|
const fg = idx % 2 === 0 ? plateTextColor : plateAltTextColor;
|
|
471
531
|
const efs = Math.round(fontSize * emphasisScale);
|
|
472
|
-
|
|
532
|
+
const plateTokens = plateReveal ? seg.tokens.filter((token2) => currentTimeMs >= token2.fromMs) : seg.tokens;
|
|
533
|
+
const reservedWidth = plateReveal ? measureVisualRun(seg, fontSize, style, faces) : void 0;
|
|
534
|
+
return /* @__PURE__ */ React.createElement("span", { key: si, style: {
|
|
535
|
+
position: "relative",
|
|
536
|
+
display: "inline-block",
|
|
537
|
+
...reservedWidth !== void 0 ? { width: reservedWidth } : {},
|
|
538
|
+
opacity,
|
|
539
|
+
transform: entranceTransform,
|
|
540
|
+
transformOrigin: "center"
|
|
541
|
+
} }, /* @__PURE__ */ React.createElement(
|
|
473
542
|
"span",
|
|
474
543
|
{
|
|
475
544
|
style: {
|
|
@@ -488,10 +557,10 @@ function Captions({
|
|
|
488
557
|
whiteSpace: "nowrap"
|
|
489
558
|
}
|
|
490
559
|
},
|
|
491
|
-
|
|
560
|
+
plateTokens.map((token2, tokenIndex) => /* @__PURE__ */ React.createElement("span", { key: token2.fromMs, style: {
|
|
492
561
|
opacity: syncWordVisibility && tokenIndex > 0 ? currentTimeMs < token2.fromMs ? 0 : entranceOf(token2, true).opacity : 1
|
|
493
562
|
} }, tokenIndex > 0 ? " " : "", token2.text.trim()))
|
|
494
|
-
), annKind && annotatedToken && currentTimeMs >= annotatedToken.fromMs ? /* @__PURE__ */ React.createElement(Marker, { spec: { kind: annKind, color: annotationColor }, progress: markerP }) : null);
|
|
563
|
+
), annKind && annotatedToken && currentTimeMs >= annotatedToken.fromMs ? /* @__PURE__ */ React.createElement(Marker, { spec: { kind: annKind, color: annotationColor, strokeWidth: annotationStrokeWidth }, progress: markerP }) : null);
|
|
495
564
|
}
|
|
496
565
|
const token = first;
|
|
497
566
|
const isActive = token === activeToken;
|
|
@@ -500,7 +569,7 @@ function Captions({
|
|
|
500
569
|
const tokenWeight = isEmphasis ? emphasisFontWeight : style.fontWeight;
|
|
501
570
|
const tokenFamily = isEmphasis ? emphasisFontFamily : style.fontFamily;
|
|
502
571
|
const tokenTransform = isEmphasis ? emphasisTextTransform : style.textTransform;
|
|
503
|
-
const tokenLetterSpacing = isEmphasis
|
|
572
|
+
const tokenLetterSpacing = isEmphasis ? emphasisLetterSpacing ? `${emphasisLetterSpacing}px` : void 0 : letterSpacing ? `${letterSpacing}px` : void 0;
|
|
504
573
|
const tokenFontStyle = isEmphasis ? emphasisFontStyle : "normal";
|
|
505
574
|
let tokenColor = style.color;
|
|
506
575
|
if (isActive && !emphasisPlate) tokenColor = style.highlightColor;
|
|
@@ -523,7 +592,7 @@ function Captions({
|
|
|
523
592
|
},
|
|
524
593
|
emphasisPlate ? token.text.trim() : token.text
|
|
525
594
|
);
|
|
526
|
-
return /* @__PURE__ */ React.createElement("span", { key: si, style: { position: "relative", display: "inline-block", opacity, transform: entranceTransform, transformOrigin: "center" } }, inner, annKind && annotatedToken && currentTimeMs >= annotatedToken.fromMs ? /* @__PURE__ */ React.createElement(Marker, { spec: { kind: annKind, color: annotationColor }, progress: markerP }) : null);
|
|
595
|
+
return /* @__PURE__ */ React.createElement("span", { key: si, style: { position: "relative", display: "inline-block", opacity, transform: entranceTransform, transformOrigin: "center" } }, inner, annKind && annotatedToken && currentTimeMs >= annotatedToken.fromMs ? /* @__PURE__ */ React.createElement(Marker, { spec: { kind: annKind, color: annotationColor, strokeWidth: annotationStrokeWidth }, progress: markerP }) : null);
|
|
527
596
|
}));
|
|
528
597
|
});
|
|
529
598
|
})()
|
package/dist/render-harness.js
CHANGED
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
parseSceneComponentCaptureIntentV1,
|
|
47
47
|
prepareSceneShotRenderInput,
|
|
48
48
|
readSceneShotManifest
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-GZMKTLO3.js";
|
|
50
50
|
import "./chunk-QH3YI3ND.js";
|
|
51
51
|
import "./chunk-JPMVNMF3.js";
|
|
52
52
|
import "./chunk-IMIUHG2E.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cueframe/kernel",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Publish-only aggregate of CueFrame's isomorphic kernel packages — composition, primitives, authoring, MCP, and friends shipped as one npm artifact. Members remain separate workspace packages; this only changes what ships.",
|
|
6
6
|
"files": [
|
|
@@ -16,26 +16,26 @@
|
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"tsup": "^8.3.5",
|
|
18
18
|
"typescript": "^5.9.3",
|
|
19
|
-
"@cueframe/brand-derivation": "0.1.0",
|
|
20
19
|
"@cueframe/animate": "0.1.0",
|
|
21
|
-
"@cueframe/cloud-import": "0.1.0",
|
|
22
|
-
"@cueframe/account-model": "0.1.0",
|
|
23
20
|
"@cueframe/authoring": "0.1.0",
|
|
21
|
+
"@cueframe/account-model": "0.1.0",
|
|
22
|
+
"@cueframe/cloud-import": "0.1.0",
|
|
24
23
|
"@cueframe/compose": "0.1.0",
|
|
25
24
|
"@cueframe/composition": "0.1.0",
|
|
25
|
+
"@cueframe/composition-ops": "0.1.0",
|
|
26
26
|
"@cueframe/component-runtime": "0.1.0",
|
|
27
|
-
"@cueframe/
|
|
27
|
+
"@cueframe/brand-derivation": "0.1.0",
|
|
28
28
|
"@cueframe/core": "0.1.0",
|
|
29
|
-
"@cueframe/
|
|
30
|
-
"@cueframe/composition-ops": "0.1.0",
|
|
31
|
-
"@cueframe/foundation": "0.1.0",
|
|
29
|
+
"@cueframe/director": "0.1.0",
|
|
32
30
|
"@cueframe/errors": "0.1.0",
|
|
31
|
+
"@cueframe/foundation": "0.1.0",
|
|
32
|
+
"@cueframe/nle-export": "0.1.0",
|
|
33
33
|
"@cueframe/media-model": "0.1.0",
|
|
34
34
|
"@cueframe/perception": "0.1.0",
|
|
35
|
-
"@cueframe/
|
|
36
|
-
"@cueframe/
|
|
35
|
+
"@cueframe/mcp": "0.1.0",
|
|
36
|
+
"@cueframe/primitives": "0.1.0",
|
|
37
37
|
"@cueframe/render-harness": "0.1.0",
|
|
38
|
-
"@cueframe/
|
|
38
|
+
"@cueframe/plane": "0.1.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"gsap": "3.13.0",
|