@unseenco/theatre-core 0.4.3 → 0.6.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.
package/dist/index.js CHANGED
@@ -241,34 +241,88 @@ var require_propose = __commonJS({
241
241
  // core/src/index.ts
242
242
  var index_exports = {};
243
243
  __export(index_exports, {
244
+ PAGE_MODE_SEQUENCE_LENGTH: () => PAGE_MODE_SEQUENCE_LENGTH,
245
+ PAGE_MODE_SUB_UNITS_PER_UNIT: () => PAGE_MODE_SUB_UNITS_PER_UNIT,
244
246
  attachGsapSequenceBridge: () => attachGsapSequenceBridge,
247
+ attachSheetScrollDriver: () => attachSheetScrollDriver,
248
+ attachTheatrePageScroll: () => attachTheatrePageScroll,
249
+ configureTheatrePageScroll: () => configureTheatrePageScroll,
250
+ createDefaultPageScrollDriver: () => createDefaultPageScrollDriver,
251
+ createElementHorizontalScrollDriver: () => createElementHorizontalScrollDriver,
252
+ createElementScrollDriver: () => createElementScrollDriver,
253
+ createNativeDocumentHorizontalScrollDriver: () => createNativeDocumentHorizontalScrollDriver,
254
+ createNativeDocumentScrollDriver: () => createNativeDocumentScrollDriver,
245
255
  createRafDriver: () => createRafDriver,
256
+ defaultPageScrollContext: () => defaultPageScrollContext,
257
+ getActivePageScrollContext: () => getActivePageScrollContext,
246
258
  getProject: () => getProject,
259
+ getSheetScrollDriver: () => getSheetScrollDriver,
260
+ getTheatreCoreRafDriver: () => getTheatreCoreRafDriver,
261
+ getTheatrePageScrollConfig: () => getTheatrePageScrollConfig,
262
+ getTheatrePageScrollContext: () => getTheatrePageScrollContext,
263
+ isNativeDocumentScroller: () => isNativeDocumentScroller,
264
+ isPageScrollTrigger: () => isPageScrollTrigger,
247
265
  isRemoteEditorWindow: () => isRemoteEditorWindow,
266
+ isVerticalPageScrollTrigger: () => isVerticalPageScrollTrigger,
248
267
  notify: () => notify,
249
268
  onChange: () => onChange,
269
+ pageScrollProgressFromSequence: () => pageScrollProgressFromSequence,
270
+ pageScrollScrollersMatch: () => pageScrollScrollersMatch,
250
271
  privateAPI: () => privateAPI,
272
+ resolvePageScrollAxis: () => resolvePageScrollAxis,
273
+ resolvePageScrollScroller: () => resolvePageScrollScroller,
274
+ setActivePageScrollContext: () => setActivePageScrollContext,
251
275
  setCoreRafDriver: () => setCoreRafDriver,
276
+ setPageScrollProgress: () => setPageScrollProgress,
252
277
  setPrivateAPI: () => setPrivateAPI,
278
+ syncNativeDocumentScrollToSequencePosition: () => syncNativeDocumentScrollToSequencePosition,
279
+ syncPageScrollToSequencePosition: () => syncPageScrollToSequencePosition,
253
280
  types: () => propTypes_exports,
254
- val: () => val11
281
+ val: () => val14
255
282
  });
256
283
  module.exports = __toCommonJS(index_exports);
257
284
 
258
285
  // core/src/coreExports.ts
259
286
  var coreExports_exports = {};
260
287
  __export(coreExports_exports, {
288
+ PAGE_MODE_SEQUENCE_LENGTH: () => PAGE_MODE_SEQUENCE_LENGTH,
289
+ PAGE_MODE_SUB_UNITS_PER_UNIT: () => PAGE_MODE_SUB_UNITS_PER_UNIT,
261
290
  attachGsapSequenceBridge: () => attachGsapSequenceBridge,
291
+ attachSheetScrollDriver: () => attachSheetScrollDriver,
292
+ attachTheatrePageScroll: () => attachTheatrePageScroll,
293
+ configureTheatrePageScroll: () => configureTheatrePageScroll,
294
+ createDefaultPageScrollDriver: () => createDefaultPageScrollDriver,
295
+ createElementHorizontalScrollDriver: () => createElementHorizontalScrollDriver,
296
+ createElementScrollDriver: () => createElementScrollDriver,
297
+ createNativeDocumentHorizontalScrollDriver: () => createNativeDocumentHorizontalScrollDriver,
298
+ createNativeDocumentScrollDriver: () => createNativeDocumentScrollDriver,
262
299
  createRafDriver: () => createRafDriver,
300
+ defaultPageScrollContext: () => defaultPageScrollContext,
301
+ getActivePageScrollContext: () => getActivePageScrollContext,
263
302
  getProject: () => getProject,
303
+ getSheetScrollDriver: () => getSheetScrollDriver,
304
+ getTheatreCoreRafDriver: () => getTheatreCoreRafDriver,
305
+ getTheatrePageScrollConfig: () => getTheatrePageScrollConfig,
306
+ getTheatrePageScrollContext: () => getTheatrePageScrollContext,
307
+ isNativeDocumentScroller: () => isNativeDocumentScroller,
308
+ isPageScrollTrigger: () => isPageScrollTrigger,
264
309
  isRemoteEditorWindow: () => isRemoteEditorWindow,
310
+ isVerticalPageScrollTrigger: () => isVerticalPageScrollTrigger,
265
311
  notify: () => notify,
266
312
  onChange: () => onChange,
313
+ pageScrollProgressFromSequence: () => pageScrollProgressFromSequence,
314
+ pageScrollScrollersMatch: () => pageScrollScrollersMatch,
267
315
  privateAPI: () => privateAPI,
316
+ resolvePageScrollAxis: () => resolvePageScrollAxis,
317
+ resolvePageScrollScroller: () => resolvePageScrollScroller,
318
+ setActivePageScrollContext: () => setActivePageScrollContext,
268
319
  setCoreRafDriver: () => setCoreRafDriver,
320
+ setPageScrollProgress: () => setPageScrollProgress,
269
321
  setPrivateAPI: () => setPrivateAPI,
322
+ syncNativeDocumentScrollToSequencePosition: () => syncNativeDocumentScrollToSequencePosition,
323
+ syncPageScrollToSequencePosition: () => syncPageScrollToSequencePosition,
270
324
  types: () => propTypes_exports,
271
- val: () => val11
325
+ val: () => val14
272
326
  });
273
327
 
274
328
  // core/src/projects/projectsSingleton.ts
@@ -293,6 +347,82 @@ var ProjectsSingleton = class {
293
347
  var singleton = new ProjectsSingleton();
294
348
  var projectsSingleton_default = singleton;
295
349
 
350
+ // core/src/rafDrivers.ts
351
+ var import_theatre_dataverse2 = require("@unseenco/theatre-dataverse");
352
+ var lastDriverId = 0;
353
+ function createRafDriver(conf) {
354
+ const tick = (time) => {
355
+ ticker.tick(time);
356
+ };
357
+ const ticker = new import_theatre_dataverse2.Ticker({
358
+ onActive() {
359
+ conf?.start?.();
360
+ },
361
+ onDormant() {
362
+ conf?.stop?.();
363
+ }
364
+ });
365
+ const driverPublicApi = {
366
+ tick,
367
+ id: lastDriverId++,
368
+ name: conf?.name ?? "CustomRafDriver-".concat(lastDriverId),
369
+ type: "Theatre_RafDriver_PublicAPI"
370
+ };
371
+ const driverPrivateApi = {
372
+ type: "Theatre_RafDriver_PrivateAPI",
373
+ publicApi: driverPublicApi,
374
+ ticker,
375
+ start: conf?.start,
376
+ stop: conf?.stop
377
+ };
378
+ setPrivateAPI(driverPublicApi, driverPrivateApi);
379
+ return driverPublicApi;
380
+ }
381
+
382
+ // core/src/coreTicker.ts
383
+ function createBasicRafDriver() {
384
+ let rafId = null;
385
+ const start = () => {
386
+ if (typeof window !== "undefined") {
387
+ const onAnimationFrame = (t2) => {
388
+ driver.tick(t2);
389
+ rafId = window.requestAnimationFrame(onAnimationFrame);
390
+ };
391
+ rafId = window.requestAnimationFrame(onAnimationFrame);
392
+ } else {
393
+ driver.tick(0);
394
+ setTimeout(() => driver.tick(1), 0);
395
+ }
396
+ };
397
+ const stop = () => {
398
+ if (typeof window !== "undefined") {
399
+ if (rafId !== null) {
400
+ window.cancelAnimationFrame(rafId);
401
+ }
402
+ } else {
403
+ }
404
+ };
405
+ const driver = createRafDriver({ name: "DefaultCoreRafDriver", start, stop });
406
+ return driver;
407
+ }
408
+ var coreRafDriver;
409
+ function getCoreRafDriver() {
410
+ if (!coreRafDriver) {
411
+ setCoreRafDriver(createBasicRafDriver());
412
+ }
413
+ return coreRafDriver;
414
+ }
415
+ function getCoreTicker() {
416
+ return getCoreRafDriver().ticker;
417
+ }
418
+ function setCoreRafDriver(driver) {
419
+ if (coreRafDriver) {
420
+ throw new Error("`setCoreRafDriver()` is already called.");
421
+ }
422
+ const driverPrivateApi = privateAPI(driver);
423
+ coreRafDriver = driverPrivateApi;
424
+ }
425
+
296
426
  // core/src/privateAPIs.ts
297
427
  var publicAPIToPrivateAPIMap = /* @__PURE__ */ new WeakMap();
298
428
  function privateAPI(pub) {
@@ -301,6 +431,23 @@ function privateAPI(pub) {
301
431
  function setPrivateAPI(pub, priv) {
302
432
  publicAPIToPrivateAPIMap.set(pub, priv);
303
433
  }
434
+ function getTheatreCoreRafDriver() {
435
+ return getCoreRafDriver().publicApi;
436
+ }
437
+
438
+ // core/src/sheets/applySheetRuntimeOptions.ts
439
+ function applySheetRuntimeOptions(sheet, opts) {
440
+ if (!opts) return;
441
+ if (opts.sequenceMode !== void 0) {
442
+ sheet.setSequenceMode(opts.sequenceMode);
443
+ }
444
+ if (opts.scrollDriver !== void 0) {
445
+ sheet.setPageScrollDriver(opts.scrollDriver);
446
+ }
447
+ if (opts.gsap === true) {
448
+ sheet.enableGsapSequenceBridge();
449
+ }
450
+ }
304
451
 
305
452
  // shared/src/utils/index.ts
306
453
  var emptyArray = [];
@@ -867,7 +1014,7 @@ var SimpleCache = class {
867
1014
  };
868
1015
 
869
1016
  // core/src/sheetObjects/SheetObjectTemplate.ts
870
- var import_theatre_dataverse7 = require("@unseenco/theatre-dataverse");
1017
+ var import_theatre_dataverse9 = require("@unseenco/theatre-dataverse");
871
1018
 
872
1019
  // ../node_modules/lodash-es/_defineProperty.js
873
1020
  var defineProperty = (function() {
@@ -978,181 +1125,6 @@ function generateDefaultsForCompound(config) {
978
1125
  return defaults;
979
1126
  }
980
1127
 
981
- // core/src/sequences/interpolationTripleAtPosition.ts
982
- var import_theatre_dataverse2 = require("@unseenco/theatre-dataverse");
983
- var import_UnitBezier = __toESM(require_UnitBezier());
984
- function interpolationTripleAtPosition(ctx, trackP, timeD) {
985
- return (0, import_theatre_dataverse2.prism)(() => {
986
- const track = (0, import_theatre_dataverse2.val)(trackP);
987
- const driverD = import_theatre_dataverse2.prism.memo(
988
- "driver",
989
- () => {
990
- if (!track) {
991
- return (0, import_theatre_dataverse2.prism)(() => void 0);
992
- } else if (track.type === "BasicKeyframedTrack") {
993
- return _forKeyframedTrack(ctx, track, timeD);
994
- } else if (track.type === "GsapClipTrack") {
995
- return (0, import_theatre_dataverse2.prism)(() => void 0);
996
- } else {
997
- ctx.logger.error("Track type not yet supported.");
998
- return (0, import_theatre_dataverse2.prism)(() => void 0);
999
- }
1000
- },
1001
- [track]
1002
- );
1003
- return driverD.getValue();
1004
- });
1005
- }
1006
- function _forKeyframedTrack(ctx, track, timeD) {
1007
- return (0, import_theatre_dataverse2.prism)(() => {
1008
- let stateRef = import_theatre_dataverse2.prism.ref("state", { started: false });
1009
- let state = stateRef.current;
1010
- const time = timeD.getValue();
1011
- if (!state.started || time < state.validFrom || state.validTo <= time) {
1012
- stateRef.current = state = updateState(ctx, timeD, track);
1013
- }
1014
- return state.der.getValue();
1015
- });
1016
- }
1017
- var undefinedConstD = (0, import_theatre_dataverse2.prism)(() => void 0);
1018
- function updateState(ctx, progressionD, track) {
1019
- const progression = progressionD.getValue();
1020
- if (track.keyframes.length === 0) {
1021
- return {
1022
- started: true,
1023
- validFrom: -Infinity,
1024
- validTo: Infinity,
1025
- der: undefinedConstD
1026
- };
1027
- }
1028
- let currentKeyframeIndex = 0;
1029
- while (true) {
1030
- const currentKeyframe = track.keyframes[currentKeyframeIndex];
1031
- if (!currentKeyframe) {
1032
- if (process.env.NODE_ENV !== "production") {
1033
- ctx.logger.error("Bug here");
1034
- }
1035
- return states.error;
1036
- }
1037
- const isLastKeyframe = currentKeyframeIndex === track.keyframes.length - 1;
1038
- if (progression < currentKeyframe.position) {
1039
- if (currentKeyframeIndex === 0) {
1040
- return states.beforeFirstKeyframe(currentKeyframe);
1041
- } else {
1042
- if (process.env.NODE_ENV !== "production") {
1043
- ctx.logger.error("Bug here");
1044
- }
1045
- return states.error;
1046
- }
1047
- } else if (currentKeyframe.position === progression) {
1048
- if (isLastKeyframe) {
1049
- return states.lastKeyframe(currentKeyframe);
1050
- } else {
1051
- return states.between(
1052
- currentKeyframe,
1053
- track.keyframes[currentKeyframeIndex + 1],
1054
- progressionD
1055
- );
1056
- }
1057
- } else {
1058
- if (currentKeyframeIndex === track.keyframes.length - 1) {
1059
- return states.lastKeyframe(currentKeyframe);
1060
- } else {
1061
- const nextKeyframeIndex = currentKeyframeIndex + 1;
1062
- if (track.keyframes[nextKeyframeIndex].position <= progression) {
1063
- currentKeyframeIndex = nextKeyframeIndex;
1064
- continue;
1065
- } else {
1066
- return states.between(
1067
- currentKeyframe,
1068
- track.keyframes[currentKeyframeIndex + 1],
1069
- progressionD
1070
- );
1071
- }
1072
- }
1073
- }
1074
- }
1075
- }
1076
- var states = {
1077
- beforeFirstKeyframe(kf) {
1078
- return {
1079
- started: true,
1080
- validFrom: -Infinity,
1081
- validTo: kf.position,
1082
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: kf.value, progression: 0 }))
1083
- };
1084
- },
1085
- lastKeyframe(kf) {
1086
- return {
1087
- started: true,
1088
- validFrom: kf.position,
1089
- validTo: Infinity,
1090
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: kf.value, progression: 0 }))
1091
- };
1092
- },
1093
- between(left, right, progressionD) {
1094
- if (!left.connectedRight) {
1095
- return {
1096
- started: true,
1097
- validFrom: left.position,
1098
- validTo: right.position,
1099
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: left.value, progression: 0 }))
1100
- };
1101
- }
1102
- const globalProgressionToLocalProgression = (globalProgression) => {
1103
- return (globalProgression - left.position) / (right.position - left.position);
1104
- };
1105
- if (!left.type || left.type === "bezier") {
1106
- const solver = new import_UnitBezier.default(
1107
- left.handles[2],
1108
- left.handles[3],
1109
- right.handles[0],
1110
- right.handles[1]
1111
- );
1112
- const bezierDer = (0, import_theatre_dataverse2.prism)(() => {
1113
- const progression = globalProgressionToLocalProgression(
1114
- progressionD.getValue()
1115
- );
1116
- const valueProgression = solver.solveSimple(progression);
1117
- return {
1118
- left: left.value,
1119
- right: right.value,
1120
- progression: valueProgression
1121
- };
1122
- });
1123
- return {
1124
- started: true,
1125
- validFrom: left.position,
1126
- validTo: right.position,
1127
- der: bezierDer
1128
- };
1129
- }
1130
- const holdDer = (0, import_theatre_dataverse2.prism)(() => {
1131
- const progression = globalProgressionToLocalProgression(
1132
- progressionD.getValue()
1133
- );
1134
- const valueProgression = Math.floor(progression);
1135
- return {
1136
- left: left.value,
1137
- right: right.value,
1138
- progression: valueProgression
1139
- };
1140
- });
1141
- return {
1142
- started: true,
1143
- validFrom: left.position,
1144
- validTo: right.position,
1145
- der: holdDer
1146
- };
1147
- },
1148
- error: {
1149
- started: true,
1150
- validFrom: -Infinity,
1151
- validTo: Infinity,
1152
- der: undefinedConstD
1153
- }
1154
- };
1155
-
1156
1128
  // shared/src/utils/deepMergeWithCache.ts
1157
1129
  function deepMergeWithCache(base, override, cache2) {
1158
1130
  const _cache = cache2;
@@ -1192,7 +1164,7 @@ var valToAtom = (key, vals) => {
1192
1164
  };
1193
1165
 
1194
1166
  // core/src/sheetObjects/SheetObject.ts
1195
- var import_theatre_dataverse6 = require("@unseenco/theatre-dataverse");
1167
+ var import_theatre_dataverse8 = require("@unseenco/theatre-dataverse");
1196
1168
 
1197
1169
  // core/src/sheetObjects/TheatreSheetObject.ts
1198
1170
  var import_theatre_dataverse4 = require("@unseenco/theatre-dataverse");
@@ -3236,11 +3208,11 @@ function sanitizeCompoundProps(props) {
3236
3208
  );
3237
3209
  }
3238
3210
  }
3239
- const val12 = props[key];
3240
- if (isLonghandPropType(val12)) {
3241
- sanitizedProps[key] = val12;
3211
+ const val15 = props[key];
3212
+ if (isLonghandPropType(val15)) {
3213
+ sanitizedProps[key] = val15;
3242
3214
  } else {
3243
- sanitizedProps[key] = toLonghandProp(val12);
3215
+ sanitizedProps[key] = toLonghandProp(val15);
3244
3216
  }
3245
3217
  }
3246
3218
  return sanitizedProps;
@@ -3338,15 +3310,15 @@ var file = (defaultValue, opts = {}) => {
3338
3310
  deserializeAndSanitize: _ensureFile
3339
3311
  };
3340
3312
  };
3341
- var _ensureFile = (val12) => {
3342
- if (!val12) return void 0;
3313
+ var _ensureFile = (val15) => {
3314
+ if (!val15) return void 0;
3343
3315
  let valid = true;
3344
- if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3316
+ if (typeof val15.id !== "string" && ![null, void 0].includes(val15.id)) {
3345
3317
  valid = false;
3346
3318
  }
3347
- if (val12.type !== "file") valid = false;
3319
+ if (val15.type !== "file") valid = false;
3348
3320
  if (!valid) return void 0;
3349
- return val12;
3321
+ return val15;
3350
3322
  };
3351
3323
  var image = (defaultValue, opts = {}) => {
3352
3324
  if (process.env.NODE_ENV !== "production") {
@@ -3370,15 +3342,15 @@ var image = (defaultValue, opts = {}) => {
3370
3342
  deserializeAndSanitize: _ensureImage
3371
3343
  };
3372
3344
  };
3373
- var _ensureImage = (val12) => {
3374
- if (!val12) return void 0;
3345
+ var _ensureImage = (val15) => {
3346
+ if (!val15) return void 0;
3375
3347
  let valid = true;
3376
- if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3348
+ if (typeof val15.id !== "string" && ![null, void 0].includes(val15.id)) {
3377
3349
  valid = false;
3378
3350
  }
3379
- if (val12.type !== "image") valid = false;
3351
+ if (val15.type !== "image") valid = false;
3380
3352
  if (!valid) return void 0;
3381
- return val12;
3353
+ return val15;
3382
3354
  };
3383
3355
  var number = (defaultValue, opts = {}) => {
3384
3356
  if (process.env.NODE_ENV !== "production") {
@@ -3501,11 +3473,11 @@ var rgba = (defaultValue = { r: 0, g: 0, b: 0, a: 1 }, opts = {}) => {
3501
3473
  deserializeAndSanitize: _sanitizeRgba
3502
3474
  };
3503
3475
  };
3504
- var _sanitizeRgba = (val12) => {
3505
- if (!val12) return void 0;
3476
+ var _sanitizeRgba = (val15) => {
3477
+ if (!val15) return void 0;
3506
3478
  let valid = true;
3507
3479
  for (const c2 of ["r", "g", "b", "a"]) {
3508
- if (!Object.prototype.hasOwnProperty.call(val12, c2) || typeof val12[c2] !== "number") {
3480
+ if (!Object.prototype.hasOwnProperty.call(val15, c2) || typeof val15[c2] !== "number") {
3509
3481
  valid = false;
3510
3482
  }
3511
3483
  }
@@ -3514,7 +3486,7 @@ var _sanitizeRgba = (val12) => {
3514
3486
  for (const c2 of ["r", "g", "b", "a"]) {
3515
3487
  ;
3516
3488
  sanitized[c2] = Math.min(
3517
- Math.max(val12[c2], 0),
3489
+ Math.max(val15[c2], 0),
3518
3490
  1
3519
3491
  );
3520
3492
  }
@@ -3553,8 +3525,8 @@ var boolean = (defaultValue, opts = {}) => {
3553
3525
  deserializeAndSanitize: _ensureBoolean
3554
3526
  };
3555
3527
  };
3556
- var _ensureBoolean = (val12) => {
3557
- return typeof val12 === "boolean" ? val12 : void 0;
3528
+ var _ensureBoolean = (val15) => {
3529
+ return typeof val15 === "boolean" ? val15 : void 0;
3558
3530
  };
3559
3531
  function leftInterpolate(left) {
3560
3532
  return left;
@@ -3761,8 +3733,8 @@ var TheatreSheetObject = class {
3761
3733
  }
3762
3734
  return der.getValue();
3763
3735
  }
3764
- set initialValue(val12) {
3765
- privateAPI(this).setInitialValue(val12);
3736
+ set initialValue(val15) {
3737
+ privateAPI(this).setInitialValue(val15);
3766
3738
  }
3767
3739
  showPropsOf(objects) {
3768
3740
  const host = privateAPI(this);
@@ -3802,16 +3774,194 @@ var TheatreSheetObject = class {
3802
3774
  }
3803
3775
  };
3804
3776
 
3805
- // shared/src/propTypes/utils.ts
3806
- var import_fast_deep_equal = __toESM(require_fast_deep_equal());
3807
-
3808
- // shared/src/utils/memoizeFn.ts
3809
- function memoizeFn(producer) {
3810
- const cache2 = /* @__PURE__ */ new WeakMap();
3811
- return (k2) => {
3812
- if (!cache2.has(k2)) {
3813
- cache2.set(k2, producer(k2));
3814
- }
3777
+ // core/src/sequences/interpolationTripleAtPosition.ts
3778
+ var import_theatre_dataverse5 = require("@unseenco/theatre-dataverse");
3779
+ var import_UnitBezier = __toESM(require_UnitBezier());
3780
+ function interpolationTripleAtPosition(ctx, trackP, timeD) {
3781
+ return (0, import_theatre_dataverse5.prism)(() => {
3782
+ const track = (0, import_theatre_dataverse5.val)(trackP);
3783
+ const driverD = import_theatre_dataverse5.prism.memo(
3784
+ "driver",
3785
+ () => {
3786
+ if (!track) {
3787
+ return (0, import_theatre_dataverse5.prism)(() => void 0);
3788
+ } else if (track.type === "BasicKeyframedTrack") {
3789
+ return _forKeyframedTrack(ctx, track, timeD);
3790
+ } else if (track.type === "GsapClipTrack") {
3791
+ return (0, import_theatre_dataverse5.prism)(() => void 0);
3792
+ } else {
3793
+ ctx.logger.error("Track type not yet supported.");
3794
+ return (0, import_theatre_dataverse5.prism)(() => void 0);
3795
+ }
3796
+ },
3797
+ [track]
3798
+ );
3799
+ return driverD.getValue();
3800
+ });
3801
+ }
3802
+ function _forKeyframedTrack(ctx, track, timeD) {
3803
+ return (0, import_theatre_dataverse5.prism)(() => {
3804
+ let stateRef = import_theatre_dataverse5.prism.ref("state", { started: false });
3805
+ let state = stateRef.current;
3806
+ const time = timeD.getValue();
3807
+ if (!state.started || time < state.validFrom || state.validTo <= time) {
3808
+ stateRef.current = state = updateState(ctx, timeD, track);
3809
+ }
3810
+ return state.der.getValue();
3811
+ });
3812
+ }
3813
+ var undefinedConstD = (0, import_theatre_dataverse5.prism)(() => void 0);
3814
+ function updateState(ctx, progressionD, track) {
3815
+ const progression = progressionD.getValue();
3816
+ if (track.keyframes.length === 0) {
3817
+ return {
3818
+ started: true,
3819
+ validFrom: -Infinity,
3820
+ validTo: Infinity,
3821
+ der: undefinedConstD
3822
+ };
3823
+ }
3824
+ let currentKeyframeIndex = 0;
3825
+ while (true) {
3826
+ const currentKeyframe = track.keyframes[currentKeyframeIndex];
3827
+ if (!currentKeyframe) {
3828
+ if (process.env.NODE_ENV !== "production") {
3829
+ ctx.logger.error("Bug here");
3830
+ }
3831
+ return states.error;
3832
+ }
3833
+ const isLastKeyframe = currentKeyframeIndex === track.keyframes.length - 1;
3834
+ if (progression < currentKeyframe.position) {
3835
+ if (currentKeyframeIndex === 0) {
3836
+ return states.beforeFirstKeyframe(currentKeyframe);
3837
+ } else {
3838
+ if (process.env.NODE_ENV !== "production") {
3839
+ ctx.logger.error("Bug here");
3840
+ }
3841
+ return states.error;
3842
+ }
3843
+ } else if (currentKeyframe.position === progression) {
3844
+ if (isLastKeyframe) {
3845
+ return states.lastKeyframe(currentKeyframe);
3846
+ } else {
3847
+ return states.between(
3848
+ currentKeyframe,
3849
+ track.keyframes[currentKeyframeIndex + 1],
3850
+ progressionD
3851
+ );
3852
+ }
3853
+ } else {
3854
+ if (currentKeyframeIndex === track.keyframes.length - 1) {
3855
+ return states.lastKeyframe(currentKeyframe);
3856
+ } else {
3857
+ const nextKeyframeIndex = currentKeyframeIndex + 1;
3858
+ if (track.keyframes[nextKeyframeIndex].position <= progression) {
3859
+ currentKeyframeIndex = nextKeyframeIndex;
3860
+ continue;
3861
+ } else {
3862
+ return states.between(
3863
+ currentKeyframe,
3864
+ track.keyframes[currentKeyframeIndex + 1],
3865
+ progressionD
3866
+ );
3867
+ }
3868
+ }
3869
+ }
3870
+ }
3871
+ }
3872
+ var states = {
3873
+ beforeFirstKeyframe(kf) {
3874
+ return {
3875
+ started: true,
3876
+ validFrom: -Infinity,
3877
+ validTo: kf.position,
3878
+ der: (0, import_theatre_dataverse5.prism)(() => ({ left: kf.value, progression: 0 }))
3879
+ };
3880
+ },
3881
+ lastKeyframe(kf) {
3882
+ return {
3883
+ started: true,
3884
+ validFrom: kf.position,
3885
+ validTo: Infinity,
3886
+ der: (0, import_theatre_dataverse5.prism)(() => ({ left: kf.value, progression: 0 }))
3887
+ };
3888
+ },
3889
+ between(left, right, progressionD) {
3890
+ if (!left.connectedRight) {
3891
+ return {
3892
+ started: true,
3893
+ validFrom: left.position,
3894
+ validTo: right.position,
3895
+ der: (0, import_theatre_dataverse5.prism)(() => ({ left: left.value, progression: 0 }))
3896
+ };
3897
+ }
3898
+ const globalProgressionToLocalProgression = (globalProgression) => {
3899
+ return (globalProgression - left.position) / (right.position - left.position);
3900
+ };
3901
+ if (!left.type || left.type === "bezier") {
3902
+ const solver = new import_UnitBezier.default(
3903
+ left.handles[2],
3904
+ left.handles[3],
3905
+ right.handles[0],
3906
+ right.handles[1]
3907
+ );
3908
+ const bezierDer = (0, import_theatre_dataverse5.prism)(() => {
3909
+ const progression = globalProgressionToLocalProgression(
3910
+ progressionD.getValue()
3911
+ );
3912
+ const valueProgression = solver.solveSimple(progression);
3913
+ return {
3914
+ left: left.value,
3915
+ right: right.value,
3916
+ progression: valueProgression
3917
+ };
3918
+ });
3919
+ return {
3920
+ started: true,
3921
+ validFrom: left.position,
3922
+ validTo: right.position,
3923
+ der: bezierDer
3924
+ };
3925
+ }
3926
+ const holdDer = (0, import_theatre_dataverse5.prism)(() => {
3927
+ const progression = globalProgressionToLocalProgression(
3928
+ progressionD.getValue()
3929
+ );
3930
+ const valueProgression = Math.floor(progression);
3931
+ return {
3932
+ left: left.value,
3933
+ right: right.value,
3934
+ progression: valueProgression
3935
+ };
3936
+ });
3937
+ return {
3938
+ started: true,
3939
+ validFrom: left.position,
3940
+ validTo: right.position,
3941
+ der: holdDer
3942
+ };
3943
+ },
3944
+ error: {
3945
+ started: true,
3946
+ validFrom: -Infinity,
3947
+ validTo: Infinity,
3948
+ der: undefinedConstD
3949
+ }
3950
+ };
3951
+
3952
+ // core/src/sheetObjects/sheetObjectSequencedFull.ts
3953
+ var import_theatre_dataverse7 = require("@unseenco/theatre-dataverse");
3954
+
3955
+ // shared/src/propTypes/utils.ts
3956
+ var import_fast_deep_equal = __toESM(require_fast_deep_equal());
3957
+
3958
+ // shared/src/utils/memoizeFn.ts
3959
+ function memoizeFn(producer) {
3960
+ const cache2 = /* @__PURE__ */ new WeakMap();
3961
+ return (k2) => {
3962
+ if (!cache2.has(k2)) {
3963
+ cache2.set(k2, producer(k2));
3964
+ }
3815
3965
  return cache2.get(k2);
3816
3966
  };
3817
3967
  }
@@ -4119,45 +4269,8 @@ function* iteratePropType(conf, pathPrefix) {
4119
4269
  }
4120
4270
  }
4121
4271
 
4122
- // shared/src/utils/updateDeep.ts
4123
- function updateDeep(obj, path, reducer) {
4124
- if (path.length === 0) return reducer(obj);
4125
- return hoop(obj, path, reducer);
4126
- }
4127
- var hoop = (s2, path, reducer) => {
4128
- if (path.length === 0) {
4129
- return reducer(s2);
4130
- }
4131
- if (Array.isArray(s2)) {
4132
- let [index, ...restOfPath] = path;
4133
- index = parseInt(String(index), 10);
4134
- if (isNaN(index)) index = 0;
4135
- const oldVal = s2[index];
4136
- const newVal = hoop(oldVal, restOfPath, reducer);
4137
- if (oldVal === newVal) return s2;
4138
- const newS = [...s2];
4139
- newS.splice(index, 1, newVal);
4140
- return newS;
4141
- } else if (typeof s2 === "object" && s2 !== null) {
4142
- const [key, ...restOfPath] = path;
4143
- const oldVal = s2[key];
4144
- const newVal = hoop(oldVal, restOfPath, reducer);
4145
- if (oldVal === newVal) return s2;
4146
- const newS = { ...s2, [key]: newVal };
4147
- return newS;
4148
- } else {
4149
- const [key, ...restOfPath] = path;
4150
- return { [key]: hoop(void 0, restOfPath, reducer) };
4151
- }
4152
- };
4153
-
4154
- // shared/src/utils/setDeepImmutable.ts
4155
- function setDeepImmutable(obj, path, replace) {
4156
- return updateDeep(obj, path, () => replace);
4157
- }
4158
-
4159
4272
  // core/src/sequences/sequenceVariants.ts
4160
- var import_theatre_dataverse5 = require("@unseenco/theatre-dataverse");
4273
+ var import_theatre_dataverse6 = require("@unseenco/theatre-dataverse");
4161
4274
 
4162
4275
  // shared/src/utils/sheetProps.ts
4163
4276
  var SHEET_PROPS_OBJECT_KEY = "__theatre_sheet_props__";
@@ -4225,17 +4338,17 @@ function getSequenceStateFromSheet(sheetState, variantId) {
4225
4338
  return void 0;
4226
4339
  }
4227
4340
  function valTrackIdByPropPathForObject(sheetStatePointer, variantId, objectKey) {
4228
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById);
4229
- const sequenceFromMap = (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId]);
4341
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById);
4342
+ const sequenceFromMap = (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId]);
4230
4343
  if (sequenceFromMap !== void 0) {
4231
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4232
- return (0, import_theatre_dataverse5.val)(
4344
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4345
+ return (0, import_theatre_dataverse6.val)(
4233
4346
  sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey]?.trackIdByPropPath
4234
4347
  );
4235
4348
  }
4236
4349
  if (variantId === DEFAULT_SEQUENCE_VARIANT) {
4237
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequence?.tracksByObject);
4238
- return (0, import_theatre_dataverse5.val)(
4350
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequence?.tracksByObject);
4351
+ return (0, import_theatre_dataverse6.val)(
4239
4352
  sheetStatePointer.sequence?.tracksByObject[objectKey]?.trackIdByPropPath
4240
4353
  );
4241
4354
  }
@@ -4243,11 +4356,11 @@ function valTrackIdByPropPathForObject(sheetStatePointer, variantId, objectKey)
4243
4356
  }
4244
4357
  function valUnsequencedPropPathsForObject(sheetStatePointer, variantId, objectKey) {
4245
4358
  if (variantId === DEFAULT_SEQUENCE_VARIANT) return void 0;
4246
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById);
4247
- const sequenceFromMap = (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId]);
4359
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById);
4360
+ const sequenceFromMap = (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId]);
4248
4361
  if (sequenceFromMap !== void 0) {
4249
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4250
- return (0, import_theatre_dataverse5.val)(
4362
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4363
+ return (0, import_theatre_dataverse6.val)(
4251
4364
  sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey]?.unsequencedPropPaths
4252
4365
  );
4253
4366
  }
@@ -4275,7 +4388,7 @@ function validateSequenceVariantIdOrThrow(value, fnName) {
4275
4388
  return idTrimmed;
4276
4389
  }
4277
4390
  function pointerToSequenceTrackData(sheetStatePointer, variantId, objectKey, trackId) {
4278
- const sheetState = (0, import_theatre_dataverse5.val)(sheetStatePointer);
4391
+ const sheetState = (0, import_theatre_dataverse6.val)(sheetStatePointer);
4279
4392
  if (sheetState?.sequencesById?.[variantId]) {
4280
4393
  return sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey].trackData[trackId];
4281
4394
  }
@@ -4309,54 +4422,186 @@ function validateSequenceVariantsOrThrow(variants, fnName) {
4309
4422
  return sanitized;
4310
4423
  }
4311
4424
 
4312
- // core/src/sheetObjects/SheetObject.ts
4313
- var SheetObject = class {
4314
- constructor(sheet, template, nativeObject) {
4315
- this.sheet = sheet;
4316
- this.template = template;
4317
- this.nativeObject = nativeObject;
4318
- __publicField(this, "$$isPointerToPrismProvider", true);
4319
- __publicField(this, "address");
4320
- __publicField(this, "publicApi");
4321
- __publicField(this, "_initialValue", new import_theatre_dataverse6.Atom({}));
4322
- /**
4323
- * Highest-priority override layer, written to by `RemoteSync` when a value
4324
- * update arrives from a remote editor window (see `internal/RemoteSync.ts`).
4325
- * Empty (`{}`) unless a remote editor is actually connected, so it's a
4326
- * no-op merge for every app that never uses the remote-sync feature.
4327
- */
4328
- __publicField(this, "_remoteOverride", new import_theatre_dataverse6.Atom({}));
4329
- /**
4330
- * Session-only overrides for props with `persist: false`. Not written to
4331
- * persisted project state and cleared on refresh.
4332
- */
4333
- __publicField(this, "_sessionOverrides", new import_theatre_dataverse6.Atom({}));
4334
- __publicField(this, "_cache", new SimpleCache());
4335
- __publicField(this, "_logger");
4336
- __publicField(this, "_internalUtilCtx");
4337
- this._logger = sheet._logger.named(
4338
- "SheetObject",
4339
- template.address.objectKey
4425
+ // core/src/sheetObjects/sheetObjectSequencedFull.ts
4426
+ function trackIdToPrism(obj, trackId, trackVariant) {
4427
+ const activeVariant = (0, import_theatre_dataverse7.val)(obj.sheet.effectiveActiveSequenceVariantD);
4428
+ const trackP = pointerToSequenceTrackData(
4429
+ obj.template.project.pointers.historic.sheetsById[obj.address.sheetId],
4430
+ trackVariant,
4431
+ obj.address.objectKey,
4432
+ trackId
4433
+ );
4434
+ const timeD = obj.sheet.getSequence(activeVariant).positionPrism;
4435
+ return interpolationTripleAtPosition(obj._internalUtilCtx, trackP, timeD);
4436
+ }
4437
+ function getSequencedValues(obj) {
4438
+ return (0, import_theatre_dataverse7.prism)(() => {
4439
+ const activeVariant = (0, import_theatre_dataverse7.val)(obj.sheet.effectiveActiveSequenceVariantD);
4440
+ const sequenceVariant = isSheetPropsObjectKey(obj.address.objectKey) ? DEFAULT_SEQUENCE_VARIANT : activeVariant;
4441
+ const tracksToProcessD = import_theatre_dataverse7.prism.memo(
4442
+ "tracksToProcess",
4443
+ () => obj.template.getArrayOfValidSequenceTracks(sequenceVariant),
4444
+ [sequenceVariant]
4340
4445
  );
4341
- this._logger._trace("creating object");
4342
- this._internalUtilCtx = { logger: this._logger.utilFor.internal() };
4343
- this.address = {
4344
- ...template.address,
4345
- sheetInstanceId: sheet.address.sheetInstanceId
4346
- };
4347
- this.publicApi = new TheatreSheetObject(this);
4348
- }
4349
- get type() {
4350
- return "Theatre_SheetObject";
4351
- }
4352
- getValues() {
4353
- return this._cache.get(
4354
- "getValues()",
4355
- () => (0, import_theatre_dataverse6.prism)(() => {
4356
- const defaults = (0, import_theatre_dataverse6.val)(this.template.getDefaultValues());
4357
- const initial = (0, import_theatre_dataverse6.val)(this._initialValue.pointer);
4358
- const withInitialCache = import_theatre_dataverse6.prism.memo(
4359
- "withInitialCache",
4446
+ const tracksToProcess = (0, import_theatre_dataverse7.val)(tracksToProcessD);
4447
+ const valsAtom = new import_theatre_dataverse7.Atom({});
4448
+ const config = (0, import_theatre_dataverse7.val)(obj.template.configPointer);
4449
+ import_theatre_dataverse7.prism.effect(
4450
+ "processTracks",
4451
+ () => {
4452
+ const untaps = [];
4453
+ for (const { trackId, pathToProp, trackVariant } of tracksToProcess) {
4454
+ if (obj.template.isNonSequencablePropPath(pathToProp)) continue;
4455
+ const pr = trackIdToPrism(obj, trackId, trackVariant);
4456
+ const propConfig = getPropConfigByPath(
4457
+ config,
4458
+ pathToProp
4459
+ );
4460
+ const deserializeAndSanitize = propConfig.deserializeAndSanitize;
4461
+ const interpolate = propConfig.interpolate;
4462
+ const updateSequenceValueFromItsPrism = () => {
4463
+ const triple = pr.getValue();
4464
+ if (!triple)
4465
+ return valsAtom.setByPointer(
4466
+ (p2) => pointerDeep(p2, pathToProp),
4467
+ void 0
4468
+ );
4469
+ const leftDeserialized = deserializeAndSanitize(triple.left);
4470
+ const left = leftDeserialized === void 0 ? propConfig.default : leftDeserialized;
4471
+ if (triple.right === void 0)
4472
+ return valsAtom.setByPointer(
4473
+ (p2) => pointerDeep(p2, pathToProp),
4474
+ left
4475
+ );
4476
+ const rightDeserialized = deserializeAndSanitize(triple.right);
4477
+ const right = rightDeserialized === void 0 ? propConfig.default : rightDeserialized;
4478
+ return valsAtom.setByPointer(
4479
+ (p2) => pointerDeep(p2, pathToProp),
4480
+ interpolate(left, right, triple.progression)
4481
+ );
4482
+ };
4483
+ const untap = pr.onStale(updateSequenceValueFromItsPrism);
4484
+ updateSequenceValueFromItsPrism();
4485
+ untaps.push(untap);
4486
+ }
4487
+ return () => {
4488
+ for (const untap of untaps) {
4489
+ untap();
4490
+ }
4491
+ };
4492
+ },
4493
+ [config, ...tracksToProcess]
4494
+ );
4495
+ return valsAtom.pointer;
4496
+ });
4497
+ }
4498
+ function mergeSequencedValuesIntoFinal(obj, base, withSeqsCache) {
4499
+ const pointerToSequencedValuesD = import_theatre_dataverse7.prism.memo(
4500
+ "seq",
4501
+ () => getSequencedValues(obj),
4502
+ []
4503
+ );
4504
+ const sequenced = (0, import_theatre_dataverse7.val)((0, import_theatre_dataverse7.val)(pointerToSequencedValuesD));
4505
+ return deepMergeWithCache(base, sequenced, withSeqsCache);
4506
+ }
4507
+
4508
+ // core/src/utils/isTheatreLiteMode.ts
4509
+ function isTheatreLiteMode() {
4510
+ if (false) {
4511
+ return true;
4512
+ }
4513
+ if (typeof globalThis !== "undefined") {
4514
+ return !!globalThis.__THEATRE_FORCE_LITE__;
4515
+ }
4516
+ return false;
4517
+ }
4518
+
4519
+ // shared/src/utils/updateDeep.ts
4520
+ function updateDeep(obj, path, reducer) {
4521
+ if (path.length === 0) return reducer(obj);
4522
+ return hoop(obj, path, reducer);
4523
+ }
4524
+ var hoop = (s2, path, reducer) => {
4525
+ if (path.length === 0) {
4526
+ return reducer(s2);
4527
+ }
4528
+ if (Array.isArray(s2)) {
4529
+ let [index, ...restOfPath] = path;
4530
+ index = parseInt(String(index), 10);
4531
+ if (isNaN(index)) index = 0;
4532
+ const oldVal = s2[index];
4533
+ const newVal = hoop(oldVal, restOfPath, reducer);
4534
+ if (oldVal === newVal) return s2;
4535
+ const newS = [...s2];
4536
+ newS.splice(index, 1, newVal);
4537
+ return newS;
4538
+ } else if (typeof s2 === "object" && s2 !== null) {
4539
+ const [key, ...restOfPath] = path;
4540
+ const oldVal = s2[key];
4541
+ const newVal = hoop(oldVal, restOfPath, reducer);
4542
+ if (oldVal === newVal) return s2;
4543
+ const newS = { ...s2, [key]: newVal };
4544
+ return newS;
4545
+ } else {
4546
+ const [key, ...restOfPath] = path;
4547
+ return { [key]: hoop(void 0, restOfPath, reducer) };
4548
+ }
4549
+ };
4550
+
4551
+ // shared/src/utils/setDeepImmutable.ts
4552
+ function setDeepImmutable(obj, path, replace) {
4553
+ return updateDeep(obj, path, () => replace);
4554
+ }
4555
+
4556
+ // core/src/sheetObjects/SheetObject.ts
4557
+ var SheetObject = class {
4558
+ constructor(sheet, template, nativeObject) {
4559
+ this.sheet = sheet;
4560
+ this.template = template;
4561
+ this.nativeObject = nativeObject;
4562
+ __publicField(this, "$$isPointerToPrismProvider", true);
4563
+ __publicField(this, "address");
4564
+ __publicField(this, "publicApi");
4565
+ __publicField(this, "_initialValue", new import_theatre_dataverse8.Atom({}));
4566
+ /**
4567
+ * Highest-priority override layer, written to by `RemoteSync` when a value
4568
+ * update arrives from a remote editor window (see `internal/RemoteSync.ts`).
4569
+ * Empty (`{}`) unless a remote editor is actually connected, so it's a
4570
+ * no-op merge for every app that never uses the remote-sync feature.
4571
+ */
4572
+ __publicField(this, "_remoteOverride", new import_theatre_dataverse8.Atom({}));
4573
+ /**
4574
+ * Session-only overrides for props with `persist: false`. Not written to
4575
+ * persisted project state and cleared on refresh.
4576
+ */
4577
+ __publicField(this, "_sessionOverrides", new import_theatre_dataverse8.Atom({}));
4578
+ __publicField(this, "_cache", new SimpleCache());
4579
+ __publicField(this, "_logger");
4580
+ /** @internal Used by `sheetObjectSequencedFull`. */
4581
+ __publicField(this, "_internalUtilCtx");
4582
+ this._logger = sheet._logger.named(
4583
+ "SheetObject",
4584
+ template.address.objectKey
4585
+ );
4586
+ this._logger._trace("creating object");
4587
+ this._internalUtilCtx = { logger: this._logger.utilFor.internal() };
4588
+ this.address = {
4589
+ ...template.address,
4590
+ sheetInstanceId: sheet.address.sheetInstanceId
4591
+ };
4592
+ this.publicApi = new TheatreSheetObject(this);
4593
+ }
4594
+ get type() {
4595
+ return "Theatre_SheetObject";
4596
+ }
4597
+ getValues() {
4598
+ return this._cache.get(
4599
+ "getValues()",
4600
+ () => (0, import_theatre_dataverse8.prism)(() => {
4601
+ const defaults = (0, import_theatre_dataverse8.val)(this.template.getDefaultValues());
4602
+ const initial = (0, import_theatre_dataverse8.val)(this._initialValue.pointer);
4603
+ const withInitialCache = import_theatre_dataverse8.prism.memo(
4604
+ "withInitialCache",
4360
4605
  () => /* @__PURE__ */ new WeakMap(),
4361
4606
  []
4362
4607
  );
@@ -4365,8 +4610,8 @@ var SheetObject = class {
4365
4610
  initial,
4366
4611
  withInitialCache
4367
4612
  );
4368
- const ahistoricStatics = (0, import_theatre_dataverse6.val)(this.template.getAhistoricStaticValues());
4369
- const withAhistoricStaticsCache = import_theatre_dataverse6.prism.memo(
4613
+ const ahistoricStatics = (0, import_theatre_dataverse8.val)(this.template.getAhistoricStaticValues());
4614
+ const withAhistoricStaticsCache = import_theatre_dataverse8.prism.memo(
4370
4615
  "withAhistoricStatics",
4371
4616
  () => /* @__PURE__ */ new WeakMap(),
4372
4617
  []
@@ -4376,10 +4621,10 @@ var SheetObject = class {
4376
4621
  ahistoricStatics,
4377
4622
  withAhistoricStaticsCache
4378
4623
  );
4379
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4624
+ const activeVariant = (0, import_theatre_dataverse8.val)(this.sheet.effectiveActiveSequenceVariantD);
4380
4625
  const staticVariant = isSheetPropsObjectKey(this.address.objectKey) ? DEFAULT_SEQUENCE_VARIANT : activeVariant;
4381
- const statics = (0, import_theatre_dataverse6.val)(this.template.getStaticValues(staticVariant));
4382
- const withStaticsCache = import_theatre_dataverse6.prism.memo(
4626
+ const statics = (0, import_theatre_dataverse8.val)(this.template.getStaticValues(staticVariant));
4627
+ const withStaticsCache = import_theatre_dataverse8.prism.memo(
4383
4628
  "withStatics",
4384
4629
  () => /* @__PURE__ */ new WeakMap(),
4385
4630
  []
@@ -4390,24 +4635,16 @@ var SheetObject = class {
4390
4635
  withStaticsCache
4391
4636
  );
4392
4637
  let final = withStatics;
4393
- let sequenced;
4394
- {
4395
- const pointerToSequencedValuesD = import_theatre_dataverse6.prism.memo(
4396
- "seq",
4397
- () => this.getSequencedValues(),
4398
- []
4399
- );
4400
- const withSeqsCache = import_theatre_dataverse6.prism.memo(
4638
+ if (!isTheatreLiteMode()) {
4639
+ const withSeqsCache = import_theatre_dataverse8.prism.memo(
4401
4640
  "withSeqsCache",
4402
4641
  () => /* @__PURE__ */ new WeakMap(),
4403
4642
  []
4404
4643
  );
4405
- sequenced = (0, import_theatre_dataverse6.val)((0, import_theatre_dataverse6.val)(pointerToSequencedValuesD));
4406
- const withSeqs = deepMergeWithCache(final, sequenced, withSeqsCache);
4407
- final = withSeqs;
4644
+ final = mergeSequencedValuesIntoFinal(this, final, withSeqsCache);
4408
4645
  }
4409
- const sessionOverrides = (0, import_theatre_dataverse6.val)(this._sessionOverrides.pointer);
4410
- const withSessionOverridesCache = import_theatre_dataverse6.prism.memo(
4646
+ const sessionOverrides = (0, import_theatre_dataverse8.val)(this._sessionOverrides.pointer);
4647
+ const withSessionOverridesCache = import_theatre_dataverse8.prism.memo(
4411
4648
  "withSessionOverridesCache",
4412
4649
  () => /* @__PURE__ */ new WeakMap(),
4413
4650
  []
@@ -4417,8 +4654,8 @@ var SheetObject = class {
4417
4654
  sessionOverrides,
4418
4655
  withSessionOverridesCache
4419
4656
  );
4420
- const remoteOverride = (0, import_theatre_dataverse6.val)(this._remoteOverride.pointer);
4421
- const withRemoteOverrideCache = import_theatre_dataverse6.prism.memo(
4657
+ const remoteOverride = (0, import_theatre_dataverse8.val)(this._remoteOverride.pointer);
4658
+ const withRemoteOverrideCache = import_theatre_dataverse8.prism.memo(
4422
4659
  "withRemoteOverrideCache",
4423
4660
  () => /* @__PURE__ */ new WeakMap(),
4424
4661
  []
@@ -4433,106 +4670,31 @@ var SheetObject = class {
4433
4670
  })
4434
4671
  );
4435
4672
  }
4436
- getValueByPointer(pointer3) {
4437
- const allValuesP = (0, import_theatre_dataverse6.val)(this.getValues());
4438
- const { path } = (0, import_theatre_dataverse6.getPointerParts)(pointer3);
4439
- return (0, import_theatre_dataverse6.val)(
4673
+ getValueByPointer(pointer4) {
4674
+ const allValuesP = (0, import_theatre_dataverse8.val)(this.getValues());
4675
+ const { path } = (0, import_theatre_dataverse8.getPointerParts)(pointer4);
4676
+ return (0, import_theatre_dataverse8.val)(
4440
4677
  pointerDeep(allValuesP, path)
4441
4678
  );
4442
4679
  }
4443
- pointerToPrism(pointer3) {
4444
- const { path } = (0, import_theatre_dataverse6.getPointerParts)(pointer3);
4445
- return (0, import_theatre_dataverse6.prism)(() => {
4446
- const allValuesP = (0, import_theatre_dataverse6.val)(this.getValues());
4447
- return (0, import_theatre_dataverse6.val)(pointerDeep(allValuesP, path));
4448
- });
4449
- }
4450
- /**
4451
- * Returns values of props that are sequenced.
4452
- */
4453
- getSequencedValues() {
4454
- return (0, import_theatre_dataverse6.prism)(() => {
4455
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4456
- const sequenceVariant = isSheetPropsObjectKey(this.address.objectKey) ? DEFAULT_SEQUENCE_VARIANT : activeVariant;
4457
- const tracksToProcessD = import_theatre_dataverse6.prism.memo(
4458
- "tracksToProcess",
4459
- () => this.template.getArrayOfValidSequenceTracks(sequenceVariant),
4460
- [sequenceVariant]
4461
- );
4462
- const tracksToProcess = (0, import_theatre_dataverse6.val)(tracksToProcessD);
4463
- const valsAtom = new import_theatre_dataverse6.Atom({});
4464
- const config = (0, import_theatre_dataverse6.val)(this.template.configPointer);
4465
- import_theatre_dataverse6.prism.effect(
4466
- "processTracks",
4467
- () => {
4468
- const untaps = [];
4469
- for (const { trackId, pathToProp, trackVariant } of tracksToProcess) {
4470
- if (this.template.isNonSequencablePropPath(pathToProp)) continue;
4471
- const pr = this._trackIdToPrism(trackId, trackVariant);
4472
- const propConfig = getPropConfigByPath(
4473
- config,
4474
- pathToProp
4475
- );
4476
- const deserializeAndSanitize = propConfig.deserializeAndSanitize;
4477
- const interpolate = propConfig.interpolate;
4478
- const updateSequenceValueFromItsPrism = () => {
4479
- const triple = pr.getValue();
4480
- if (!triple)
4481
- return valsAtom.setByPointer(
4482
- (p2) => pointerDeep(p2, pathToProp),
4483
- void 0
4484
- );
4485
- const leftDeserialized = deserializeAndSanitize(triple.left);
4486
- const left = leftDeserialized === void 0 ? propConfig.default : leftDeserialized;
4487
- if (triple.right === void 0)
4488
- return valsAtom.setByPointer(
4489
- (p2) => pointerDeep(p2, pathToProp),
4490
- left
4491
- );
4492
- const rightDeserialized = deserializeAndSanitize(triple.right);
4493
- const right = rightDeserialized === void 0 ? propConfig.default : rightDeserialized;
4494
- return valsAtom.setByPointer(
4495
- (p2) => pointerDeep(p2, pathToProp),
4496
- interpolate(left, right, triple.progression)
4497
- );
4498
- };
4499
- const untap = pr.onStale(updateSequenceValueFromItsPrism);
4500
- updateSequenceValueFromItsPrism();
4501
- untaps.push(untap);
4502
- }
4503
- return () => {
4504
- for (const untap of untaps) {
4505
- untap();
4506
- }
4507
- };
4508
- },
4509
- [config, ...tracksToProcess]
4510
- );
4511
- return valsAtom.pointer;
4680
+ pointerToPrism(pointer4) {
4681
+ const { path } = (0, import_theatre_dataverse8.getPointerParts)(pointer4);
4682
+ return (0, import_theatre_dataverse8.prism)(() => {
4683
+ const allValuesP = (0, import_theatre_dataverse8.val)(this.getValues());
4684
+ return (0, import_theatre_dataverse8.val)(pointerDeep(allValuesP, path));
4512
4685
  });
4513
4686
  }
4514
- _trackIdToPrism(trackId, trackVariant) {
4515
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4516
- const trackP = pointerToSequenceTrackData(
4517
- this.template.project.pointers.historic.sheetsById[this.address.sheetId],
4518
- trackVariant,
4519
- this.address.objectKey,
4520
- trackId
4521
- );
4522
- const timeD = this.sheet.getSequence(activeVariant).positionPrism;
4523
- return interpolationTripleAtPosition(this._internalUtilCtx, trackP, timeD);
4524
- }
4525
4687
  get propsP() {
4526
4688
  return this._cache.get(
4527
4689
  "propsP",
4528
- () => (0, import_theatre_dataverse6.pointer)({ root: this, path: [] })
4690
+ () => (0, import_theatre_dataverse8.pointer)({ root: this, path: [] })
4529
4691
  );
4530
4692
  }
4531
- validateValue(pointer3, value) {
4693
+ validateValue(pointer4, value) {
4532
4694
  }
4533
- setInitialValue(val12) {
4534
- this.validateValue(this.propsP, val12);
4535
- this._initialValue.set(val12);
4695
+ setInitialValue(val15) {
4696
+ this.validateValue(this.propsP, val15);
4697
+ this._initialValue.set(val15);
4536
4698
  }
4537
4699
  setSessionOverride(path, value) {
4538
4700
  const propConfig = getPropConfigByPath(this.template.staticConfig, path);
@@ -4552,8 +4714,8 @@ var SheetObject = class {
4552
4714
  * Internal: called by `RemoteSync` when a value update for this object
4553
4715
  * arrives from a remote editor window. Not exposed on the public API.
4554
4716
  */
4555
- setRemoteOverride(val12) {
4556
- this._remoteOverride.set(val12);
4717
+ setRemoteOverride(val15) {
4718
+ this._remoteOverride.set(val15);
4557
4719
  }
4558
4720
  /**
4559
4721
  * Internal: used by `RemoteSync` to subscribe to this object's fully
@@ -4562,7 +4724,7 @@ var SheetObject = class {
4562
4724
  */
4563
4725
  onFinalValueChange(fn2) {
4564
4726
  return onChange(
4565
- (0, import_theatre_dataverse6.prism)(() => (0, import_theatre_dataverse6.val)(this.getValues().getValue())),
4727
+ (0, import_theatre_dataverse8.prism)(() => (0, import_theatre_dataverse8.val)(this.getValues().getValue())),
4566
4728
  fn2
4567
4729
  );
4568
4730
  }
@@ -5133,9 +5295,9 @@ var SheetObjectTemplate = class {
5133
5295
  config,
5134
5296
  sheetTemplate.project
5135
5297
  );
5136
- this._config = new import_theatre_dataverse7.Atom(configWithPrecisionDefaults);
5137
- this._temp_actions_atom = new import_theatre_dataverse7.Atom(_temp_actions);
5138
- this.showPropsOf_atom = new import_theatre_dataverse7.Atom([]);
5298
+ this._config = new import_theatre_dataverse9.Atom(configWithPrecisionDefaults);
5299
+ this._temp_actions_atom = new import_theatre_dataverse9.Atom(_temp_actions);
5300
+ this.showPropsOf_atom = new import_theatre_dataverse9.Atom([]);
5139
5301
  this._transientPropPaths = normalizeTransientPropPaths(
5140
5302
  transient,
5141
5303
  config,
@@ -5192,7 +5354,7 @@ var SheetObjectTemplate = class {
5192
5354
  return this.showPropsOf_atom.pointer;
5193
5355
  }
5194
5356
  _stripNonPersistingPropsFromAhistoricState() {
5195
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5357
+ const config = (0, import_theatre_dataverse9.val)(this.configPointer);
5196
5358
  this.project._stripNonPersistingPropsFromAhistoric(
5197
5359
  this.address.sheetId,
5198
5360
  this.address.objectKey,
@@ -5321,8 +5483,8 @@ var SheetObjectTemplate = class {
5321
5483
  getDefaultValues() {
5322
5484
  return this._cache.get(
5323
5485
  "getDefaultValues()",
5324
- () => (0, import_theatre_dataverse7.prism)(() => {
5325
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5486
+ () => (0, import_theatre_dataverse9.prism)(() => {
5487
+ const config = (0, import_theatre_dataverse9.val)(this.configPointer);
5326
5488
  return getPropDefaultsOfSheetObject(config);
5327
5489
  })
5328
5490
  );
@@ -5334,14 +5496,14 @@ var SheetObjectTemplate = class {
5334
5496
  getStaticValues(sequenceVariant = DEFAULT_SEQUENCE_VARIANT) {
5335
5497
  return this._cache.get(
5336
5498
  "getStaticValues:".concat(sequenceVariant),
5337
- () => (0, import_theatre_dataverse7.prism)(() => {
5338
- const sheetState = (0, import_theatre_dataverse7.val)(this.pointerToSheetState);
5499
+ () => (0, import_theatre_dataverse9.prism)(() => {
5500
+ const sheetState = (0, import_theatre_dataverse9.val)(this.pointerToSheetState);
5339
5501
  const json = getEffectiveStaticOverrideForObject(
5340
5502
  sheetState,
5341
5503
  sequenceVariant,
5342
5504
  this.address.objectKey
5343
5505
  ) ?? {};
5344
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5506
+ const config = (0, import_theatre_dataverse9.val)(this.configPointer);
5345
5507
  const deserialized = config.deserializeAndSanitize(json) || {};
5346
5508
  const withoutNonPersisting = stripNonPersistingPropValuesFromMap(
5347
5509
  deserialized,
@@ -5364,9 +5526,9 @@ var SheetObjectTemplate = class {
5364
5526
  getAhistoricStaticValues() {
5365
5527
  return this._cache.get(
5366
5528
  "getAhistoricStaticValues",
5367
- () => (0, import_theatre_dataverse7.prism)(() => {
5368
- const json = (0, import_theatre_dataverse7.val)(this.pointerToAhistoricStaticOverrides) ?? {};
5369
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5529
+ () => (0, import_theatre_dataverse9.prism)(() => {
5530
+ const json = (0, import_theatre_dataverse9.val)(this.pointerToAhistoricStaticOverrides) ?? {};
5531
+ const config = (0, import_theatre_dataverse9.val)(this.configPointer);
5370
5532
  const deserialized = config.deserializeAndSanitize(json) || {};
5371
5533
  return stripNonPersistingPropValuesFromMap(deserialized, config);
5372
5534
  })
@@ -5381,13 +5543,13 @@ var SheetObjectTemplate = class {
5381
5543
  getArrayOfValidSequenceTracks(sequenceVariant) {
5382
5544
  return this._cache.get(
5383
5545
  "getArrayOfValidSequenceTracks:".concat(sequenceVariant),
5384
- () => (0, import_theatre_dataverse7.prism)(
5546
+ () => (0, import_theatre_dataverse9.prism)(
5385
5547
  () => {
5386
5548
  const effectiveSequenceVariant = isSheetPropsObjectKey(
5387
5549
  this.address.objectKey
5388
5550
  ) ? DEFAULT_SEQUENCE_VARIANT : sequenceVariant;
5389
5551
  const pointerToSheetState = this.project.pointers.historic.sheetsById[this.address.sheetId];
5390
- (0, import_theatre_dataverse7.val)(pointerToSheetState.variantObjectOverrides);
5552
+ (0, import_theatre_dataverse9.val)(pointerToSheetState.variantObjectOverrides);
5391
5553
  const defaultTrackIdByPropPath = valTrackIdByPropPathForObject(
5392
5554
  pointerToSheetState,
5393
5555
  DEFAULT_SEQUENCE_VARIANT,
@@ -5413,7 +5575,7 @@ var SheetObjectTemplate = class {
5413
5575
  return emptyArray;
5414
5576
  }
5415
5577
  const arrayOfIds = [];
5416
- const objectConfig = (0, import_theatre_dataverse7.val)(this.configPointer);
5578
+ const objectConfig = (0, import_theatre_dataverse9.val)(this.configPointer);
5417
5579
  for (const [pathToPropInString, effectiveTrack] of Object.entries(
5418
5580
  mergedTrackMap
5419
5581
  )) {
@@ -5463,8 +5625,8 @@ var SheetObjectTemplate = class {
5463
5625
  getMapOfValidSequenceTracks_forStudio(sequenceVariant) {
5464
5626
  return this._cache.get(
5465
5627
  "getMapOfValidSequenceTracks_forStudio:".concat(sequenceVariant),
5466
- () => (0, import_theatre_dataverse7.prism)(() => {
5467
- const arr = (0, import_theatre_dataverse7.val)(this.getArrayOfValidSequenceTracks(sequenceVariant));
5628
+ () => (0, import_theatre_dataverse9.prism)(() => {
5629
+ const arr = (0, import_theatre_dataverse9.val)(this.getArrayOfValidSequenceTracks(sequenceVariant));
5468
5630
  let map = {};
5469
5631
  for (const { pathToProp, trackId } of arr) {
5470
5632
  set_default(map, pathToProp, trackId);
@@ -5484,9 +5646,9 @@ var SheetObjectTemplate = class {
5484
5646
  getStaticButNotSequencedOverrides(sequenceVariant) {
5485
5647
  return this._cache.get(
5486
5648
  "getStaticButNotSequencedOverrides:".concat(sequenceVariant),
5487
- () => (0, import_theatre_dataverse7.prism)(() => {
5488
- const staticOverrides = (0, import_theatre_dataverse7.val)(this.getStaticValues(sequenceVariant));
5489
- const arrayOfValidSequenceTracks = (0, import_theatre_dataverse7.val)(
5649
+ () => (0, import_theatre_dataverse9.prism)(() => {
5650
+ const staticOverrides = (0, import_theatre_dataverse9.val)(this.getStaticValues(sequenceVariant));
5651
+ const arrayOfValidSequenceTracks = (0, import_theatre_dataverse9.val)(
5490
5652
  this.getArrayOfValidSequenceTracks(sequenceVariant)
5491
5653
  );
5492
5654
  const staticButNotSequencedOverrides = cloneDeep_default(staticOverrides);
@@ -5511,8 +5673,8 @@ var SheetObjectTemplate = class {
5511
5673
  })
5512
5674
  );
5513
5675
  }
5514
- getDefaultsAtPointer(pointer3) {
5515
- const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
5676
+ getDefaultsAtPointer(pointer4) {
5677
+ const { path } = (0, import_theatre_dataverse9.getPointerParts)(pointer4);
5516
5678
  const defaults = this.getDefaultValues().getValue();
5517
5679
  const defaultsAtPath = getDeep(defaults, path);
5518
5680
  return defaultsAtPath;
@@ -5533,243 +5695,77 @@ function parsePathToProp(pathToPropInString) {
5533
5695
  }
5534
5696
 
5535
5697
  // core/src/sheets/SheetTemplate.ts
5536
- var import_theatre_dataverse16 = require("@unseenco/theatre-dataverse");
5537
-
5538
- // shared/src/utils/didYouMean.ts
5539
- var import_propose = __toESM(require_propose());
5540
- function didYouMean(str, dictionary, prepend = "Did you mean ", append = "?") {
5541
- const p2 = (0, import_propose.default)(str, dictionary, {
5542
- threshold: 0.7
5543
- });
5544
- if (p2) {
5545
- return prepend + JSON.stringify(p2) + append;
5546
- } else {
5547
- return "";
5548
- }
5549
- }
5698
+ var import_theatre_dataverse23 = require("@unseenco/theatre-dataverse");
5550
5699
 
5551
- // core/src/sequences/Sequence.ts
5700
+ // core/src/sequences/LiteSequence.ts
5552
5701
  var import_theatre_dataverse11 = require("@unseenco/theatre-dataverse");
5553
- var import_theatre_dataverse12 = require("@unseenco/theatre-dataverse");
5554
- var import_theatre_dataverse13 = require("@unseenco/theatre-dataverse");
5555
- var import_theatre_dataverse14 = require("@unseenco/theatre-dataverse");
5556
-
5557
- // shared/src/utils/defer.ts
5558
- function defer() {
5559
- let resolve;
5560
- let reject;
5561
- const promise = new Promise((rs, rj) => {
5562
- resolve = (v2) => {
5563
- rs(v2);
5564
- deferred.status = "resolved";
5565
- };
5566
- reject = (v2) => {
5567
- rj(v2);
5568
- deferred.status = "rejected";
5569
- };
5570
- });
5571
- const deferred = {
5572
- resolve,
5573
- reject,
5574
- promise,
5575
- status: "pending"
5576
- };
5577
- return deferred;
5578
- }
5579
-
5580
- // shared/src/utils/noop.ts
5581
- var noop = () => {
5582
- };
5583
- var noop_default = noop;
5584
5702
 
5585
- // core/src/sequences/playbackControllers/DefaultPlaybackController.ts
5586
- var import_theatre_dataverse8 = require("@unseenco/theatre-dataverse");
5587
- var DefaultPlaybackController = class {
5703
+ // core/src/sequences/TheatreSequenceLite.ts
5704
+ var import_theatre_dataverse10 = require("@unseenco/theatre-dataverse");
5705
+ var LITE_DEFAULT_LENGTH = 10;
5706
+ var TheatreSequenceLite = class {
5588
5707
  constructor() {
5589
- __publicField(this, "_stopPlayCallback", noop_default);
5590
- __publicField(this, "_state", new import_theatre_dataverse8.Atom({
5591
- position: 0,
5592
- playing: false
5708
+ __publicField(this, "type", "Theatre_Sequence_PublicAPI");
5709
+ __publicField(this, "_state", new import_theatre_dataverse10.Atom({
5710
+ playing: false,
5711
+ length: LITE_DEFAULT_LENGTH,
5712
+ position: 0
5593
5713
  }));
5594
- __publicField(this, "statePointer");
5595
- this.statePointer = this._state.pointer;
5714
+ __publicField(this, "pointer", (0, import_theatre_dataverse10.pointer)({ root: this._state.pointer, path: [] }));
5596
5715
  }
5597
- destroy() {
5716
+ play() {
5717
+ return Promise.resolve(true);
5598
5718
  }
5599
5719
  pause() {
5600
- this._stopPlayCallback();
5601
- this.playing = false;
5602
- this._stopPlayCallback = noop_default;
5603
5720
  }
5604
- gotoPosition(time) {
5605
- this._updatePositionInState(time);
5721
+ get position() {
5722
+ return 0;
5606
5723
  }
5607
- _updatePositionInState(time) {
5608
- this._state.setByPointer((p2) => p2.position, time);
5724
+ set position(_position) {
5609
5725
  }
5610
- getCurrentPosition() {
5611
- return this._state.get().position;
5726
+ __experimental_getKeyframes(_prop) {
5727
+ return [];
5612
5728
  }
5613
- get playing() {
5614
- return this._state.get().playing;
5729
+ __experimental_getGsapClips() {
5730
+ return [];
5615
5731
  }
5616
- set playing(playing) {
5617
- this._state.setByPointer((p2) => p2.playing, playing);
5732
+ __experimental_getGsapScrollTriggers() {
5733
+ return [];
5618
5734
  }
5619
- play(iterationCount, range, rate, direction, ticker) {
5620
- if (this.playing) {
5621
- this.pause();
5735
+ attachAudio(_args) {
5736
+ return Promise.reject(
5737
+ new Error(
5738
+ "sequence.attachAudio() is not available in @unseenco/theatre-core-lite"
5739
+ )
5740
+ );
5741
+ }
5742
+ };
5743
+
5744
+ // core/src/sequences/LiteSequence.ts
5745
+ var LiteSequence = class {
5746
+ constructor() {
5747
+ __publicField(this, "publicApi", new TheatreSequenceLite());
5748
+ __publicField(this, "positionPrism", (0, import_theatre_dataverse11.prism)(() => 0));
5749
+ }
5750
+ pause() {
5751
+ }
5752
+ };
5753
+
5754
+ // shared/src/globalVariableNames.ts
5755
+ var studioBundle = "__TheatreJS_StudioBundle";
5756
+ var coreBundle = "__TheatreJS_CoreBundle";
5757
+ var notifications = "__TheatreJS_Notifications";
5758
+
5759
+ // shared/src/notify.ts
5760
+ var createHandler = (type) => (...args) => {
5761
+ switch (type) {
5762
+ case "success": {
5763
+ logger_default.debug(args.slice(0, 2).join("\n"));
5764
+ break;
5622
5765
  }
5623
- this.playing = true;
5624
- const iterationLength = range[1] - range[0];
5625
- {
5626
- const startPos = this.getCurrentPosition();
5627
- if (startPos < range[0] || startPos > range[1]) {
5628
- if (direction === "normal" || direction === "alternate") {
5629
- this._updatePositionInState(range[0]);
5630
- } else if (direction === "reverse" || direction === "alternateReverse") {
5631
- this._updatePositionInState(range[1]);
5632
- }
5633
- } else if (direction === "normal" || direction === "alternate") {
5634
- if (startPos === range[1]) {
5635
- this._updatePositionInState(range[0]);
5636
- }
5637
- } else {
5638
- if (startPos === range[0]) {
5639
- this._updatePositionInState(range[1]);
5640
- }
5641
- }
5642
- }
5643
- const deferred = defer();
5644
- const initialTickerTime = ticker.time;
5645
- const totalPlaybackLength = iterationLength * iterationCount;
5646
- let initialElapsedPos = this.getCurrentPosition() - range[0];
5647
- if (direction === "reverse" || direction === "alternateReverse") {
5648
- initialElapsedPos = range[1] - this.getCurrentPosition();
5649
- }
5650
- const tick = (currentTickerTime) => {
5651
- const elapsedTickerTime = Math.max(
5652
- currentTickerTime - initialTickerTime,
5653
- 0
5654
- );
5655
- const elapsedTickerTimeInSeconds = elapsedTickerTime / 1e3;
5656
- const elapsedPos = Math.min(
5657
- elapsedTickerTimeInSeconds * rate + initialElapsedPos,
5658
- totalPlaybackLength
5659
- );
5660
- if (elapsedPos !== totalPlaybackLength) {
5661
- const iterationNumber = Math.floor(elapsedPos / iterationLength);
5662
- let currentIterationPos = elapsedPos / iterationLength % 1 * iterationLength;
5663
- if (direction !== "normal") {
5664
- if (direction === "reverse") {
5665
- currentIterationPos = iterationLength - currentIterationPos;
5666
- } else {
5667
- const isCurrentIterationNumberEven = iterationNumber % 2 === 0;
5668
- if (direction === "alternate") {
5669
- if (!isCurrentIterationNumberEven) {
5670
- currentIterationPos = iterationLength - currentIterationPos;
5671
- }
5672
- } else {
5673
- if (isCurrentIterationNumberEven) {
5674
- currentIterationPos = iterationLength - currentIterationPos;
5675
- }
5676
- }
5677
- }
5678
- }
5679
- this._updatePositionInState(currentIterationPos + range[0]);
5680
- requestNextTick();
5681
- } else {
5682
- if (direction === "normal") {
5683
- this._updatePositionInState(range[1]);
5684
- } else if (direction === "reverse") {
5685
- this._updatePositionInState(range[0]);
5686
- } else {
5687
- const isLastIterationEven = (iterationCount - 1) % 2 === 0;
5688
- if (direction === "alternate") {
5689
- if (isLastIterationEven) {
5690
- this._updatePositionInState(range[1]);
5691
- } else {
5692
- this._updatePositionInState(range[0]);
5693
- }
5694
- } else {
5695
- if (isLastIterationEven) {
5696
- this._updatePositionInState(range[0]);
5697
- } else {
5698
- this._updatePositionInState(range[1]);
5699
- }
5700
- }
5701
- }
5702
- this.playing = false;
5703
- deferred.resolve(true);
5704
- }
5705
- };
5706
- this._stopPlayCallback = () => {
5707
- ticker.offThisOrNextTick(tick);
5708
- ticker.offNextTick(tick);
5709
- if (this.playing) deferred.resolve(false);
5710
- };
5711
- const requestNextTick = () => ticker.onNextTick(tick);
5712
- ticker.onThisOrNextTick(tick);
5713
- return deferred.promise;
5714
- }
5715
- playDynamicRange(rangeD, ticker) {
5716
- if (this.playing) {
5717
- this.pause();
5718
- }
5719
- this.playing = true;
5720
- const deferred = defer();
5721
- const untapFromRangeD = rangeD.keepHot();
5722
- void deferred.promise.then(untapFromRangeD, untapFromRangeD);
5723
- let lastTickerTime = ticker.time;
5724
- const tick = (currentTickerTime) => {
5725
- const elapsedSinceLastTick = Math.max(
5726
- currentTickerTime - lastTickerTime,
5727
- 0
5728
- );
5729
- lastTickerTime = currentTickerTime;
5730
- const elapsedSinceLastTickInSeconds = elapsedSinceLastTick / 1e3;
5731
- const lastPosition = this.getCurrentPosition();
5732
- const range = rangeD.getValue();
5733
- if (lastPosition < range[0] || lastPosition > range[1]) {
5734
- this.gotoPosition(range[0]);
5735
- } else {
5736
- let newPosition = lastPosition + elapsedSinceLastTickInSeconds;
5737
- if (newPosition > range[1]) {
5738
- newPosition = range[0] + (newPosition - range[1]);
5739
- }
5740
- this.gotoPosition(newPosition);
5741
- }
5742
- requestNextTick();
5743
- };
5744
- this._stopPlayCallback = () => {
5745
- ticker.offThisOrNextTick(tick);
5746
- ticker.offNextTick(tick);
5747
- deferred.resolve(false);
5748
- };
5749
- const requestNextTick = () => ticker.onNextTick(tick);
5750
- ticker.onThisOrNextTick(tick);
5751
- return deferred.promise;
5752
- }
5753
- };
5754
-
5755
- // core/src/sequences/playbackControllers/AudioPlaybackController.ts
5756
- var import_theatre_dataverse9 = require("@unseenco/theatre-dataverse");
5757
-
5758
- // shared/src/globalVariableNames.ts
5759
- var studioBundle = "__TheatreJS_StudioBundle";
5760
- var coreBundle = "__TheatreJS_CoreBundle";
5761
- var notifications = "__TheatreJS_Notifications";
5762
-
5763
- // shared/src/notify.ts
5764
- var createHandler = (type) => (...args) => {
5765
- switch (type) {
5766
- case "success": {
5767
- logger_default.debug(args.slice(0, 2).join("\n"));
5768
- break;
5769
- }
5770
- case "info": {
5771
- logger_default.debug(args.slice(0, 2).join("\n"));
5772
- break;
5766
+ case "info": {
5767
+ logger_default.debug(args.slice(0, 2).join("\n"));
5768
+ break;
5773
5769
  }
5774
5770
  case "warning": {
5775
5771
  logger_default.warn(args.slice(0, 2).join("\n"));
@@ -5804,89 +5800,624 @@ if (typeof window !== "undefined") {
5804
5800
  });
5805
5801
  }
5806
5802
 
5807
- // core/src/sequences/playbackControllers/AudioPlaybackController.ts
5808
- var AudioPlaybackController = class {
5809
- constructor(_decodedBuffer, _audioContext, _nodeDestination) {
5810
- this._decodedBuffer = _decodedBuffer;
5811
- this._audioContext = _audioContext;
5812
- this._nodeDestination = _nodeDestination;
5813
- __publicField(this, "_mainGain");
5814
- __publicField(this, "_state", new import_theatre_dataverse9.Atom({
5815
- position: 0,
5816
- playing: false
5817
- }));
5818
- __publicField(this, "statePointer");
5819
- __publicField(this, "_stopPlayCallback", noop_default);
5820
- this.statePointer = this._state.pointer;
5821
- this._mainGain = this._audioContext.createGain();
5822
- this._mainGain.connect(this._nodeDestination);
5803
+ // shared/src/utils/slashedPaths.ts
5804
+ var normalizeSlashedPath = (p2) => p2.replace(/^[\s\/]*/, "").replace(/[\s\/]*$/, "").replace(/\s*\/\s*/g, " / ");
5805
+ var getValidationErrorsOfSlashedPath = (p2) => {
5806
+ if (typeof p2 !== "string") return "it is not a string. (it is a ".concat(typeof p2, ")");
5807
+ const components = p2.split(/\//);
5808
+ if (components.length === 0) return "it is empty.";
5809
+ for (let i2 = 0; i2 < components.length; i2++) {
5810
+ const component = components[i2].trim();
5811
+ if (component.length === 0) return "the component #".concat(i2 + 1, " is empty.");
5812
+ if (component.length > 64)
5813
+ return "the component '".concat(component, "' must have 64 characters or less.");
5823
5814
  }
5824
- playDynamicRange(rangeD, ticker) {
5825
- const deferred = defer();
5826
- if (this._playing) this.pause();
5827
- this._playing = true;
5828
- let stop = void 0;
5829
- const play = () => {
5830
- stop?.();
5831
- stop = this._loopInRange(rangeD.getValue(), ticker).stop;
5832
- };
5833
- const untapFromRangeD = rangeD.onStale(play);
5834
- play();
5835
- this._stopPlayCallback = () => {
5836
- stop?.();
5837
- untapFromRangeD();
5838
- deferred.resolve(false);
5839
- };
5840
- return deferred.promise;
5815
+ };
5816
+ function validateAndSanitiseSlashedPathOrThrow(unsanitisedPath, fnName) {
5817
+ const sanitisedPath = normalizeSlashedPath(unsanitisedPath);
5818
+ if (process.env.NODE_ENV !== "development") {
5819
+ return sanitisedPath;
5841
5820
  }
5842
- _loopInRange(range, ticker) {
5843
- const rate = 1;
5844
- let startPos = this.getCurrentPosition();
5845
- const iterationLength = range[1] - range[0];
5846
- if (startPos < range[0] || startPos > range[1]) {
5847
- this._updatePositionInState(range[0]);
5848
- } else if (startPos === range[1]) {
5849
- this._updatePositionInState(range[0]);
5850
- }
5851
- startPos = this.getCurrentPosition();
5852
- const currentSource = this._audioContext.createBufferSource();
5853
- currentSource.buffer = this._decodedBuffer;
5854
- currentSource.connect(this._mainGain);
5855
- currentSource.playbackRate.value = rate;
5856
- currentSource.loop = true;
5857
- currentSource.loopStart = range[0];
5858
- currentSource.loopEnd = range[1];
5859
- const initialTickerTime = ticker.time;
5860
- let initialElapsedPos = startPos - range[0];
5861
- currentSource.start(0, startPos);
5862
- const tick = (currentTickerTime) => {
5863
- const elapsedTickerTime = Math.max(
5864
- currentTickerTime - initialTickerTime,
5865
- 0
5866
- );
5867
- const elapsedTickerTimeInSeconds = elapsedTickerTime / 1e3;
5868
- const elapsedPos = elapsedTickerTimeInSeconds * rate + initialElapsedPos;
5869
- let currentIterationPos = elapsedPos / iterationLength % 1 * iterationLength;
5870
- this._updatePositionInState(currentIterationPos + range[0]);
5871
- requestNextTick();
5872
- };
5873
- const requestNextTick = () => ticker.onNextTick(tick);
5874
- ticker.onThisOrNextTick(tick);
5875
- const stop = () => {
5876
- currentSource.stop();
5877
- currentSource.disconnect();
5878
- ticker.offThisOrNextTick(tick);
5879
- ticker.offNextTick(tick);
5880
- };
5881
- return { stop };
5821
+ const validation = getValidationErrorsOfSlashedPath(sanitisedPath);
5822
+ if (validation) {
5823
+ throw new InvalidArgumentError(
5824
+ "The path in ".concat(fnName, "(").concat(typeof unsanitisedPath === "string" ? '"'.concat(unsanitisedPath, '"') : "", ") is invalid because ").concat(validation)
5825
+ );
5882
5826
  }
5883
- get _playing() {
5884
- return this._state.get().playing;
5827
+ if (unsanitisedPath !== sanitisedPath) {
5828
+ notify.warning(
5829
+ "Invalid path provided to object",
5830
+ "The path in `".concat(fnName, '("').concat(unsanitisedPath, '")` was sanitized to `"').concat(sanitisedPath, '"`.\n\n') + "Please replace the path with the sanitized one, otherwise it will likely break in the future.",
5831
+ [
5832
+ {
5833
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/objects#creating-objects",
5834
+ title: "Sheet Objects"
5835
+ },
5836
+ {
5837
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sheet.object",
5838
+ title: "API"
5839
+ }
5840
+ ]
5841
+ );
5885
5842
  }
5886
- set _playing(playing) {
5887
- this._state.setByPointer((p2) => p2.playing, playing);
5843
+ return sanitisedPath;
5844
+ }
5845
+
5846
+ // shared/src/utils/outlineNamespaces.ts
5847
+ function parseOutlineNamespacePath(namespacePath, fnName) {
5848
+ return validateAndSanitiseSlashedPathOrThrow(namespacePath, fnName).split(
5849
+ /\s*\/\s*/g
5850
+ );
5851
+ }
5852
+
5853
+ // core/src/sheets/TheatreSheet.ts
5854
+ var import_fast_deep_equal2 = __toESM(require_fast_deep_equal());
5855
+ var TheatreSheet = class {
5856
+ get type() {
5857
+ return "Theatre_Sheet_PublicAPI";
5888
5858
  }
5889
- destroy() {
5859
+ /**
5860
+ * @internal
5861
+ */
5862
+ constructor(sheet) {
5863
+ setPrivateAPI(this, sheet);
5864
+ }
5865
+ object(key, config, opts) {
5866
+ const internal2 = privateAPI(this);
5867
+ const sanitizedPath = validateAndSanitiseSlashedPathOrThrow(
5868
+ key,
5869
+ "sheet.object"
5870
+ );
5871
+ if (isSheetPropsObjectKey(sanitizedPath)) {
5872
+ throw new InvalidArgumentError(
5873
+ 'The key "'.concat(sanitizedPath, '" is reserved for sheet-level props. Use sheet.props() instead of sheet.object().')
5874
+ );
5875
+ }
5876
+ const existingObject = internal2.getObject(sanitizedPath);
5877
+ const nativeObject = null;
5878
+ const actions = opts?.__actions__THIS_API_IS_UNSTABLE_AND_WILL_CHANGE_IN_THE_NEXT_VERSION;
5879
+ if (existingObject) {
5880
+ if (process.env.NODE_ENV !== "production") {
5881
+ const prevConfig = getUnsanitizedObjectProps(existingObject);
5882
+ if (prevConfig) {
5883
+ if (!(0, import_fast_deep_equal2.default)(config, prevConfig)) {
5884
+ if (opts?.reconfigure === true) {
5885
+ const sanitizedConfig = compound(config);
5886
+ existingObject.template.reconfigure(sanitizedConfig);
5887
+ if (opts.transient !== void 0) {
5888
+ existingObject.template.setTransientPropPaths(
5889
+ opts.transient,
5890
+ sanitizedConfig
5891
+ );
5892
+ }
5893
+ if (opts.static !== void 0) {
5894
+ existingObject.template.setStaticPropPaths(
5895
+ opts.static,
5896
+ sanitizedConfig
5897
+ );
5898
+ }
5899
+ if (opts.showPropsOf !== void 0) {
5900
+ existingObject.template.setShowPropsOf(
5901
+ resolveShowPropsOfSources(
5902
+ existingObject,
5903
+ opts.showPropsOf,
5904
+ "sheet.object(..., {showPropsOf})"
5905
+ )
5906
+ );
5907
+ }
5908
+ setUnsanitizedObjectProps(existingObject, config);
5909
+ return existingObject.publicApi;
5910
+ } else {
5911
+ throw new Error(
5912
+ 'You seem to have called sheet.object("'.concat(key, '", config) twice, with different values for `config`. ') + "This is disallowed because changing the config of an object on the fly would make it difficult to reason about.\n\n" + 'You can fix this by either re-using the existing object, or calling sheet.object("'.concat(key, '", config) with the same config.\n\n') + "If you mean to reconfigure the object's config, set `{reconfigure: true}` in sheet.object(\"".concat(key, '", config, {reconfigure: true})')
5913
+ );
5914
+ }
5915
+ }
5916
+ }
5917
+ }
5918
+ if (actions) {
5919
+ existingObject.template._temp_setActions(actions);
5920
+ }
5921
+ if (opts?.visible !== void 0) {
5922
+ existingObject.template.setVisibleInOutline(opts.visible);
5923
+ }
5924
+ if (opts?.transient !== void 0) {
5925
+ existingObject.template.setTransientPropPaths(
5926
+ opts.transient,
5927
+ existingObject.template.staticConfig
5928
+ );
5929
+ }
5930
+ if (opts?.static !== void 0) {
5931
+ existingObject.template.setStaticPropPaths(
5932
+ opts.static,
5933
+ existingObject.template.staticConfig
5934
+ );
5935
+ }
5936
+ if (opts?.showPropsOf !== void 0) {
5937
+ existingObject.template.setShowPropsOf(
5938
+ resolveShowPropsOfSources(
5939
+ existingObject,
5940
+ opts.showPropsOf,
5941
+ "sheet.object(..., {showPropsOf})"
5942
+ )
5943
+ );
5944
+ }
5945
+ return existingObject.publicApi;
5946
+ } else {
5947
+ const sanitizedConfig = compound(config);
5948
+ const object = internal2.createObject(
5949
+ sanitizedPath,
5950
+ nativeObject,
5951
+ sanitizedConfig,
5952
+ actions,
5953
+ opts?.visible,
5954
+ opts?.transient,
5955
+ opts?.static
5956
+ );
5957
+ if (process.env.NODE_ENV !== "production") {
5958
+ setUnsanitizedObjectProps(object, config);
5959
+ }
5960
+ if (opts?.showPropsOf !== void 0) {
5961
+ object.template.setShowPropsOf(
5962
+ resolveShowPropsOfSources(
5963
+ object,
5964
+ opts.showPropsOf,
5965
+ "sheet.object(..., {showPropsOf})"
5966
+ )
5967
+ );
5968
+ }
5969
+ return object.publicApi;
5970
+ }
5971
+ }
5972
+ props(config, opts) {
5973
+ const internal2 = privateAPI(this);
5974
+ const objectKey = SHEET_PROPS_OBJECT_KEY;
5975
+ const existingObject = internal2.getSheetPropsObject();
5976
+ const nativeObject = null;
5977
+ const actions = opts?.__actions__THIS_API_IS_UNSTABLE_AND_WILL_CHANGE_IN_THE_NEXT_VERSION;
5978
+ if (existingObject) {
5979
+ if (process.env.NODE_ENV !== "production") {
5980
+ const prevConfig = getUnsanitizedObjectProps(existingObject);
5981
+ if (prevConfig) {
5982
+ if (!(0, import_fast_deep_equal2.default)(config, prevConfig)) {
5983
+ if (opts?.reconfigure === true) {
5984
+ const sanitizedConfig2 = compound(config);
5985
+ existingObject.template.reconfigure(sanitizedConfig2);
5986
+ if (opts.transient !== void 0) {
5987
+ existingObject.template.setTransientPropPaths(
5988
+ opts.transient,
5989
+ sanitizedConfig2
5990
+ );
5991
+ }
5992
+ if (opts.static !== void 0) {
5993
+ existingObject.template.setStaticPropPaths(
5994
+ opts.static,
5995
+ sanitizedConfig2
5996
+ );
5997
+ }
5998
+ setUnsanitizedObjectProps(existingObject, config);
5999
+ return existingObject.publicApi;
6000
+ } else {
6001
+ throw new Error(
6002
+ "You seem to have called sheet.props(config) twice, with different values for `config`. Use the same config on repeat calls, or pass `{reconfigure: true}` to change the schema."
6003
+ );
6004
+ }
6005
+ }
6006
+ }
6007
+ }
6008
+ if (actions) {
6009
+ existingObject.template._temp_setActions(actions);
6010
+ }
6011
+ if (opts?.transient !== void 0) {
6012
+ existingObject.template.setTransientPropPaths(
6013
+ opts.transient,
6014
+ existingObject.template.staticConfig
6015
+ );
6016
+ }
6017
+ if (opts?.static !== void 0) {
6018
+ existingObject.template.setStaticPropPaths(
6019
+ opts.static,
6020
+ existingObject.template.staticConfig
6021
+ );
6022
+ }
6023
+ return existingObject.publicApi;
6024
+ }
6025
+ const sanitizedConfig = compound(config);
6026
+ const object = internal2.createObject(
6027
+ objectKey,
6028
+ nativeObject,
6029
+ sanitizedConfig,
6030
+ actions,
6031
+ false,
6032
+ opts?.transient,
6033
+ opts?.static
6034
+ );
6035
+ if (process.env.NODE_ENV !== "production") {
6036
+ setUnsanitizedObjectProps(object, config);
6037
+ }
6038
+ return object.publicApi;
6039
+ }
6040
+ get sequence() {
6041
+ return privateAPI(this).getSequence().publicApi;
6042
+ }
6043
+ declareSequenceVariants(variants) {
6044
+ privateAPI(this).template.declareSequenceVariants(variants);
6045
+ }
6046
+ setActiveSequenceVariant(variant) {
6047
+ privateAPI(this).setActiveSequenceVariant(variant);
6048
+ }
6049
+ getActiveSequenceVariant() {
6050
+ return privateAPI(this).getActiveSequenceVariant();
6051
+ }
6052
+ getSequenceMode() {
6053
+ return privateAPI(this).getSequenceMode();
6054
+ }
6055
+ setSequenceMode(mode) {
6056
+ privateAPI(this).setSequenceMode(mode);
6057
+ }
6058
+ setPageScrollDriver(driver) {
6059
+ privateAPI(this).setPageScrollDriver(driver);
6060
+ }
6061
+ get project() {
6062
+ return privateAPI(this).project.publicApi;
6063
+ }
6064
+ get address() {
6065
+ return { ...privateAPI(this).address };
6066
+ }
6067
+ detachObject(key) {
6068
+ const internal2 = privateAPI(this);
6069
+ const sanitizedPath = validateAndSanitiseSlashedPathOrThrow(
6070
+ key,
6071
+ 'sheet.deleteObject("'.concat(key, '")')
6072
+ );
6073
+ if (isSheetPropsObjectKey(sanitizedPath)) {
6074
+ throw new InvalidArgumentError(
6075
+ "Sheet props cannot be detached. They are removed when the sheet instance is unloaded."
6076
+ );
6077
+ }
6078
+ const obj = internal2.getObject(sanitizedPath);
6079
+ if (!obj) {
6080
+ notify.warning(
6081
+ "Couldn't delete object \"".concat(sanitizedPath, '"'),
6082
+ 'There is no object with key "'.concat(sanitizedPath, '".\n\nTo fix this, make sure you are calling `sheet.deleteObject("').concat(sanitizedPath, '")` with the correct key.')
6083
+ );
6084
+ console.warn('Object key "'.concat(sanitizedPath, '" does not exist.'));
6085
+ return;
6086
+ }
6087
+ internal2.deleteObject(sanitizedPath);
6088
+ }
6089
+ getObjects() {
6090
+ return privateAPI(this).getObjects().map((obj) => obj.publicApi);
6091
+ }
6092
+ unload() {
6093
+ privateAPI(this).unload();
6094
+ }
6095
+ declareOutlineNamespace(namespacePath, opts) {
6096
+ const internal2 = privateAPI(this);
6097
+ const parsedPath = parseOutlineNamespacePath(
6098
+ namespacePath,
6099
+ "sheet.declareOutlineNamespace"
6100
+ );
6101
+ internal2.template.setOutlineNamespaceConfig(parsedPath.join(" / "), {
6102
+ defaultCollapsed: opts?.collapsed
6103
+ });
6104
+ }
6105
+ setOutlineNamespaceCollapsed(namespacePath, collapsed) {
6106
+ const internal2 = privateAPI(this);
6107
+ const parsedPath = parseOutlineNamespacePath(
6108
+ namespacePath,
6109
+ "sheet.setOutlineNamespaceCollapsed"
6110
+ );
6111
+ internal2.template.setOutlineNamespaceConfig(parsedPath.join(" / "), {
6112
+ collapsed
6113
+ });
6114
+ }
6115
+ };
6116
+
6117
+ // core/src/sheets/Sheet.ts
6118
+ var import_theatre_dataverse22 = require("@unseenco/theatre-dataverse");
6119
+
6120
+ // shared/src/utils/didYouMean.ts
6121
+ var import_propose = __toESM(require_propose());
6122
+ function didYouMean(str, dictionary, prepend = "Did you mean ", append = "?") {
6123
+ const p2 = (0, import_propose.default)(str, dictionary, {
6124
+ threshold: 0.7
6125
+ });
6126
+ if (p2) {
6127
+ return prepend + JSON.stringify(p2) + append;
6128
+ } else {
6129
+ return "";
6130
+ }
6131
+ }
6132
+
6133
+ // core/src/sequences/Sequence.ts
6134
+ var import_theatre_dataverse15 = require("@unseenco/theatre-dataverse");
6135
+ var import_theatre_dataverse16 = require("@unseenco/theatre-dataverse");
6136
+ var import_theatre_dataverse17 = require("@unseenco/theatre-dataverse");
6137
+ var import_theatre_dataverse18 = require("@unseenco/theatre-dataverse");
6138
+
6139
+ // shared/src/utils/defer.ts
6140
+ function defer() {
6141
+ let resolve;
6142
+ let reject;
6143
+ const promise = new Promise((rs, rj) => {
6144
+ resolve = (v2) => {
6145
+ rs(v2);
6146
+ deferred.status = "resolved";
6147
+ };
6148
+ reject = (v2) => {
6149
+ rj(v2);
6150
+ deferred.status = "rejected";
6151
+ };
6152
+ });
6153
+ const deferred = {
6154
+ resolve,
6155
+ reject,
6156
+ promise,
6157
+ status: "pending"
6158
+ };
6159
+ return deferred;
6160
+ }
6161
+
6162
+ // shared/src/utils/noop.ts
6163
+ var noop = () => {
6164
+ };
6165
+ var noop_default = noop;
6166
+
6167
+ // core/src/sequences/playbackControllers/DefaultPlaybackController.ts
6168
+ var import_theatre_dataverse12 = require("@unseenco/theatre-dataverse");
6169
+ var DefaultPlaybackController = class {
6170
+ constructor() {
6171
+ __publicField(this, "_stopPlayCallback", noop_default);
6172
+ __publicField(this, "_state", new import_theatre_dataverse12.Atom({
6173
+ position: 0,
6174
+ playing: false
6175
+ }));
6176
+ __publicField(this, "statePointer");
6177
+ this.statePointer = this._state.pointer;
6178
+ }
6179
+ destroy() {
6180
+ }
6181
+ pause() {
6182
+ this._stopPlayCallback();
6183
+ this.playing = false;
6184
+ this._stopPlayCallback = noop_default;
6185
+ }
6186
+ gotoPosition(time) {
6187
+ this._updatePositionInState(time);
6188
+ }
6189
+ _updatePositionInState(time) {
6190
+ this._state.setByPointer((p2) => p2.position, time);
6191
+ }
6192
+ getCurrentPosition() {
6193
+ return this._state.get().position;
6194
+ }
6195
+ get playing() {
6196
+ return this._state.get().playing;
6197
+ }
6198
+ set playing(playing) {
6199
+ this._state.setByPointer((p2) => p2.playing, playing);
6200
+ }
6201
+ play(iterationCount, range, rate, direction, ticker) {
6202
+ if (this.playing) {
6203
+ this.pause();
6204
+ }
6205
+ this.playing = true;
6206
+ const iterationLength = range[1] - range[0];
6207
+ {
6208
+ const startPos = this.getCurrentPosition();
6209
+ if (startPos < range[0] || startPos > range[1]) {
6210
+ if (direction === "normal" || direction === "alternate") {
6211
+ this._updatePositionInState(range[0]);
6212
+ } else if (direction === "reverse" || direction === "alternateReverse") {
6213
+ this._updatePositionInState(range[1]);
6214
+ }
6215
+ } else if (direction === "normal" || direction === "alternate") {
6216
+ if (startPos === range[1]) {
6217
+ this._updatePositionInState(range[0]);
6218
+ }
6219
+ } else {
6220
+ if (startPos === range[0]) {
6221
+ this._updatePositionInState(range[1]);
6222
+ }
6223
+ }
6224
+ }
6225
+ const deferred = defer();
6226
+ const initialTickerTime = ticker.time;
6227
+ const totalPlaybackLength = iterationLength * iterationCount;
6228
+ let initialElapsedPos = this.getCurrentPosition() - range[0];
6229
+ if (direction === "reverse" || direction === "alternateReverse") {
6230
+ initialElapsedPos = range[1] - this.getCurrentPosition();
6231
+ }
6232
+ const tick = (currentTickerTime) => {
6233
+ const elapsedTickerTime = Math.max(
6234
+ currentTickerTime - initialTickerTime,
6235
+ 0
6236
+ );
6237
+ const elapsedTickerTimeInSeconds = elapsedTickerTime / 1e3;
6238
+ const elapsedPos = Math.min(
6239
+ elapsedTickerTimeInSeconds * rate + initialElapsedPos,
6240
+ totalPlaybackLength
6241
+ );
6242
+ if (elapsedPos !== totalPlaybackLength) {
6243
+ const iterationNumber = Math.floor(elapsedPos / iterationLength);
6244
+ let currentIterationPos = elapsedPos / iterationLength % 1 * iterationLength;
6245
+ if (direction !== "normal") {
6246
+ if (direction === "reverse") {
6247
+ currentIterationPos = iterationLength - currentIterationPos;
6248
+ } else {
6249
+ const isCurrentIterationNumberEven = iterationNumber % 2 === 0;
6250
+ if (direction === "alternate") {
6251
+ if (!isCurrentIterationNumberEven) {
6252
+ currentIterationPos = iterationLength - currentIterationPos;
6253
+ }
6254
+ } else {
6255
+ if (isCurrentIterationNumberEven) {
6256
+ currentIterationPos = iterationLength - currentIterationPos;
6257
+ }
6258
+ }
6259
+ }
6260
+ }
6261
+ this._updatePositionInState(currentIterationPos + range[0]);
6262
+ requestNextTick();
6263
+ } else {
6264
+ if (direction === "normal") {
6265
+ this._updatePositionInState(range[1]);
6266
+ } else if (direction === "reverse") {
6267
+ this._updatePositionInState(range[0]);
6268
+ } else {
6269
+ const isLastIterationEven = (iterationCount - 1) % 2 === 0;
6270
+ if (direction === "alternate") {
6271
+ if (isLastIterationEven) {
6272
+ this._updatePositionInState(range[1]);
6273
+ } else {
6274
+ this._updatePositionInState(range[0]);
6275
+ }
6276
+ } else {
6277
+ if (isLastIterationEven) {
6278
+ this._updatePositionInState(range[0]);
6279
+ } else {
6280
+ this._updatePositionInState(range[1]);
6281
+ }
6282
+ }
6283
+ }
6284
+ this.playing = false;
6285
+ deferred.resolve(true);
6286
+ }
6287
+ };
6288
+ this._stopPlayCallback = () => {
6289
+ ticker.offThisOrNextTick(tick);
6290
+ ticker.offNextTick(tick);
6291
+ if (this.playing) deferred.resolve(false);
6292
+ };
6293
+ const requestNextTick = () => ticker.onNextTick(tick);
6294
+ ticker.onThisOrNextTick(tick);
6295
+ return deferred.promise;
6296
+ }
6297
+ playDynamicRange(rangeD, ticker) {
6298
+ if (this.playing) {
6299
+ this.pause();
6300
+ }
6301
+ this.playing = true;
6302
+ const deferred = defer();
6303
+ const untapFromRangeD = rangeD.keepHot();
6304
+ void deferred.promise.then(untapFromRangeD, untapFromRangeD);
6305
+ let lastTickerTime = ticker.time;
6306
+ const tick = (currentTickerTime) => {
6307
+ const elapsedSinceLastTick = Math.max(
6308
+ currentTickerTime - lastTickerTime,
6309
+ 0
6310
+ );
6311
+ lastTickerTime = currentTickerTime;
6312
+ const elapsedSinceLastTickInSeconds = elapsedSinceLastTick / 1e3;
6313
+ const lastPosition = this.getCurrentPosition();
6314
+ const range = rangeD.getValue();
6315
+ if (lastPosition < range[0] || lastPosition > range[1]) {
6316
+ this.gotoPosition(range[0]);
6317
+ } else {
6318
+ let newPosition = lastPosition + elapsedSinceLastTickInSeconds;
6319
+ if (newPosition > range[1]) {
6320
+ newPosition = range[0] + (newPosition - range[1]);
6321
+ }
6322
+ this.gotoPosition(newPosition);
6323
+ }
6324
+ requestNextTick();
6325
+ };
6326
+ this._stopPlayCallback = () => {
6327
+ ticker.offThisOrNextTick(tick);
6328
+ ticker.offNextTick(tick);
6329
+ deferred.resolve(false);
6330
+ };
6331
+ const requestNextTick = () => ticker.onNextTick(tick);
6332
+ ticker.onThisOrNextTick(tick);
6333
+ return deferred.promise;
6334
+ }
6335
+ };
6336
+
6337
+ // core/src/sequences/playbackControllers/AudioPlaybackController.ts
6338
+ var import_theatre_dataverse13 = require("@unseenco/theatre-dataverse");
6339
+ var AudioPlaybackController = class {
6340
+ constructor(_decodedBuffer, _audioContext, _nodeDestination) {
6341
+ this._decodedBuffer = _decodedBuffer;
6342
+ this._audioContext = _audioContext;
6343
+ this._nodeDestination = _nodeDestination;
6344
+ __publicField(this, "_mainGain");
6345
+ __publicField(this, "_state", new import_theatre_dataverse13.Atom({
6346
+ position: 0,
6347
+ playing: false
6348
+ }));
6349
+ __publicField(this, "statePointer");
6350
+ __publicField(this, "_stopPlayCallback", noop_default);
6351
+ this.statePointer = this._state.pointer;
6352
+ this._mainGain = this._audioContext.createGain();
6353
+ this._mainGain.connect(this._nodeDestination);
6354
+ }
6355
+ playDynamicRange(rangeD, ticker) {
6356
+ const deferred = defer();
6357
+ if (this._playing) this.pause();
6358
+ this._playing = true;
6359
+ let stop = void 0;
6360
+ const play = () => {
6361
+ stop?.();
6362
+ stop = this._loopInRange(rangeD.getValue(), ticker).stop;
6363
+ };
6364
+ const untapFromRangeD = rangeD.onStale(play);
6365
+ play();
6366
+ this._stopPlayCallback = () => {
6367
+ stop?.();
6368
+ untapFromRangeD();
6369
+ deferred.resolve(false);
6370
+ };
6371
+ return deferred.promise;
6372
+ }
6373
+ _loopInRange(range, ticker) {
6374
+ const rate = 1;
6375
+ let startPos = this.getCurrentPosition();
6376
+ const iterationLength = range[1] - range[0];
6377
+ if (startPos < range[0] || startPos > range[1]) {
6378
+ this._updatePositionInState(range[0]);
6379
+ } else if (startPos === range[1]) {
6380
+ this._updatePositionInState(range[0]);
6381
+ }
6382
+ startPos = this.getCurrentPosition();
6383
+ const currentSource = this._audioContext.createBufferSource();
6384
+ currentSource.buffer = this._decodedBuffer;
6385
+ currentSource.connect(this._mainGain);
6386
+ currentSource.playbackRate.value = rate;
6387
+ currentSource.loop = true;
6388
+ currentSource.loopStart = range[0];
6389
+ currentSource.loopEnd = range[1];
6390
+ const initialTickerTime = ticker.time;
6391
+ let initialElapsedPos = startPos - range[0];
6392
+ currentSource.start(0, startPos);
6393
+ const tick = (currentTickerTime) => {
6394
+ const elapsedTickerTime = Math.max(
6395
+ currentTickerTime - initialTickerTime,
6396
+ 0
6397
+ );
6398
+ const elapsedTickerTimeInSeconds = elapsedTickerTime / 1e3;
6399
+ const elapsedPos = elapsedTickerTimeInSeconds * rate + initialElapsedPos;
6400
+ let currentIterationPos = elapsedPos / iterationLength % 1 * iterationLength;
6401
+ this._updatePositionInState(currentIterationPos + range[0]);
6402
+ requestNextTick();
6403
+ };
6404
+ const requestNextTick = () => ticker.onNextTick(tick);
6405
+ ticker.onThisOrNextTick(tick);
6406
+ const stop = () => {
6407
+ currentSource.stop();
6408
+ currentSource.disconnect();
6409
+ ticker.offThisOrNextTick(tick);
6410
+ ticker.offNextTick(tick);
6411
+ };
6412
+ return { stop };
6413
+ }
6414
+ get _playing() {
6415
+ return this._state.get().playing;
6416
+ }
6417
+ set _playing(playing) {
6418
+ this._state.setByPointer((p2) => p2.playing, playing);
6419
+ }
6420
+ destroy() {
5890
6421
  }
5891
6422
  pause() {
5892
6423
  this._stopPlayCallback();
@@ -5931,11 +6462,11 @@ var AudioPlaybackController = class {
5931
6462
  "The sequence will still play, but only 1000 times. The `iterationCount: ".concat(iterationCount, "` provided to `sequence.play()`\nis too high for a sequence with audio.\n\nTo fix this, either set `iterationCount` to a lower value, or remove the audio from the sequence."),
5932
6463
  [
5933
6464
  {
5934
- url: "https://www.theatrejs.com/docs/latest/manual/audio",
6465
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/audio",
5935
6466
  title: "Using Audio"
5936
6467
  },
5937
6468
  {
5938
- url: "https://www.theatrejs.com/docs/latest/api/core#sequence.attachaudio",
6469
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sequence.attachaudio",
5939
6470
  title: "Audio API"
5940
6471
  }
5941
6472
  ]
@@ -5988,82 +6519,6 @@ var AudioPlaybackController = class {
5988
6519
  }
5989
6520
  };
5990
6521
 
5991
- // core/src/rafDrivers.ts
5992
- var import_theatre_dataverse10 = require("@unseenco/theatre-dataverse");
5993
- var lastDriverId = 0;
5994
- function createRafDriver(conf) {
5995
- const tick = (time) => {
5996
- ticker.tick(time);
5997
- };
5998
- const ticker = new import_theatre_dataverse10.Ticker({
5999
- onActive() {
6000
- conf?.start?.();
6001
- },
6002
- onDormant() {
6003
- conf?.stop?.();
6004
- }
6005
- });
6006
- const driverPublicApi = {
6007
- tick,
6008
- id: lastDriverId++,
6009
- name: conf?.name ?? "CustomRafDriver-".concat(lastDriverId),
6010
- type: "Theatre_RafDriver_PublicAPI"
6011
- };
6012
- const driverPrivateApi = {
6013
- type: "Theatre_RafDriver_PrivateAPI",
6014
- publicApi: driverPublicApi,
6015
- ticker,
6016
- start: conf?.start,
6017
- stop: conf?.stop
6018
- };
6019
- setPrivateAPI(driverPublicApi, driverPrivateApi);
6020
- return driverPublicApi;
6021
- }
6022
-
6023
- // core/src/coreTicker.ts
6024
- function createBasicRafDriver() {
6025
- let rafId = null;
6026
- const start = () => {
6027
- if (typeof window !== "undefined") {
6028
- const onAnimationFrame = (t2) => {
6029
- driver.tick(t2);
6030
- rafId = window.requestAnimationFrame(onAnimationFrame);
6031
- };
6032
- rafId = window.requestAnimationFrame(onAnimationFrame);
6033
- } else {
6034
- driver.tick(0);
6035
- setTimeout(() => driver.tick(1), 0);
6036
- }
6037
- };
6038
- const stop = () => {
6039
- if (typeof window !== "undefined") {
6040
- if (rafId !== null) {
6041
- window.cancelAnimationFrame(rafId);
6042
- }
6043
- } else {
6044
- }
6045
- };
6046
- const driver = createRafDriver({ name: "DefaultCoreRafDriver", start, stop });
6047
- return driver;
6048
- }
6049
- var coreRafDriver;
6050
- function getCoreRafDriver() {
6051
- if (!coreRafDriver) {
6052
- setCoreRafDriver(createBasicRafDriver());
6053
- }
6054
- return coreRafDriver;
6055
- }
6056
- function getCoreTicker() {
6057
- return getCoreRafDriver().ticker;
6058
- }
6059
- function setCoreRafDriver(driver) {
6060
- if (coreRafDriver) {
6061
- throw new Error("`setCoreRafDriver()` is already called.");
6062
- }
6063
- const driverPrivateApi = privateAPI(driver);
6064
- coreRafDriver = driverPrivateApi;
6065
- }
6066
-
6067
6522
  // core/src/sequences/TheatreSequence.ts
6068
6523
  var TheatreSequence = class {
6069
6524
  get type() {
@@ -6087,7 +6542,7 @@ var TheatreSequence = class {
6087
6542
  "You seem to have called `sequence.play()` before the project has finished loading.\n\nThis would **not** a problem in production when using `@unseenco/theatre-core`, since Theatre.js loads instantly in core mode. However, when using `@unseenco/theatre-studio`, it takes a few milliseconds for it to load your project's state, before which your sequences cannot start playing.\n\nTo fix this, simply defer calling `sequence.play()` until after the project is loaded, like this:\n\n```\nproject.ready.then(() => {\n sequence.play()\n})\n```",
6088
6543
  [
6089
6544
  {
6090
- url: "https://www.theatrejs.com/docs/0.5/api/core#project.ready",
6545
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#project.ready",
6091
6546
  title: "Project.ready"
6092
6547
  }
6093
6548
  ]
@@ -6113,14 +6568,27 @@ var TheatreSequence = class {
6113
6568
  __experimental_getGsapClips() {
6114
6569
  return privateAPI(this).getGsapClips();
6115
6570
  }
6571
+ __experimental_getGsapScrollTriggers() {
6572
+ return privateAPI(this).getGsapScrollTriggers();
6573
+ }
6116
6574
  async attachAudio(args) {
6575
+ const priv = privateAPI(this);
6576
+ if (priv._sheet.getSequenceMode() === "page") {
6577
+ notify.warning(
6578
+ "Audio is not supported in page mode",
6579
+ "Sequence audio expects time in seconds. Use time mode for attachAudio(), or scrub scroll-driven animation without audio."
6580
+ );
6581
+ return Promise.reject(
6582
+ new Error("sequence.attachAudio() is not supported in page mode")
6583
+ );
6584
+ }
6117
6585
  const { audioContext, destinationNode, decodedBuffer, gainNode } = await resolveAudioBuffer(args);
6118
6586
  const playbackController = new AudioPlaybackController(
6119
6587
  decodedBuffer,
6120
6588
  audioContext,
6121
6589
  gainNode
6122
6590
  );
6123
- privateAPI(this).replacePlaybackController(playbackController);
6591
+ priv.replacePlaybackController(playbackController);
6124
6592
  return { audioContext, destinationNode, decodedBuffer, gainNode };
6125
6593
  }
6126
6594
  get pointer() {
@@ -6218,6 +6686,31 @@ async function resolveAudioBuffer(args) {
6218
6686
  };
6219
6687
  }
6220
6688
 
6689
+ // shared/src/gsap/gsapStudioRegistryRevision.ts
6690
+ var import_theatre_dataverse14 = require("@unseenco/theatre-dataverse");
6691
+ var revisionAtom = new import_theatre_dataverse14.Atom(0);
6692
+ var gsapStudioRegistryRevisionPointer = revisionAtom.pointer;
6693
+
6694
+ // shared/src/gsap/scrollTriggerRegistry.ts
6695
+ var DEFAULT_SHEET_INSTANCE_ID = "default";
6696
+ var REGISTRY_KEY = "__unseenco_theatre_gsap_scrollTriggerRegistry__";
6697
+ function sheetAddressKey(address) {
6698
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID;
6699
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId);
6700
+ }
6701
+ function getStore() {
6702
+ const g2 = globalThis;
6703
+ if (!g2[REGISTRY_KEY]) {
6704
+ g2[REGISTRY_KEY] = { bySheetAddress: /* @__PURE__ */ new Map() };
6705
+ }
6706
+ return g2[REGISTRY_KEY];
6707
+ }
6708
+ function listScrollTriggerEntriesForSheet(sheetKey) {
6709
+ const map = getStore().bySheetAddress.get(sheetKey);
6710
+ if (!map) return [];
6711
+ return [...map.values()].sort((a2, b2) => a2.layout.start - b2.layout.start);
6712
+ }
6713
+
6221
6714
  // shared/src/sequence/trackData.ts
6222
6715
  function isBasicKeyframedTrack(track) {
6223
6716
  return track.type === "BasicKeyframedTrack";
@@ -6260,7 +6753,7 @@ var Sequence = class {
6260
6753
  __publicField(this, "_positionD");
6261
6754
  __publicField(this, "_positionFormatterD");
6262
6755
  __publicField(this, "_playableRangeD");
6263
- __publicField(this, "pointer", (0, import_theatre_dataverse13.pointer)({ root: this, path: [] }));
6756
+ __publicField(this, "pointer", (0, import_theatre_dataverse17.pointer)({ root: this, path: [] }));
6264
6757
  __publicField(this, "$$isPointerToPrismProvider", true);
6265
6758
  __publicField(this, "_logger");
6266
6759
  __publicField(this, "closestGridPosition", (posInUnitSpace) => {
@@ -6273,32 +6766,35 @@ var Sequence = class {
6273
6766
  this._logger = _project._logger.named("Sheet", _sheet.address.sheetId).named("Instance", _sheet.address.sheetInstanceId).named("Variant", _sequenceVariant);
6274
6767
  this.address = { ...this._sheet.address, sequenceName: _sequenceVariant };
6275
6768
  this.publicApi = new TheatreSequence(this);
6276
- this._playbackControllerBox = new import_theatre_dataverse12.Atom(
6769
+ this._playbackControllerBox = new import_theatre_dataverse16.Atom(
6277
6770
  playbackController ?? new DefaultPlaybackController()
6278
6771
  );
6279
- this._prismOfStatePointer = (0, import_theatre_dataverse14.prism)(
6772
+ this._prismOfStatePointer = (0, import_theatre_dataverse18.prism)(
6280
6773
  () => this._playbackControllerBox.prism.getValue().statePointer
6281
6774
  );
6282
- this._positionD = (0, import_theatre_dataverse14.prism)(() => {
6775
+ this._positionD = (0, import_theatre_dataverse18.prism)(() => {
6283
6776
  const statePointer = this._prismOfStatePointer.getValue();
6284
- return (0, import_theatre_dataverse14.val)(statePointer.position);
6777
+ return (0, import_theatre_dataverse18.val)(statePointer.position);
6285
6778
  });
6286
- this._positionFormatterD = (0, import_theatre_dataverse14.prism)(() => {
6287
- const subUnitsPerUnit = (0, import_theatre_dataverse14.val)(this._subUnitsPerUnitD);
6779
+ this._positionFormatterD = (0, import_theatre_dataverse18.prism)(() => {
6780
+ const subUnitsPerUnit = (0, import_theatre_dataverse18.val)(this._subUnitsPerUnitD);
6781
+ if (this._sheet.getSequenceMode() === "page") {
6782
+ return new PercentBasedPositionFormatter(subUnitsPerUnit);
6783
+ }
6288
6784
  return new TimeBasedPositionFormatter(subUnitsPerUnit);
6289
6785
  });
6290
6786
  }
6291
- pointerToPrism(pointer3) {
6292
- const { path } = (0, import_theatre_dataverse11.getPointerParts)(pointer3);
6787
+ pointerToPrism(pointer4) {
6788
+ const { path } = (0, import_theatre_dataverse15.getPointerParts)(pointer4);
6293
6789
  if (path.length === 0) {
6294
- return (0, import_theatre_dataverse14.prism)(() => ({
6295
- length: (0, import_theatre_dataverse14.val)(this.pointer.length),
6296
- playing: (0, import_theatre_dataverse14.val)(this.pointer.playing),
6297
- position: (0, import_theatre_dataverse14.val)(this.pointer.position)
6790
+ return (0, import_theatre_dataverse18.prism)(() => ({
6791
+ length: (0, import_theatre_dataverse18.val)(this.pointer.length),
6792
+ playing: (0, import_theatre_dataverse18.val)(this.pointer.playing),
6793
+ position: (0, import_theatre_dataverse18.val)(this.pointer.position)
6298
6794
  }));
6299
6795
  }
6300
6796
  if (path.length > 1) {
6301
- return (0, import_theatre_dataverse14.prism)(() => void 0);
6797
+ return (0, import_theatre_dataverse18.prism)(() => void 0);
6302
6798
  }
6303
6799
  const [prop] = path;
6304
6800
  if (prop === "length") {
@@ -6306,11 +6802,11 @@ var Sequence = class {
6306
6802
  } else if (prop === "position") {
6307
6803
  return this._positionD;
6308
6804
  } else if (prop === "playing") {
6309
- return (0, import_theatre_dataverse14.prism)(() => {
6310
- return (0, import_theatre_dataverse14.val)(this._prismOfStatePointer.getValue().playing);
6805
+ return (0, import_theatre_dataverse18.prism)(() => {
6806
+ return (0, import_theatre_dataverse18.val)(this._prismOfStatePointer.getValue().playing);
6311
6807
  });
6312
6808
  } else {
6313
- return (0, import_theatre_dataverse14.prism)(() => void 0);
6809
+ return (0, import_theatre_dataverse18.prism)(() => void 0);
6314
6810
  }
6315
6811
  }
6316
6812
  /**
@@ -6319,13 +6815,13 @@ var Sequence = class {
6319
6815
  * Theoretically, this method can be called from inside a prism so it can be reactive.
6320
6816
  */
6321
6817
  getKeyframesOfSimpleProp(prop) {
6322
- const { path, root: root2 } = (0, import_theatre_dataverse11.getPointerParts)(prop);
6818
+ const { path, root: root2 } = (0, import_theatre_dataverse15.getPointerParts)(prop);
6323
6819
  if (!isSheetObject(root2)) {
6324
6820
  throw new InvalidArgumentError(
6325
6821
  "Argument prop must be a pointer to a SheetObject property"
6326
6822
  );
6327
6823
  }
6328
- const sheetState = (0, import_theatre_dataverse14.val)(
6824
+ const sheetState = (0, import_theatre_dataverse18.val)(
6329
6825
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6330
6826
  );
6331
6827
  const trackP = getSequenceStateFromSheet(sheetState, this._sequenceVariant)?.tracksByObject[root2.address.objectKey];
@@ -6348,7 +6844,7 @@ var Sequence = class {
6348
6844
  * @internal Used by the public sequence API.
6349
6845
  */
6350
6846
  getGsapClipsForObject(objectKey) {
6351
- const sheetState = (0, import_theatre_dataverse14.val)(
6847
+ const sheetState = (0, import_theatre_dataverse18.val)(
6352
6848
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6353
6849
  );
6354
6850
  const tracksOfObject = getSequenceStateFromSheet(
@@ -6365,7 +6861,7 @@ var Sequence = class {
6365
6861
  return result.sort((a2, b2) => a2.clip.start - b2.clip.start);
6366
6862
  }
6367
6863
  getGsapClips() {
6368
- const sheetState = (0, import_theatre_dataverse14.val)(
6864
+ const sheetState = (0, import_theatre_dataverse18.val)(
6369
6865
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6370
6866
  );
6371
6867
  const sequenceState = getSequenceStateFromSheet(
@@ -6390,6 +6886,21 @@ var Sequence = class {
6390
6886
  }
6391
6887
  return result.sort((a2, b2) => a2.clip.start - b2.clip.start);
6392
6888
  }
6889
+ getGsapScrollTriggers() {
6890
+ if (this._sheet.getSequenceMode() !== "page") {
6891
+ return [];
6892
+ }
6893
+ const key = sheetAddressKey(this._sheet.address);
6894
+ return listScrollTriggerEntriesForSheet(key).filter((entry) => entry.sheetObject != null).map((entry) => ({
6895
+ objectKey: entry.sheetObject.address.objectKey,
6896
+ scrollTriggerId: entry.id,
6897
+ label: entry.label,
6898
+ layout: entry.layout,
6899
+ kind: entry.kind,
6900
+ animationSpanSeconds: entry.animationSpanSeconds,
6901
+ timelineChildren: entry.timelineChildren
6902
+ }));
6903
+ }
6393
6904
  get positionFormatter() {
6394
6905
  return this._positionFormatterD.getValue();
6395
6906
  }
@@ -6432,542 +6943,704 @@ var Sequence = class {
6432
6943
  position = this.length;
6433
6944
  }
6434
6945
  const dur = this.length;
6435
- this._playbackControllerBox.get().gotoPosition(position > dur ? dur : position);
6436
- }
6437
- getDurationCold() {
6438
- return this._lengthD.getValue();
6439
- }
6440
- get playing() {
6441
- return (0, import_theatre_dataverse14.val)(this._playbackControllerBox.get().statePointer.playing);
6442
- }
6443
- _makeRangeFromSequenceTemplate() {
6444
- return (0, import_theatre_dataverse14.prism)(() => {
6445
- return [0, (0, import_theatre_dataverse14.val)(this._lengthD)];
6446
- });
6447
- }
6448
- /**
6449
- * Controls the playback within a range. Repeats infinitely unless stopped.
6450
- *
6451
- * @remarks
6452
- * One use case for this is to play the playback within the focus range.
6453
- *
6454
- * @param rangeD - The prism that contains the range that will be used for the playback
6455
- *
6456
- * @returns a promise that gets rejected if the playback stopped for whatever reason
6457
- *
6458
- */
6459
- playDynamicRange(rangeD, ticker) {
6460
- return this._playbackControllerBox.get().playDynamicRange(rangeD, ticker);
6461
- }
6462
- async play(conf, ticker) {
6463
- const sequenceDuration = this.length;
6464
- const range = conf && conf.range ? conf.range : [0, sequenceDuration];
6465
- if (process.env.NODE_ENV !== "production") {
6466
- if (typeof range[0] !== "number" || range[0] < 0) {
6467
- throw new InvalidArgumentError(
6468
- "Argument conf.range[0] in sequence.play(conf) must be a positive number. ".concat(JSON.stringify(
6469
- range[0]
6470
- ), " given.")
6471
- );
6472
- }
6473
- if (range[0] >= sequenceDuration) {
6474
- throw new InvalidArgumentError(
6475
- "Argument conf.range[0] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ".concat(sequenceDuration, "s. ").concat(JSON.stringify(
6476
- range[0]
6477
- ), " given.")
6478
- );
6479
- }
6480
- if (typeof range[1] !== "number" || range[1] <= 0) {
6481
- throw new InvalidArgumentError(
6482
- "Argument conf.range[1] in sequence.play(conf) must be a number larger than zero. ".concat(JSON.stringify(
6483
- range[1]
6484
- ), " given.")
6485
- );
6486
- }
6487
- if (range[1] > sequenceDuration) {
6488
- notify.warning(
6489
- "Couldn't play sequence in given range",
6490
- "Your animation will still play until the end of the sequence, however the argument `conf.range[1]` given in `sequence.play(conf)` (".concat(JSON.stringify(
6491
- range[1]
6492
- ), "s) is longer than the duration of the sequence (").concat(sequenceDuration, "s).\n\nTo fix this, either set `conf.range[1]` to be less the duration of the sequence, or adjust the sequence duration in the UI."),
6493
- [
6494
- {
6495
- url: "https://www.theatrejs.com/docs/latest/manual/sequences",
6496
- title: "Sequences"
6497
- },
6498
- {
6499
- url: "https://www.theatrejs.com/docs/latest/manual/sequences",
6500
- title: "Playback API"
6501
- }
6502
- ]
6503
- );
6504
- range[1] = sequenceDuration;
6505
- }
6506
- if (range[1] <= range[0]) {
6507
- throw new InvalidArgumentError(
6508
- "Argument conf.range[1] in sequence.play(conf) must be larger than conf.range[0]. ".concat(JSON.stringify(
6509
- range
6510
- ), " given.")
6511
- );
6512
- }
6513
- }
6514
- const iterationCount = conf && typeof conf.iterationCount === "number" ? conf.iterationCount : 1;
6515
- if (process.env.NODE_ENV !== "production") {
6516
- if (!(Number.isInteger(iterationCount) && iterationCount > 0) && iterationCount !== Infinity) {
6517
- throw new InvalidArgumentError(
6518
- "Argument conf.iterationCount in sequence.play(conf) must be an integer larger than 0. ".concat(JSON.stringify(
6519
- iterationCount
6520
- ), " given.")
6521
- );
6522
- }
6523
- }
6524
- const rate = conf && typeof conf.rate !== "undefined" ? conf.rate : 1;
6525
- if (process.env.NODE_ENV !== "production") {
6526
- if (typeof rate !== "number" || rate === 0) {
6527
- throw new InvalidArgumentError(
6528
- "Argument conf.rate in sequence.play(conf) must be a number larger than 0. ".concat(JSON.stringify(
6529
- rate
6530
- ), " given.")
6531
- );
6532
- }
6533
- if (rate < 0) {
6534
- throw new InvalidArgumentError(
6535
- "Argument conf.rate in sequence.play(conf) must be a number larger than 0. ".concat(JSON.stringify(
6536
- rate
6537
- ), " given. If you want the animation to play backwards, try setting conf.direction to 'reverse' or 'alternateReverse'.")
6538
- );
6539
- }
6540
- }
6541
- const direction = conf && conf.direction ? conf.direction : "normal";
6542
- if (process.env.NODE_ENV !== "production") {
6543
- if (possibleDirections.indexOf(direction) === -1) {
6544
- throw new InvalidArgumentError(
6545
- "Argument conf.direction in sequence.play(conf) must be one of ".concat(JSON.stringify(
6546
- possibleDirections
6547
- ), ". ").concat(JSON.stringify(direction), " given. ").concat(didYouMean(
6548
- direction,
6549
- possibleDirections
6550
- ))
6551
- );
6552
- }
6553
- }
6554
- return await this._play(
6555
- iterationCount,
6556
- [range[0], range[1]],
6557
- rate,
6558
- direction,
6559
- ticker
6560
- );
6561
- }
6562
- _play(iterationCount, range, rate, direction, ticker) {
6563
- return this._playbackControllerBox.get().play(iterationCount, range, rate, direction, ticker);
6564
- }
6565
- pause() {
6566
- this._playbackControllerBox.get().pause();
6567
- }
6568
- replacePlaybackController(playbackController) {
6569
- this.pause();
6570
- const oldController = this._playbackControllerBox.get();
6571
- this._playbackControllerBox.set(playbackController);
6572
- const time = oldController.getCurrentPosition();
6573
- oldController.destroy();
6574
- playbackController.gotoPosition(time);
6575
- }
6576
- };
6577
- var TimeBasedPositionFormatter = class {
6578
- constructor(_fps) {
6579
- this._fps = _fps;
6580
- }
6581
- formatSubUnitForGrid(posInUnitSpace) {
6582
- const subSecondPos = posInUnitSpace % 1;
6583
- const frame = 1 / this._fps;
6584
- const frames = Math.round(subSecondPos / frame);
6585
- return frames + "f";
6586
- }
6587
- formatFullUnitForGrid(posInUnitSpace) {
6588
- let p2 = posInUnitSpace;
6589
- let s2 = "";
6590
- if (p2 >= hour) {
6591
- const hours = Math.floor(p2 / hour);
6592
- s2 += hours + "h";
6593
- p2 = p2 % hour;
6594
- }
6595
- if (p2 >= minute) {
6596
- const minutes = Math.floor(p2 / minute);
6597
- s2 += minutes + "m";
6598
- p2 = p2 % minute;
6599
- }
6600
- if (p2 >= second) {
6601
- const seconds = Math.floor(p2 / second);
6602
- s2 += seconds + "s";
6603
- p2 = p2 % second;
6604
- }
6605
- const frame = 1 / this._fps;
6606
- if (p2 >= frame) {
6607
- const frames = Math.floor(p2 / frame);
6608
- s2 += frames + "f";
6609
- p2 = p2 % frame;
6610
- }
6611
- return s2.length === 0 ? "0s" : s2;
6612
- }
6613
- formatForPlayhead(posInUnitSpace) {
6614
- let p2 = posInUnitSpace;
6615
- let s2 = "";
6616
- if (p2 >= hour) {
6617
- const hours = Math.floor(p2 / hour);
6618
- s2 += padStart_default(hours.toString(), 2, "0") + "h";
6619
- p2 = p2 % hour;
6620
- }
6621
- if (p2 >= minute) {
6622
- const minutes = Math.floor(p2 / minute);
6623
- s2 += padStart_default(minutes.toString(), 2, "0") + "m";
6624
- p2 = p2 % minute;
6625
- } else if (s2.length > 0) {
6626
- s2 += "00m";
6627
- }
6628
- if (p2 >= second) {
6629
- const seconds = Math.floor(p2 / second);
6630
- s2 += padStart_default(seconds.toString(), 2, "0") + "s";
6631
- p2 = p2 % second;
6632
- } else {
6633
- s2 += "00s";
6634
- }
6635
- const frameLength = 1 / this._fps;
6636
- if (p2 >= frameLength) {
6637
- const frames = Math.round(p2 / frameLength);
6638
- s2 += padStart_default(frames.toString(), 2, "0") + "f";
6639
- p2 = p2 % frameLength;
6640
- } else if (p2 / frameLength > 0.98) {
6641
- const frames = 1;
6642
- s2 += padStart_default(frames.toString(), 2, "0") + "f";
6643
- p2 = p2 % frameLength;
6644
- } else {
6645
- s2 += "00f";
6646
- }
6647
- return s2.length === 0 ? "00s00f" : s2;
6648
- }
6649
- formatBasic(posInUnitSpace) {
6650
- return posInUnitSpace.toFixed(2) + "s";
6651
- }
6652
- };
6653
- var second = 1;
6654
- var minute = second * 60;
6655
- var hour = minute * 60;
6656
-
6657
- // shared/src/utils/slashedPaths.ts
6658
- var normalizeSlashedPath = (p2) => p2.replace(/^[\s\/]*/, "").replace(/[\s\/]*$/, "").replace(/\s*\/\s*/g, " / ");
6659
- var getValidationErrorsOfSlashedPath = (p2) => {
6660
- if (typeof p2 !== "string") return "it is not a string. (it is a ".concat(typeof p2, ")");
6661
- const components = p2.split(/\//);
6662
- if (components.length === 0) return "it is empty.";
6663
- for (let i2 = 0; i2 < components.length; i2++) {
6664
- const component = components[i2].trim();
6665
- if (component.length === 0) return "the component #".concat(i2 + 1, " is empty.");
6666
- if (component.length > 64)
6667
- return "the component '".concat(component, "' must have 64 characters or less.");
6668
- }
6669
- };
6670
- function validateAndSanitiseSlashedPathOrThrow(unsanitisedPath, fnName) {
6671
- const sanitisedPath = normalizeSlashedPath(unsanitisedPath);
6672
- if (process.env.NODE_ENV !== "development") {
6673
- return sanitisedPath;
6946
+ this._playbackControllerBox.get().gotoPosition(position > dur ? dur : position);
6674
6947
  }
6675
- const validation = getValidationErrorsOfSlashedPath(sanitisedPath);
6676
- if (validation) {
6677
- throw new InvalidArgumentError(
6678
- "The path in ".concat(fnName, "(").concat(typeof unsanitisedPath === "string" ? '"'.concat(unsanitisedPath, '"') : "", ") is invalid because ").concat(validation)
6679
- );
6948
+ getDurationCold() {
6949
+ return this._lengthD.getValue();
6680
6950
  }
6681
- if (unsanitisedPath !== sanitisedPath) {
6682
- notify.warning(
6683
- "Invalid path provided to object",
6684
- "The path in `".concat(fnName, '("').concat(unsanitisedPath, '")` was sanitized to `"').concat(sanitisedPath, '"`.\n\n') + "Please replace the path with the sanitized one, otherwise it will likely break in the future.",
6685
- [
6686
- {
6687
- url: "https://www.theatrejs.com/docs/latest/manual/objects#creating-sheet-objects",
6688
- title: "Sheet Objects"
6689
- },
6690
- {
6691
- url: "https://www.theatrejs.com/docs/latest/api/core#sheet.object",
6692
- title: "API"
6693
- }
6694
- ]
6695
- );
6951
+ get playing() {
6952
+ return (0, import_theatre_dataverse18.val)(this._playbackControllerBox.get().statePointer.playing);
6696
6953
  }
6697
- return sanitisedPath;
6698
- }
6699
-
6700
- // shared/src/utils/outlineNamespaces.ts
6701
- function parseOutlineNamespacePath(namespacePath, fnName) {
6702
- return validateAndSanitiseSlashedPathOrThrow(namespacePath, fnName).split(
6703
- /\s*\/\s*/g
6704
- );
6705
- }
6706
-
6707
- // core/src/sheets/TheatreSheet.ts
6708
- var import_fast_deep_equal2 = __toESM(require_fast_deep_equal());
6709
- var TheatreSheet = class {
6710
- get type() {
6711
- return "Theatre_Sheet_PublicAPI";
6954
+ _makeRangeFromSequenceTemplate() {
6955
+ return (0, import_theatre_dataverse18.prism)(() => {
6956
+ return [0, (0, import_theatre_dataverse18.val)(this._lengthD)];
6957
+ });
6712
6958
  }
6713
6959
  /**
6714
- * @internal
6960
+ * Controls the playback within a range. Repeats infinitely unless stopped.
6961
+ *
6962
+ * @remarks
6963
+ * One use case for this is to play the playback within the focus range.
6964
+ *
6965
+ * @param rangeD - The prism that contains the range that will be used for the playback
6966
+ *
6967
+ * @returns a promise that gets rejected if the playback stopped for whatever reason
6968
+ *
6715
6969
  */
6716
- constructor(sheet) {
6717
- setPrivateAPI(this, sheet);
6970
+ playDynamicRange(rangeD, ticker) {
6971
+ return this._playbackControllerBox.get().playDynamicRange(rangeD, ticker);
6718
6972
  }
6719
- object(key, config, opts) {
6720
- const internal2 = privateAPI(this);
6721
- const sanitizedPath = validateAndSanitiseSlashedPathOrThrow(
6722
- key,
6723
- "sheet.object"
6724
- );
6725
- if (isSheetPropsObjectKey(sanitizedPath)) {
6726
- throw new InvalidArgumentError(
6727
- 'The key "'.concat(sanitizedPath, '" is reserved for sheet-level props. Use sheet.props() instead of sheet.object().')
6973
+ async play(conf, ticker) {
6974
+ if (this._sheet.getSequenceMode() === "page") {
6975
+ notify.warning(
6976
+ "Playback is disabled in page mode",
6977
+ "The sequence is driven by page scroll. Scrub the playhead or scroll the page instead of calling sequence.play()."
6728
6978
  );
6979
+ return false;
6729
6980
  }
6730
- const existingObject = internal2.getObject(sanitizedPath);
6731
- const nativeObject = null;
6732
- const actions = opts?.__actions__THIS_API_IS_UNSTABLE_AND_WILL_CHANGE_IN_THE_NEXT_VERSION;
6733
- if (existingObject) {
6734
- if (process.env.NODE_ENV !== "production") {
6735
- const prevConfig = getUnsanitizedObjectProps(existingObject);
6736
- if (prevConfig) {
6737
- if (!(0, import_fast_deep_equal2.default)(config, prevConfig)) {
6738
- if (opts?.reconfigure === true) {
6739
- const sanitizedConfig = compound(config);
6740
- existingObject.template.reconfigure(sanitizedConfig);
6741
- if (opts.transient !== void 0) {
6742
- existingObject.template.setTransientPropPaths(
6743
- opts.transient,
6744
- sanitizedConfig
6745
- );
6746
- }
6747
- if (opts.static !== void 0) {
6748
- existingObject.template.setStaticPropPaths(
6749
- opts.static,
6750
- sanitizedConfig
6751
- );
6752
- }
6753
- if (opts.showPropsOf !== void 0) {
6754
- existingObject.template.setShowPropsOf(
6755
- resolveShowPropsOfSources(
6756
- existingObject,
6757
- opts.showPropsOf,
6758
- "sheet.object(..., {showPropsOf})"
6759
- )
6760
- );
6761
- }
6762
- setUnsanitizedObjectProps(existingObject, config);
6763
- return existingObject.publicApi;
6764
- } else {
6765
- throw new Error(
6766
- 'You seem to have called sheet.object("'.concat(key, '", config) twice, with different values for `config`. ') + "This is disallowed because changing the config of an object on the fly would make it difficult to reason about.\n\n" + 'You can fix this by either re-using the existing object, or calling sheet.object("'.concat(key, '", config) with the same config.\n\n') + "If you mean to reconfigure the object's config, set `{reconfigure: true}` in sheet.object(\"".concat(key, '", config, {reconfigure: true})')
6767
- );
6768
- }
6769
- }
6770
- }
6771
- }
6772
- if (actions) {
6773
- existingObject.template._temp_setActions(actions);
6774
- }
6775
- if (opts?.visible !== void 0) {
6776
- existingObject.template.setVisibleInOutline(opts.visible);
6777
- }
6778
- if (opts?.transient !== void 0) {
6779
- existingObject.template.setTransientPropPaths(
6780
- opts.transient,
6781
- existingObject.template.staticConfig
6981
+ const sequenceDuration = this.length;
6982
+ const range = conf && conf.range ? conf.range : [0, sequenceDuration];
6983
+ if (process.env.NODE_ENV !== "production") {
6984
+ if (typeof range[0] !== "number" || range[0] < 0) {
6985
+ throw new InvalidArgumentError(
6986
+ "Argument conf.range[0] in sequence.play(conf) must be a positive number. ".concat(JSON.stringify(
6987
+ range[0]
6988
+ ), " given.")
6782
6989
  );
6783
6990
  }
6784
- if (opts?.static !== void 0) {
6785
- existingObject.template.setStaticPropPaths(
6786
- opts.static,
6787
- existingObject.template.staticConfig
6991
+ if (range[0] >= sequenceDuration) {
6992
+ throw new InvalidArgumentError(
6993
+ "Argument conf.range[0] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ".concat(sequenceDuration, "s. ").concat(JSON.stringify(
6994
+ range[0]
6995
+ ), " given.")
6788
6996
  );
6789
6997
  }
6790
- if (opts?.showPropsOf !== void 0) {
6791
- existingObject.template.setShowPropsOf(
6792
- resolveShowPropsOfSources(
6793
- existingObject,
6794
- opts.showPropsOf,
6795
- "sheet.object(..., {showPropsOf})"
6796
- )
6998
+ if (typeof range[1] !== "number" || range[1] <= 0) {
6999
+ throw new InvalidArgumentError(
7000
+ "Argument conf.range[1] in sequence.play(conf) must be a number larger than zero. ".concat(JSON.stringify(
7001
+ range[1]
7002
+ ), " given.")
6797
7003
  );
6798
7004
  }
6799
- return existingObject.publicApi;
6800
- } else {
6801
- const sanitizedConfig = compound(config);
6802
- const object = internal2.createObject(
6803
- sanitizedPath,
6804
- nativeObject,
6805
- sanitizedConfig,
6806
- actions,
6807
- opts?.visible,
6808
- opts?.transient,
6809
- opts?.static
6810
- );
6811
- if (process.env.NODE_ENV !== "production") {
6812
- setUnsanitizedObjectProps(object, config);
7005
+ if (range[1] > sequenceDuration) {
7006
+ notify.warning(
7007
+ "Couldn't play sequence in given range",
7008
+ "Your animation will still play until the end of the sequence, however the argument `conf.range[1]` given in `sequence.play(conf)` (".concat(JSON.stringify(
7009
+ range[1]
7010
+ ), "s) is longer than the duration of the sequence (").concat(sequenceDuration, "s).\n\nTo fix this, either set `conf.range[1]` to be less the duration of the sequence, or adjust the sequence duration in the UI."),
7011
+ [
7012
+ {
7013
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/sequences",
7014
+ title: "Sequences"
7015
+ },
7016
+ {
7017
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/sequences",
7018
+ title: "Playback API"
7019
+ }
7020
+ ]
7021
+ );
7022
+ range[1] = sequenceDuration;
6813
7023
  }
6814
- if (opts?.showPropsOf !== void 0) {
6815
- object.template.setShowPropsOf(
6816
- resolveShowPropsOfSources(
6817
- object,
6818
- opts.showPropsOf,
6819
- "sheet.object(..., {showPropsOf})"
6820
- )
7024
+ if (range[1] <= range[0]) {
7025
+ throw new InvalidArgumentError(
7026
+ "Argument conf.range[1] in sequence.play(conf) must be larger than conf.range[0]. ".concat(JSON.stringify(
7027
+ range
7028
+ ), " given.")
6821
7029
  );
6822
7030
  }
6823
- return object.publicApi;
6824
7031
  }
6825
- }
6826
- props(config, opts) {
6827
- const internal2 = privateAPI(this);
6828
- const objectKey = SHEET_PROPS_OBJECT_KEY;
6829
- const existingObject = internal2.getSheetPropsObject();
6830
- const nativeObject = null;
6831
- const actions = opts?.__actions__THIS_API_IS_UNSTABLE_AND_WILL_CHANGE_IN_THE_NEXT_VERSION;
6832
- if (existingObject) {
6833
- if (process.env.NODE_ENV !== "production") {
6834
- const prevConfig = getUnsanitizedObjectProps(existingObject);
6835
- if (prevConfig) {
6836
- if (!(0, import_fast_deep_equal2.default)(config, prevConfig)) {
6837
- if (opts?.reconfigure === true) {
6838
- const sanitizedConfig2 = compound(config);
6839
- existingObject.template.reconfigure(sanitizedConfig2);
6840
- if (opts.transient !== void 0) {
6841
- existingObject.template.setTransientPropPaths(
6842
- opts.transient,
6843
- sanitizedConfig2
6844
- );
6845
- }
6846
- if (opts.static !== void 0) {
6847
- existingObject.template.setStaticPropPaths(
6848
- opts.static,
6849
- sanitizedConfig2
6850
- );
6851
- }
6852
- setUnsanitizedObjectProps(existingObject, config);
6853
- return existingObject.publicApi;
6854
- } else {
6855
- throw new Error(
6856
- "You seem to have called sheet.props(config) twice, with different values for `config`. Use the same config on repeat calls, or pass `{reconfigure: true}` to change the schema."
6857
- );
6858
- }
6859
- }
6860
- }
6861
- }
6862
- if (actions) {
6863
- existingObject.template._temp_setActions(actions);
7032
+ const iterationCount = conf && typeof conf.iterationCount === "number" ? conf.iterationCount : 1;
7033
+ if (process.env.NODE_ENV !== "production") {
7034
+ if (!(Number.isInteger(iterationCount) && iterationCount > 0) && iterationCount !== Infinity) {
7035
+ throw new InvalidArgumentError(
7036
+ "Argument conf.iterationCount in sequence.play(conf) must be an integer larger than 0. ".concat(JSON.stringify(
7037
+ iterationCount
7038
+ ), " given.")
7039
+ );
6864
7040
  }
6865
- if (opts?.transient !== void 0) {
6866
- existingObject.template.setTransientPropPaths(
6867
- opts.transient,
6868
- existingObject.template.staticConfig
7041
+ }
7042
+ const rate = conf && typeof conf.rate !== "undefined" ? conf.rate : 1;
7043
+ if (process.env.NODE_ENV !== "production") {
7044
+ if (typeof rate !== "number" || rate === 0) {
7045
+ throw new InvalidArgumentError(
7046
+ "Argument conf.rate in sequence.play(conf) must be a number larger than 0. ".concat(JSON.stringify(
7047
+ rate
7048
+ ), " given.")
6869
7049
  );
6870
7050
  }
6871
- if (opts?.static !== void 0) {
6872
- existingObject.template.setStaticPropPaths(
6873
- opts.static,
6874
- existingObject.template.staticConfig
7051
+ if (rate < 0) {
7052
+ throw new InvalidArgumentError(
7053
+ "Argument conf.rate in sequence.play(conf) must be a number larger than 0. ".concat(JSON.stringify(
7054
+ rate
7055
+ ), " given. If you want the animation to play backwards, try setting conf.direction to 'reverse' or 'alternateReverse'.")
6875
7056
  );
6876
7057
  }
6877
- return existingObject.publicApi;
6878
7058
  }
6879
- const sanitizedConfig = compound(config);
6880
- const object = internal2.createObject(
6881
- objectKey,
6882
- nativeObject,
6883
- sanitizedConfig,
6884
- actions,
6885
- false,
6886
- opts?.transient,
6887
- opts?.static
6888
- );
7059
+ const direction = conf && conf.direction ? conf.direction : "normal";
6889
7060
  if (process.env.NODE_ENV !== "production") {
6890
- setUnsanitizedObjectProps(object, config);
7061
+ if (possibleDirections.indexOf(direction) === -1) {
7062
+ throw new InvalidArgumentError(
7063
+ "Argument conf.direction in sequence.play(conf) must be one of ".concat(JSON.stringify(
7064
+ possibleDirections
7065
+ ), ". ").concat(JSON.stringify(direction), " given. ").concat(didYouMean(
7066
+ direction,
7067
+ possibleDirections
7068
+ ))
7069
+ );
7070
+ }
6891
7071
  }
6892
- return object.publicApi;
7072
+ return await this._play(
7073
+ iterationCount,
7074
+ [range[0], range[1]],
7075
+ rate,
7076
+ direction,
7077
+ ticker
7078
+ );
6893
7079
  }
6894
- get sequence() {
6895
- return privateAPI(this).getSequence().publicApi;
7080
+ _play(iterationCount, range, rate, direction, ticker) {
7081
+ return this._playbackControllerBox.get().play(iterationCount, range, rate, direction, ticker);
6896
7082
  }
6897
- declareSequenceVariants(variants) {
6898
- privateAPI(this).template.declareSequenceVariants(variants);
7083
+ pause() {
7084
+ this._playbackControllerBox.get().pause();
6899
7085
  }
6900
- setActiveSequenceVariant(variant) {
6901
- privateAPI(this).setActiveSequenceVariant(variant);
7086
+ replacePlaybackController(playbackController) {
7087
+ this.pause();
7088
+ const oldController = this._playbackControllerBox.get();
7089
+ this._playbackControllerBox.set(playbackController);
7090
+ const time = oldController.getCurrentPosition();
7091
+ oldController.destroy();
7092
+ playbackController.gotoPosition(time);
6902
7093
  }
6903
- getActiveSequenceVariant() {
6904
- return privateAPI(this).getActiveSequenceVariant();
7094
+ };
7095
+ var TimeBasedPositionFormatter = class {
7096
+ constructor(_fps) {
7097
+ this._fps = _fps;
6905
7098
  }
6906
- get project() {
6907
- return privateAPI(this).project.publicApi;
7099
+ formatSubUnitForGrid(posInUnitSpace) {
7100
+ const subSecondPos = posInUnitSpace % 1;
7101
+ const frame = 1 / this._fps;
7102
+ const frames = Math.round(subSecondPos / frame);
7103
+ return frames + "f";
6908
7104
  }
6909
- get address() {
6910
- return { ...privateAPI(this).address };
7105
+ formatFullUnitForGrid(posInUnitSpace) {
7106
+ let p2 = posInUnitSpace;
7107
+ let s2 = "";
7108
+ if (p2 >= hour) {
7109
+ const hours = Math.floor(p2 / hour);
7110
+ s2 += hours + "h";
7111
+ p2 = p2 % hour;
7112
+ }
7113
+ if (p2 >= minute) {
7114
+ const minutes = Math.floor(p2 / minute);
7115
+ s2 += minutes + "m";
7116
+ p2 = p2 % minute;
7117
+ }
7118
+ if (p2 >= second) {
7119
+ const seconds = Math.floor(p2 / second);
7120
+ s2 += seconds + "s";
7121
+ p2 = p2 % second;
7122
+ }
7123
+ const frame = 1 / this._fps;
7124
+ if (p2 >= frame) {
7125
+ const frames = Math.floor(p2 / frame);
7126
+ s2 += frames + "f";
7127
+ p2 = p2 % frame;
7128
+ }
7129
+ return s2.length === 0 ? "0s" : s2;
6911
7130
  }
6912
- detachObject(key) {
6913
- const internal2 = privateAPI(this);
6914
- const sanitizedPath = validateAndSanitiseSlashedPathOrThrow(
6915
- key,
6916
- 'sheet.deleteObject("'.concat(key, '")')
7131
+ formatForPlayhead(posInUnitSpace) {
7132
+ let p2 = posInUnitSpace;
7133
+ let s2 = "";
7134
+ if (p2 >= hour) {
7135
+ const hours = Math.floor(p2 / hour);
7136
+ s2 += padStart_default(hours.toString(), 2, "0") + "h";
7137
+ p2 = p2 % hour;
7138
+ }
7139
+ if (p2 >= minute) {
7140
+ const minutes = Math.floor(p2 / minute);
7141
+ s2 += padStart_default(minutes.toString(), 2, "0") + "m";
7142
+ p2 = p2 % minute;
7143
+ } else if (s2.length > 0) {
7144
+ s2 += "00m";
7145
+ }
7146
+ if (p2 >= second) {
7147
+ const seconds = Math.floor(p2 / second);
7148
+ s2 += padStart_default(seconds.toString(), 2, "0") + "s";
7149
+ p2 = p2 % second;
7150
+ } else {
7151
+ s2 += "00s";
7152
+ }
7153
+ const frameLength = 1 / this._fps;
7154
+ if (p2 >= frameLength) {
7155
+ const frames = Math.round(p2 / frameLength);
7156
+ s2 += padStart_default(frames.toString(), 2, "0") + "f";
7157
+ p2 = p2 % frameLength;
7158
+ } else if (p2 / frameLength > 0.98) {
7159
+ const frames = 1;
7160
+ s2 += padStart_default(frames.toString(), 2, "0") + "f";
7161
+ p2 = p2 % frameLength;
7162
+ } else {
7163
+ s2 += "00f";
7164
+ }
7165
+ return s2.length === 0 ? "00s00f" : s2;
7166
+ }
7167
+ formatBasic(posInUnitSpace) {
7168
+ return posInUnitSpace.toFixed(2) + "s";
7169
+ }
7170
+ };
7171
+ var PercentBasedPositionFormatter = class {
7172
+ constructor(_subUnitsPerUnit) {
7173
+ this._subUnitsPerUnit = _subUnitsPerUnit;
7174
+ }
7175
+ formatSubUnitForGrid(posInUnitSpace) {
7176
+ const subUnitSize = 1 / this._subUnitsPerUnit;
7177
+ const withinUnit = posInUnitSpace % 1;
7178
+ const tenths = Math.round(withinUnit / subUnitSize);
7179
+ return tenths + "t";
7180
+ }
7181
+ formatFullUnitForGrid(posInUnitSpace) {
7182
+ return Math.round(posInUnitSpace) + "%";
7183
+ }
7184
+ formatForPlayhead(posInUnitSpace) {
7185
+ const whole = Math.floor(posInUnitSpace);
7186
+ const subUnitSize = 1 / this._subUnitsPerUnit;
7187
+ const withinUnit = posInUnitSpace - whole;
7188
+ const tenths = Math.round(withinUnit / subUnitSize);
7189
+ if (tenths <= 0) {
7190
+ return whole + "%";
7191
+ }
7192
+ return whole + "." + tenths + "%";
7193
+ }
7194
+ formatBasic(posInUnitSpace) {
7195
+ return posInUnitSpace.toFixed(1) + "%";
7196
+ }
7197
+ };
7198
+ var second = 1;
7199
+ var minute = second * 60;
7200
+ var hour = minute * 60;
7201
+
7202
+ // core/src/sheets/sheetGetSequenceFull.ts
7203
+ var import_theatre_dataverse19 = require("@unseenco/theatre-dataverse");
7204
+
7205
+ // core/src/sheets/sheetSequenceMode.ts
7206
+ var PAGE_MODE_SEQUENCE_LENGTH = 100;
7207
+ var PAGE_MODE_SUB_UNITS_PER_UNIT = 10;
7208
+
7209
+ // core/src/sheets/sheetGetSequenceFull.ts
7210
+ var sanitizeSequenceLength = (len) => typeof len === "number" && isFinite(len) && len > 0 ? len : 10;
7211
+ var sanitizeSequenceSubUnitsPerUnit = (subs) => typeof subs === "number" && isInteger_default(subs) && subs > 0 ? subs : 30;
7212
+ function getOrCreateFullSequence(sheet, sequences, variantId) {
7213
+ if (!sequences[variantId]) {
7214
+ const lengthD = (0, import_theatre_dataverse19.prism)(() => {
7215
+ if ((0, import_theatre_dataverse19.val)(sheet.sequenceModeP) === "page") {
7216
+ return PAGE_MODE_SEQUENCE_LENGTH;
7217
+ }
7218
+ const sheetState = (0, import_theatre_dataverse19.val)(
7219
+ sheet.project.pointers.historic.sheetsById[sheet.address.sheetId]
7220
+ );
7221
+ const unsanitized = getSequenceStateFromSheet(
7222
+ sheetState,
7223
+ variantId
7224
+ )?.length;
7225
+ return sanitizeSequenceLength(unsanitized);
7226
+ });
7227
+ const subUnitsPerUnitD = (0, import_theatre_dataverse19.prism)(() => {
7228
+ if ((0, import_theatre_dataverse19.val)(sheet.sequenceModeP) === "page") {
7229
+ return PAGE_MODE_SUB_UNITS_PER_UNIT;
7230
+ }
7231
+ const sheetState = (0, import_theatre_dataverse19.val)(
7232
+ sheet.project.pointers.historic.sheetsById[sheet.address.sheetId]
7233
+ );
7234
+ const unsanitized = getSequenceStateFromSheet(
7235
+ sheetState,
7236
+ variantId
7237
+ )?.subUnitsPerUnit;
7238
+ return sanitizeSequenceSubUnitsPerUnit(unsanitized);
7239
+ });
7240
+ sequences[variantId] = new Sequence(
7241
+ sheet.template.project,
7242
+ sheet,
7243
+ lengthD,
7244
+ subUnitsPerUnitD,
7245
+ variantId
6917
7246
  );
6918
- if (isSheetPropsObjectKey(sanitizedPath)) {
6919
- throw new InvalidArgumentError(
6920
- "Sheet props cannot be detached. They are removed when the sheet instance is unloaded."
7247
+ }
7248
+ return sequences[variantId];
7249
+ }
7250
+
7251
+ // shared/src/gsap/applyTimelineChildTiming.ts
7252
+ function applyTimelineChildTimingToGsap(rootAnimation, timelineChildren, childById, onRebuild) {
7253
+ if (!timelineChildren.length) return true;
7254
+ let ok = applyTimelineChildTimingToGsapInner(
7255
+ rootAnimation,
7256
+ timelineChildren,
7257
+ childById
7258
+ );
7259
+ if (!ok && onRebuild) {
7260
+ const rebuilt = onRebuild();
7261
+ if (rebuilt) {
7262
+ ok = applyTimelineChildTimingToGsapInner(
7263
+ rebuilt,
7264
+ timelineChildren,
7265
+ childById
6921
7266
  );
6922
7267
  }
6923
- const obj = internal2.getObject(sanitizedPath);
6924
- if (!obj) {
6925
- notify.warning(
6926
- "Couldn't delete object \"".concat(sanitizedPath, '"'),
6927
- 'There is no object with key "'.concat(sanitizedPath, '".\n\nTo fix this, make sure you are calling `sheet.deleteObject("').concat(sanitizedPath, '")` with the correct key.')
6928
- );
6929
- console.warn('Object key "'.concat(sanitizedPath, '" does not exist.'));
6930
- return;
7268
+ }
7269
+ return ok;
7270
+ }
7271
+ function applyTimelineChildTimingToGsapInner(rootAnimation, timelineChildren, childById) {
7272
+ if (!childById || timelineChildren.length === 0) return true;
7273
+ let ok = true;
7274
+ for (const childState of timelineChildren) {
7275
+ const tween = childById.get(childState.childId);
7276
+ if (!tween) continue;
7277
+ try {
7278
+ const t2 = tween;
7279
+ if (typeof t2.startTime === "function") {
7280
+ t2.startTime(childState.localStart);
7281
+ }
7282
+ if (typeof t2.duration === "function") {
7283
+ t2.duration(childState.localDuration);
7284
+ }
7285
+ } catch {
7286
+ ok = false;
7287
+ }
7288
+ }
7289
+ return ok;
7290
+ }
7291
+
7292
+ // shared/src/gsap/syncGsapClipProgress.ts
7293
+ function getGsapAnimationTargetKey(animation, fallbackAnimationId) {
7294
+ const tween = animation;
7295
+ const targets = tween.targets?.();
7296
+ if (targets && targets.length > 0) {
7297
+ return targets[0];
7298
+ }
7299
+ return fallbackAnimationId;
7300
+ }
7301
+ function syncRegisteredGsapAnimationsForClips(sequencePosition, clips) {
7302
+ const enriched = [];
7303
+ for (const clip of clips) {
7304
+ const entry = getAnimationEntryBySheetAddressKey(
7305
+ clip.sheetObjectAddressKey,
7306
+ clip.gsapAnimationId
7307
+ );
7308
+ if (!entry?.animation) continue;
7309
+ enriched.push({
7310
+ ...clip,
7311
+ entry,
7312
+ targetKey: getGsapAnimationTargetKey(
7313
+ entry.animation,
7314
+ clip.gsapAnimationId
7315
+ )
7316
+ });
7317
+ }
7318
+ const byTarget = /* @__PURE__ */ new Map();
7319
+ for (const item of enriched) {
7320
+ const list = byTarget.get(item.targetKey) ?? [];
7321
+ list.push(item);
7322
+ byTarget.set(item.targetKey, list);
7323
+ }
7324
+ for (const group of byTarget.values()) {
7325
+ const sorted = [...group].sort((a2, b2) => a2.start - b2.start);
7326
+ for (const clip of sorted) {
7327
+ const progress = gsapClipSyncProgress(sequencePosition, clip);
7328
+ const entry = clip.entry;
7329
+ const animation = entry.animation;
7330
+ if (entry.kind === "timeline" && clip.timelineChildren && clip.timelineChildren.length > 0) {
7331
+ applyTimelineChildTimingToGsap(
7332
+ entry.animation,
7333
+ clip.timelineChildren,
7334
+ entry.timelineChildById,
7335
+ entry.onRebuildTimeline
7336
+ );
7337
+ const span = clip.timelineSpan ?? readGsapTweenTimelineDuration(entry.animation);
7338
+ const t2 = progress * Math.max(span, 0.01);
7339
+ if (typeof animation.time === "function") {
7340
+ animation.time(t2, true);
7341
+ } else {
7342
+ animation.progress?.(progress, true);
7343
+ }
7344
+ } else {
7345
+ animation.progress?.(progress, true);
7346
+ }
6931
7347
  }
6932
- internal2.deleteObject(sanitizedPath);
6933
7348
  }
6934
- getObjects() {
6935
- return privateAPI(this).getObjects().map((obj) => obj.publicApi);
7349
+ }
7350
+ function readGsapTweenTimelineDuration(animation) {
7351
+ const tween = animation;
7352
+ const total = tween.totalDuration?.();
7353
+ if (typeof total === "number" && total > 0) return total;
7354
+ const d2 = tween.duration();
7355
+ return d2 > 0 ? d2 : 1;
7356
+ }
7357
+
7358
+ // shared/src/gsap/gsapAnimationRegistry.ts
7359
+ var DEFAULT_SHEET_INSTANCE_ID2 = "default";
7360
+ var REGISTRY_KEY2 = "__unseenco_theatre_gsap_animationRegistry__";
7361
+ function sheetObjectAddressKeyFromParts(address) {
7362
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID2;
7363
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId, "|").concat(address.objectKey);
7364
+ }
7365
+ function getStore2() {
7366
+ const g2 = globalThis;
7367
+ if (!g2[REGISTRY_KEY2]) {
7368
+ g2[REGISTRY_KEY2] = {
7369
+ bySheetAddress: /* @__PURE__ */ new Map()
7370
+ };
6936
7371
  }
6937
- unload() {
6938
- privateAPI(this).unload();
7372
+ return g2[REGISTRY_KEY2];
7373
+ }
7374
+ function getAnimationEntryBySheetAddressKey(sheetObjectAddressKey, animationId) {
7375
+ return getStore2().bySheetAddress.get(sheetObjectAddressKey)?.get(animationId);
7376
+ }
7377
+
7378
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
7379
+ var import_theatre_dataverse20 = require("@unseenco/theatre-dataverse");
7380
+
7381
+ // shared/src/gsap/syncGsapClipsAtSequencePosition.ts
7382
+ function syncGsapClipsAtSequencePosition(position, clips) {
7383
+ syncRegisteredGsapAnimationsForClips(
7384
+ position,
7385
+ clips
7386
+ );
7387
+ }
7388
+
7389
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
7390
+ function subscribeGsapClipSyncAtPlayhead(source) {
7391
+ const positionPointer = source.pointer.position;
7392
+ const positionPrism = (0, import_theatre_dataverse20.pointerToPrism)(positionPointer);
7393
+ const clipsPrism = (0, import_theatre_dataverse20.prism)(() => source.getGsapClipTimings());
7394
+ const syncNow = () => {
7395
+ const clips = clipsPrism.getValue();
7396
+ if (clips.length === 0) return;
7397
+ syncGsapClipsAtSequencePosition((0, import_theatre_dataverse20.val)(positionPointer), clips);
7398
+ };
7399
+ const untapPosition = positionPrism.onStale(syncNow);
7400
+ const untapClips = clipsPrism.onStale(syncNow);
7401
+ syncNow();
7402
+ return () => {
7403
+ untapPosition();
7404
+ untapClips();
7405
+ };
7406
+ }
7407
+
7408
+ // core/src/gsap/attachGsapSequenceBridge.ts
7409
+ function attachGsapSequenceBridge(sheet) {
7410
+ const sequence = sheet.sequence;
7411
+ const sheetAddress = privateAPI(sheet).address;
7412
+ return subscribeGsapClipSyncAtPlayhead({
7413
+ pointer: sequence.pointer,
7414
+ getGsapClipTimings: () => sequence.__experimental_getGsapClips().map(({ objectKey, clip }) => ({
7415
+ sheetObjectAddressKey: sheetObjectAddressKeyFromParts({
7416
+ projectId: sheetAddress.projectId,
7417
+ sheetId: sheetAddress.sheetId,
7418
+ sheetInstanceId: sheetAddress.sheetInstanceId,
7419
+ objectKey
7420
+ }),
7421
+ gsapAnimationId: clip.gsapAnimationId,
7422
+ start: clip.start,
7423
+ duration: clip.duration,
7424
+ timelineChildren: clip.timelineChildren,
7425
+ timelineSpan: clip.timelineSpan
7426
+ }))
7427
+ });
7428
+ }
7429
+
7430
+ // core/src/sheets/attachSheetScrollDriver.ts
7431
+ var import_theatre_dataverse21 = require("@unseenco/theatre-dataverse");
7432
+ var sheetScrollDrivers = /* @__PURE__ */ new WeakMap();
7433
+ var pageScrollDrivenSequencePositionListeners = /* @__PURE__ */ new Set();
7434
+ function onPageScrollDrivenSequencePosition(listener) {
7435
+ pageScrollDrivenSequencePositionListeners.add(listener);
7436
+ return () => {
7437
+ pageScrollDrivenSequencePositionListeners.delete(listener);
7438
+ };
7439
+ }
7440
+ function notifyPageScrollDrivenSequencePosition(sheet, position) {
7441
+ for (const listener of pageScrollDrivenSequencePositionListeners) {
7442
+ listener(sheet, position);
6939
7443
  }
6940
- declareOutlineNamespace(namespacePath, opts) {
6941
- const internal2 = privateAPI(this);
6942
- const parsedPath = parseOutlineNamespacePath(
6943
- namespacePath,
6944
- "sheet.declareOutlineNamespace"
6945
- );
6946
- internal2.template.setOutlineNamespaceConfig(parsedPath.join(" / "), {
6947
- defaultCollapsed: opts?.collapsed
6948
- });
7444
+ }
7445
+ function getSheetScrollDriver(sheet) {
7446
+ return sheetScrollDrivers.get(sheet);
7447
+ }
7448
+ function rememberSheetScrollDriver(sheet, driver) {
7449
+ sheetScrollDrivers.set(sheet, driver);
7450
+ }
7451
+ function progressFromScrollPosition(position, max) {
7452
+ if (max <= 0) return 0;
7453
+ if (position <= 0) return 0;
7454
+ if (position >= max - 1) return 1;
7455
+ return position / max;
7456
+ }
7457
+ function getNativeDocumentScrollingElement() {
7458
+ return document.scrollingElement ?? document.documentElement;
7459
+ }
7460
+ function addNativeDocumentScrollListener(handler) {
7461
+ document.addEventListener("scroll", handler, { passive: true, capture: true });
7462
+ return () => document.removeEventListener("scroll", handler, { capture: true });
7463
+ }
7464
+ function createScrollDriverFromElement(getMaxScroll, getScrollPos, setScrollPos, addScrollListener) {
7465
+ let suppressScrollEvents = false;
7466
+ let suppressGeneration = 0;
7467
+ const getProgress = () => {
7468
+ const max = getMaxScroll();
7469
+ return progressFromScrollPosition(getScrollPos(), max);
7470
+ };
7471
+ const setProgress = (progress) => {
7472
+ const max = getMaxScroll();
7473
+ const clamped = Math.max(0, Math.min(1, progress));
7474
+ const gen = ++suppressGeneration;
7475
+ suppressScrollEvents = true;
7476
+ setScrollPos(clamped * max);
7477
+ const release = () => {
7478
+ if (gen === suppressGeneration) {
7479
+ suppressScrollEvents = false;
7480
+ }
7481
+ };
7482
+ requestAnimationFrame(() => requestAnimationFrame(release));
7483
+ };
7484
+ return {
7485
+ getProgress,
7486
+ setProgress,
7487
+ subscribe(onProgressChange) {
7488
+ let rafId = 0;
7489
+ const flush = () => {
7490
+ rafId = 0;
7491
+ if (suppressScrollEvents) return;
7492
+ onProgressChange(getProgress());
7493
+ };
7494
+ const scheduleFlush = () => {
7495
+ if (rafId !== 0) return;
7496
+ rafId = requestAnimationFrame(flush);
7497
+ };
7498
+ const handler = () => scheduleFlush();
7499
+ const removeScroll = addScrollListener(handler);
7500
+ const onResize = () => scheduleFlush();
7501
+ window.addEventListener("resize", onResize);
7502
+ return () => {
7503
+ removeScroll();
7504
+ window.removeEventListener("resize", onResize);
7505
+ if (rafId !== 0) cancelAnimationFrame(rafId);
7506
+ };
7507
+ }
7508
+ };
7509
+ }
7510
+ function createNativeDocumentScrollDriver() {
7511
+ const getMaxScroll = () => {
7512
+ const el = document.documentElement;
7513
+ return Math.max(0, el.scrollHeight - window.innerHeight);
7514
+ };
7515
+ return createScrollDriverFromElement(
7516
+ getMaxScroll,
7517
+ () => window.scrollY,
7518
+ (y2) => window.scrollTo({ top: y2, behavior: "instant" }),
7519
+ addNativeDocumentScrollListener
7520
+ );
7521
+ }
7522
+ function createNativeDocumentHorizontalScrollDriver() {
7523
+ const getMaxScroll = () => {
7524
+ const el = getNativeDocumentScrollingElement();
7525
+ return Math.max(0, el.scrollWidth - el.clientWidth);
7526
+ };
7527
+ const getScrollLeft = () => {
7528
+ const el = getNativeDocumentScrollingElement();
7529
+ return el.scrollLeft;
7530
+ };
7531
+ return createScrollDriverFromElement(
7532
+ getMaxScroll,
7533
+ getScrollLeft,
7534
+ (x2) => {
7535
+ getNativeDocumentScrollingElement().scrollLeft = x2;
7536
+ },
7537
+ addNativeDocumentScrollListener
7538
+ );
7539
+ }
7540
+ function createElementScrollDriver(element) {
7541
+ const getMaxScroll = () => Math.max(0, element.scrollHeight - element.clientHeight);
7542
+ return createScrollDriverFromElement(
7543
+ getMaxScroll,
7544
+ () => element.scrollTop,
7545
+ (y2) => {
7546
+ element.scrollTop = y2;
7547
+ },
7548
+ (handler) => {
7549
+ element.addEventListener("scroll", handler, { passive: true });
7550
+ return () => element.removeEventListener("scroll", handler);
7551
+ }
7552
+ );
7553
+ }
7554
+ function createElementHorizontalScrollDriver(element) {
7555
+ const getMaxScroll = () => Math.max(0, element.scrollWidth - element.clientWidth);
7556
+ return createScrollDriverFromElement(
7557
+ getMaxScroll,
7558
+ () => element.scrollLeft,
7559
+ (x2) => {
7560
+ element.scrollLeft = x2;
7561
+ },
7562
+ (handler) => {
7563
+ element.addEventListener("scroll", handler, { passive: true });
7564
+ return () => element.removeEventListener("scroll", handler);
7565
+ }
7566
+ );
7567
+ }
7568
+ function attachSheetScrollDriver(sheet, driver = createNativeDocumentScrollDriver()) {
7569
+ rememberSheetScrollDriver(sheet, driver);
7570
+ const sequence = sheet.sequence;
7571
+ const syncPositionFromScroll = (progress) => {
7572
+ const length = (0, import_theatre_dataverse21.val)(sequence.pointer.length);
7573
+ if (length <= 0) return;
7574
+ sequence.position = progress * length;
7575
+ };
7576
+ const untapScroll = driver.subscribe((progress) => {
7577
+ syncPositionFromScroll(progress);
7578
+ notifyPageScrollDrivenSequencePosition(sheet, sequence.position);
7579
+ });
7580
+ syncPositionFromScroll(driver.getProgress());
7581
+ return () => {
7582
+ untapScroll();
7583
+ };
7584
+ }
7585
+ function pageScrollProgressFromSequence(sheet) {
7586
+ const length = (0, import_theatre_dataverse21.val)(sheet.sequence.pointer.length);
7587
+ if (length <= 0) return 0;
7588
+ return sheet.sequence.position / length;
7589
+ }
7590
+ function setPageScrollProgress(sheet, progress) {
7591
+ const length = (0, import_theatre_dataverse21.val)(sheet.sequence.pointer.length);
7592
+ if (length <= 0) return;
7593
+ const clamped = Math.max(0, Math.min(1, progress));
7594
+ sheet.sequence.position = clamped * length;
7595
+ }
7596
+ function syncPageScrollToSequencePosition(sheet, driver = getSheetScrollDriver(sheet) ?? createNativeDocumentScrollDriver()) {
7597
+ const progress = pageScrollProgressFromSequence(sheet);
7598
+ driver.setProgress(progress);
7599
+ }
7600
+ function syncNativeDocumentScrollToSequencePosition(sheet) {
7601
+ syncPageScrollToSequencePosition(sheet, createNativeDocumentScrollDriver());
7602
+ }
7603
+
7604
+ // core/src/sheets/sheetPageScrollAndGsapFull.ts
7605
+ function syncPageScrollDriverForSheet(host) {
7606
+ host._pageScrollDisposer?.();
7607
+ host._pageScrollDisposer = void 0;
7608
+ if (host.getSequenceMode() === "page") {
7609
+ const driver = host._customPageScrollDriver ?? createNativeDocumentScrollDriver();
7610
+ host._pageScrollDisposer = attachSheetScrollDriver(host.publicApi, driver);
6949
7611
  }
6950
- setOutlineNamespaceCollapsed(namespacePath, collapsed) {
6951
- const internal2 = privateAPI(this);
6952
- const parsedPath = parseOutlineNamespacePath(
6953
- namespacePath,
6954
- "sheet.setOutlineNamespaceCollapsed"
6955
- );
6956
- internal2.template.setOutlineNamespaceConfig(parsedPath.join(" / "), {
6957
- collapsed
6958
- });
7612
+ }
7613
+ function reattachGsapBridgeForSheet(host) {
7614
+ if (host._gsapBridgeDisposer) {
7615
+ host._gsapBridgeDisposer();
7616
+ host._gsapBridgeDisposer = attachGsapSequenceBridge(host.publicApi);
6959
7617
  }
6960
- };
7618
+ }
7619
+ function enableGsapSequenceBridgeForSheet(host) {
7620
+ if (host._gsapBridgeDisposer) return;
7621
+ host._gsapBridgeDisposer = attachGsapSequenceBridge(host.publicApi);
7622
+ syncPageScrollDriverForSheet(host);
7623
+ }
7624
+ function disposeRuntimeIntegrationsForSheet(host) {
7625
+ host._pageScrollDisposer?.();
7626
+ host._pageScrollDisposer = void 0;
7627
+ host._gsapBridgeDisposer?.();
7628
+ host._gsapBridgeDisposer = void 0;
7629
+ }
7630
+ function setPageScrollDriverForSheet(host, driver) {
7631
+ host._customPageScrollDriver = driver;
7632
+ syncPageScrollDriverForSheet(host);
7633
+ }
6961
7634
 
6962
7635
  // core/src/sheets/Sheet.ts
6963
- var import_theatre_dataverse15 = require("@unseenco/theatre-dataverse");
6964
7636
  var Sheet = class {
6965
7637
  constructor(template, instanceId) {
6966
7638
  this.template = template;
6967
7639
  this.instanceId = instanceId;
6968
- __publicField(this, "_objects", new import_theatre_dataverse15.Atom({}));
7640
+ __publicField(this, "_objects", new import_theatre_dataverse22.Atom({}));
6969
7641
  __publicField(this, "_sequences", {});
6970
- __publicField(this, "_activeSequenceVariant", new import_theatre_dataverse15.Atom(
7642
+ __publicField(this, "_liteSequences", {});
7643
+ __publicField(this, "_activeSequenceVariant", new import_theatre_dataverse22.Atom(
6971
7644
  DEFAULT_SEQUENCE_VARIANT
6972
7645
  ));
6973
7646
  /**
@@ -6975,7 +7648,15 @@ var Sheet = class {
6975
7648
  * value resolution (preview). User code can still update `_activeSequenceVariant`
6976
7649
  * via `setActiveSequenceVariant()` without affecting the Studio preview.
6977
7650
  */
6978
- __publicField(this, "_studioPreviewVariantOverride", new import_theatre_dataverse15.Atom(void 0));
7651
+ __publicField(this, "_studioPreviewVariantOverride", new import_theatre_dataverse22.Atom(void 0));
7652
+ __publicField(this, "_sequenceMode", new import_theatre_dataverse22.Atom("time"));
7653
+ __publicField(this, "sequenceModeP", this._sequenceMode.pointer);
7654
+ /** @internal Used by full-runtime scroll/GSAP helpers (`sheetPageScrollAndGsapFull`). */
7655
+ __publicField(this, "_pageScrollDisposer");
7656
+ /** @internal */
7657
+ __publicField(this, "_customPageScrollDriver");
7658
+ /** @internal */
7659
+ __publicField(this, "_gsapBridgeDisposer");
6979
7660
  __publicField(this, "activeSequenceVariantP", this._activeSequenceVariant.pointer);
6980
7661
  __publicField(this, "effectiveActiveSequenceVariantD");
6981
7662
  __publicField(this, "address");
@@ -6992,12 +7673,12 @@ var Sheet = class {
6992
7673
  sheetInstanceId: this.instanceId
6993
7674
  };
6994
7675
  this.publicApi = new TheatreSheet(this);
6995
- this.effectiveActiveSequenceVariantD = (0, import_theatre_dataverse15.prism)(() => {
6996
- const studioOverride = (0, import_theatre_dataverse15.val)(this._studioPreviewVariantOverride.pointer);
7676
+ this.effectiveActiveSequenceVariantD = (0, import_theatre_dataverse22.prism)(() => {
7677
+ const studioOverride = (0, import_theatre_dataverse22.val)(this._studioPreviewVariantOverride.pointer);
6997
7678
  if (studioOverride !== void 0) {
6998
7679
  return studioOverride;
6999
7680
  }
7000
- return (0, import_theatre_dataverse15.val)(this._activeSequenceVariant.pointer);
7681
+ return (0, import_theatre_dataverse22.val)(this._activeSequenceVariant.pointer);
7001
7682
  });
7002
7683
  }
7003
7684
  /**
@@ -7048,8 +7729,11 @@ var Sheet = class {
7048
7729
  * this sheet instance from the project. Persisted state is kept.
7049
7730
  */
7050
7731
  unload() {
7051
- for (const sequence of Object.values(this._sequences)) {
7052
- sequence.pause();
7732
+ this.disposeRuntimeIntegrations();
7733
+ if (!isTheatreLiteMode()) {
7734
+ for (const sequence of Object.values(this._sequences)) {
7735
+ sequence.pause();
7736
+ }
7053
7737
  }
7054
7738
  for (const objectKey of Object.keys(
7055
7739
  this._objects.get()
@@ -7059,37 +7743,14 @@ var Sheet = class {
7059
7743
  this.project._unloadSheetInstance(this);
7060
7744
  }
7061
7745
  getSequence(variant) {
7062
- const variantId = variant ?? (0, import_theatre_dataverse15.val)(this._activeSequenceVariant.pointer);
7063
- if (!this._sequences[variantId]) {
7064
- const lengthD = (0, import_theatre_dataverse15.prism)(() => {
7065
- const sheetState = (0, import_theatre_dataverse15.val)(
7066
- this.project.pointers.historic.sheetsById[this.address.sheetId]
7067
- );
7068
- const unsanitized = getSequenceStateFromSheet(
7069
- sheetState,
7070
- variantId
7071
- )?.length;
7072
- return sanitizeSequenceLength(unsanitized);
7073
- });
7074
- const subUnitsPerUnitD = (0, import_theatre_dataverse15.prism)(() => {
7075
- const sheetState = (0, import_theatre_dataverse15.val)(
7076
- this.project.pointers.historic.sheetsById[this.address.sheetId]
7077
- );
7078
- const unsanitized = getSequenceStateFromSheet(
7079
- sheetState,
7080
- variantId
7081
- )?.subUnitsPerUnit;
7082
- return sanitizeSequenceSubUnitsPerUnit(unsanitized);
7083
- });
7084
- this._sequences[variantId] = new Sequence(
7085
- this.template.project,
7086
- this,
7087
- lengthD,
7088
- subUnitsPerUnitD,
7089
- variantId
7090
- );
7746
+ const variantId = variant ?? (0, import_theatre_dataverse22.val)(this._activeSequenceVariant.pointer);
7747
+ if (isTheatreLiteMode()) {
7748
+ if (!this._liteSequences[variantId]) {
7749
+ this._liteSequences[variantId] = new LiteSequence();
7750
+ }
7751
+ return this._liteSequences[variantId];
7091
7752
  }
7092
- return this._sequences[variantId];
7753
+ return getOrCreateFullSequence(this, this._sequences, variantId);
7093
7754
  }
7094
7755
  getActiveSequenceVariant() {
7095
7756
  return this._activeSequenceVariant.get();
@@ -7124,9 +7785,32 @@ var Sheet = class {
7124
7785
  }
7125
7786
  this._studioPreviewVariantOverride.set(variantId);
7126
7787
  }
7788
+ getSequenceMode() {
7789
+ return this._sequenceMode.get();
7790
+ }
7791
+ setSequenceMode(mode) {
7792
+ if (isTheatreLiteMode()) return;
7793
+ if (this._sequenceMode.get() === mode) return;
7794
+ this._sequenceMode.set(mode);
7795
+ syncPageScrollDriverForSheet(this);
7796
+ reattachGsapBridgeForSheet(this);
7797
+ }
7798
+ enableGsapSequenceBridge() {
7799
+ if (isTheatreLiteMode()) return;
7800
+ enableGsapSequenceBridgeForSheet(this);
7801
+ }
7802
+ disposeRuntimeIntegrations() {
7803
+ if (isTheatreLiteMode()) return;
7804
+ disposeRuntimeIntegrationsForSheet(this);
7805
+ }
7806
+ setPageScrollDriver(driver) {
7807
+ if (isTheatreLiteMode()) return;
7808
+ setPageScrollDriverForSheet(this, driver);
7809
+ }
7810
+ getPageScrollDriver() {
7811
+ return this._customPageScrollDriver;
7812
+ }
7127
7813
  };
7128
- var sanitizeSequenceLength = (len) => typeof len === "number" && isFinite(len) && len > 0 ? len : 10;
7129
- var sanitizeSequenceSubUnitsPerUnit = (subs) => typeof subs === "number" && isInteger_default(subs) && subs >= 1 && subs <= 1e3 ? subs : 30;
7130
7814
 
7131
7815
  // core/src/sheets/SheetTemplate.ts
7132
7816
  var SheetTemplate = class {
@@ -7134,13 +7818,13 @@ var SheetTemplate = class {
7134
7818
  this.project = project;
7135
7819
  __publicField(this, "type", "Theatre_SheetTemplate");
7136
7820
  __publicField(this, "address");
7137
- __publicField(this, "_instances", new import_theatre_dataverse16.Atom({}));
7821
+ __publicField(this, "_instances", new import_theatre_dataverse23.Atom({}));
7138
7822
  __publicField(this, "instancesP", this._instances.pointer);
7139
- __publicField(this, "_objectTemplates", new import_theatre_dataverse16.Atom({}));
7823
+ __publicField(this, "_objectTemplates", new import_theatre_dataverse23.Atom({}));
7140
7824
  __publicField(this, "objectTemplatesP", this._objectTemplates.pointer);
7141
7825
  __publicField(this, "_pendingOutlineNamespaces", {});
7142
7826
  __publicField(this, "_sequenceVariants", [DEFAULT_SEQUENCE_VARIANT]);
7143
- __publicField(this, "_visibleInOutline", new import_theatre_dataverse16.Atom(true));
7827
+ __publicField(this, "_visibleInOutline", new import_theatre_dataverse23.Atom(true));
7144
7828
  __publicField(this, "visibleInOutlineP", this._visibleInOutline.pointer);
7145
7829
  this.address = { ...project.address, sheetId };
7146
7830
  }
@@ -7222,8 +7906,8 @@ var SheetTemplate = class {
7222
7906
  };
7223
7907
 
7224
7908
  // core/src/projects/Project.ts
7225
- var import_theatre_dataverse19 = require("@unseenco/theatre-dataverse");
7226
- var import_theatre_dataverse20 = require("@unseenco/theatre-dataverse");
7909
+ var import_theatre_dataverse26 = require("@unseenco/theatre-dataverse");
7910
+ var import_theatre_dataverse27 = require("@unseenco/theatre-dataverse");
7227
7911
 
7228
7912
  // shared/src/utils/delay.ts
7229
7913
  var delay = (dur) => new Promise((resolve) => setTimeout(resolve, dur));
@@ -7661,8 +8345,165 @@ async function initialiseProjectState(studio, project, onDiskState) {
7661
8345
  });
7662
8346
  }
7663
8347
 
8348
+ // shared/src/sheets/pageScrollContext.ts
8349
+ var defaultPageScrollContext = {
8350
+ scroller: null,
8351
+ axis: "vertical"
8352
+ };
8353
+ var activePageScrollContext = defaultPageScrollContext;
8354
+ function setActivePageScrollContext(context) {
8355
+ activePageScrollContext = {
8356
+ scroller: context.scroller,
8357
+ axis: context.axis ?? "vertical"
8358
+ };
8359
+ }
8360
+ function getActivePageScrollContext() {
8361
+ return activePageScrollContext;
8362
+ }
8363
+ function resolvePageScrollAxis(context = defaultPageScrollContext) {
8364
+ return context.axis ?? "vertical";
8365
+ }
8366
+ function resolvePageScrollScroller(st, defaultsScroller) {
8367
+ const surface = st;
8368
+ const fromSt = surface.scroller ?? surface.vars?.scroller;
8369
+ if (fromSt != null) {
8370
+ return fromSt;
8371
+ }
8372
+ if (defaultsScroller !== void 0) {
8373
+ return defaultsScroller;
8374
+ }
8375
+ return null;
8376
+ }
8377
+ function isWindowLike(value) {
8378
+ return typeof Window !== "undefined" && (value === window || value instanceof Window);
8379
+ }
8380
+ function isNativeDocumentScroller(scroller) {
8381
+ if (scroller == null) return true;
8382
+ if (isWindowLike(scroller)) return true;
8383
+ if (typeof document === "undefined") return false;
8384
+ return scroller === document.documentElement || scroller === document.body;
8385
+ }
8386
+ function pageScrollScrollersMatch(a2, b2) {
8387
+ if (a2 === b2) return true;
8388
+ if (isNativeDocumentScroller(a2) && isNativeDocumentScroller(b2)) return true;
8389
+ return false;
8390
+ }
8391
+ function isScrollTriggerHorizontal(st) {
8392
+ const surface = st;
8393
+ return surface.horizontal === true || surface.vars?.horizontal === true;
8394
+ }
8395
+ function isPageScrollTrigger(st, context = defaultPageScrollContext) {
8396
+ const axis = resolvePageScrollAxis(context);
8397
+ const stHorizontal = isScrollTriggerHorizontal(st);
8398
+ if (stHorizontal !== (axis === "horizontal")) {
8399
+ return false;
8400
+ }
8401
+ const stScroller = resolvePageScrollScroller(st, context.scroller);
8402
+ return pageScrollScrollersMatch(stScroller, context.scroller);
8403
+ }
8404
+ function isVerticalPageScrollTrigger(st, context = defaultPageScrollContext) {
8405
+ return isPageScrollTrigger(st, {
8406
+ scroller: context.scroller,
8407
+ axis: "vertical"
8408
+ });
8409
+ }
8410
+
8411
+ // shared/src/gsap/scrollTriggerLayout.ts
8412
+ function getNativeDocumentMaxScroll(axis = "vertical") {
8413
+ if (typeof document === "undefined" || typeof window === "undefined") {
8414
+ return 0;
8415
+ }
8416
+ const el = document.documentElement;
8417
+ if (axis === "horizontal") {
8418
+ const scrolling = document.scrollingElement ?? el;
8419
+ return Math.max(0, scrolling.scrollWidth - scrolling.clientWidth);
8420
+ }
8421
+ return Math.max(0, el.scrollHeight - window.innerHeight);
8422
+ }
8423
+ function getMaxScrollForScroller(scroller, axis = "vertical") {
8424
+ if (typeof document === "undefined" || typeof window === "undefined") {
8425
+ return 0;
8426
+ }
8427
+ if (isNativeDocumentScroller(scroller)) {
8428
+ return getNativeDocumentMaxScroll(axis);
8429
+ }
8430
+ const el = scroller;
8431
+ if (axis === "horizontal") {
8432
+ return Math.max(0, el.scrollWidth - el.clientWidth);
8433
+ }
8434
+ return Math.max(0, el.scrollHeight - el.clientHeight);
8435
+ }
8436
+ function getMaxScrollForPageScrollContext(scroller, axis = "vertical") {
8437
+ return getMaxScrollForScroller(scroller, axis);
8438
+ }
8439
+
8440
+ // shared/src/gsap/domElementHighlightTarget.ts
8441
+ function resolveDomElementHighlightTarget(target) {
8442
+ if (typeof document === "undefined") {
8443
+ return null;
8444
+ }
8445
+ if (target.type === "id") {
8446
+ return document.getElementById(target.id);
8447
+ }
8448
+ try {
8449
+ const match = document.querySelector(target.selector);
8450
+ return match instanceof Element ? match : null;
8451
+ } catch {
8452
+ return null;
8453
+ }
8454
+ }
8455
+
8456
+ // shared/src/sheets/remoteDomElementHighlight.ts
8457
+ var listeners = /* @__PURE__ */ new Set();
8458
+ function setRemoteDomElementHighlight(element) {
8459
+ for (const listener of listeners) {
8460
+ listener(element);
8461
+ }
8462
+ }
8463
+
8464
+ // shared/src/sheets/remotePageScrollMetrics.ts
8465
+ var remoteMetrics;
8466
+ var listeners2 = /* @__PURE__ */ new Set();
8467
+ function setRemotePageScrollMetrics(metrics) {
8468
+ const prev = remoteMetrics;
8469
+ remoteMetrics = metrics;
8470
+ if (prev?.maxScroll !== metrics?.maxScroll || prev?.axis !== metrics?.axis) {
8471
+ for (const listener of listeners2) {
8472
+ listener();
8473
+ }
8474
+ }
8475
+ }
8476
+
7664
8477
  // core/src/internal/RemoteSync.ts
7665
- var import_theatre_dataverse17 = require("@unseenco/theatre-dataverse");
8478
+ var import_theatre_dataverse24 = require("@unseenco/theatre-dataverse");
8479
+
8480
+ // core/src/internal/createDebouncedCallback.ts
8481
+ function createDebouncedCallback(fn2, delayMs) {
8482
+ let timeoutId;
8483
+ const clearPending = () => {
8484
+ if (timeoutId !== void 0) {
8485
+ clearTimeout(timeoutId);
8486
+ timeoutId = void 0;
8487
+ }
8488
+ };
8489
+ return {
8490
+ schedule() {
8491
+ clearPending();
8492
+ timeoutId = setTimeout(() => {
8493
+ timeoutId = void 0;
8494
+ fn2();
8495
+ }, delayMs);
8496
+ },
8497
+ flush() {
8498
+ if (timeoutId === void 0) return;
8499
+ clearPending();
8500
+ fn2();
8501
+ },
8502
+ cancel() {
8503
+ clearPending();
8504
+ }
8505
+ };
8506
+ }
7666
8507
 
7667
8508
  // core/src/internal/remoteEditor.ts
7668
8509
  function isRemoteEditorWindow() {
@@ -7670,6 +8511,10 @@ function isRemoteEditorWindow() {
7670
8511
  }
7671
8512
 
7672
8513
  // core/src/internal/RemoteSync.ts
8514
+ var REMOTE_HISTORIC_SYNC_DEBOUNCE_MS = 100;
8515
+ function shouldSyncPageScrollWhenApplyingTimelineUpdate(isEditor, sequenceMode) {
8516
+ return !isEditor && sequenceMode === "page";
8517
+ }
7673
8518
  var RemoteSync = class {
7674
8519
  constructor(project) {
7675
8520
  this.project = project;
@@ -7680,34 +8525,37 @@ var RemoteSync = class {
7680
8525
  __publicField(this, "objectUnsubs", /* @__PURE__ */ new Map());
7681
8526
  __publicField(this, "studio");
7682
8527
  __publicField(this, "activeSheet");
8528
+ __publicField(this, "historicSyncDebounce");
8529
+ __publicField(this, "lastBroadcastHistoricFingerprint");
8530
+ __publicField(this, "historicSyncUnsubs", []);
8531
+ __publicField(this, "remoteEditorActive", false);
8532
+ __publicField(this, "suppressTimelineBroadcast", false);
8533
+ __publicField(this, "listenerTimelineUnsub");
8534
+ __publicField(this, "listenerMetricsUnsubs", []);
8535
+ __publicField(this, "broadcastPageScrollMetrics");
7683
8536
  if (typeof BroadcastChannel === "undefined") return;
7684
8537
  this.channel = new BroadcastChannel(
7685
8538
  "theatre-remote:".concat(project.address.projectId)
7686
8539
  );
8540
+ this.channel.onmessage = (event) => {
8541
+ this._handleIncoming(event.data);
8542
+ };
7687
8543
  if (!this.isEditor) {
7688
- this.channel.onmessage = (event) => {
7689
- this._handleIncoming(event.data);
7690
- };
8544
+ this.listenerTimelineUnsub = onPageScrollDrivenSequencePosition(
8545
+ (sheet, position) => {
8546
+ this._broadcastTimelineFromListener(sheet, position);
8547
+ }
8548
+ );
7691
8549
  } else {
7692
8550
  const channel = this.channel;
7693
8551
  window.addEventListener("pagehide", () => {
7694
- const data = {};
7695
- if (this.studio) {
7696
- const projectId = this.project.address.projectId;
7697
- const historic = (0, import_theatre_dataverse17.val)(
7698
- this.studio.atomP.historic.coreByProject[projectId]
7699
- );
7700
- const ahistoric = (0, import_theatre_dataverse17.val)(
7701
- this.studio.atomP.ahistoric.coreByProject[projectId]
7702
- );
7703
- if (historic) {
7704
- data.historic = JSON.parse(JSON.stringify(historic));
7705
- if (ahistoric) {
7706
- data.ahistoric = JSON.parse(JSON.stringify(ahistoric));
7707
- }
7708
- }
8552
+ this.historicSyncDebounce?.flush();
8553
+ const data = this._readHistoricSnapshotFromStudio();
8554
+ if (data && this.lastBroadcastHistoricFingerprint === fingerprintHistoricSnapshot(data)) {
8555
+ channel.postMessage({ event: "disconnect", data: {} });
8556
+ return;
7709
8557
  }
7710
- channel.postMessage({ event: "disconnect", data });
8558
+ channel.postMessage({ event: "disconnect", data: data ?? {} });
7711
8559
  });
7712
8560
  }
7713
8561
  }
@@ -7758,8 +8606,13 @@ var RemoteSync = class {
7758
8606
  }
7759
8607
  attachStudio(studio) {
7760
8608
  this.studio = studio;
7761
- if (!this.isEditor || !this.channel) return;
8609
+ if (!this.channel) return;
8610
+ if (!this.isEditor) {
8611
+ this._attachListenerPageScrollMetricsBroadcast();
8612
+ return;
8613
+ }
7762
8614
  const channel = this.channel;
8615
+ channel.postMessage({ event: "editorHello", data: {} });
7763
8616
  const projectId = this.project.address.projectId;
7764
8617
  studio.publicApi.onSelectionChange((selection) => {
7765
8618
  for (const item of selection) {
@@ -7784,7 +8637,7 @@ var RemoteSync = class {
7784
8637
  let lastPosition;
7785
8638
  const ticker = getCoreTicker();
7786
8639
  const pollTimelinePosition = () => {
7787
- if (this.activeSheet) {
8640
+ if (this.activeSheet && !this.suppressTimelineBroadcast) {
7788
8641
  const position = this.activeSheet.publicApi.sequence.position;
7789
8642
  if (position !== lastPosition) {
7790
8643
  lastPosition = position;
@@ -7795,12 +8648,120 @@ var RemoteSync = class {
7795
8648
  channel.postMessage(message);
7796
8649
  }
7797
8650
  }
7798
- ticker.onNextTick(pollTimelinePosition);
8651
+ ticker.onNextTick(pollTimelinePosition);
8652
+ };
8653
+ ticker.onNextTick(pollTimelinePosition);
8654
+ this.historicSyncDebounce = createDebouncedCallback(() => {
8655
+ this._broadcastHistoricSnapshot();
8656
+ }, REMOTE_HISTORIC_SYNC_DEBOUNCE_MS);
8657
+ const scheduleHistoricSync = () => {
8658
+ this.historicSyncDebounce?.schedule();
8659
+ };
8660
+ void studio.initialized.then(() => {
8661
+ this.historicSyncUnsubs.push(
8662
+ (0, import_theatre_dataverse24.pointerToPrism)(studio.atomP.historic.coreByProject[projectId]).onChange(
8663
+ studio.ticker,
8664
+ scheduleHistoricSync,
8665
+ true
8666
+ ),
8667
+ (0, import_theatre_dataverse24.pointerToPrism)(
8668
+ studio.atomP.ahistoric.coreByProject[projectId]
8669
+ ).onChange(studio.ticker, scheduleHistoricSync, true)
8670
+ );
8671
+ });
8672
+ }
8673
+ _readHistoricSnapshotFromStudio() {
8674
+ if (!this.studio) return void 0;
8675
+ const projectId = this.project.address.projectId;
8676
+ const historic = (0, import_theatre_dataverse24.val)(
8677
+ this.studio.atomP.historic.coreByProject[projectId]
8678
+ );
8679
+ if (!historic) return void 0;
8680
+ const data = {
8681
+ historic: JSON.parse(JSON.stringify(historic))
8682
+ };
8683
+ const ahistoric = (0, import_theatre_dataverse24.val)(
8684
+ this.studio.atomP.ahistoric.coreByProject[projectId]
8685
+ );
8686
+ if (ahistoric) {
8687
+ data.ahistoric = JSON.parse(JSON.stringify(ahistoric));
8688
+ }
8689
+ return data;
8690
+ }
8691
+ _broadcastHistoricSnapshot(options) {
8692
+ if (!this.channel) return;
8693
+ const data = this._readHistoricSnapshotFromStudio();
8694
+ if (!data) return;
8695
+ const fingerprint = fingerprintHistoricSnapshot(data);
8696
+ if (!options?.force && fingerprint === this.lastBroadcastHistoricFingerprint) {
8697
+ return;
8698
+ }
8699
+ this.lastBroadcastHistoricFingerprint = fingerprint;
8700
+ const message = { event: "updateHistoric", data };
8701
+ this.channel.postMessage(message);
8702
+ }
8703
+ _applyHistoricSnapshot(historic, ahistoric) {
8704
+ if (!this.studio) return;
8705
+ const projectId = this.project.address.projectId;
8706
+ this.studio.transaction(({ drafts }) => {
8707
+ drafts.historic.coreByProject[projectId] = historic;
8708
+ if (ahistoric) {
8709
+ drafts.ahistoric.coreByProject[projectId] = ahistoric;
8710
+ }
8711
+ drafts.ephemeral.coreByProject[projectId].loadingState = {
8712
+ type: "loaded"
8713
+ };
8714
+ });
8715
+ }
8716
+ _broadcastTimelineFromListener(sheet, position) {
8717
+ if (this.isEditor || !this.channel || !this.remoteEditorActive || this.suppressTimelineBroadcast) {
8718
+ return;
8719
+ }
8720
+ const registered = this.sheets.get(sheet.address.sheetId);
8721
+ if (!registered || registered.getSequenceMode() !== "page") return;
8722
+ const message = {
8723
+ event: "updateTimeline",
8724
+ data: { sheet: sheet.address.sheetId, position }
7799
8725
  };
7800
- ticker.onNextTick(pollTimelinePosition);
8726
+ this.channel.postMessage(message);
8727
+ }
8728
+ _postPageScrollMetrics() {
8729
+ if (!this.remoteEditorActive || !this.channel) return;
8730
+ const ctx = getActivePageScrollContext();
8731
+ const axis = resolvePageScrollAxis(ctx);
8732
+ const maxScroll = getMaxScrollForPageScrollContext(ctx.scroller, axis);
8733
+ const message = {
8734
+ event: "pageScrollMetrics",
8735
+ data: { maxScroll, axis }
8736
+ };
8737
+ this.channel.postMessage(message);
8738
+ }
8739
+ _attachListenerPageScrollMetricsBroadcast() {
8740
+ if (this.isEditor || !this.channel) return;
8741
+ const broadcast = () => this._postPageScrollMetrics();
8742
+ this.broadcastPageScrollMetrics = broadcast;
8743
+ const onScroll = () => broadcast();
8744
+ document.addEventListener("scroll", onScroll, { passive: true, capture: true });
8745
+ const onResize = () => broadcast();
8746
+ window.addEventListener("resize", onResize);
8747
+ const ScrollTrigger = globalThis.ScrollTrigger;
8748
+ ScrollTrigger?.addEventListener?.("refresh", broadcast);
8749
+ broadcast();
8750
+ this.listenerMetricsUnsubs.push(() => {
8751
+ document.removeEventListener("scroll", onScroll, { capture: true });
8752
+ window.removeEventListener("resize", onResize);
8753
+ ScrollTrigger?.removeEventListener?.("refresh", broadcast);
8754
+ });
7801
8755
  }
7802
8756
  _handleIncoming(msg) {
7803
8757
  switch (msg.event) {
8758
+ case "editorHello": {
8759
+ if (this.isEditor) break;
8760
+ this.remoteEditorActive = true;
8761
+ this.broadcastPageScrollMetrics?.();
8762
+ this._broadcastHistoricSnapshot({ force: true });
8763
+ break;
8764
+ }
7804
8765
  case "setSheet": {
7805
8766
  const sheet = this.sheets.get(msg.data.sheet);
7806
8767
  if (sheet && this.studio) {
@@ -7825,32 +8786,67 @@ var RemoteSync = class {
7825
8786
  const sheet = this.sheets.get(msg.data.sheet);
7826
8787
  if (sheet) {
7827
8788
  this.activeSheet = sheet;
8789
+ this.suppressTimelineBroadcast = true;
7828
8790
  sheet.publicApi.sequence.position = msg.data.position;
8791
+ if (shouldSyncPageScrollWhenApplyingTimelineUpdate(
8792
+ this.isEditor,
8793
+ sheet.getSequenceMode()
8794
+ )) {
8795
+ syncPageScrollToSequencePosition(sheet.publicApi);
8796
+ }
8797
+ requestAnimationFrame(() => {
8798
+ this.suppressTimelineBroadcast = false;
8799
+ });
8800
+ }
8801
+ break;
8802
+ }
8803
+ case "pageScrollMetrics": {
8804
+ if (!this.isEditor) break;
8805
+ const { maxScroll, axis } = msg.data;
8806
+ setRemotePageScrollMetrics({ maxScroll, axis });
8807
+ break;
8808
+ }
8809
+ case "highlightDomTarget": {
8810
+ if (this.isEditor || !this.remoteEditorActive) break;
8811
+ const target = msg.data.target;
8812
+ const element = resolveDomElementHighlightTarget(target);
8813
+ setRemoteDomElementHighlight(element);
8814
+ break;
8815
+ }
8816
+ case "clearDomHighlight": {
8817
+ if (this.isEditor || !this.remoteEditorActive) break;
8818
+ setRemoteDomElementHighlight(null);
8819
+ break;
8820
+ }
8821
+ case "updateHistoric": {
8822
+ const { historic, ahistoric } = msg.data;
8823
+ if (historic) {
8824
+ this._applyHistoricSnapshot(historic, ahistoric);
7829
8825
  }
7830
8826
  break;
7831
8827
  }
7832
8828
  case "disconnect": {
7833
8829
  const { historic, ahistoric } = msg.data;
7834
- if (historic && this.studio) {
7835
- const projectId = this.project.address.projectId;
7836
- this.studio.transaction(({ drafts }) => {
7837
- drafts.historic.coreByProject[projectId] = historic;
7838
- if (ahistoric) {
7839
- drafts.ahistoric.coreByProject[projectId] = ahistoric;
7840
- }
7841
- drafts.ephemeral.coreByProject[projectId].loadingState = {
7842
- type: "loaded"
7843
- };
7844
- });
8830
+ if (historic) {
8831
+ this._applyHistoricSnapshot(historic, ahistoric);
7845
8832
  }
7846
8833
  for (const obj of this.objects.values()) {
7847
8834
  obj.setRemoteOverride({});
7848
8835
  }
8836
+ if (!this.isEditor) {
8837
+ this.remoteEditorActive = false;
8838
+ setRemoteDomElementHighlight(null);
8839
+ } else {
8840
+ setRemotePageScrollMetrics(void 0);
8841
+ }
7849
8842
  break;
7850
8843
  }
7851
8844
  }
7852
8845
  }
7853
8846
  };
8847
+ function fingerprintHistoricSnapshot(data) {
8848
+ return JSON.stringify(data);
8849
+ }
7854
8850
 
7855
8851
  // core/src/_coreLogger.ts
7856
8852
  function noop2() {
@@ -7877,7 +8873,7 @@ function _coreLogger(config) {
7877
8873
  }
7878
8874
 
7879
8875
  // shared/src/utils/assets.ts
7880
- var import_theatre_dataverse18 = require("@unseenco/theatre-dataverse");
8876
+ var import_theatre_dataverse25 = require("@unseenco/theatre-dataverse");
7881
8877
 
7882
8878
  // shared/src/utils/forEachDeep.ts
7883
8879
  function forEachPropDeep(m, fn2, startingPath = []) {
@@ -7947,7 +8943,7 @@ var Project = class {
7947
8943
  __publicField(this, "_studioReadyDeferred");
7948
8944
  __publicField(this, "_assetStorageReadyDeferred");
7949
8945
  __publicField(this, "_readyPromise");
7950
- __publicField(this, "_sheetTemplates", new import_theatre_dataverse20.Atom({}));
8946
+ __publicField(this, "_sheetTemplates", new import_theatre_dataverse27.Atom({}));
7951
8947
  __publicField(this, "sheetTemplatesP", this._sheetTemplates.pointer);
7952
8948
  __publicField(this, "_studio");
7953
8949
  __publicField(this, "_onDiskStateAtom");
@@ -7960,7 +8956,7 @@ var Project = class {
7960
8956
  this._logger.traceDev("creating project");
7961
8957
  this.address = { projectId: id };
7962
8958
  this._remoteSync = new RemoteSync(this);
7963
- const onDiskStateAtom = new import_theatre_dataverse20.Atom({
8959
+ const onDiskStateAtom = new import_theatre_dataverse27.Atom({
7964
8960
  ahistoric: {
7965
8961
  ahistoricStuff: ""
7966
8962
  },
@@ -7986,9 +8982,9 @@ var Project = class {
7986
8982
  }
7987
8983
  };
7988
8984
  this._pointerProxies = {
7989
- historic: new import_theatre_dataverse19.PointerProxy(onDiskStateAtom.pointer.historic),
7990
- ahistoric: new import_theatre_dataverse19.PointerProxy(onDiskStateAtom.pointer.ahistoric),
7991
- ephemeral: new import_theatre_dataverse19.PointerProxy(onDiskStateAtom.pointer.ephemeral)
8985
+ historic: new import_theatre_dataverse26.PointerProxy(onDiskStateAtom.pointer.historic),
8986
+ ahistoric: new import_theatre_dataverse26.PointerProxy(onDiskStateAtom.pointer.ahistoric),
8987
+ ephemeral: new import_theatre_dataverse26.PointerProxy(onDiskStateAtom.pointer.ephemeral)
7992
8988
  };
7993
8989
  this.pointers = {
7994
8990
  historic: this._pointerProxies.historic.pointer,
@@ -8015,14 +9011,14 @@ var Project = class {
8015
9011
  if (typeof window === "undefined") {
8016
9012
  if (process.env.NODE_ENV === "production") {
8017
9013
  console.error(
8018
- 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. ') + "You can safely ignore this message if you're developing a Next.js/Remix project in development mode. But if you are shipping to your end-users, then you need to set config.state, otherwise your project's state will be empty and nothing will animate. Learn more at https://www.theatrejs.com/docs/latest/manual/projects#state"
9014
+ 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. ') + "You can safely ignore this message if you're developing a Next.js/Remix project in development mode. But if you are shipping to your end-users, then you need to set config.state, otherwise your project's state will be empty and nothing will animate. Learn more at https://unseen-theatre.netlify.app/docs/guide/manual/projects#state"
8019
9015
  );
8020
9016
  }
8021
9017
  } else {
8022
9018
  setTimeout(() => {
8023
9019
  if (!this._studio) {
8024
9020
  throw new Error(
8025
- 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. This is fine ') + "while you are using @unseenco/theatre-core along with @unseenco/theatre-studio. But since @unseenco/theatre-studio " + 'is not loaded, the state of project "'.concat(id, '" will be empty.\n\n') + "To fix this, you need to add @unseenco/theatre-studio into the bundle and export the project's state. Learn how to do that at https://www.theatrejs.com/docs/latest/manual/projects#state\n"
9021
+ 'Argument config.state in Theatre.getProject("'.concat(id, '", config) is empty. This is fine ') + "while you are using @unseenco/theatre-core along with @unseenco/theatre-studio. But since @unseenco/theatre-studio " + 'is not loaded, the state of project "'.concat(id, '" will be empty.\n\n') + "To fix this, you need to add @unseenco/theatre-studio into the bundle and export the project's state. Learn how to do that at https://unseen-theatre.netlify.app/docs/guide/manual/projects#state\n"
8026
9022
  );
8027
9023
  }
8028
9024
  }, 1e3);
@@ -8086,6 +9082,7 @@ var Project = class {
8086
9082
  template.setVisibleInOutline(opts.visible);
8087
9083
  }
8088
9084
  const sheet = template.getInstance(instanceId);
9085
+ applySheetRuntimeOptions(sheet, opts);
8089
9086
  this._remoteSync.registerSheet(sheet);
8090
9087
  return sheet;
8091
9088
  }
@@ -8366,13 +9363,13 @@ var Project = class {
8366
9363
  };
8367
9364
 
8368
9365
  // shared/src/utils/sanitizers.ts
8369
- var _validateSym = (val12, thingy, range) => {
8370
- if (typeof val12 !== "string") {
8371
- return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val12), " given.");
8372
- } else if (val12.trim().length !== val12.length) {
8373
- return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val12, "' given.");
8374
- } else if (val12.length < range[0] || val12.length > range[1]) {
8375
- return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val12, "' given.");
9366
+ var _validateSym = (val15, thingy, range) => {
9367
+ if (typeof val15 !== "string") {
9368
+ return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val15), " given.");
9369
+ } else if (val15.trim().length !== val15.length) {
9370
+ return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val15, "' given.");
9371
+ } else if (val15.length < range[0] || val15.length > range[1]) {
9372
+ return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val15, "' given.");
8376
9373
  }
8377
9374
  };
8378
9375
  var validateName = (name, thingy, shouldThrow = false) => {
@@ -8486,196 +9483,10 @@ var TheatreProject = class {
8486
9483
  }
8487
9484
  };
8488
9485
 
8489
- // core/src/coreExports.ts
9486
+ // core/src/coreExportsShared.ts
8490
9487
  var import_fast_deep_equal3 = __toESM(require_fast_deep_equal());
8491
- var import_theatre_dataverse23 = require("@unseenco/theatre-dataverse");
8492
- var import_theatre_dataverse24 = require("@unseenco/theatre-dataverse");
8493
-
8494
- // shared/src/gsap/applyTimelineChildTiming.ts
8495
- function applyTimelineChildTimingToGsap(rootAnimation, timelineChildren, childById, onRebuild) {
8496
- if (!timelineChildren.length) return true;
8497
- let ok = applyTimelineChildTimingToGsapInner(
8498
- rootAnimation,
8499
- timelineChildren,
8500
- childById
8501
- );
8502
- if (!ok && onRebuild) {
8503
- const rebuilt = onRebuild();
8504
- if (rebuilt) {
8505
- ok = applyTimelineChildTimingToGsapInner(
8506
- rebuilt,
8507
- timelineChildren,
8508
- childById
8509
- );
8510
- }
8511
- }
8512
- return ok;
8513
- }
8514
- function applyTimelineChildTimingToGsapInner(rootAnimation, timelineChildren, childById) {
8515
- if (!childById || timelineChildren.length === 0) return true;
8516
- let ok = true;
8517
- for (const childState of timelineChildren) {
8518
- const tween = childById.get(childState.childId);
8519
- if (!tween) continue;
8520
- try {
8521
- const t2 = tween;
8522
- if (typeof t2.startTime === "function") {
8523
- t2.startTime(childState.localStart);
8524
- }
8525
- if (typeof t2.duration === "function") {
8526
- t2.duration(childState.localDuration);
8527
- }
8528
- } catch {
8529
- ok = false;
8530
- }
8531
- }
8532
- return ok;
8533
- }
8534
-
8535
- // shared/src/gsap/syncGsapClipProgress.ts
8536
- function getGsapAnimationTargetKey(animation, fallbackAnimationId) {
8537
- const tween = animation;
8538
- const targets = tween.targets?.();
8539
- if (targets && targets.length > 0) {
8540
- return targets[0];
8541
- }
8542
- return fallbackAnimationId;
8543
- }
8544
- function syncRegisteredGsapAnimationsForClips(sequencePosition, clips) {
8545
- const enriched = [];
8546
- for (const clip of clips) {
8547
- const entry = getAnimationEntryBySheetAddressKey(
8548
- clip.sheetObjectAddressKey,
8549
- clip.gsapAnimationId
8550
- );
8551
- if (!entry?.animation) continue;
8552
- enriched.push({
8553
- ...clip,
8554
- entry,
8555
- targetKey: getGsapAnimationTargetKey(
8556
- entry.animation,
8557
- clip.gsapAnimationId
8558
- )
8559
- });
8560
- }
8561
- const byTarget = /* @__PURE__ */ new Map();
8562
- for (const item of enriched) {
8563
- const list = byTarget.get(item.targetKey) ?? [];
8564
- list.push(item);
8565
- byTarget.set(item.targetKey, list);
8566
- }
8567
- for (const group of byTarget.values()) {
8568
- const sorted = [...group].sort((a2, b2) => a2.start - b2.start);
8569
- for (const clip of sorted) {
8570
- const progress = gsapClipSyncProgress(sequencePosition, clip);
8571
- const entry = clip.entry;
8572
- const animation = entry.animation;
8573
- if (entry.kind === "timeline" && clip.timelineChildren && clip.timelineChildren.length > 0) {
8574
- applyTimelineChildTimingToGsap(
8575
- entry.animation,
8576
- clip.timelineChildren,
8577
- entry.timelineChildById,
8578
- entry.onRebuildTimeline
8579
- );
8580
- const span = clip.timelineSpan ?? readGsapTweenTimelineDuration(entry.animation);
8581
- const t2 = progress * Math.max(span, 0.01);
8582
- if (typeof animation.time === "function") {
8583
- animation.time(t2, true);
8584
- } else {
8585
- animation.progress?.(progress, true);
8586
- }
8587
- } else {
8588
- animation.progress?.(progress, true);
8589
- }
8590
- }
8591
- }
8592
- }
8593
- function readGsapTweenTimelineDuration(animation) {
8594
- const tween = animation;
8595
- const total = tween.totalDuration?.();
8596
- if (typeof total === "number" && total > 0) return total;
8597
- const d2 = tween.duration();
8598
- return d2 > 0 ? d2 : 1;
8599
- }
8600
-
8601
- // shared/src/gsap/gsapStudioRegistryRevision.ts
8602
- var import_theatre_dataverse21 = require("@unseenco/theatre-dataverse");
8603
- var revisionAtom = new import_theatre_dataverse21.Atom(0);
8604
- var gsapStudioRegistryRevisionPointer = revisionAtom.pointer;
8605
-
8606
- // shared/src/gsap/gsapAnimationRegistry.ts
8607
- var DEFAULT_SHEET_INSTANCE_ID = "default";
8608
- var REGISTRY_KEY = "__unseenco_theatre_gsap_animationRegistry__";
8609
- function sheetObjectAddressKeyFromParts(address) {
8610
- const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID;
8611
- return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId, "|").concat(address.objectKey);
8612
- }
8613
- function getStore() {
8614
- const g2 = globalThis;
8615
- if (!g2[REGISTRY_KEY]) {
8616
- g2[REGISTRY_KEY] = {
8617
- bySheetAddress: /* @__PURE__ */ new Map()
8618
- };
8619
- }
8620
- return g2[REGISTRY_KEY];
8621
- }
8622
- function getAnimationEntryBySheetAddressKey(sheetObjectAddressKey, animationId) {
8623
- return getStore().bySheetAddress.get(sheetObjectAddressKey)?.get(animationId);
8624
- }
8625
-
8626
- // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
8627
- var import_theatre_dataverse22 = require("@unseenco/theatre-dataverse");
8628
-
8629
- // shared/src/gsap/syncGsapClipsAtSequencePosition.ts
8630
- function syncGsapClipsAtSequencePosition(position, clips) {
8631
- syncRegisteredGsapAnimationsForClips(
8632
- position,
8633
- clips
8634
- );
8635
- }
8636
-
8637
- // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
8638
- function subscribeGsapClipSyncAtPlayhead(source) {
8639
- const positionPointer = source.pointer.position;
8640
- const positionPrism = (0, import_theatre_dataverse22.pointerToPrism)(positionPointer);
8641
- const clipsPrism = (0, import_theatre_dataverse22.prism)(() => source.getGsapClipTimings());
8642
- const syncNow = () => {
8643
- const clips = clipsPrism.getValue();
8644
- if (clips.length === 0) return;
8645
- syncGsapClipsAtSequencePosition((0, import_theatre_dataverse22.val)(positionPointer), clips);
8646
- };
8647
- const untapPosition = positionPrism.onStale(syncNow);
8648
- const untapClips = clipsPrism.onStale(syncNow);
8649
- syncNow();
8650
- return () => {
8651
- untapPosition();
8652
- untapClips();
8653
- };
8654
- }
8655
-
8656
- // core/src/gsap/attachGsapSequenceBridge.ts
8657
- function attachGsapSequenceBridge(sheet) {
8658
- const sequence = sheet.sequence;
8659
- const sheetAddress = privateAPI(sheet).address;
8660
- return subscribeGsapClipSyncAtPlayhead({
8661
- pointer: sequence.pointer,
8662
- getGsapClipTimings: () => sequence.__experimental_getGsapClips().map(({ objectKey, clip }) => ({
8663
- sheetObjectAddressKey: sheetObjectAddressKeyFromParts({
8664
- projectId: sheetAddress.projectId,
8665
- sheetId: sheetAddress.sheetId,
8666
- sheetInstanceId: sheetAddress.sheetInstanceId,
8667
- objectKey
8668
- }),
8669
- gsapAnimationId: clip.gsapAnimationId,
8670
- start: clip.start,
8671
- duration: clip.duration,
8672
- timelineChildren: clip.timelineChildren,
8673
- timelineSpan: clip.timelineSpan
8674
- }))
8675
- });
8676
- }
8677
-
8678
- // core/src/coreExports.ts
9488
+ var import_theatre_dataverse28 = require("@unseenco/theatre-dataverse");
9489
+ var import_theatre_dataverse29 = require("@unseenco/theatre-dataverse");
8679
9490
  function getProject(id, config = {}) {
8680
9491
  const existingProject = projectsSingleton_default.get(id);
8681
9492
  if (existingProject) {
@@ -8753,28 +9564,97 @@ var validateProjectIdOrThrow = (value) => {
8753
9564
  );
8754
9565
  }
8755
9566
  };
8756
- function onChange(pointer3, callback, rafDriver) {
9567
+ function onChange(pointer4, callback, rafDriver) {
8757
9568
  const ticker = rafDriver ? privateAPI(rafDriver).ticker : getCoreTicker();
8758
- if ((0, import_theatre_dataverse23.isPointer)(pointer3)) {
8759
- const pr = (0, import_theatre_dataverse24.pointerToPrism)(pointer3);
9569
+ if ((0, import_theatre_dataverse28.isPointer)(pointer4)) {
9570
+ const pr = (0, import_theatre_dataverse29.pointerToPrism)(pointer4);
8760
9571
  return pr.onChange(ticker, callback, true);
8761
- } else if ((0, import_theatre_dataverse24.isPrism)(pointer3)) {
8762
- return pointer3.onChange(ticker, callback, true);
9572
+ } else if ((0, import_theatre_dataverse29.isPrism)(pointer4)) {
9573
+ return pointer4.onChange(ticker, callback, true);
8763
9574
  } else {
8764
9575
  throw new Error(
8765
9576
  "Called onChange(p) where p is neither a pointer nor a prism."
8766
9577
  );
8767
9578
  }
8768
9579
  }
8769
- function val11(pointer3) {
8770
- if ((0, import_theatre_dataverse23.isPointer)(pointer3)) {
8771
- return (0, import_theatre_dataverse24.pointerToPrism)(pointer3).getValue();
9580
+ function val14(pointer4) {
9581
+ if ((0, import_theatre_dataverse28.isPointer)(pointer4)) {
9582
+ return (0, import_theatre_dataverse29.pointerToPrism)(pointer4).getValue();
8772
9583
  } else {
8773
9584
  throw new Error("Called val(p) where p is not a pointer.");
8774
9585
  }
8775
9586
  }
8776
9587
 
9588
+ // core/src/sheets/theatrePageScroll.ts
9589
+ var pageScrollConfig = {};
9590
+ function buildPageScrollContextFromConfig() {
9591
+ return {
9592
+ scroller: pageScrollConfig.scroller ?? defaultPageScrollContext.scroller,
9593
+ axis: pageScrollConfig.axis ?? defaultPageScrollContext.axis
9594
+ };
9595
+ }
9596
+ function configureTheatrePageScroll(config) {
9597
+ const prev = pageScrollConfig;
9598
+ pageScrollConfig = {
9599
+ scroller: config.scroller ?? prev.scroller,
9600
+ axis: config.axis ?? prev.axis
9601
+ };
9602
+ if (config.scroller !== void 0 || config.axis !== void 0) {
9603
+ setActivePageScrollContext(buildPageScrollContextFromConfig());
9604
+ }
9605
+ return {
9606
+ reset() {
9607
+ pageScrollConfig = prev;
9608
+ setActivePageScrollContext(
9609
+ prev.scroller !== void 0 || prev.axis !== void 0 ? {
9610
+ scroller: prev.scroller ?? defaultPageScrollContext.scroller,
9611
+ axis: prev.axis ?? defaultPageScrollContext.axis
9612
+ } : defaultPageScrollContext
9613
+ );
9614
+ }
9615
+ };
9616
+ }
9617
+ function getTheatrePageScrollConfig() {
9618
+ return pageScrollConfig;
9619
+ }
9620
+ function getTheatrePageScrollContext() {
9621
+ const ctx = buildPageScrollContextFromConfig();
9622
+ setActivePageScrollContext(ctx);
9623
+ return ctx;
9624
+ }
9625
+ function createDefaultPageScrollDriver(scroller = getTheatrePageScrollContext().scroller, axis = resolvePageScrollAxis(getTheatrePageScrollContext())) {
9626
+ if (typeof document !== "undefined" && scroller != null && !isNativeDocumentScroller(scroller) && scroller instanceof HTMLElement) {
9627
+ return axis === "horizontal" ? createElementHorizontalScrollDriver(scroller) : createElementScrollDriver(scroller);
9628
+ }
9629
+ return axis === "horizontal" ? createNativeDocumentHorizontalScrollDriver() : createNativeDocumentScrollDriver();
9630
+ }
9631
+ function attachTheatrePageScroll(sheet, options = {}) {
9632
+ const ctx = getTheatrePageScrollContext();
9633
+ const driver = options.driver ?? createDefaultPageScrollDriver(ctx.scroller, resolvePageScrollAxis(ctx));
9634
+ sheet.setPageScrollDriver(driver);
9635
+ return () => {
9636
+ sheet.setPageScrollDriver(void 0);
9637
+ };
9638
+ }
9639
+
9640
+ // core/src/coreExports-lite.ts
9641
+ var coreExports_lite_exports = {};
9642
+ __export(coreExports_lite_exports, {
9643
+ createRafDriver: () => createRafDriver,
9644
+ getProject: () => getProject,
9645
+ getTheatreCoreRafDriver: () => getTheatreCoreRafDriver,
9646
+ isRemoteEditorWindow: () => isRemoteEditorWindow,
9647
+ notify: () => notify,
9648
+ onChange: () => onChange,
9649
+ privateAPI: () => privateAPI,
9650
+ setCoreRafDriver: () => setCoreRafDriver,
9651
+ setPrivateAPI: () => setPrivateAPI,
9652
+ types: () => propTypes_exports,
9653
+ val: () => val14
9654
+ });
9655
+
8777
9656
  // core/src/CoreBundle.ts
9657
+ var coreExports = isTheatreLiteMode() ? coreExports_lite_exports : coreExports_exports;
8778
9658
  var CoreBundle = class {
8779
9659
  constructor() {
8780
9660
  __publicField(this, "_studio");
@@ -8783,7 +9663,7 @@ var CoreBundle = class {
8783
9663
  return "Theatre_CoreBundle";
8784
9664
  }
8785
9665
  get version() {
8786
- return "0.4.3";
9666
+ return "0.6.0";
8787
9667
  }
8788
9668
  getBitsForStudio(studio, callback) {
8789
9669
  if (this._studio) {
@@ -8795,7 +9675,7 @@ var CoreBundle = class {
8795
9675
  const bits = {
8796
9676
  projectsP: projectsSingleton_default.atom.pointer.projects,
8797
9677
  privateAPI,
8798
- coreExports: coreExports_exports,
9678
+ coreExports,
8799
9679
  getCoreRafDriver
8800
9680
  };
8801
9681
  callback(bits);
@@ -8806,6 +9686,15 @@ var CoreBundle = class {
8806
9686
  registerCoreBundle();
8807
9687
  function registerCoreBundle() {
8808
9688
  if (typeof window == "undefined") return;
9689
+ if (globalThis.__THEATRE_FORCE_LITE__) {
9690
+ const liteBundle = (
9691
+ // @ts-ignore ignore
9692
+ window[coreBundle]
9693
+ );
9694
+ if (liteBundle) {
9695
+ return;
9696
+ }
9697
+ }
8809
9698
  const existingBundle = (
8810
9699
  // @ts-ignore ignore
8811
9700
  window[coreBundle]