@scenar/core 0.9.1 → 0.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 (81) hide show
  1. package/embed/host-controller.d.ts +7 -0
  2. package/embed/host-controller.d.ts.map +1 -1
  3. package/embed/host-controller.js +1 -0
  4. package/embed/host-controller.js.map +1 -1
  5. package/embed/protocol.d.ts +35 -3
  6. package/embed/protocol.d.ts.map +1 -1
  7. package/embed/protocol.js +37 -4
  8. package/embed/protocol.js.map +1 -1
  9. package/index.d.ts +18 -2
  10. package/index.d.ts.map +1 -1
  11. package/index.js +9 -1
  12. package/index.js.map +1 -1
  13. package/package.json +1 -1
  14. package/presenter/derive-presenter-timeline.d.ts +36 -0
  15. package/presenter/derive-presenter-timeline.d.ts.map +1 -0
  16. package/presenter/derive-presenter-timeline.js +31 -0
  17. package/presenter/derive-presenter-timeline.js.map +1 -0
  18. package/presenter/presenter-opacity.d.ts +32 -0
  19. package/presenter/presenter-opacity.d.ts.map +1 -0
  20. package/presenter/presenter-opacity.js +40 -0
  21. package/presenter/presenter-opacity.js.map +1 -0
  22. package/presenter/types.d.ts +45 -0
  23. package/presenter/types.d.ts.map +1 -0
  24. package/presenter/types.js +16 -0
  25. package/presenter/types.js.map +1 -0
  26. package/scenario/apply-title-cards.d.ts +53 -0
  27. package/scenario/apply-title-cards.d.ts.map +1 -0
  28. package/scenario/apply-title-cards.js +113 -0
  29. package/scenario/apply-title-cards.js.map +1 -0
  30. package/scenario/bundle.d.ts +15 -0
  31. package/scenario/bundle.d.ts.map +1 -1
  32. package/scenario/soundtrack.d.ts +46 -0
  33. package/scenario/soundtrack.d.ts.map +1 -0
  34. package/scenario/soundtrack.js +11 -0
  35. package/scenario/soundtrack.js.map +1 -0
  36. package/scenario/title-cards.d.ts +64 -0
  37. package/scenario/title-cards.d.ts.map +1 -0
  38. package/scenario/title-cards.js +20 -0
  39. package/scenario/title-cards.js.map +1 -0
  40. package/scenario/types.d.ts +36 -2
  41. package/scenario/types.d.ts.map +1 -1
  42. package/src/embed/host-controller.test.ts +6 -0
  43. package/src/embed/host-controller.ts +8 -0
  44. package/src/embed/protocol.test.ts +53 -0
  45. package/src/embed/protocol.ts +76 -8
  46. package/src/index.ts +33 -1
  47. package/src/presenter/derive-presenter-timeline.test.ts +138 -0
  48. package/src/presenter/derive-presenter-timeline.ts +54 -0
  49. package/src/presenter/presenter-opacity.test.ts +47 -0
  50. package/src/presenter/presenter-opacity.ts +43 -0
  51. package/src/presenter/types.ts +46 -0
  52. package/src/scenario/apply-title-cards.test.ts +268 -0
  53. package/src/scenario/apply-title-cards.ts +141 -0
  54. package/src/scenario/bundle.ts +15 -0
  55. package/src/scenario/soundtrack.ts +47 -0
  56. package/src/scenario/title-cards.ts +67 -0
  57. package/src/scenario/types.ts +36 -2
  58. package/src/timeline/compute-step-timeline.test.ts +21 -0
  59. package/src/timeline/compute-step-timeline.ts +30 -7
  60. package/src/timeline/derive-action-events.test.ts +144 -0
  61. package/src/timeline/derive-action-events.ts +116 -0
  62. package/src/timeline/derive-sfx-timeline.test.ts +114 -0
  63. package/src/timeline/derive-sfx-timeline.ts +79 -0
  64. package/src/timeline/music-envelope.test.ts +141 -0
  65. package/src/timeline/music-envelope.ts +131 -0
  66. package/timeline/compute-step-timeline.d.ts +28 -3
  67. package/timeline/compute-step-timeline.d.ts.map +1 -1
  68. package/timeline/compute-step-timeline.js +11 -3
  69. package/timeline/compute-step-timeline.js.map +1 -1
  70. package/timeline/derive-action-events.d.ts +40 -0
  71. package/timeline/derive-action-events.d.ts.map +1 -0
  72. package/timeline/derive-action-events.js +71 -0
  73. package/timeline/derive-action-events.js.map +1 -0
  74. package/timeline/derive-sfx-timeline.d.ts +36 -0
  75. package/timeline/derive-sfx-timeline.d.ts.map +1 -0
  76. package/timeline/derive-sfx-timeline.js +49 -0
  77. package/timeline/derive-sfx-timeline.js.map +1 -0
  78. package/timeline/music-envelope.d.ts +69 -0
  79. package/timeline/music-envelope.d.ts.map +1 -0
  80. package/timeline/music-envelope.js +95 -0
  81. package/timeline/music-envelope.js.map +1 -0
@@ -24,6 +24,13 @@ export interface ScenarEmbedHostController {
24
24
  seek(timeMs: number): void;
25
25
  setMuted(muted: boolean): void;
26
26
  setVolume(volume: number): void;
27
+ /**
28
+ * Report the scale factor the host is rendering the iframe at (1 = native),
29
+ * so the player's chrome layer can counter-scale its transport controls
30
+ * back to native pixel size. Sent by hosts running the iframe-as-screen
31
+ * mode; players without the capability ignore it.
32
+ */
33
+ setHostScale(scale: number): void;
27
34
  prefetch(): void;
28
35
  /**
29
36
  * Tell the embed to stop (best effort) and detach the host message listener.
@@ -1 +1 @@
1
- {"version":3,"file":"host-controller.d.ts","sourceRoot":"","sources":["../../src/embed/host-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,eAAe,CAAC;AAEvB;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACtD;AAED,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACxC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,IAAI,IAAI,CAAC;IACjB;;;;OAIG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,GAAE,sBAA2B,GACnC,yBAAyB,CA+B3B"}
1
+ {"version":3,"file":"host-controller.d.ts","sourceRoot":"","sources":["../../src/embed/host-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,eAAe,CAAC;AAEvB;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACtD;AAED,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACxC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,IAAI,IAAI,CAAC;IACjB;;;;OAIG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,GAAE,sBAA2B,GACnC,yBAAyB,CAgC3B"}
@@ -41,6 +41,7 @@ export function createEmbedHostController(target, options = {}) {
41
41
  seek: (timeMs) => send({ type: "seek", timeMs }),
42
42
  setMuted: (muted) => send({ type: "setMuted", muted }),
43
43
  setVolume: (volume) => send({ type: "setVolume", volume }),
44
+ setHostScale: (scale) => send({ type: "setHostScale", scale }),
44
45
  prefetch: () => send({ type: "prefetch" }),
45
46
  destroy: () => {
46
47
  send({ type: "destroy" });
@@ -1 +1 @@
1
- {"version":3,"file":"host-controller.js","sourceRoot":"","sources":["../../src/embed/host-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EACjB,eAAe,GAChB,MAAM,eAAe,CAAC;AAsCvB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAA6B,EAC7B,UAAkC,EAAE;IAEpC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAClC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC5B,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;IAEhD,MAAM,IAAI,GAAG,CAAC,OAA2B,EAAQ,EAAE;QACjD,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAQ,EAAE;QAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,aAAa;YAAE,OAAO;QAClD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO;QACpC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,IAAI,SAAS;QAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAE7D,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAClC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACtD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QAC1D,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC1C,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAC1B,IAAI,SAAS;gBAAE,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAClE,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"host-controller.js","sourceRoot":"","sources":["../../src/embed/host-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EACjB,eAAe,GAChB,MAAM,eAAe,CAAC;AA6CvB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAA6B,EAC7B,UAAkC,EAAE;IAEpC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAClC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC5B,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;IAEhD,MAAM,IAAI,GAAG,CAAC,OAA2B,EAAQ,EAAE;QACjD,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAQ,EAAE;QAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,aAAa;YAAE,OAAO;QAClD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO;QACpC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,IAAI,SAAS;QAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAE7D,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAClC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACtD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QAC1D,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;QAC9D,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC1C,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAC1B,IAAI,SAAS;gBAAE,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAClE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -18,11 +18,30 @@
18
18
  export declare const SCENAR_EMBED_SOURCE = "scenar-embed";
19
19
  /** Protocol version. Bump only on a breaking change to the message shapes. */
20
20
  export declare const SCENAR_EMBED_PROTOCOL_VERSION = 1;
21
+ /**
22
+ * The canonical viewport a packed scenario was authored and bundled at, in CSS
23
+ * pixels — the same numbers `scenar pack` bakes into the bundle and records in
24
+ * `scenario.json`.
25
+ *
26
+ * Carried on `ready` so a host can lay the iframe out at this exact size and
27
+ * scale it as one unit (the iframe-as-screen mode in `@scenar/embed`): the
28
+ * embedded document's media queries then resolve against the canonical width,
29
+ * so responsive components render the same variant they would in a real
30
+ * browser window of that size — instead of the narrow variant the host
31
+ * column's width would select.
32
+ */
33
+ export interface ScenarEmbedViewport {
34
+ readonly widthPx: number;
35
+ readonly heightPx: number;
36
+ }
21
37
  /**
22
38
  * Events the embedded player emits to the host (embed -> host).
23
39
  *
24
40
  * - `ready` — the player has mounted; carries scenario shape the host can use
25
- * to size or label the frame.
41
+ * to size or label the frame. `viewport` (when the bundle knows it) is the
42
+ * canonical size the scenario was packed at — see {@link ScenarEmbedViewport}.
43
+ * Optional for compatibility: bundles packed before the field existed omit
44
+ * it, and hosts must treat its absence as "fit content inside the iframe".
26
45
  * - `resize` — the rendered content height changed (dynamic-height hosts).
27
46
  * - `started` / `paused` / `completed` — transport state transitions.
28
47
  * - `stepchange` — the active step changed.
@@ -35,6 +54,7 @@ export type ScenarEmbedEvent = {
35
54
  readonly type: "ready";
36
55
  readonly totalSteps: number;
37
56
  readonly hasNarration: boolean;
57
+ readonly viewport?: ScenarEmbedViewport;
38
58
  } | {
39
59
  readonly type: "resize";
40
60
  readonly widthPx: number;
@@ -63,8 +83,17 @@ export type ScenarEmbedEvent = {
63
83
  /**
64
84
  * Commands the host may send to the embedded player (host -> embed).
65
85
  *
66
- * State-setting commands (`setMuted`, `setVolume`) are idempotent by design so
67
- * a host never has to track the player's internal state to stay in sync.
86
+ * State-setting commands (`setMuted`, `setVolume`, `setHostScale`) are
87
+ * idempotent by design so a host never has to track the player's internal
88
+ * state to stay in sync.
89
+ *
90
+ * `setHostScale` accompanies the iframe-as-screen mode: when the host lays
91
+ * the iframe out at the canonical viewport and scales it as one unit, every
92
+ * pixel inside — including the player's transport controls — shrinks by that
93
+ * factor. The player's chrome layer counter-scales by `1 / scale` so controls
94
+ * keep rendering at native pixel size (the ViewportChrome contract), which
95
+ * only the host can enable because a cross-origin document cannot observe the
96
+ * transform applied to its own frame.
68
97
  */
69
98
  export type ScenarEmbedCommand = {
70
99
  readonly type: "play";
@@ -79,6 +108,9 @@ export type ScenarEmbedCommand = {
79
108
  } | {
80
109
  readonly type: "setVolume";
81
110
  readonly volume: number;
111
+ } | {
112
+ readonly type: "setHostScale";
113
+ readonly scale: number;
82
114
  } | {
83
115
  readonly type: "prefetch";
84
116
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/embed/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAElD,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAAE,GACvF;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxF;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAEjC,oEAAoE;AACpE,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,mBAAmB,CAAC;IAC5C,QAAQ,CAAC,CAAC,EAAE,OAAO,6BAA6B,CAAC;CAClD;AAED,qEAAqE;AACrE,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;AAE7E,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;AAEjF,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,uBAAuB,CAEhF;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,yBAAyB,CAExF;AAcD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAkB1E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAqCtE"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/embed/protocol.ts"],"names":[],"mappings":"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"}
package/embed/protocol.js CHANGED
@@ -59,10 +59,33 @@ export function parseEmbedCommand(data) {
59
59
  return typeof data["muted"] === "boolean" ? { type, muted: data["muted"] } : null;
60
60
  case "setVolume":
61
61
  return isFiniteNumber(data["volume"]) ? { type, volume: data["volume"] } : null;
62
+ case "setHostScale":
63
+ return isFiniteNumber(data["scale"]) && data["scale"] > 0
64
+ ? { type, scale: data["scale"] }
65
+ : null;
62
66
  default:
63
67
  return null;
64
68
  }
65
69
  }
70
+ /**
71
+ * Parse the optional `viewport` field of a `ready` payload. Absent -> the
72
+ * event simply has no viewport (a pre-viewport bundle). Present but malformed
73
+ * -> the whole event is rejected, exactly like a mistyped required field: a
74
+ * half-valid message is a protocol violation, not a degraded mode.
75
+ */
76
+ function parseReadyViewport(value) {
77
+ if (value === undefined)
78
+ return {};
79
+ if (typeof value !== "object" || value === null)
80
+ return null;
81
+ const record = value;
82
+ return isFiniteNumber(record["widthPx"]) &&
83
+ record["widthPx"] > 0 &&
84
+ isFiniteNumber(record["heightPx"]) &&
85
+ record["heightPx"] > 0
86
+ ? { viewport: { widthPx: record["widthPx"], heightPx: record["heightPx"] } }
87
+ : null;
88
+ }
66
89
  /**
67
90
  * Parse an inbound `MessageEvent.data` into a typed event, or return `null`.
68
91
  *
@@ -79,10 +102,20 @@ export function parseEmbedEvent(data) {
79
102
  case "completed":
80
103
  case "audioBlocked":
81
104
  return { type };
82
- case "ready":
83
- return isFiniteNumber(data["totalSteps"]) && typeof data["hasNarration"] === "boolean"
84
- ? { type, totalSteps: data["totalSteps"], hasNarration: data["hasNarration"] }
85
- : null;
105
+ case "ready": {
106
+ if (!isFiniteNumber(data["totalSteps"]) || typeof data["hasNarration"] !== "boolean") {
107
+ return null;
108
+ }
109
+ const parsedViewport = parseReadyViewport(data["viewport"]);
110
+ if (parsedViewport === null)
111
+ return null;
112
+ return {
113
+ type,
114
+ totalSteps: data["totalSteps"],
115
+ hasNarration: data["hasNarration"],
116
+ ...parsedViewport,
117
+ };
118
+ }
86
119
  case "resize":
87
120
  return isFiniteNumber(data["widthPx"]) && isFiniteNumber(data["heightPx"])
88
121
  ? { type, widthPx: data["widthPx"], heightPx: data["heightPx"] }
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/embed/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/embed/protocol.ts"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,22 +1,38 @@
1
1
  export type { ScenarioStep } from "./scenario/types.js";
2
2
  export type { ScenarioBundle } from "./scenario/bundle.js";
3
3
  export type { ActionType, StepAction, UseStepInteractionsOptions, } from "./scenario/step-action.js";
4
+ export type { Soundtrack } from "./scenario/soundtrack.js";
5
+ export { MUSIC_VOLUME_DEFAULT, DUCKING_VOLUME_DEFAULT, } from "./scenario/soundtrack.js";
6
+ export type { TitleCard, TitleCards, StepCard } from "./scenario/title-cards.js";
7
+ export { TITLE_CARD_DURATION_DEFAULT_MS } from "./scenario/title-cards.js";
8
+ export type { AppliedTitleCards } from "./scenario/apply-title-cards.js";
9
+ export { applyTitleCards } from "./scenario/apply-title-cards.js";
4
10
  export type { NarrationEntry, NarrationManifest } from "./narration/types.js";
11
+ export type { PresenterEntry, PresenterManifest } from "./presenter/types.js";
12
+ export type { PresenterWindow } from "./presenter/derive-presenter-timeline.js";
13
+ export { derivePresenterTimeline } from "./presenter/derive-presenter-timeline.js";
14
+ export { PRESENTER_FADE_MS, presenterOpacityAt } from "./presenter/presenter-opacity.js";
5
15
  export type { ViewportTransform, ViewportCameraMove } from "./viewport/transform.js";
6
16
  export { VIEWPORT_TRANSFORM_IDENTITY, VIEWPORT_CAMERA_AT_REST, cameraEase, interpolateViewportTransform, } from "./viewport/transform.js";
7
17
  export type { Position } from "./cursor/compute-position.js";
8
18
  export { computeCursorPosition } from "./cursor/compute-position.js";
9
19
  export type { StepTimeline } from "./timeline/compute-step-timeline.js";
10
- export { computeStepTimeline } from "./timeline/compute-step-timeline.js";
20
+ export { FINAL_DWELL_MS, computeStepTimeline } from "./timeline/compute-step-timeline.js";
11
21
  export { deriveStepFromTime } from "./timeline/derive-step.js";
12
22
  export { getStepDurationMs } from "./timeline/step-duration.js";
23
+ export type { ActionEvent, ActionEventKind } from "./timeline/derive-action-events.js";
24
+ export { deriveActionEvents } from "./timeline/derive-action-events.js";
25
+ export type { SfxEvent, SfxSound } from "./timeline/derive-sfx-timeline.js";
26
+ export { deriveSfxTimeline } from "./timeline/derive-sfx-timeline.js";
27
+ export type { DuckingWindow, MusicEnvelope } from "./timeline/music-envelope.js";
28
+ export { MUSIC_FADE_IN_MS, MUSIC_FADE_OUT_MS, DUCKING_RAMP_MS, computeMusicEnvelope, musicGainAt, } from "./timeline/music-envelope.js";
13
29
  export type { ScenarioShot } from "./timeline/collect-shots.js";
14
30
  export { SHOT_NAME_PATTERN, collectScenarioShots, collectShotNames, } from "./timeline/collect-shots.js";
15
31
  export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, CAMERA_TRANSITION_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
16
32
  export { findScrollParent, scrollTargetIntoView, scrollTargetIntoViewInstant, } from "./dom/scroll.js";
17
33
  export { CURSOR_TARGET_ATTRIBUTE, SCROLL_TARGET_ATTRIBUTE, HOVER_STATE_ATTRIBUTE, DRAG_STATE_ATTRIBUTE, cursorTargetSelector, scrollTargetSelector, } from "./targeting/data-attributes.js";
18
34
  export { SCENAR_EMBED_SOURCE, SCENAR_EMBED_PROTOCOL_VERSION, frameEmbedEvent, frameEmbedCommand, parseEmbedCommand, parseEmbedEvent, } from "./embed/protocol.js";
19
- export type { ScenarEmbedEvent, ScenarEmbedCommand, ScenarEmbedEventMessage, ScenarEmbedCommandMessage, } from "./embed/protocol.js";
35
+ export type { ScenarEmbedEvent, ScenarEmbedCommand, ScenarEmbedEventMessage, ScenarEmbedCommandMessage, ScenarEmbedViewport, } from "./embed/protocol.js";
20
36
  export { createEmbedHostController } from "./embed/host-controller.js";
21
37
  export type { ScenarEmbedHostController, ScenarEmbedHostTarget, ScenarEmbedHostOptions, } from "./embed/host-controller.js";
22
38
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EACV,UAAU,EACV,UAAU,EACV,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -1,10 +1,18 @@
1
1
  // @scenar/core — public API
2
2
  // Pure TypeScript types, timing, and utilities for scenario playback.
3
+ export { MUSIC_VOLUME_DEFAULT, DUCKING_VOLUME_DEFAULT, } from "./scenario/soundtrack.js";
4
+ export { TITLE_CARD_DURATION_DEFAULT_MS } from "./scenario/title-cards.js";
5
+ export { applyTitleCards } from "./scenario/apply-title-cards.js";
6
+ export { derivePresenterTimeline } from "./presenter/derive-presenter-timeline.js";
7
+ export { PRESENTER_FADE_MS, presenterOpacityAt } from "./presenter/presenter-opacity.js";
3
8
  export { VIEWPORT_TRANSFORM_IDENTITY, VIEWPORT_CAMERA_AT_REST, cameraEase, interpolateViewportTransform, } from "./viewport/transform.js";
4
9
  export { computeCursorPosition } from "./cursor/compute-position.js";
5
- export { computeStepTimeline } from "./timeline/compute-step-timeline.js";
10
+ export { FINAL_DWELL_MS, computeStepTimeline } from "./timeline/compute-step-timeline.js";
6
11
  export { deriveStepFromTime } from "./timeline/derive-step.js";
7
12
  export { getStepDurationMs } from "./timeline/step-duration.js";
13
+ export { deriveActionEvents } from "./timeline/derive-action-events.js";
14
+ export { deriveSfxTimeline } from "./timeline/derive-sfx-timeline.js";
15
+ export { MUSIC_FADE_IN_MS, MUSIC_FADE_OUT_MS, DUCKING_RAMP_MS, computeMusicEnvelope, musicGainAt, } from "./timeline/music-envelope.js";
8
16
  export { SHOT_NAME_PATTERN, collectScenarioShots, collectShotNames, } from "./timeline/collect-shots.js";
9
17
  // Timing constants
10
18
  export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, CAMERA_TRANSITION_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,sEAAsE;AAgBtE,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,mBAAmB;AACnB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,oCAAoC;AACpC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAExC,0EAA0E;AAC1E,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAQ7B,uEAAuE;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,sEAAsE;AAatE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAQlE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAIzF,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAExE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,mBAAmB;AACnB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,oCAAoC;AACpC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAExC,0EAA0E;AAC1E,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAS7B,uEAAuE;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scenar/core",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "Pure TypeScript types, timing, and utilities for the Scenar scenario engine.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -0,0 +1,36 @@
1
+ import type { StepTimeline } from "../timeline/compute-step-timeline.js";
2
+ import type { PresenterManifest } from "./types.js";
3
+ /**
4
+ * One presenter clip's place on the scenario timeline: when it becomes
5
+ * visible (its step's start) and how long it plays.
6
+ *
7
+ * A window never outlives its step — `scenar presenter` writes clip
8
+ * durations from the narration manifest, and step timing already waits
9
+ * for narration (`max(delayMs, narration duration)`), so the clip fits
10
+ * by construction. When the step outlives the clip (a long `delayMs`),
11
+ * the frame fades out at clip end (see `presenterOpacityAt`).
12
+ */
13
+ export interface PresenterWindow {
14
+ /** Index into the EXPANDED step list (same domain as `stepTimeline`). */
15
+ readonly stepIndex: number;
16
+ /** Clip start in scenario time — the step's start, in milliseconds. */
17
+ readonly startMs: number;
18
+ /** Clip length in milliseconds. */
19
+ readonly clipDurationMs: number;
20
+ }
21
+ /**
22
+ * Derive every presenter clip's timeline window from the (expanded,
23
+ * card-padded) presenter manifest and the step timeline computed over
24
+ * the same expanded steps.
25
+ *
26
+ * This is the one implementation both outputs consume: the browser
27
+ * player uses windows for expected-position math in its drift
28
+ * corrections; the video export converts `startMs` to frames for
29
+ * Sequence placement. Pure function — same inputs, same windows, in
30
+ * both time domains.
31
+ *
32
+ * Manifest entries beyond the timeline's step count are ignored (a
33
+ * stale manifest degrades, exactly as narration does).
34
+ */
35
+ export declare function derivePresenterTimeline(presenterManifest: PresenterManifest | undefined, stepTimeline: StepTimeline): readonly PresenterWindow[];
36
+ //# sourceMappingURL=derive-presenter-timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive-presenter-timeline.d.ts","sourceRoot":"","sources":["../../src/presenter/derive-presenter-timeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mCAAmC;IACnC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAChD,YAAY,EAAE,YAAY,GACzB,SAAS,eAAe,EAAE,CAc5B"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Derive every presenter clip's timeline window from the (expanded,
3
+ * card-padded) presenter manifest and the step timeline computed over
4
+ * the same expanded steps.
5
+ *
6
+ * This is the one implementation both outputs consume: the browser
7
+ * player uses windows for expected-position math in its drift
8
+ * corrections; the video export converts `startMs` to frames for
9
+ * Sequence placement. Pure function — same inputs, same windows, in
10
+ * both time domains.
11
+ *
12
+ * Manifest entries beyond the timeline's step count are ignored (a
13
+ * stale manifest degrades, exactly as narration does).
14
+ */
15
+ export function derivePresenterTimeline(presenterManifest, stepTimeline) {
16
+ if (!presenterManifest)
17
+ return [];
18
+ const windows = [];
19
+ for (let i = 0; i < stepTimeline.stepStartTimesMs.length; i++) {
20
+ const entry = presenterManifest.steps[i];
21
+ if (!entry)
22
+ continue;
23
+ windows.push({
24
+ stepIndex: i,
25
+ startMs: stepTimeline.stepStartTimesMs[i],
26
+ clipDurationMs: entry.durationMs,
27
+ });
28
+ }
29
+ return windows;
30
+ }
31
+ //# sourceMappingURL=derive-presenter-timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive-presenter-timeline.js","sourceRoot":"","sources":["../../src/presenter/derive-presenter-timeline.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CACrC,iBAAgD,EAChD,YAA0B;IAE1B,IAAI,CAAC,iBAAiB;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9D,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,OAAO,CAAC,IAAI,CAAC;YACX,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAE;YAC1C,cAAc,EAAE,KAAK,CAAC,UAAU;SACjC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The presenter frame's fade treatment, as a pure function of time —
3
+ * so the browser player and the video export render the identical
4
+ * fade from the same math (one implementation, both time domains).
5
+ */
6
+ /**
7
+ * Fade length at each end of a presenter clip, in milliseconds.
8
+ *
9
+ * The fade-in doubles as the swap treatment: it absorbs the measured
10
+ * src-swap pop-in (≤133 ms worst case across browsers), so no
11
+ * double-buffering machinery is needed. The fade-out is the exit
12
+ * grammar — the presenter finishes and steps aside, rather than
13
+ * freezing mid-gesture when the step outlives the clip.
14
+ */
15
+ export declare const PRESENTER_FADE_MS = 200;
16
+ /**
17
+ * The presenter frame's opacity at `intraStepMs` milliseconds into its
18
+ * step, for a clip of `clipDurationMs`.
19
+ *
20
+ * Ramps 0→1 over the first {@link PRESENTER_FADE_MS}, holds 1, ramps
21
+ * 1→0 over the last {@link PRESENTER_FADE_MS}, and is 0 outside the
22
+ * clip (before its start, and for the remainder of a step that
23
+ * outlives it). Clips shorter than two fades never reach full
24
+ * opacity — the ramps intersect at the midpoint, keeping the curve
25
+ * continuous.
26
+ *
27
+ * Reduced-motion is a consumer concern: the browser player hides the
28
+ * presenter entirely under `prefers-reduced-motion`, and the export
29
+ * has no such media query — neither needs a flag here.
30
+ */
31
+ export declare function presenterOpacityAt(intraStepMs: number, clipDurationMs: number): number;
32
+ //# sourceMappingURL=presenter-opacity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter-opacity.d.ts","sourceRoot":"","sources":["../../src/presenter/presenter-opacity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,MAAM,CAOR"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The presenter frame's fade treatment, as a pure function of time —
3
+ * so the browser player and the video export render the identical
4
+ * fade from the same math (one implementation, both time domains).
5
+ */
6
+ /**
7
+ * Fade length at each end of a presenter clip, in milliseconds.
8
+ *
9
+ * The fade-in doubles as the swap treatment: it absorbs the measured
10
+ * src-swap pop-in (≤133 ms worst case across browsers), so no
11
+ * double-buffering machinery is needed. The fade-out is the exit
12
+ * grammar — the presenter finishes and steps aside, rather than
13
+ * freezing mid-gesture when the step outlives the clip.
14
+ */
15
+ export const PRESENTER_FADE_MS = 200;
16
+ /**
17
+ * The presenter frame's opacity at `intraStepMs` milliseconds into its
18
+ * step, for a clip of `clipDurationMs`.
19
+ *
20
+ * Ramps 0→1 over the first {@link PRESENTER_FADE_MS}, holds 1, ramps
21
+ * 1→0 over the last {@link PRESENTER_FADE_MS}, and is 0 outside the
22
+ * clip (before its start, and for the remainder of a step that
23
+ * outlives it). Clips shorter than two fades never reach full
24
+ * opacity — the ramps intersect at the midpoint, keeping the curve
25
+ * continuous.
26
+ *
27
+ * Reduced-motion is a consumer concern: the browser player hides the
28
+ * presenter entirely under `prefers-reduced-motion`, and the export
29
+ * has no such media query — neither needs a flag here.
30
+ */
31
+ export function presenterOpacityAt(intraStepMs, clipDurationMs) {
32
+ if (clipDurationMs <= 0)
33
+ return 0;
34
+ if (intraStepMs <= 0 || intraStepMs >= clipDurationMs)
35
+ return 0;
36
+ const fadeIn = intraStepMs / PRESENTER_FADE_MS;
37
+ const fadeOut = (clipDurationMs - intraStepMs) / PRESENTER_FADE_MS;
38
+ return Math.min(fadeIn, fadeOut, 1);
39
+ }
40
+ //# sourceMappingURL=presenter-opacity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter-opacity.js","sourceRoot":"","sources":["../../src/presenter/presenter-opacity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,cAAsB;IAEtB,IAAI,cAAc,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,cAAc;QAAE,OAAO,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,WAAW,GAAG,iBAAiB,CAAC;IAC/C,MAAM,OAAO,GAAG,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,iBAAiB,CAAC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Runtime presenter clip data produced by `scenar presenter`.
3
+ *
4
+ * The presenter track is structurally a second narration pipeline:
5
+ * generation happens at compile time (the CLI calls the avatar
6
+ * provider once and stores the result), and playback consumes fixed
7
+ * assets through a positional manifest. Playback never calls an AI
8
+ * service — a scenario whose clips have not been generated yet simply
9
+ * plays without the presenter.
10
+ *
11
+ * Deliberately its own type, not a generic "clip manifest" shared with
12
+ * narration: the two are structurally identical today, but their doc
13
+ * contracts differ, and that difference IS the domain knowledge.
14
+ */
15
+ /** A single presenter clip for one scenario step. */
16
+ export interface PresenterEntry {
17
+ /**
18
+ * URL of the clip, relative to the manifest's own location
19
+ * (e.g. "./step-2.mp4") — the same convention narration uses.
20
+ */
21
+ readonly src: string;
22
+ /**
23
+ * Duration of the clip in milliseconds. Written from the narration
24
+ * manifest's duration for the same step (the clip is lip-synced to
25
+ * that audio and matches it exactly), so presenter timing and
26
+ * narration timing can never disagree.
27
+ */
28
+ readonly durationMs: number;
29
+ }
30
+ /**
31
+ * Per-scenario manifest mapping step indices to presenter clips.
32
+ *
33
+ * Array position corresponds to the AUTHORED step index — like the
34
+ * narration manifest, it never knows about synthesized title-card
35
+ * steps. Bundle assembly (`applyTitleCards`) pads `null` entries at
36
+ * injected card positions so the expanded manifest lines up with the
37
+ * expanded steps; cards never show the presenter.
38
+ *
39
+ * Steps without a presenter (not opted in, or generation failed and
40
+ * playback degrades per-step) use `null`.
41
+ */
42
+ export interface PresenterManifest {
43
+ readonly steps: readonly (PresenterEntry | null)[];
44
+ }
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/presenter/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC;CACpD"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Runtime presenter clip data produced by `scenar presenter`.
3
+ *
4
+ * The presenter track is structurally a second narration pipeline:
5
+ * generation happens at compile time (the CLI calls the avatar
6
+ * provider once and stores the result), and playback consumes fixed
7
+ * assets through a positional manifest. Playback never calls an AI
8
+ * service — a scenario whose clips have not been generated yet simply
9
+ * plays without the presenter.
10
+ *
11
+ * Deliberately its own type, not a generic "clip manifest" shared with
12
+ * narration: the two are structurally identical today, but their doc
13
+ * contracts differ, and that difference IS the domain knowledge.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/presenter/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Card synthesis: expand a scenario's steps (and narration manifest)
3
+ * with its configured intro/outro title cards.
4
+ *
5
+ * This is THE one place card steps are constructed. It runs exactly
6
+ * once per playback surface, at bundle assembly — the generated render
7
+ * and pack entries, the CLI's `loadBundle`, and (for direct React
8
+ * integrators) one documented call between `createScenario()` and the
9
+ * player. Authoring surfaces (`createScenario`, `loadScenarioFromProto`)
10
+ * carry the `titleCards` config through untouched, exactly like
11
+ * `soundtrack` — so expanded output never carries the config and double
12
+ * expansion is impossible by data flow.
13
+ *
14
+ * The positional manifests stay keyed to AUTHORED steps everywhere
15
+ * (`scenar narrate` and `scenar presenter` never see cards); this
16
+ * function pads `null` entries at the injected positions — narration
17
+ * and presenter in the same single pass — so the expanded manifests
18
+ * line up with the expanded steps. Existing manifests therefore stay
19
+ * valid when an author adds cards later — no regeneration required.
20
+ */
21
+ import type { NarrationManifest } from "../narration/types.js";
22
+ import type { PresenterManifest } from "../presenter/types.js";
23
+ import type { ScenarioStep } from "./types.js";
24
+ import { type TitleCards } from "./title-cards.js";
25
+ /** The result of card expansion: steps and manifests, index-aligned. */
26
+ export interface AppliedTitleCards<T> {
27
+ readonly steps: readonly ScenarioStep<T>[];
28
+ readonly narrationManifest: NarrationManifest | undefined;
29
+ readonly presenterManifest: PresenterManifest | undefined;
30
+ }
31
+ /**
32
+ * Expand `steps` (and the index-parallel narration and presenter
33
+ * manifests, when they exist) with the configured intro/outro cards.
34
+ *
35
+ * - **Intro**: prepended at index 0 with `delayMs: 0`; the card's
36
+ * visible time is encoded as the following step's transition delay
37
+ * (`max(authored delayMs, card duration)`), which is exactly how
38
+ * `computeStepTimeline` reads step 0's duration.
39
+ * - **Outro**: appended with `delayMs: FINAL_DWELL_MS`, so the last
40
+ * authored step keeps precisely the closing dwell it has today (or
41
+ * its narration, whichever is longer) before the card appears. The
42
+ * card's own visible time is its `durationMs` — `computeStepTimeline`
43
+ * reads a final card step's duration as the closing dwell. The outro
44
+ * carries two housekeeping interactions at step entry (`clear_cursor`
45
+ * and a viewport reset) so a scenario ending with a visible cursor or
46
+ * an active zoom never leaks that state onto the card. Neither action
47
+ * maps to a sound effect.
48
+ *
49
+ * Pure and non-mutating. When `titleCards` configures no card, the
50
+ * inputs are returned as-is (byte-identical no-op).
51
+ */
52
+ export declare function applyTitleCards<T>(steps: readonly ScenarioStep<T>[], narrationManifest: NarrationManifest | undefined, titleCards: TitleCards | undefined, presenterManifest?: PresenterManifest): AppliedTitleCards<T>;
53
+ //# sourceMappingURL=apply-title-cards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-title-cards.d.ts","sourceRoot":"","sources":["../../src/scenario/apply-title-cards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAE1B,wEAAwE;AACxE,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC3D;AAYD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,EACjC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAChD,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,iBAAiB,CAAC,CAAC,CAAC,CA8CtB"}