@cueframe/kernel 0.2.47 → 0.2.49

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.
@@ -1,6 +1,19 @@
1
1
  import type { Composition } from "../../composition/validators/index.js";
2
- import type { CompositionAudioTrack, CompositionClip, CompositionOverlay, RenderInput } from "./types.js";
2
+ import type { CompositionAudioTrack, CompositionClip, CompositionEffect, CompositionOverlay, RenderInput } from "./types.js";
3
3
  export declare function applyRoleDefaultGains(audioTracks: CompositionAudioTrack[], composition: Composition): void;
4
4
  export declare function applyDuckEnvelopes(audioTracks: CompositionAudioTrack[], composition: Composition, fps: number): void;
5
5
  export declare function bindBehindSubjectHosts(overlays: CompositionOverlay[], clips: readonly CompositionClip[]): void;
6
- export declare function assertBehindSubjectCaptionCoverage(captionSegments: RenderInput['captionSegments'], clips: readonly CompositionClip[], fps: number): void;
6
+ export declare function assertBehindSubjectCaptionCoverage(captionSegments: RenderInput['captionSegments'], clips: readonly CompositionClip[], fps: number, output: {
7
+ width: number;
8
+ height: number;
9
+ }, effects?: readonly CompositionEffect[]): void;
10
+ /** The visible full-frame picture at each interval, following the renderer's zIndex/layer order. */
11
+ export declare function visiblePackedHostWindows(clips: readonly CompositionClip[], startFrame: number, endFrame: number, output: {
12
+ width: number;
13
+ height: number;
14
+ }, effects?: readonly CompositionEffect[]): Array<{
15
+ startFrame: number;
16
+ endFrame: number;
17
+ hostClipId?: string;
18
+ candidateClipIds: string[];
19
+ }>;
@@ -3,7 +3,7 @@ import type { RenderInput } from "./types.js";
3
3
  import type { TrajectoryData } from "../../composition/reframe/trajectory.js";
4
4
  import { type PreparedRenderInputLeaseV1, type SceneShotPreparationDependenciesV1 } from "./sceneShotPreparation.js";
5
5
  export { validateComposition } from "./compositionValidation.js";
6
- export { assertBehindSubjectCaptionCoverage } from "./compositionAudioAndDepth.js";
6
+ export { assertBehindSubjectCaptionCoverage, visiblePackedHostWindows } from "./compositionAudioAndDepth.js";
7
7
  /** Re-exported from `trackProjection`, where the frame-lattice helpers it belongs with now live. */
8
8
  export { playableSpans, projectMediaPlaybackSpans } from "./trackProjection.js";
9
9
  export declare function compositionFormatDimensions(format: Format): {
@@ -20,6 +20,11 @@ export declare function compositionToRenderInput(composition: Composition, srcUr
20
20
  * no scene lane.
21
21
  */
22
22
  isSceneClip?: (clip: WireClip) => boolean;
23
+ /** Dimensions of source media, keyed by mediaId. Missing or invalid values remain unprojected. */
24
+ sourceDimensions?: Record<string, {
25
+ width: number;
26
+ height: number;
27
+ }>;
23
28
  }): RenderInput;
24
29
  /**
25
30
  * Projection plus the host's resolved bindings. When the host pins `componentSources`, every
@@ -51,6 +56,10 @@ export declare function assembleRenderInput(composition: Composition, resolved:
51
56
  coViewUrls?: Record<string, string>;
52
57
  alphaUrls?: Record<string, string>;
53
58
  trajectories?: Record<string, TrajectoryData>;
59
+ sourceDimensions?: Record<string, {
60
+ width: number;
61
+ height: number;
62
+ }>;
54
63
  fontAssets?: NonNullable<RenderInput["brandKit"]>["fontAssets"];
55
64
  componentSources?: RenderInput["componentSources"];
56
65
  }): RenderInput;
@@ -11,7 +11,7 @@ export type { EmphasisWord } from './emphasis.js';
11
11
  export type { DocNode, TranscriptUtterance } from './captions.js';
12
12
  export { buildEmphasisSet, isEmphasized } from './emphasis.js';
13
13
  export { extractCaptionWordsFromDoc, sliceTranscriptWords, splitIntoSentences } from './captions.js';
14
- export { compositionToRenderInput, referencedMediaIds, assembleRenderInput, assemblePreparedRenderInput, validateComposition, compositionFormatDimensions, playableSpans, projectMediaPlaybackSpans, assertBehindSubjectCaptionCoverage, } from './compositionRender.js';
14
+ export { compositionToRenderInput, referencedMediaIds, assembleRenderInput, assemblePreparedRenderInput, validateComposition, compositionFormatDimensions, playableSpans, projectMediaPlaybackSpans, assertBehindSubjectCaptionCoverage, visiblePackedHostWindows, } from './compositionRender.js';
15
15
  export { bookendFrames, resolveBookendTimeline, CARD_BOOKEND_DEFAULT_MS, VIDEO_BOOKEND_DEFAULT_MS, } from './bookends.js';
16
16
  export type { BookendTimeline } from './bookends.js';
17
17
  export { DEFAULT_FPS, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_RENDER_SETTINGS, FORMAT_PRESETS, RESOLUTION_PRESETS, bppToCrf, ensureEven, qualityToCrf, resolutionToOutputSize, } from './exportSettings.js';
@@ -44,7 +44,10 @@ export declare function projectMediaPlaybackSpans({ startTime, duration, trim, e
44
44
  timelineStartFrames: number;
45
45
  durationInFrames: number;
46
46
  }>;
47
- export declare function projectMediaTrack(track: Track, trackIndex: number, trackCount: number, fps: number, srcUrls: Record<string, string>, trajectoryUrls?: Record<string, string>, coViewUrls?: Record<string, string>, trajectories?: Record<string, TrajectoryData>): {
47
+ export declare function projectMediaTrack(track: Track, trackIndex: number, trackCount: number, fps: number, srcUrls: Record<string, string>, trajectoryUrls?: Record<string, string>, coViewUrls?: Record<string, string>, trajectories?: Record<string, TrajectoryData>, sourceDimensions?: Record<string, {
48
+ width: number;
49
+ height: number;
50
+ }>): {
48
51
  clips: CompositionClip[];
49
52
  audio: CompositionAudioTrack[];
50
53
  effects: CompositionEffect[];
@@ -45,6 +45,9 @@ export interface CompositionClip extends ProjectedVisualIdentity {
45
45
  previewSrc?: string;
46
46
  sourceInFrames: number;
47
47
  sourceOutFrames: number;
48
+ /** Intrinsic media dimensions from the admitted media pool; absent when unverified. */
49
+ sourceWidth?: number;
50
+ sourceHeight?: number;
48
51
  timelineStartFrames: number;
49
52
  durationInFrames: number;
50
53
  trimStartFrames?: number;
package/dist/authoring.js CHANGED
@@ -48,10 +48,10 @@ import {
48
48
  formatPlanSteps,
49
49
  initCodeGenPrompts
50
50
  } from "./chunk-Y4HPN4BC.js";
51
- import "./chunk-FGJ7GKWZ.js";
51
+ import "./chunk-6WQHVYJD.js";
52
52
  import {
53
53
  cssLayoutVars
54
- } from "./chunk-W5W3FDDI.js";
54
+ } from "./chunk-Z6NY6MCL.js";
55
55
  import "./chunk-ILO4NEZ3.js";
56
56
  import "./chunk-7AZLFN26.js";
57
57
  import "./chunk-VG2ND6PX.js";
@@ -3,6 +3,14 @@ import {
3
3
  buildEasedZooms,
4
4
  buildPannedCenters
5
5
  } from "./chunk-QH3YI3ND.js";
6
+ import {
7
+ flattenCompoundClips,
8
+ hasCompoundClips
9
+ } from "./chunk-IMIUHG2E.js";
10
+ import {
11
+ compositionHasVo,
12
+ roleDefaultGainDb
13
+ } from "./chunk-VZ7TYX6Z.js";
6
14
  import {
7
15
  DOMINANCE_WEIGHTS,
8
16
  ENTER_SEC,
@@ -21,14 +29,6 @@ import {
21
29
  segmentShots,
22
30
  stabilizeSelectionHysteresis
23
31
  } from "./chunk-JPMVNMF3.js";
24
- import {
25
- flattenCompoundClips,
26
- hasCompoundClips
27
- } from "./chunk-IMIUHG2E.js";
28
- import {
29
- compositionHasVo,
30
- roleDefaultGainDb
31
- } from "./chunk-VZ7TYX6Z.js";
32
32
  import {
33
33
  SHOT_SCALE_TARGET,
34
34
  shotScaleZoom
@@ -1223,30 +1223,93 @@ function bindBehindSubjectHosts(overlays, clips) {
1223
1223
  );
1224
1224
  }
1225
1225
  }
1226
- function assertBehindSubjectCaptionCoverage(captionSegments, clips, fps) {
1227
- const packed = clips.filter((clip) => clip.packedUrl !== void 0);
1226
+ function assertBehindSubjectCaptionCoverage(captionSegments, clips, fps, output, effects = []) {
1228
1227
  for (const segment of captionSegments ?? []) {
1229
1228
  for (const word of segment) {
1230
1229
  const startFrame = Math.round(word.startMs / 1e3 * fps);
1231
1230
  const endFrame = Math.max(startFrame + 1, Math.round(word.endMs / 1e3 * fps));
1232
- const covering = packed.filter((clip) => {
1233
- const clipEnd = clip.timelineStartFrames + clip.durationInFrames;
1234
- return clip.timelineStartFrames <= startFrame && clipEnd >= endFrame;
1235
- });
1236
- if (covering.length === 1) continue;
1237
- const overlapping = packed.filter((clip) => {
1238
- const clipEnd = clip.timelineStartFrames + clip.durationInFrames;
1239
- return clip.timelineStartFrames < endFrame && clipEnd > startFrame;
1231
+ for (const window of visiblePackedHostWindows(clips, startFrame, endFrame, output, effects)) {
1232
+ if (window.hostClipId) continue;
1233
+ const code = window.candidateClipIds.length > 1 ? "behind_subject_caption_host_ambiguous" : "behind_subject_caption_host_missing";
1234
+ throw renderInputError(
1235
+ code,
1236
+ `Behind-subject caption word '${word.text}' is not fully covered by a unique visible packed host during frames [${window.startFrame}, ${window.endFrame}); an exact matte is required for the visible picture.`,
1237
+ { candidateClipIds: window.candidateClipIds, startFrame: window.startFrame, endFrame: window.endFrame }
1238
+ );
1239
+ }
1240
+ }
1241
+ }
1242
+ }
1243
+ var FULL_RECT = { left: 0, top: 0, right: 1, bottom: 1 };
1244
+ function hasClipEffect(clip, effects) {
1245
+ return effects.some((effect) => effect.target.kind === "clip" && effect.trackId === clip.trackId && effect.contentIndex === clip.contentIndex);
1246
+ }
1247
+ function pictureRect(clip, output, effects) {
1248
+ if (clip.cropTrajectory || clip.cropTrajectoryUrl || hasClipEffect(clip, effects)) return void 0;
1249
+ if (clip.fit !== "contain") return FULL_RECT;
1250
+ const sourceWidth = clip.sourceWidth;
1251
+ const sourceHeight = clip.sourceHeight;
1252
+ if (!sourceWidth || !sourceHeight || !output.width || !output.height) return void 0;
1253
+ const sourceAspect = sourceWidth / sourceHeight;
1254
+ const outputAspect = output.width / output.height;
1255
+ if (sourceAspect >= outputAspect) {
1256
+ const pictureHeight = outputAspect / sourceAspect;
1257
+ return { left: 0, right: 1, top: (1 - pictureHeight) / 2, bottom: (1 + pictureHeight) / 2 };
1258
+ }
1259
+ const pictureWidth = sourceAspect / outputAspect;
1260
+ return { left: (1 - pictureWidth) / 2, right: (1 + pictureWidth) / 2, top: 0, bottom: 1 };
1261
+ }
1262
+ function coversLowerPictures(upper, lower, output, effects) {
1263
+ const upperRect = pictureRect(upper, output, effects);
1264
+ if (!upperRect) return false;
1265
+ const epsilon = 1e-6;
1266
+ return lower.every((clip) => {
1267
+ const rect = pictureRect(clip, output, effects) ?? FULL_RECT;
1268
+ return upperRect.left <= rect.left + epsilon && upperRect.top <= rect.top + epsilon && upperRect.right + epsilon >= rect.right && upperRect.bottom + epsilon >= rect.bottom;
1269
+ });
1270
+ }
1271
+ function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects = []) {
1272
+ if (endFrame <= startFrame) return [];
1273
+ const boundaries = /* @__PURE__ */ new Set([startFrame, endFrame]);
1274
+ for (const clip of clips) {
1275
+ const start = clip.timelineStartFrames;
1276
+ const end = start + clip.durationInFrames;
1277
+ if (start > startFrame && start < endFrame) boundaries.add(start);
1278
+ if (end > startFrame && end < endFrame) boundaries.add(end);
1279
+ }
1280
+ const points = [...boundaries].sort((a, b) => a - b);
1281
+ const windows = [];
1282
+ for (let i = 0; i < points.length - 1; i++) {
1283
+ const start = points[i];
1284
+ const end = points[i + 1];
1285
+ const active = clips.filter(
1286
+ (clip) => clip.timelineStartFrames <= start && clip.timelineStartFrames + clip.durationInFrames >= end
1287
+ );
1288
+ const topLayer = Math.max(...active.map((clip) => clip.layerIndex));
1289
+ const top = active.filter((clip) => clip.layerIndex === topLayer);
1290
+ const fullFrame = top[0]?.region === void 0 || top[0].region.x === 0 && top[0].region.y === 0 && top[0].region.w === 1 && top[0].region.h === 1;
1291
+ const provesOcclusion = top.length === 1 && fullFrame && (active.length === 1 || coversLowerPictures(
1292
+ top[0],
1293
+ active.filter((clip) => clip !== top[0]),
1294
+ output,
1295
+ effects
1296
+ ));
1297
+ const host = provesOcclusion && top[0].packedUrl ? top[0] : void 0;
1298
+ const unresolvedOverlap = top.length > 1 || top.length === 1 && !!top[0].packedUrl && active.length > 1 && !provesOcclusion;
1299
+ const candidates = unresolvedOverlap ? active.filter((clip) => clip.packedUrl).map((clip) => clip.id) : top.map((clip) => clip.id);
1300
+ const previous = windows[windows.length - 1];
1301
+ if (previous && previous.endFrame === start && previous.hostClipId === host?.id && previous.candidateClipIds.join("\0") === candidates.join("\0")) {
1302
+ previous.endFrame = end;
1303
+ } else {
1304
+ windows.push({
1305
+ startFrame: start,
1306
+ endFrame: end,
1307
+ ...host ? { hostClipId: host.id } : {},
1308
+ candidateClipIds: candidates
1240
1309
  });
1241
- const candidates = covering.length > 1 ? covering : overlapping;
1242
- const code = candidates.length > 1 ? "behind_subject_caption_host_ambiguous" : "behind_subject_caption_host_missing";
1243
- throw renderInputError(
1244
- code,
1245
- candidates.length > 1 ? `Behind-subject caption word '${word.text}' is covered by multiple packed clips (${candidates.map((clip) => clip.id).join(", ")}).` : `Behind-subject caption word '${word.text}' is not fully covered by one packed clip; an exact matte is required for its entire interval.`,
1246
- { candidateClipIds: candidates.map((clip) => clip.id), startFrame, endFrame }
1247
- );
1248
1310
  }
1249
1311
  }
1312
+ return windows;
1250
1313
  }
1251
1314
 
1252
1315
  // ../execution/core/src/render/trackProjection.ts
@@ -1374,7 +1437,7 @@ function projectMediaPlaybackSpans({
1374
1437
  };
1375
1438
  });
1376
1439
  }
1377
- function projectMediaTrack(track, trackIndex, trackCount, fps, srcUrls, trajectoryUrls, coViewUrls, trajectories) {
1440
+ function projectMediaTrack(track, trackIndex, trackCount, fps, srcUrls, trajectoryUrls, coViewUrls, trajectories, sourceDimensions) {
1378
1441
  const clips = [];
1379
1442
  const audio = [];
1380
1443
  const effects = [];
@@ -1395,6 +1458,8 @@ function projectMediaTrack(track, trackIndex, trackCount, fps, srcUrls, trajecto
1395
1458
  compositionPath: `composition.tracks[${track.id}].contents[${i}].source.mediaId`
1396
1459
  });
1397
1460
  const packedUrl = coViewUrls?.[c.id];
1461
+ const dimensions = sourceDimensions?.[c.source.mediaId];
1462
+ const validDimensions = dimensions !== void 0 && Number.isFinite(dimensions.width) && dimensions.width > 0 && Number.isFinite(dimensions.height) && dimensions.height > 0;
1398
1463
  const packedEnvelopeFields = packedUrl === void 0 ? [] : [
1399
1464
  c.region !== void 0 && !(c.region.x === 0 && c.region.y === 0 && c.region.w === 1 && c.region.h === 1) ? "region" : null,
1400
1465
  c.opacity !== void 0 && c.opacity !== 1 ? "opacity" : null,
@@ -1461,6 +1526,10 @@ function projectMediaTrack(track, trackIndex, trackCount, fps, srcUrls, trajecto
1461
1526
  src,
1462
1527
  sourceInFrames: span.sourceInFrames,
1463
1528
  sourceOutFrames: span.sourceOutFrames,
1529
+ ...validDimensions ? {
1530
+ sourceWidth: dimensions.width,
1531
+ sourceHeight: dimensions.height
1532
+ } : {},
1464
1533
  timelineStartFrames: timelineCursorFrames,
1465
1534
  durationInFrames: subDurationFrames,
1466
1535
  trimStartFrames: frames(c.source.trim?.start ?? 0, fps),
@@ -1816,7 +1885,8 @@ function compositionToRenderInput(composition, srcUrls, trajectoryUrls, coViewUr
1816
1885
  srcUrls,
1817
1886
  trajectoryUrls,
1818
1887
  coViewUrls,
1819
- trajectories
1888
+ trajectories,
1889
+ options?.sourceDimensions
1820
1890
  );
1821
1891
  clips.push(...c);
1822
1892
  audioTracks.push(...audio);
@@ -1876,7 +1946,7 @@ function compositionToRenderInput(composition, srcUrls, trajectoryUrls, coViewUr
1876
1946
  const bodyDurationInFrames = maxBackgroundEndFrames > 0 ? Math.min(maxEndFrames, maxBackgroundEndFrames) : maxEndFrames;
1877
1947
  const captionSegments = composition.captions?.segments.map((seg) => seg.words).filter((words) => words.length > 0);
1878
1948
  if (composition.captions?.zPlane === "behind-subject") {
1879
- assertBehindSubjectCaptionCoverage(captionSegments, clips, fps);
1949
+ assertBehindSubjectCaptionCoverage(captionSegments, clips, fps, { width, height }, effects);
1880
1950
  }
1881
1951
  const brandKit = composition.brandKit;
1882
1952
  const { totalFrames: durationInFrames } = resolveBookendTimeline(
@@ -1956,7 +2026,10 @@ function assembleRenderInput(composition, resolved) {
1956
2026
  resolved.trajectories,
1957
2027
  // The same manifest-backed answer the shape rules used, so projection cannot floor a scene
1958
2028
  // clip's boundary into a length the rules above would have refused.
1959
- resolveSource ? { isSceneClip: (clip) => isSceneShotClip(clip, resolveSource) } : void 0
2029
+ {
2030
+ ...resolveSource ? { isSceneClip: (clip) => isSceneShotClip(clip, resolveSource) } : {},
2031
+ sourceDimensions: resolved.sourceDimensions
2032
+ }
1960
2033
  );
1961
2034
  if (renderInput.brandKit && resolved.fontAssets && resolved.fontAssets.length > 0) {
1962
2035
  renderInput.brandKit.fontAssets = resolved.fontAssets;
@@ -2973,6 +3046,7 @@ export {
2973
3046
  resolveBookendTimeline,
2974
3047
  validateComposition,
2975
3048
  assertBehindSubjectCaptionCoverage,
3049
+ visiblePackedHostWindows,
2976
3050
  playableSpans,
2977
3051
  projectMediaPlaybackSpans,
2978
3052
  compositionFormatDimensions,
@@ -2,7 +2,7 @@ import {
2
2
  activeFaceKeepOutSeries,
3
3
  boundingBox,
4
4
  resolveBrandRefsDeep
5
- } from "./chunk-W5W3FDDI.js";
5
+ } from "./chunk-Z6NY6MCL.js";
6
6
  import {
7
7
  CueframeError,
8
8
  encodeError
@@ -3,7 +3,7 @@ import {
3
3
  projectMediaPlaybackSpans,
4
4
  sliceTranscriptWords,
5
5
  splitIntoSentences
6
- } from "./chunk-FEG264CF.js";
6
+ } from "./chunk-4QMRY7KU.js";
7
7
  import {
8
8
  createHeadlessStore,
9
9
  findClipById,
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-AOIY7NGF.js";
32
32
  import {
33
33
  CompositionOp
34
- } from "./chunk-KCXADPOC.js";
34
+ } from "./chunk-DJRKEUK3.js";
35
35
 
36
36
  // ../mcp/src/prompts.ts
37
37
  var skillListCache = null;
@@ -84,11 +84,12 @@ function resolveBrandKit(kit, compositionWidth) {
84
84
  };
85
85
  const captionBaseFamily = effectiveCaptionFamily(kit).family;
86
86
  const cp = kit.captionProfile;
87
+ const captionInk = (color) => cp?.plate === "none" ? color : clampToFloor(color, safe.captionScrim, FLOORS.body);
87
88
  const caption = {
88
- fg: cp?.emphasisColor ? clampToFloor(cp.emphasisColor, safe.captionScrim, FLOORS.body) : safe.captionFg,
89
+ fg: cp?.emphasisColor ? captionInk(cp.emphasisColor) : safe.captionFg,
89
90
  scrim: safe.captionScrim,
90
- ...cp?.color ? { color: clampToFloor(cp.color, safe.captionScrim, FLOORS.body) } : {},
91
- ...cp?.highlightColor ? { highlightColor: clampToFloor(cp.highlightColor, safe.captionScrim, FLOORS.body) } : {},
91
+ ...cp?.color ? { color: captionInk(cp.color) } : {},
92
+ ...cp?.highlightColor ? { highlightColor: captionInk(cp.highlightColor) } : {},
92
93
  ...cp?.plate ? { plate: cp.plate } : {},
93
94
  ...cp?.entrance ? { entrance: cp.entrance } : {},
94
95
  ...cp?.entranceMs != null ? { entranceMs: cp.entranceMs } : {},
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  placeInLegalArea,
3
3
  resolveBrandRefsDeep
4
- } from "../chunk-W5W3FDDI.js";
4
+ } from "../chunk-Z6NY6MCL.js";
5
5
  import "../chunk-ILO4NEZ3.js";
6
6
  import "../chunk-VG2ND6PX.js";
7
7
  import {
@@ -32,7 +32,7 @@ import {
32
32
  silhouetteKeepOutForWindow,
33
33
  sourceRectToOutput,
34
34
  sourceWindowKey
35
- } from "../chunk-FGJ7GKWZ.js";
35
+ } from "../chunk-6WQHVYJD.js";
36
36
  import {
37
37
  BRAND_TOKEN_REFS,
38
38
  BRAND_TOKEN_ROOT_KEYS,
@@ -69,7 +69,7 @@ import {
69
69
  resolveLayoutIntent,
70
70
  resolveOverlayRegion,
71
71
  unionFaceKeepOutSeries
72
- } from "../chunk-W5W3FDDI.js";
72
+ } from "../chunk-Z6NY6MCL.js";
73
73
  import {
74
74
  contrastRatio
75
75
  } from "../chunk-ILO4NEZ3.js";
@@ -20,12 +20,12 @@ import {
20
20
  replaceRegion,
21
21
  resolveClipKind,
22
22
  wrapWithOpRecorder
23
- } from "./chunk-KCXADPOC.js";
24
- import "./chunk-FEG264CF.js";
23
+ } from "./chunk-DJRKEUK3.js";
24
+ import "./chunk-4QMRY7KU.js";
25
25
  import "./chunk-QH3YI3ND.js";
26
- import "./chunk-JPMVNMF3.js";
27
26
  import "./chunk-IMIUHG2E.js";
28
27
  import "./chunk-VZ7TYX6Z.js";
28
+ import "./chunk-JPMVNMF3.js";
29
29
  import "./chunk-T56BK7NS.js";
30
30
  import "./chunk-VEQTURKN.js";
31
31
  import "./chunk-AG7HKF2U.js";
@@ -46,7 +46,7 @@ import {
46
46
  silhouetteKeepOutForWindow,
47
47
  sourceRectToOutput,
48
48
  sourceWindowKey
49
- } from "./chunk-FGJ7GKWZ.js";
49
+ } from "./chunk-6WQHVYJD.js";
50
50
  import {
51
51
  BRAND_TOKEN_REFS,
52
52
  BRAND_TOKEN_ROOT_KEYS,
@@ -83,7 +83,7 @@ import {
83
83
  resolveLayoutIntent,
84
84
  resolveOverlayRegion,
85
85
  unionFaceKeepOutSeries
86
- } from "./chunk-W5W3FDDI.js";
86
+ } from "./chunk-Z6NY6MCL.js";
87
87
  import {
88
88
  contrastRatio
89
89
  } from "./chunk-ILO4NEZ3.js";
@@ -66,16 +66,17 @@ import {
66
66
  selectedFaceCenter,
67
67
  sliceTranscriptWords,
68
68
  splitIntoSentences,
69
- validateComposition
70
- } from "../chunk-FEG264CF.js";
69
+ validateComposition,
70
+ visiblePackedHostWindows
71
+ } from "../chunk-4QMRY7KU.js";
71
72
  import {
72
73
  buildEasedZooms,
73
74
  buildPannedCenters,
74
75
  easeOutCubic
75
76
  } from "../chunk-QH3YI3ND.js";
76
- import "../chunk-JPMVNMF3.js";
77
77
  import "../chunk-IMIUHG2E.js";
78
78
  import "../chunk-VZ7TYX6Z.js";
79
+ import "../chunk-JPMVNMF3.js";
79
80
  import "../chunk-T56BK7NS.js";
80
81
  import "../chunk-KYRDKK2D.js";
81
82
  import "../chunk-WREYUH2E.js";
@@ -156,5 +157,6 @@ export {
156
157
  selectedFaceCenter,
157
158
  sliceTranscriptWords,
158
159
  splitIntoSentences,
159
- validateComposition
160
+ validateComposition,
161
+ visiblePackedHostWindows
160
162
  };
package/dist/core.js CHANGED
@@ -10,11 +10,11 @@ import {
10
10
  ensureEven,
11
11
  extractCaptionWordsFromDoc,
12
12
  isEmphasized
13
- } from "./chunk-FEG264CF.js";
13
+ } from "./chunk-4QMRY7KU.js";
14
14
  import "./chunk-QH3YI3ND.js";
15
- import "./chunk-JPMVNMF3.js";
16
15
  import "./chunk-IMIUHG2E.js";
17
16
  import "./chunk-VZ7TYX6Z.js";
17
+ import "./chunk-JPMVNMF3.js";
18
18
  import "./chunk-T56BK7NS.js";
19
19
  import "./chunk-KYRDKK2D.js";
20
20
  import "./chunk-WREYUH2E.js";
@@ -8,17 +8,17 @@ import {
8
8
  registerRawTools,
9
9
  registerSkillPrompts,
10
10
  titleCase
11
- } from "../chunk-OYWX4NEP.js";
11
+ } from "../chunk-E3FYYVCG.js";
12
12
  import "../chunk-FYS2XUKJ.js";
13
13
  import "../chunk-XSBVOXSB.js";
14
14
  import "../chunk-CFIQY4OE.js";
15
15
  import "../chunk-AOIY7NGF.js";
16
- import "../chunk-KCXADPOC.js";
17
- import "../chunk-FEG264CF.js";
16
+ import "../chunk-DJRKEUK3.js";
17
+ import "../chunk-4QMRY7KU.js";
18
18
  import "../chunk-QH3YI3ND.js";
19
- import "../chunk-JPMVNMF3.js";
20
19
  import "../chunk-IMIUHG2E.js";
21
20
  import "../chunk-VZ7TYX6Z.js";
21
+ import "../chunk-JPMVNMF3.js";
22
22
  import "../chunk-T56BK7NS.js";
23
23
  import "../chunk-VEQTURKN.js";
24
24
  import "../chunk-AG7HKF2U.js";
package/dist/mcp.js CHANGED
@@ -8,17 +8,17 @@ import {
8
8
  buildServer,
9
9
  registerCuratedTools,
10
10
  registerRawTools
11
- } from "./chunk-OYWX4NEP.js";
11
+ } from "./chunk-E3FYYVCG.js";
12
12
  import "./chunk-FYS2XUKJ.js";
13
13
  import "./chunk-XSBVOXSB.js";
14
14
  import "./chunk-CFIQY4OE.js";
15
15
  import "./chunk-AOIY7NGF.js";
16
- import "./chunk-KCXADPOC.js";
17
- import "./chunk-FEG264CF.js";
16
+ import "./chunk-DJRKEUK3.js";
17
+ import "./chunk-4QMRY7KU.js";
18
18
  import "./chunk-QH3YI3ND.js";
19
- import "./chunk-JPMVNMF3.js";
20
19
  import "./chunk-IMIUHG2E.js";
21
20
  import "./chunk-VZ7TYX6Z.js";
21
+ import "./chunk-JPMVNMF3.js";
22
22
  import "./chunk-T56BK7NS.js";
23
23
  import "./chunk-VEQTURKN.js";
24
24
  import "./chunk-AG7HKF2U.js";
@@ -94,7 +94,7 @@ function assignTimeline(raw, lingerMs) {
94
94
 
95
95
  // ../execution/primitives/src/captions/placement.ts
96
96
  function resolveCaptionPlacement(position, region) {
97
- const vertical = region ? { bottom: `${Math.max(0, (1 - (region.y + region.h)) * 100)}%` } : position === "top" ? { top: "8%" } : position === "center" ? { top: "50%", transform: "translateY(-50%)" } : { bottom: "10%" };
97
+ const vertical = position === "top" ? { top: "8%" } : position === "center" ? { top: "50%", transform: "translateY(-50%)" } : position === "bottom" ? { bottom: "10%" } : region ? { bottom: `${Math.max(0, (1 - (region.y + region.h)) * 100)}%` } : { bottom: "10%" };
98
98
  return {
99
99
  position: "absolute",
100
100
  left: 0,
@@ -264,7 +264,7 @@ function Captions({
264
264
  style.fontWeight,
265
265
  emphasisLayout
266
266
  );
267
- const wrapperStyle = resolveCaptionPlacement(style.position, region);
267
+ const wrapperStyle = resolveCaptionPlacement(userStyle?.position, region);
268
268
  return /* @__PURE__ */ React.createElement(AbsoluteFill, { style: { pointerEvents: "none" } }, /* @__PURE__ */ React.createElement("div", { style: wrapperStyle }, /* @__PURE__ */ React.createElement(
269
269
  "div",
270
270
  {
@@ -46,11 +46,11 @@ import {
46
46
  parseSceneComponentCaptureIntentV1,
47
47
  prepareSceneShotRenderInput,
48
48
  readSceneShotManifest
49
- } from "./chunk-FEG264CF.js";
49
+ } from "./chunk-4QMRY7KU.js";
50
50
  import "./chunk-QH3YI3ND.js";
51
- import "./chunk-JPMVNMF3.js";
52
51
  import "./chunk-IMIUHG2E.js";
53
52
  import "./chunk-VZ7TYX6Z.js";
53
+ import "./chunk-JPMVNMF3.js";
54
54
  import "./chunk-T56BK7NS.js";
55
55
  import "./chunk-KYRDKK2D.js";
56
56
  import "./chunk-WREYUH2E.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cueframe/kernel",
3
- "version": "0.2.47",
3
+ "version": "0.2.49",
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": [
@@ -19,23 +19,23 @@
19
19
  "@cueframe/account-model": "0.1.0",
20
20
  "@cueframe/animate": "0.1.0",
21
21
  "@cueframe/authoring": "0.1.0",
22
- "@cueframe/cloud-import": "0.1.0",
23
22
  "@cueframe/brand-derivation": "0.1.0",
24
- "@cueframe/component-runtime": "0.1.0",
25
23
  "@cueframe/compose": "0.1.0",
24
+ "@cueframe/cloud-import": "0.1.0",
25
+ "@cueframe/composition": "0.1.0",
26
+ "@cueframe/composition-ops": "0.1.0",
27
+ "@cueframe/component-runtime": "0.1.0",
26
28
  "@cueframe/core": "0.1.0",
27
29
  "@cueframe/director": "0.1.0",
28
30
  "@cueframe/errors": "0.1.0",
29
- "@cueframe/composition-ops": "0.1.0",
30
- "@cueframe/nle-export": "0.1.0",
31
31
  "@cueframe/foundation": "0.1.0",
32
32
  "@cueframe/mcp": "0.1.0",
33
33
  "@cueframe/media-model": "0.1.0",
34
- "@cueframe/composition": "0.1.0",
34
+ "@cueframe/nle-export": "0.1.0",
35
35
  "@cueframe/perception": "0.1.0",
36
- "@cueframe/render-harness": "0.1.0",
36
+ "@cueframe/plane": "0.1.0",
37
37
  "@cueframe/primitives": "0.1.0",
38
- "@cueframe/plane": "0.1.0"
38
+ "@cueframe/render-harness": "0.1.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "gsap": "3.13.0",