@unseenco/theatre-core 0.4.3 → 0.5.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: () => val12
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: () => val12
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_dataverse8 = require("@unseenco/theatre-dataverse");
871
1018
 
872
1019
  // ../node_modules/lodash-es/_defineProperty.js
873
1020
  var defineProperty = (function() {
@@ -979,23 +1126,23 @@ function generateDefaultsForCompound(config) {
979
1126
  }
980
1127
 
981
1128
  // core/src/sequences/interpolationTripleAtPosition.ts
982
- var import_theatre_dataverse2 = require("@unseenco/theatre-dataverse");
1129
+ var import_theatre_dataverse3 = require("@unseenco/theatre-dataverse");
983
1130
  var import_UnitBezier = __toESM(require_UnitBezier());
984
1131
  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(
1132
+ return (0, import_theatre_dataverse3.prism)(() => {
1133
+ const track = (0, import_theatre_dataverse3.val)(trackP);
1134
+ const driverD = import_theatre_dataverse3.prism.memo(
988
1135
  "driver",
989
1136
  () => {
990
1137
  if (!track) {
991
- return (0, import_theatre_dataverse2.prism)(() => void 0);
1138
+ return (0, import_theatre_dataverse3.prism)(() => void 0);
992
1139
  } else if (track.type === "BasicKeyframedTrack") {
993
1140
  return _forKeyframedTrack(ctx, track, timeD);
994
1141
  } else if (track.type === "GsapClipTrack") {
995
- return (0, import_theatre_dataverse2.prism)(() => void 0);
1142
+ return (0, import_theatre_dataverse3.prism)(() => void 0);
996
1143
  } else {
997
1144
  ctx.logger.error("Track type not yet supported.");
998
- return (0, import_theatre_dataverse2.prism)(() => void 0);
1145
+ return (0, import_theatre_dataverse3.prism)(() => void 0);
999
1146
  }
1000
1147
  },
1001
1148
  [track]
@@ -1004,8 +1151,8 @@ function interpolationTripleAtPosition(ctx, trackP, timeD) {
1004
1151
  });
1005
1152
  }
1006
1153
  function _forKeyframedTrack(ctx, track, timeD) {
1007
- return (0, import_theatre_dataverse2.prism)(() => {
1008
- let stateRef = import_theatre_dataverse2.prism.ref("state", { started: false });
1154
+ return (0, import_theatre_dataverse3.prism)(() => {
1155
+ let stateRef = import_theatre_dataverse3.prism.ref("state", { started: false });
1009
1156
  let state = stateRef.current;
1010
1157
  const time = timeD.getValue();
1011
1158
  if (!state.started || time < state.validFrom || state.validTo <= time) {
@@ -1014,7 +1161,7 @@ function _forKeyframedTrack(ctx, track, timeD) {
1014
1161
  return state.der.getValue();
1015
1162
  });
1016
1163
  }
1017
- var undefinedConstD = (0, import_theatre_dataverse2.prism)(() => void 0);
1164
+ var undefinedConstD = (0, import_theatre_dataverse3.prism)(() => void 0);
1018
1165
  function updateState(ctx, progressionD, track) {
1019
1166
  const progression = progressionD.getValue();
1020
1167
  if (track.keyframes.length === 0) {
@@ -1079,7 +1226,7 @@ var states = {
1079
1226
  started: true,
1080
1227
  validFrom: -Infinity,
1081
1228
  validTo: kf.position,
1082
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: kf.value, progression: 0 }))
1229
+ der: (0, import_theatre_dataverse3.prism)(() => ({ left: kf.value, progression: 0 }))
1083
1230
  };
1084
1231
  },
1085
1232
  lastKeyframe(kf) {
@@ -1087,7 +1234,7 @@ var states = {
1087
1234
  started: true,
1088
1235
  validFrom: kf.position,
1089
1236
  validTo: Infinity,
1090
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: kf.value, progression: 0 }))
1237
+ der: (0, import_theatre_dataverse3.prism)(() => ({ left: kf.value, progression: 0 }))
1091
1238
  };
1092
1239
  },
1093
1240
  between(left, right, progressionD) {
@@ -1096,7 +1243,7 @@ var states = {
1096
1243
  started: true,
1097
1244
  validFrom: left.position,
1098
1245
  validTo: right.position,
1099
- der: (0, import_theatre_dataverse2.prism)(() => ({ left: left.value, progression: 0 }))
1246
+ der: (0, import_theatre_dataverse3.prism)(() => ({ left: left.value, progression: 0 }))
1100
1247
  };
1101
1248
  }
1102
1249
  const globalProgressionToLocalProgression = (globalProgression) => {
@@ -1109,7 +1256,7 @@ var states = {
1109
1256
  right.handles[0],
1110
1257
  right.handles[1]
1111
1258
  );
1112
- const bezierDer = (0, import_theatre_dataverse2.prism)(() => {
1259
+ const bezierDer = (0, import_theatre_dataverse3.prism)(() => {
1113
1260
  const progression = globalProgressionToLocalProgression(
1114
1261
  progressionD.getValue()
1115
1262
  );
@@ -1127,7 +1274,7 @@ var states = {
1127
1274
  der: bezierDer
1128
1275
  };
1129
1276
  }
1130
- const holdDer = (0, import_theatre_dataverse2.prism)(() => {
1277
+ const holdDer = (0, import_theatre_dataverse3.prism)(() => {
1131
1278
  const progression = globalProgressionToLocalProgression(
1132
1279
  progressionD.getValue()
1133
1280
  );
@@ -1184,18 +1331,18 @@ function pointerDeep(base, toAppend) {
1184
1331
  }
1185
1332
 
1186
1333
  // shared/src/utils/valToAtom.ts
1187
- var import_theatre_dataverse3 = require("@unseenco/theatre-dataverse");
1334
+ var import_theatre_dataverse4 = require("@unseenco/theatre-dataverse");
1188
1335
  var valToAtom = (key, vals) => {
1189
- const a2 = import_theatre_dataverse3.prism.memo(key, () => new import_theatre_dataverse3.Atom(vals), []);
1336
+ const a2 = import_theatre_dataverse4.prism.memo(key, () => new import_theatre_dataverse4.Atom(vals), []);
1190
1337
  a2.set(vals);
1191
1338
  return a2;
1192
1339
  };
1193
1340
 
1194
1341
  // core/src/sheetObjects/SheetObject.ts
1195
- var import_theatre_dataverse6 = require("@unseenco/theatre-dataverse");
1342
+ var import_theatre_dataverse7 = require("@unseenco/theatre-dataverse");
1196
1343
 
1197
1344
  // core/src/sheetObjects/TheatreSheetObject.ts
1198
- var import_theatre_dataverse4 = require("@unseenco/theatre-dataverse");
1345
+ var import_theatre_dataverse5 = require("@unseenco/theatre-dataverse");
1199
1346
 
1200
1347
  // core/src/propTypes/index.ts
1201
1348
  var propTypes_exports = {};
@@ -3236,11 +3383,11 @@ function sanitizeCompoundProps(props) {
3236
3383
  );
3237
3384
  }
3238
3385
  }
3239
- const val12 = props[key];
3240
- if (isLonghandPropType(val12)) {
3241
- sanitizedProps[key] = val12;
3386
+ const val13 = props[key];
3387
+ if (isLonghandPropType(val13)) {
3388
+ sanitizedProps[key] = val13;
3242
3389
  } else {
3243
- sanitizedProps[key] = toLonghandProp(val12);
3390
+ sanitizedProps[key] = toLonghandProp(val13);
3244
3391
  }
3245
3392
  }
3246
3393
  return sanitizedProps;
@@ -3338,15 +3485,15 @@ var file = (defaultValue, opts = {}) => {
3338
3485
  deserializeAndSanitize: _ensureFile
3339
3486
  };
3340
3487
  };
3341
- var _ensureFile = (val12) => {
3342
- if (!val12) return void 0;
3488
+ var _ensureFile = (val13) => {
3489
+ if (!val13) return void 0;
3343
3490
  let valid = true;
3344
- if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3491
+ if (typeof val13.id !== "string" && ![null, void 0].includes(val13.id)) {
3345
3492
  valid = false;
3346
3493
  }
3347
- if (val12.type !== "file") valid = false;
3494
+ if (val13.type !== "file") valid = false;
3348
3495
  if (!valid) return void 0;
3349
- return val12;
3496
+ return val13;
3350
3497
  };
3351
3498
  var image = (defaultValue, opts = {}) => {
3352
3499
  if (process.env.NODE_ENV !== "production") {
@@ -3370,15 +3517,15 @@ var image = (defaultValue, opts = {}) => {
3370
3517
  deserializeAndSanitize: _ensureImage
3371
3518
  };
3372
3519
  };
3373
- var _ensureImage = (val12) => {
3374
- if (!val12) return void 0;
3520
+ var _ensureImage = (val13) => {
3521
+ if (!val13) return void 0;
3375
3522
  let valid = true;
3376
- if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3523
+ if (typeof val13.id !== "string" && ![null, void 0].includes(val13.id)) {
3377
3524
  valid = false;
3378
3525
  }
3379
- if (val12.type !== "image") valid = false;
3526
+ if (val13.type !== "image") valid = false;
3380
3527
  if (!valid) return void 0;
3381
- return val12;
3528
+ return val13;
3382
3529
  };
3383
3530
  var number = (defaultValue, opts = {}) => {
3384
3531
  if (process.env.NODE_ENV !== "production") {
@@ -3501,11 +3648,11 @@ var rgba = (defaultValue = { r: 0, g: 0, b: 0, a: 1 }, opts = {}) => {
3501
3648
  deserializeAndSanitize: _sanitizeRgba
3502
3649
  };
3503
3650
  };
3504
- var _sanitizeRgba = (val12) => {
3505
- if (!val12) return void 0;
3651
+ var _sanitizeRgba = (val13) => {
3652
+ if (!val13) return void 0;
3506
3653
  let valid = true;
3507
3654
  for (const c2 of ["r", "g", "b", "a"]) {
3508
- if (!Object.prototype.hasOwnProperty.call(val12, c2) || typeof val12[c2] !== "number") {
3655
+ if (!Object.prototype.hasOwnProperty.call(val13, c2) || typeof val13[c2] !== "number") {
3509
3656
  valid = false;
3510
3657
  }
3511
3658
  }
@@ -3514,7 +3661,7 @@ var _sanitizeRgba = (val12) => {
3514
3661
  for (const c2 of ["r", "g", "b", "a"]) {
3515
3662
  ;
3516
3663
  sanitized[c2] = Math.min(
3517
- Math.max(val12[c2], 0),
3664
+ Math.max(val13[c2], 0),
3518
3665
  1
3519
3666
  );
3520
3667
  }
@@ -3553,8 +3700,8 @@ var boolean = (defaultValue, opts = {}) => {
3553
3700
  deserializeAndSanitize: _ensureBoolean
3554
3701
  };
3555
3702
  };
3556
- var _ensureBoolean = (val12) => {
3557
- return typeof val12 === "boolean" ? val12 : void 0;
3703
+ var _ensureBoolean = (val13) => {
3704
+ return typeof val13 === "boolean" ? val13 : void 0;
3558
3705
  };
3559
3706
  function leftInterpolate(left) {
3560
3707
  return left;
@@ -3712,8 +3859,8 @@ var TheatreSheetObject = class {
3712
3859
  _valuesPrism() {
3713
3860
  return this._cache.get("_valuesPrism", () => {
3714
3861
  const sheetObject = privateAPI(this);
3715
- const d2 = (0, import_theatre_dataverse4.prism)(() => {
3716
- return (0, import_theatre_dataverse4.val)(sheetObject.getValues().getValue());
3862
+ const d2 = (0, import_theatre_dataverse5.prism)(() => {
3863
+ return (0, import_theatre_dataverse5.val)(sheetObject.getValues().getValue());
3717
3864
  });
3718
3865
  return d2;
3719
3866
  });
@@ -3721,10 +3868,10 @@ var TheatreSheetObject = class {
3721
3868
  _valuesWithVariantPrism() {
3722
3869
  return this._cache.get("_valuesWithVariantPrism", () => {
3723
3870
  const sheetObject = privateAPI(this);
3724
- return (0, import_theatre_dataverse4.prism)(() => {
3871
+ return (0, import_theatre_dataverse5.prism)(() => {
3725
3872
  return {
3726
- values: (0, import_theatre_dataverse4.val)(sheetObject.getValues().getValue()),
3727
- variant: (0, import_theatre_dataverse4.val)(sheetObject.sheet.effectiveActiveSequenceVariantD)
3873
+ values: (0, import_theatre_dataverse5.val)(sheetObject.getValues().getValue()),
3874
+ variant: (0, import_theatre_dataverse5.val)(sheetObject.sheet.effectiveActiveSequenceVariantD)
3728
3875
  };
3729
3876
  });
3730
3877
  });
@@ -3761,8 +3908,8 @@ var TheatreSheetObject = class {
3761
3908
  }
3762
3909
  return der.getValue();
3763
3910
  }
3764
- set initialValue(val12) {
3765
- privateAPI(this).setInitialValue(val12);
3911
+ set initialValue(val13) {
3912
+ privateAPI(this).setInitialValue(val13);
3766
3913
  }
3767
3914
  showPropsOf(objects) {
3768
3915
  const host = privateAPI(this);
@@ -4157,7 +4304,7 @@ function setDeepImmutable(obj, path, replace) {
4157
4304
  }
4158
4305
 
4159
4306
  // core/src/sequences/sequenceVariants.ts
4160
- var import_theatre_dataverse5 = require("@unseenco/theatre-dataverse");
4307
+ var import_theatre_dataverse6 = require("@unseenco/theatre-dataverse");
4161
4308
 
4162
4309
  // shared/src/utils/sheetProps.ts
4163
4310
  var SHEET_PROPS_OBJECT_KEY = "__theatre_sheet_props__";
@@ -4225,17 +4372,17 @@ function getSequenceStateFromSheet(sheetState, variantId) {
4225
4372
  return void 0;
4226
4373
  }
4227
4374
  function valTrackIdByPropPathForObject(sheetStatePointer, variantId, objectKey) {
4228
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById);
4229
- const sequenceFromMap = (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId]);
4375
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById);
4376
+ const sequenceFromMap = (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId]);
4230
4377
  if (sequenceFromMap !== void 0) {
4231
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4232
- return (0, import_theatre_dataverse5.val)(
4378
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4379
+ return (0, import_theatre_dataverse6.val)(
4233
4380
  sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey]?.trackIdByPropPath
4234
4381
  );
4235
4382
  }
4236
4383
  if (variantId === DEFAULT_SEQUENCE_VARIANT) {
4237
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequence?.tracksByObject);
4238
- return (0, import_theatre_dataverse5.val)(
4384
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequence?.tracksByObject);
4385
+ return (0, import_theatre_dataverse6.val)(
4239
4386
  sheetStatePointer.sequence?.tracksByObject[objectKey]?.trackIdByPropPath
4240
4387
  );
4241
4388
  }
@@ -4243,11 +4390,11 @@ function valTrackIdByPropPathForObject(sheetStatePointer, variantId, objectKey)
4243
4390
  }
4244
4391
  function valUnsequencedPropPathsForObject(sheetStatePointer, variantId, objectKey) {
4245
4392
  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]);
4393
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById);
4394
+ const sequenceFromMap = (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId]);
4248
4395
  if (sequenceFromMap !== void 0) {
4249
- (0, import_theatre_dataverse5.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4250
- return (0, import_theatre_dataverse5.val)(
4396
+ (0, import_theatre_dataverse6.val)(sheetStatePointer.sequencesById[variantId].tracksByObject);
4397
+ return (0, import_theatre_dataverse6.val)(
4251
4398
  sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey]?.unsequencedPropPaths
4252
4399
  );
4253
4400
  }
@@ -4275,7 +4422,7 @@ function validateSequenceVariantIdOrThrow(value, fnName) {
4275
4422
  return idTrimmed;
4276
4423
  }
4277
4424
  function pointerToSequenceTrackData(sheetStatePointer, variantId, objectKey, trackId) {
4278
- const sheetState = (0, import_theatre_dataverse5.val)(sheetStatePointer);
4425
+ const sheetState = (0, import_theatre_dataverse6.val)(sheetStatePointer);
4279
4426
  if (sheetState?.sequencesById?.[variantId]) {
4280
4427
  return sheetStatePointer.sequencesById[variantId].tracksByObject[objectKey].trackData[trackId];
4281
4428
  }
@@ -4318,19 +4465,19 @@ var SheetObject = class {
4318
4465
  __publicField(this, "$$isPointerToPrismProvider", true);
4319
4466
  __publicField(this, "address");
4320
4467
  __publicField(this, "publicApi");
4321
- __publicField(this, "_initialValue", new import_theatre_dataverse6.Atom({}));
4468
+ __publicField(this, "_initialValue", new import_theatre_dataverse7.Atom({}));
4322
4469
  /**
4323
4470
  * Highest-priority override layer, written to by `RemoteSync` when a value
4324
4471
  * update arrives from a remote editor window (see `internal/RemoteSync.ts`).
4325
4472
  * Empty (`{}`) unless a remote editor is actually connected, so it's a
4326
4473
  * no-op merge for every app that never uses the remote-sync feature.
4327
4474
  */
4328
- __publicField(this, "_remoteOverride", new import_theatre_dataverse6.Atom({}));
4475
+ __publicField(this, "_remoteOverride", new import_theatre_dataverse7.Atom({}));
4329
4476
  /**
4330
4477
  * Session-only overrides for props with `persist: false`. Not written to
4331
4478
  * persisted project state and cleared on refresh.
4332
4479
  */
4333
- __publicField(this, "_sessionOverrides", new import_theatre_dataverse6.Atom({}));
4480
+ __publicField(this, "_sessionOverrides", new import_theatre_dataverse7.Atom({}));
4334
4481
  __publicField(this, "_cache", new SimpleCache());
4335
4482
  __publicField(this, "_logger");
4336
4483
  __publicField(this, "_internalUtilCtx");
@@ -4352,10 +4499,10 @@ var SheetObject = class {
4352
4499
  getValues() {
4353
4500
  return this._cache.get(
4354
4501
  "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(
4502
+ () => (0, import_theatre_dataverse7.prism)(() => {
4503
+ const defaults = (0, import_theatre_dataverse7.val)(this.template.getDefaultValues());
4504
+ const initial = (0, import_theatre_dataverse7.val)(this._initialValue.pointer);
4505
+ const withInitialCache = import_theatre_dataverse7.prism.memo(
4359
4506
  "withInitialCache",
4360
4507
  () => /* @__PURE__ */ new WeakMap(),
4361
4508
  []
@@ -4365,8 +4512,8 @@ var SheetObject = class {
4365
4512
  initial,
4366
4513
  withInitialCache
4367
4514
  );
4368
- const ahistoricStatics = (0, import_theatre_dataverse6.val)(this.template.getAhistoricStaticValues());
4369
- const withAhistoricStaticsCache = import_theatre_dataverse6.prism.memo(
4515
+ const ahistoricStatics = (0, import_theatre_dataverse7.val)(this.template.getAhistoricStaticValues());
4516
+ const withAhistoricStaticsCache = import_theatre_dataverse7.prism.memo(
4370
4517
  "withAhistoricStatics",
4371
4518
  () => /* @__PURE__ */ new WeakMap(),
4372
4519
  []
@@ -4376,10 +4523,10 @@ var SheetObject = class {
4376
4523
  ahistoricStatics,
4377
4524
  withAhistoricStaticsCache
4378
4525
  );
4379
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4526
+ const activeVariant = (0, import_theatre_dataverse7.val)(this.sheet.effectiveActiveSequenceVariantD);
4380
4527
  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(
4528
+ const statics = (0, import_theatre_dataverse7.val)(this.template.getStaticValues(staticVariant));
4529
+ const withStaticsCache = import_theatre_dataverse7.prism.memo(
4383
4530
  "withStatics",
4384
4531
  () => /* @__PURE__ */ new WeakMap(),
4385
4532
  []
@@ -4392,22 +4539,22 @@ var SheetObject = class {
4392
4539
  let final = withStatics;
4393
4540
  let sequenced;
4394
4541
  {
4395
- const pointerToSequencedValuesD = import_theatre_dataverse6.prism.memo(
4542
+ const pointerToSequencedValuesD = import_theatre_dataverse7.prism.memo(
4396
4543
  "seq",
4397
4544
  () => this.getSequencedValues(),
4398
4545
  []
4399
4546
  );
4400
- const withSeqsCache = import_theatre_dataverse6.prism.memo(
4547
+ const withSeqsCache = import_theatre_dataverse7.prism.memo(
4401
4548
  "withSeqsCache",
4402
4549
  () => /* @__PURE__ */ new WeakMap(),
4403
4550
  []
4404
4551
  );
4405
- sequenced = (0, import_theatre_dataverse6.val)((0, import_theatre_dataverse6.val)(pointerToSequencedValuesD));
4552
+ sequenced = (0, import_theatre_dataverse7.val)((0, import_theatre_dataverse7.val)(pointerToSequencedValuesD));
4406
4553
  const withSeqs = deepMergeWithCache(final, sequenced, withSeqsCache);
4407
4554
  final = withSeqs;
4408
4555
  }
4409
- const sessionOverrides = (0, import_theatre_dataverse6.val)(this._sessionOverrides.pointer);
4410
- const withSessionOverridesCache = import_theatre_dataverse6.prism.memo(
4556
+ const sessionOverrides = (0, import_theatre_dataverse7.val)(this._sessionOverrides.pointer);
4557
+ const withSessionOverridesCache = import_theatre_dataverse7.prism.memo(
4411
4558
  "withSessionOverridesCache",
4412
4559
  () => /* @__PURE__ */ new WeakMap(),
4413
4560
  []
@@ -4417,8 +4564,8 @@ var SheetObject = class {
4417
4564
  sessionOverrides,
4418
4565
  withSessionOverridesCache
4419
4566
  );
4420
- const remoteOverride = (0, import_theatre_dataverse6.val)(this._remoteOverride.pointer);
4421
- const withRemoteOverrideCache = import_theatre_dataverse6.prism.memo(
4567
+ const remoteOverride = (0, import_theatre_dataverse7.val)(this._remoteOverride.pointer);
4568
+ const withRemoteOverrideCache = import_theatre_dataverse7.prism.memo(
4422
4569
  "withRemoteOverrideCache",
4423
4570
  () => /* @__PURE__ */ new WeakMap(),
4424
4571
  []
@@ -4434,35 +4581,35 @@ var SheetObject = class {
4434
4581
  );
4435
4582
  }
4436
4583
  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)(
4584
+ const allValuesP = (0, import_theatre_dataverse7.val)(this.getValues());
4585
+ const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
4586
+ return (0, import_theatre_dataverse7.val)(
4440
4587
  pointerDeep(allValuesP, path)
4441
4588
  );
4442
4589
  }
4443
4590
  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));
4591
+ const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
4592
+ return (0, import_theatre_dataverse7.prism)(() => {
4593
+ const allValuesP = (0, import_theatre_dataverse7.val)(this.getValues());
4594
+ return (0, import_theatre_dataverse7.val)(pointerDeep(allValuesP, path));
4448
4595
  });
4449
4596
  }
4450
4597
  /**
4451
4598
  * Returns values of props that are sequenced.
4452
4599
  */
4453
4600
  getSequencedValues() {
4454
- return (0, import_theatre_dataverse6.prism)(() => {
4455
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4601
+ return (0, import_theatre_dataverse7.prism)(() => {
4602
+ const activeVariant = (0, import_theatre_dataverse7.val)(this.sheet.effectiveActiveSequenceVariantD);
4456
4603
  const sequenceVariant = isSheetPropsObjectKey(this.address.objectKey) ? DEFAULT_SEQUENCE_VARIANT : activeVariant;
4457
- const tracksToProcessD = import_theatre_dataverse6.prism.memo(
4604
+ const tracksToProcessD = import_theatre_dataverse7.prism.memo(
4458
4605
  "tracksToProcess",
4459
4606
  () => this.template.getArrayOfValidSequenceTracks(sequenceVariant),
4460
4607
  [sequenceVariant]
4461
4608
  );
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(
4609
+ const tracksToProcess = (0, import_theatre_dataverse7.val)(tracksToProcessD);
4610
+ const valsAtom = new import_theatre_dataverse7.Atom({});
4611
+ const config = (0, import_theatre_dataverse7.val)(this.template.configPointer);
4612
+ import_theatre_dataverse7.prism.effect(
4466
4613
  "processTracks",
4467
4614
  () => {
4468
4615
  const untaps = [];
@@ -4512,7 +4659,7 @@ var SheetObject = class {
4512
4659
  });
4513
4660
  }
4514
4661
  _trackIdToPrism(trackId, trackVariant) {
4515
- const activeVariant = (0, import_theatre_dataverse6.val)(this.sheet.effectiveActiveSequenceVariantD);
4662
+ const activeVariant = (0, import_theatre_dataverse7.val)(this.sheet.effectiveActiveSequenceVariantD);
4516
4663
  const trackP = pointerToSequenceTrackData(
4517
4664
  this.template.project.pointers.historic.sheetsById[this.address.sheetId],
4518
4665
  trackVariant,
@@ -4525,14 +4672,14 @@ var SheetObject = class {
4525
4672
  get propsP() {
4526
4673
  return this._cache.get(
4527
4674
  "propsP",
4528
- () => (0, import_theatre_dataverse6.pointer)({ root: this, path: [] })
4675
+ () => (0, import_theatre_dataverse7.pointer)({ root: this, path: [] })
4529
4676
  );
4530
4677
  }
4531
4678
  validateValue(pointer3, value) {
4532
4679
  }
4533
- setInitialValue(val12) {
4534
- this.validateValue(this.propsP, val12);
4535
- this._initialValue.set(val12);
4680
+ setInitialValue(val13) {
4681
+ this.validateValue(this.propsP, val13);
4682
+ this._initialValue.set(val13);
4536
4683
  }
4537
4684
  setSessionOverride(path, value) {
4538
4685
  const propConfig = getPropConfigByPath(this.template.staticConfig, path);
@@ -4552,8 +4699,8 @@ var SheetObject = class {
4552
4699
  * Internal: called by `RemoteSync` when a value update for this object
4553
4700
  * arrives from a remote editor window. Not exposed on the public API.
4554
4701
  */
4555
- setRemoteOverride(val12) {
4556
- this._remoteOverride.set(val12);
4702
+ setRemoteOverride(val13) {
4703
+ this._remoteOverride.set(val13);
4557
4704
  }
4558
4705
  /**
4559
4706
  * Internal: used by `RemoteSync` to subscribe to this object's fully
@@ -4562,7 +4709,7 @@ var SheetObject = class {
4562
4709
  */
4563
4710
  onFinalValueChange(fn2) {
4564
4711
  return onChange(
4565
- (0, import_theatre_dataverse6.prism)(() => (0, import_theatre_dataverse6.val)(this.getValues().getValue())),
4712
+ (0, import_theatre_dataverse7.prism)(() => (0, import_theatre_dataverse7.val)(this.getValues().getValue())),
4566
4713
  fn2
4567
4714
  );
4568
4715
  }
@@ -5133,9 +5280,9 @@ var SheetObjectTemplate = class {
5133
5280
  config,
5134
5281
  sheetTemplate.project
5135
5282
  );
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([]);
5283
+ this._config = new import_theatre_dataverse8.Atom(configWithPrecisionDefaults);
5284
+ this._temp_actions_atom = new import_theatre_dataverse8.Atom(_temp_actions);
5285
+ this.showPropsOf_atom = new import_theatre_dataverse8.Atom([]);
5139
5286
  this._transientPropPaths = normalizeTransientPropPaths(
5140
5287
  transient,
5141
5288
  config,
@@ -5192,7 +5339,7 @@ var SheetObjectTemplate = class {
5192
5339
  return this.showPropsOf_atom.pointer;
5193
5340
  }
5194
5341
  _stripNonPersistingPropsFromAhistoricState() {
5195
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5342
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5196
5343
  this.project._stripNonPersistingPropsFromAhistoric(
5197
5344
  this.address.sheetId,
5198
5345
  this.address.objectKey,
@@ -5321,8 +5468,8 @@ var SheetObjectTemplate = class {
5321
5468
  getDefaultValues() {
5322
5469
  return this._cache.get(
5323
5470
  "getDefaultValues()",
5324
- () => (0, import_theatre_dataverse7.prism)(() => {
5325
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5471
+ () => (0, import_theatre_dataverse8.prism)(() => {
5472
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5326
5473
  return getPropDefaultsOfSheetObject(config);
5327
5474
  })
5328
5475
  );
@@ -5334,14 +5481,14 @@ var SheetObjectTemplate = class {
5334
5481
  getStaticValues(sequenceVariant = DEFAULT_SEQUENCE_VARIANT) {
5335
5482
  return this._cache.get(
5336
5483
  "getStaticValues:".concat(sequenceVariant),
5337
- () => (0, import_theatre_dataverse7.prism)(() => {
5338
- const sheetState = (0, import_theatre_dataverse7.val)(this.pointerToSheetState);
5484
+ () => (0, import_theatre_dataverse8.prism)(() => {
5485
+ const sheetState = (0, import_theatre_dataverse8.val)(this.pointerToSheetState);
5339
5486
  const json = getEffectiveStaticOverrideForObject(
5340
5487
  sheetState,
5341
5488
  sequenceVariant,
5342
5489
  this.address.objectKey
5343
5490
  ) ?? {};
5344
- const config = (0, import_theatre_dataverse7.val)(this.configPointer);
5491
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5345
5492
  const deserialized = config.deserializeAndSanitize(json) || {};
5346
5493
  const withoutNonPersisting = stripNonPersistingPropValuesFromMap(
5347
5494
  deserialized,
@@ -5364,9 +5511,9 @@ var SheetObjectTemplate = class {
5364
5511
  getAhistoricStaticValues() {
5365
5512
  return this._cache.get(
5366
5513
  "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);
5514
+ () => (0, import_theatre_dataverse8.prism)(() => {
5515
+ const json = (0, import_theatre_dataverse8.val)(this.pointerToAhistoricStaticOverrides) ?? {};
5516
+ const config = (0, import_theatre_dataverse8.val)(this.configPointer);
5370
5517
  const deserialized = config.deserializeAndSanitize(json) || {};
5371
5518
  return stripNonPersistingPropValuesFromMap(deserialized, config);
5372
5519
  })
@@ -5381,13 +5528,13 @@ var SheetObjectTemplate = class {
5381
5528
  getArrayOfValidSequenceTracks(sequenceVariant) {
5382
5529
  return this._cache.get(
5383
5530
  "getArrayOfValidSequenceTracks:".concat(sequenceVariant),
5384
- () => (0, import_theatre_dataverse7.prism)(
5531
+ () => (0, import_theatre_dataverse8.prism)(
5385
5532
  () => {
5386
5533
  const effectiveSequenceVariant = isSheetPropsObjectKey(
5387
5534
  this.address.objectKey
5388
5535
  ) ? DEFAULT_SEQUENCE_VARIANT : sequenceVariant;
5389
5536
  const pointerToSheetState = this.project.pointers.historic.sheetsById[this.address.sheetId];
5390
- (0, import_theatre_dataverse7.val)(pointerToSheetState.variantObjectOverrides);
5537
+ (0, import_theatre_dataverse8.val)(pointerToSheetState.variantObjectOverrides);
5391
5538
  const defaultTrackIdByPropPath = valTrackIdByPropPathForObject(
5392
5539
  pointerToSheetState,
5393
5540
  DEFAULT_SEQUENCE_VARIANT,
@@ -5413,7 +5560,7 @@ var SheetObjectTemplate = class {
5413
5560
  return emptyArray;
5414
5561
  }
5415
5562
  const arrayOfIds = [];
5416
- const objectConfig = (0, import_theatre_dataverse7.val)(this.configPointer);
5563
+ const objectConfig = (0, import_theatre_dataverse8.val)(this.configPointer);
5417
5564
  for (const [pathToPropInString, effectiveTrack] of Object.entries(
5418
5565
  mergedTrackMap
5419
5566
  )) {
@@ -5463,8 +5610,8 @@ var SheetObjectTemplate = class {
5463
5610
  getMapOfValidSequenceTracks_forStudio(sequenceVariant) {
5464
5611
  return this._cache.get(
5465
5612
  "getMapOfValidSequenceTracks_forStudio:".concat(sequenceVariant),
5466
- () => (0, import_theatre_dataverse7.prism)(() => {
5467
- const arr = (0, import_theatre_dataverse7.val)(this.getArrayOfValidSequenceTracks(sequenceVariant));
5613
+ () => (0, import_theatre_dataverse8.prism)(() => {
5614
+ const arr = (0, import_theatre_dataverse8.val)(this.getArrayOfValidSequenceTracks(sequenceVariant));
5468
5615
  let map = {};
5469
5616
  for (const { pathToProp, trackId } of arr) {
5470
5617
  set_default(map, pathToProp, trackId);
@@ -5484,9 +5631,9 @@ var SheetObjectTemplate = class {
5484
5631
  getStaticButNotSequencedOverrides(sequenceVariant) {
5485
5632
  return this._cache.get(
5486
5633
  "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)(
5634
+ () => (0, import_theatre_dataverse8.prism)(() => {
5635
+ const staticOverrides = (0, import_theatre_dataverse8.val)(this.getStaticValues(sequenceVariant));
5636
+ const arrayOfValidSequenceTracks = (0, import_theatre_dataverse8.val)(
5490
5637
  this.getArrayOfValidSequenceTracks(sequenceVariant)
5491
5638
  );
5492
5639
  const staticButNotSequencedOverrides = cloneDeep_default(staticOverrides);
@@ -5512,7 +5659,7 @@ var SheetObjectTemplate = class {
5512
5659
  );
5513
5660
  }
5514
5661
  getDefaultsAtPointer(pointer3) {
5515
- const { path } = (0, import_theatre_dataverse7.getPointerParts)(pointer3);
5662
+ const { path } = (0, import_theatre_dataverse8.getPointerParts)(pointer3);
5516
5663
  const defaults = this.getDefaultValues().getValue();
5517
5664
  const defaultsAtPath = getDeep(defaults, path);
5518
5665
  return defaultsAtPath;
@@ -5533,7 +5680,7 @@ function parsePathToProp(pathToPropInString) {
5533
5680
  }
5534
5681
 
5535
5682
  // core/src/sheets/SheetTemplate.ts
5536
- var import_theatre_dataverse16 = require("@unseenco/theatre-dataverse");
5683
+ var import_theatre_dataverse19 = require("@unseenco/theatre-dataverse");
5537
5684
 
5538
5685
  // shared/src/utils/didYouMean.ts
5539
5686
  var import_propose = __toESM(require_propose());
@@ -5549,10 +5696,10 @@ function didYouMean(str, dictionary, prepend = "Did you mean ", append = "?") {
5549
5696
  }
5550
5697
 
5551
5698
  // core/src/sequences/Sequence.ts
5552
- var import_theatre_dataverse11 = require("@unseenco/theatre-dataverse");
5553
5699
  var import_theatre_dataverse12 = require("@unseenco/theatre-dataverse");
5554
5700
  var import_theatre_dataverse13 = require("@unseenco/theatre-dataverse");
5555
5701
  var import_theatre_dataverse14 = require("@unseenco/theatre-dataverse");
5702
+ var import_theatre_dataverse15 = require("@unseenco/theatre-dataverse");
5556
5703
 
5557
5704
  // shared/src/utils/defer.ts
5558
5705
  function defer() {
@@ -5583,11 +5730,11 @@ var noop = () => {
5583
5730
  var noop_default = noop;
5584
5731
 
5585
5732
  // core/src/sequences/playbackControllers/DefaultPlaybackController.ts
5586
- var import_theatre_dataverse8 = require("@unseenco/theatre-dataverse");
5733
+ var import_theatre_dataverse9 = require("@unseenco/theatre-dataverse");
5587
5734
  var DefaultPlaybackController = class {
5588
5735
  constructor() {
5589
5736
  __publicField(this, "_stopPlayCallback", noop_default);
5590
- __publicField(this, "_state", new import_theatre_dataverse8.Atom({
5737
+ __publicField(this, "_state", new import_theatre_dataverse9.Atom({
5591
5738
  position: 0,
5592
5739
  playing: false
5593
5740
  }));
@@ -5753,7 +5900,7 @@ var DefaultPlaybackController = class {
5753
5900
  };
5754
5901
 
5755
5902
  // core/src/sequences/playbackControllers/AudioPlaybackController.ts
5756
- var import_theatre_dataverse9 = require("@unseenco/theatre-dataverse");
5903
+ var import_theatre_dataverse10 = require("@unseenco/theatre-dataverse");
5757
5904
 
5758
5905
  // shared/src/globalVariableNames.ts
5759
5906
  var studioBundle = "__TheatreJS_StudioBundle";
@@ -5811,7 +5958,7 @@ var AudioPlaybackController = class {
5811
5958
  this._audioContext = _audioContext;
5812
5959
  this._nodeDestination = _nodeDestination;
5813
5960
  __publicField(this, "_mainGain");
5814
- __publicField(this, "_state", new import_theatre_dataverse9.Atom({
5961
+ __publicField(this, "_state", new import_theatre_dataverse10.Atom({
5815
5962
  position: 0,
5816
5963
  playing: false
5817
5964
  }));
@@ -5931,11 +6078,11 @@ var AudioPlaybackController = class {
5931
6078
  "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
6079
  [
5933
6080
  {
5934
- url: "https://www.theatrejs.com/docs/latest/manual/audio",
6081
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/audio",
5935
6082
  title: "Using Audio"
5936
6083
  },
5937
6084
  {
5938
- url: "https://www.theatrejs.com/docs/latest/api/core#sequence.attachaudio",
6085
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sequence.attachaudio",
5939
6086
  title: "Audio API"
5940
6087
  }
5941
6088
  ]
@@ -5988,82 +6135,6 @@ var AudioPlaybackController = class {
5988
6135
  }
5989
6136
  };
5990
6137
 
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
6138
  // core/src/sequences/TheatreSequence.ts
6068
6139
  var TheatreSequence = class {
6069
6140
  get type() {
@@ -6087,7 +6158,7 @@ var TheatreSequence = class {
6087
6158
  "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
6159
  [
6089
6160
  {
6090
- url: "https://www.theatrejs.com/docs/0.5/api/core#project.ready",
6161
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#project.ready",
6091
6162
  title: "Project.ready"
6092
6163
  }
6093
6164
  ]
@@ -6113,14 +6184,27 @@ var TheatreSequence = class {
6113
6184
  __experimental_getGsapClips() {
6114
6185
  return privateAPI(this).getGsapClips();
6115
6186
  }
6187
+ __experimental_getGsapScrollTriggers() {
6188
+ return privateAPI(this).getGsapScrollTriggers();
6189
+ }
6116
6190
  async attachAudio(args) {
6191
+ const priv = privateAPI(this);
6192
+ if (priv._sheet.getSequenceMode() === "page") {
6193
+ notify.warning(
6194
+ "Audio is not supported in page mode",
6195
+ "Sequence audio expects time in seconds. Use time mode for attachAudio(), or scrub scroll-driven animation without audio."
6196
+ );
6197
+ return Promise.reject(
6198
+ new Error("sequence.attachAudio() is not supported in page mode")
6199
+ );
6200
+ }
6117
6201
  const { audioContext, destinationNode, decodedBuffer, gainNode } = await resolveAudioBuffer(args);
6118
6202
  const playbackController = new AudioPlaybackController(
6119
6203
  decodedBuffer,
6120
6204
  audioContext,
6121
6205
  gainNode
6122
6206
  );
6123
- privateAPI(this).replacePlaybackController(playbackController);
6207
+ priv.replacePlaybackController(playbackController);
6124
6208
  return { audioContext, destinationNode, decodedBuffer, gainNode };
6125
6209
  }
6126
6210
  get pointer() {
@@ -6218,6 +6302,31 @@ async function resolveAudioBuffer(args) {
6218
6302
  };
6219
6303
  }
6220
6304
 
6305
+ // shared/src/gsap/gsapStudioRegistryRevision.ts
6306
+ var import_theatre_dataverse11 = require("@unseenco/theatre-dataverse");
6307
+ var revisionAtom = new import_theatre_dataverse11.Atom(0);
6308
+ var gsapStudioRegistryRevisionPointer = revisionAtom.pointer;
6309
+
6310
+ // shared/src/gsap/scrollTriggerRegistry.ts
6311
+ var DEFAULT_SHEET_INSTANCE_ID = "default";
6312
+ var REGISTRY_KEY = "__unseenco_theatre_gsap_scrollTriggerRegistry__";
6313
+ function sheetAddressKey(address) {
6314
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID;
6315
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId);
6316
+ }
6317
+ function getStore() {
6318
+ const g2 = globalThis;
6319
+ if (!g2[REGISTRY_KEY]) {
6320
+ g2[REGISTRY_KEY] = { bySheetAddress: /* @__PURE__ */ new Map() };
6321
+ }
6322
+ return g2[REGISTRY_KEY];
6323
+ }
6324
+ function listScrollTriggerEntriesForSheet(sheetKey) {
6325
+ const map = getStore().bySheetAddress.get(sheetKey);
6326
+ if (!map) return [];
6327
+ return [...map.values()].sort((a2, b2) => a2.layout.start - b2.layout.start);
6328
+ }
6329
+
6221
6330
  // shared/src/sequence/trackData.ts
6222
6331
  function isBasicKeyframedTrack(track) {
6223
6332
  return track.type === "BasicKeyframedTrack";
@@ -6260,7 +6369,7 @@ var Sequence = class {
6260
6369
  __publicField(this, "_positionD");
6261
6370
  __publicField(this, "_positionFormatterD");
6262
6371
  __publicField(this, "_playableRangeD");
6263
- __publicField(this, "pointer", (0, import_theatre_dataverse13.pointer)({ root: this, path: [] }));
6372
+ __publicField(this, "pointer", (0, import_theatre_dataverse14.pointer)({ root: this, path: [] }));
6264
6373
  __publicField(this, "$$isPointerToPrismProvider", true);
6265
6374
  __publicField(this, "_logger");
6266
6375
  __publicField(this, "closestGridPosition", (posInUnitSpace) => {
@@ -6273,32 +6382,35 @@ var Sequence = class {
6273
6382
  this._logger = _project._logger.named("Sheet", _sheet.address.sheetId).named("Instance", _sheet.address.sheetInstanceId).named("Variant", _sequenceVariant);
6274
6383
  this.address = { ...this._sheet.address, sequenceName: _sequenceVariant };
6275
6384
  this.publicApi = new TheatreSequence(this);
6276
- this._playbackControllerBox = new import_theatre_dataverse12.Atom(
6385
+ this._playbackControllerBox = new import_theatre_dataverse13.Atom(
6277
6386
  playbackController ?? new DefaultPlaybackController()
6278
6387
  );
6279
- this._prismOfStatePointer = (0, import_theatre_dataverse14.prism)(
6388
+ this._prismOfStatePointer = (0, import_theatre_dataverse15.prism)(
6280
6389
  () => this._playbackControllerBox.prism.getValue().statePointer
6281
6390
  );
6282
- this._positionD = (0, import_theatre_dataverse14.prism)(() => {
6391
+ this._positionD = (0, import_theatre_dataverse15.prism)(() => {
6283
6392
  const statePointer = this._prismOfStatePointer.getValue();
6284
- return (0, import_theatre_dataverse14.val)(statePointer.position);
6393
+ return (0, import_theatre_dataverse15.val)(statePointer.position);
6285
6394
  });
6286
- this._positionFormatterD = (0, import_theatre_dataverse14.prism)(() => {
6287
- const subUnitsPerUnit = (0, import_theatre_dataverse14.val)(this._subUnitsPerUnitD);
6395
+ this._positionFormatterD = (0, import_theatre_dataverse15.prism)(() => {
6396
+ const subUnitsPerUnit = (0, import_theatre_dataverse15.val)(this._subUnitsPerUnitD);
6397
+ if (this._sheet.getSequenceMode() === "page") {
6398
+ return new PercentBasedPositionFormatter(subUnitsPerUnit);
6399
+ }
6288
6400
  return new TimeBasedPositionFormatter(subUnitsPerUnit);
6289
6401
  });
6290
6402
  }
6291
6403
  pointerToPrism(pointer3) {
6292
- const { path } = (0, import_theatre_dataverse11.getPointerParts)(pointer3);
6404
+ const { path } = (0, import_theatre_dataverse12.getPointerParts)(pointer3);
6293
6405
  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)
6406
+ return (0, import_theatre_dataverse15.prism)(() => ({
6407
+ length: (0, import_theatre_dataverse15.val)(this.pointer.length),
6408
+ playing: (0, import_theatre_dataverse15.val)(this.pointer.playing),
6409
+ position: (0, import_theatre_dataverse15.val)(this.pointer.position)
6298
6410
  }));
6299
6411
  }
6300
6412
  if (path.length > 1) {
6301
- return (0, import_theatre_dataverse14.prism)(() => void 0);
6413
+ return (0, import_theatre_dataverse15.prism)(() => void 0);
6302
6414
  }
6303
6415
  const [prop] = path;
6304
6416
  if (prop === "length") {
@@ -6306,11 +6418,11 @@ var Sequence = class {
6306
6418
  } else if (prop === "position") {
6307
6419
  return this._positionD;
6308
6420
  } else if (prop === "playing") {
6309
- return (0, import_theatre_dataverse14.prism)(() => {
6310
- return (0, import_theatre_dataverse14.val)(this._prismOfStatePointer.getValue().playing);
6421
+ return (0, import_theatre_dataverse15.prism)(() => {
6422
+ return (0, import_theatre_dataverse15.val)(this._prismOfStatePointer.getValue().playing);
6311
6423
  });
6312
6424
  } else {
6313
- return (0, import_theatre_dataverse14.prism)(() => void 0);
6425
+ return (0, import_theatre_dataverse15.prism)(() => void 0);
6314
6426
  }
6315
6427
  }
6316
6428
  /**
@@ -6319,13 +6431,13 @@ var Sequence = class {
6319
6431
  * Theoretically, this method can be called from inside a prism so it can be reactive.
6320
6432
  */
6321
6433
  getKeyframesOfSimpleProp(prop) {
6322
- const { path, root: root2 } = (0, import_theatre_dataverse11.getPointerParts)(prop);
6434
+ const { path, root: root2 } = (0, import_theatre_dataverse12.getPointerParts)(prop);
6323
6435
  if (!isSheetObject(root2)) {
6324
6436
  throw new InvalidArgumentError(
6325
6437
  "Argument prop must be a pointer to a SheetObject property"
6326
6438
  );
6327
6439
  }
6328
- const sheetState = (0, import_theatre_dataverse14.val)(
6440
+ const sheetState = (0, import_theatre_dataverse15.val)(
6329
6441
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6330
6442
  );
6331
6443
  const trackP = getSequenceStateFromSheet(sheetState, this._sequenceVariant)?.tracksByObject[root2.address.objectKey];
@@ -6348,7 +6460,7 @@ var Sequence = class {
6348
6460
  * @internal Used by the public sequence API.
6349
6461
  */
6350
6462
  getGsapClipsForObject(objectKey) {
6351
- const sheetState = (0, import_theatre_dataverse14.val)(
6463
+ const sheetState = (0, import_theatre_dataverse15.val)(
6352
6464
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6353
6465
  );
6354
6466
  const tracksOfObject = getSequenceStateFromSheet(
@@ -6365,7 +6477,7 @@ var Sequence = class {
6365
6477
  return result.sort((a2, b2) => a2.clip.start - b2.clip.start);
6366
6478
  }
6367
6479
  getGsapClips() {
6368
- const sheetState = (0, import_theatre_dataverse14.val)(
6480
+ const sheetState = (0, import_theatre_dataverse15.val)(
6369
6481
  this._project.pointers.historic.sheetsById[this._sheet.address.sheetId]
6370
6482
  );
6371
6483
  const sequenceState = getSequenceStateFromSheet(
@@ -6390,6 +6502,21 @@ var Sequence = class {
6390
6502
  }
6391
6503
  return result.sort((a2, b2) => a2.clip.start - b2.clip.start);
6392
6504
  }
6505
+ getGsapScrollTriggers() {
6506
+ if (this._sheet.getSequenceMode() !== "page") {
6507
+ return [];
6508
+ }
6509
+ const key = sheetAddressKey(this._sheet.address);
6510
+ return listScrollTriggerEntriesForSheet(key).filter((entry) => entry.sheetObject != null).map((entry) => ({
6511
+ objectKey: entry.sheetObject.address.objectKey,
6512
+ scrollTriggerId: entry.id,
6513
+ label: entry.label,
6514
+ layout: entry.layout,
6515
+ kind: entry.kind,
6516
+ animationSpanSeconds: entry.animationSpanSeconds,
6517
+ timelineChildren: entry.timelineChildren
6518
+ }));
6519
+ }
6393
6520
  get positionFormatter() {
6394
6521
  return this._positionFormatterD.getValue();
6395
6522
  }
@@ -6438,11 +6565,11 @@ var Sequence = class {
6438
6565
  return this._lengthD.getValue();
6439
6566
  }
6440
6567
  get playing() {
6441
- return (0, import_theatre_dataverse14.val)(this._playbackControllerBox.get().statePointer.playing);
6568
+ return (0, import_theatre_dataverse15.val)(this._playbackControllerBox.get().statePointer.playing);
6442
6569
  }
6443
6570
  _makeRangeFromSequenceTemplate() {
6444
- return (0, import_theatre_dataverse14.prism)(() => {
6445
- return [0, (0, import_theatre_dataverse14.val)(this._lengthD)];
6571
+ return (0, import_theatre_dataverse15.prism)(() => {
6572
+ return [0, (0, import_theatre_dataverse15.val)(this._lengthD)];
6446
6573
  });
6447
6574
  }
6448
6575
  /**
@@ -6460,6 +6587,13 @@ var Sequence = class {
6460
6587
  return this._playbackControllerBox.get().playDynamicRange(rangeD, ticker);
6461
6588
  }
6462
6589
  async play(conf, ticker) {
6590
+ if (this._sheet.getSequenceMode() === "page") {
6591
+ notify.warning(
6592
+ "Playback is disabled in page mode",
6593
+ "The sequence is driven by page scroll. Scrub the playhead or scroll the page instead of calling sequence.play()."
6594
+ );
6595
+ return false;
6596
+ }
6463
6597
  const sequenceDuration = this.length;
6464
6598
  const range = conf && conf.range ? conf.range : [0, sequenceDuration];
6465
6599
  if (process.env.NODE_ENV !== "production") {
@@ -6492,11 +6626,11 @@ var Sequence = class {
6492
6626
  ), "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
6627
  [
6494
6628
  {
6495
- url: "https://www.theatrejs.com/docs/latest/manual/sequences",
6629
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/sequences",
6496
6630
  title: "Sequences"
6497
6631
  },
6498
6632
  {
6499
- url: "https://www.theatrejs.com/docs/latest/manual/sequences",
6633
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/sequences",
6500
6634
  title: "Playback API"
6501
6635
  }
6502
6636
  ]
@@ -6650,6 +6784,33 @@ var TimeBasedPositionFormatter = class {
6650
6784
  return posInUnitSpace.toFixed(2) + "s";
6651
6785
  }
6652
6786
  };
6787
+ var PercentBasedPositionFormatter = class {
6788
+ constructor(_subUnitsPerUnit) {
6789
+ this._subUnitsPerUnit = _subUnitsPerUnit;
6790
+ }
6791
+ formatSubUnitForGrid(posInUnitSpace) {
6792
+ const subUnitSize = 1 / this._subUnitsPerUnit;
6793
+ const withinUnit = posInUnitSpace % 1;
6794
+ const tenths = Math.round(withinUnit / subUnitSize);
6795
+ return tenths + "t";
6796
+ }
6797
+ formatFullUnitForGrid(posInUnitSpace) {
6798
+ return Math.round(posInUnitSpace) + "%";
6799
+ }
6800
+ formatForPlayhead(posInUnitSpace) {
6801
+ const whole = Math.floor(posInUnitSpace);
6802
+ const subUnitSize = 1 / this._subUnitsPerUnit;
6803
+ const withinUnit = posInUnitSpace - whole;
6804
+ const tenths = Math.round(withinUnit / subUnitSize);
6805
+ if (tenths <= 0) {
6806
+ return whole + "%";
6807
+ }
6808
+ return whole + "." + tenths + "%";
6809
+ }
6810
+ formatBasic(posInUnitSpace) {
6811
+ return posInUnitSpace.toFixed(1) + "%";
6812
+ }
6813
+ };
6653
6814
  var second = 1;
6654
6815
  var minute = second * 60;
6655
6816
  var hour = minute * 60;
@@ -6684,11 +6845,11 @@ function validateAndSanitiseSlashedPathOrThrow(unsanitisedPath, fnName) {
6684
6845
  "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
6846
  [
6686
6847
  {
6687
- url: "https://www.theatrejs.com/docs/latest/manual/objects#creating-sheet-objects",
6848
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/objects#creating-objects",
6688
6849
  title: "Sheet Objects"
6689
6850
  },
6690
6851
  {
6691
- url: "https://www.theatrejs.com/docs/latest/api/core#sheet.object",
6852
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sheet.object",
6692
6853
  title: "API"
6693
6854
  }
6694
6855
  ]
@@ -6903,6 +7064,15 @@ var TheatreSheet = class {
6903
7064
  getActiveSequenceVariant() {
6904
7065
  return privateAPI(this).getActiveSequenceVariant();
6905
7066
  }
7067
+ getSequenceMode() {
7068
+ return privateAPI(this).getSequenceMode();
7069
+ }
7070
+ setSequenceMode(mode) {
7071
+ privateAPI(this).setSequenceMode(mode);
7072
+ }
7073
+ setPageScrollDriver(driver) {
7074
+ privateAPI(this).setPageScrollDriver(driver);
7075
+ }
6906
7076
  get project() {
6907
7077
  return privateAPI(this).project.publicApi;
6908
7078
  }
@@ -6960,30 +7130,394 @@ var TheatreSheet = class {
6960
7130
  };
6961
7131
 
6962
7132
  // core/src/sheets/Sheet.ts
6963
- var import_theatre_dataverse15 = require("@unseenco/theatre-dataverse");
6964
- var Sheet = class {
6965
- constructor(template, instanceId) {
6966
- this.template = template;
6967
- this.instanceId = instanceId;
6968
- __publicField(this, "_objects", new import_theatre_dataverse15.Atom({}));
6969
- __publicField(this, "_sequences", {});
6970
- __publicField(this, "_activeSequenceVariant", new import_theatre_dataverse15.Atom(
6971
- DEFAULT_SEQUENCE_VARIANT
6972
- ));
6973
- /**
6974
- * When Studio is open, it sets this to control which variant is used for
6975
- * value resolution (preview). User code can still update `_activeSequenceVariant`
6976
- * via `setActiveSequenceVariant()` without affecting the Studio preview.
6977
- */
6978
- __publicField(this, "_studioPreviewVariantOverride", new import_theatre_dataverse15.Atom(void 0));
6979
- __publicField(this, "activeSequenceVariantP", this._activeSequenceVariant.pointer);
6980
- __publicField(this, "effectiveActiveSequenceVariantD");
6981
- __publicField(this, "address");
6982
- __publicField(this, "publicApi");
6983
- __publicField(this, "project");
6984
- __publicField(this, "objectsP", this._objects.pointer);
6985
- __publicField(this, "type", "Theatre_Sheet");
6986
- __publicField(this, "_logger");
7133
+ var import_theatre_dataverse18 = require("@unseenco/theatre-dataverse");
7134
+
7135
+ // core/src/sheets/sheetSequenceMode.ts
7136
+ var PAGE_MODE_SEQUENCE_LENGTH = 100;
7137
+ var PAGE_MODE_SUB_UNITS_PER_UNIT = 10;
7138
+
7139
+ // shared/src/gsap/applyTimelineChildTiming.ts
7140
+ function applyTimelineChildTimingToGsap(rootAnimation, timelineChildren, childById, onRebuild) {
7141
+ if (!timelineChildren.length) return true;
7142
+ let ok = applyTimelineChildTimingToGsapInner(
7143
+ rootAnimation,
7144
+ timelineChildren,
7145
+ childById
7146
+ );
7147
+ if (!ok && onRebuild) {
7148
+ const rebuilt = onRebuild();
7149
+ if (rebuilt) {
7150
+ ok = applyTimelineChildTimingToGsapInner(
7151
+ rebuilt,
7152
+ timelineChildren,
7153
+ childById
7154
+ );
7155
+ }
7156
+ }
7157
+ return ok;
7158
+ }
7159
+ function applyTimelineChildTimingToGsapInner(rootAnimation, timelineChildren, childById) {
7160
+ if (!childById || timelineChildren.length === 0) return true;
7161
+ let ok = true;
7162
+ for (const childState of timelineChildren) {
7163
+ const tween = childById.get(childState.childId);
7164
+ if (!tween) continue;
7165
+ try {
7166
+ const t2 = tween;
7167
+ if (typeof t2.startTime === "function") {
7168
+ t2.startTime(childState.localStart);
7169
+ }
7170
+ if (typeof t2.duration === "function") {
7171
+ t2.duration(childState.localDuration);
7172
+ }
7173
+ } catch {
7174
+ ok = false;
7175
+ }
7176
+ }
7177
+ return ok;
7178
+ }
7179
+
7180
+ // shared/src/gsap/syncGsapClipProgress.ts
7181
+ function getGsapAnimationTargetKey(animation, fallbackAnimationId) {
7182
+ const tween = animation;
7183
+ const targets = tween.targets?.();
7184
+ if (targets && targets.length > 0) {
7185
+ return targets[0];
7186
+ }
7187
+ return fallbackAnimationId;
7188
+ }
7189
+ function syncRegisteredGsapAnimationsForClips(sequencePosition, clips) {
7190
+ const enriched = [];
7191
+ for (const clip of clips) {
7192
+ const entry = getAnimationEntryBySheetAddressKey(
7193
+ clip.sheetObjectAddressKey,
7194
+ clip.gsapAnimationId
7195
+ );
7196
+ if (!entry?.animation) continue;
7197
+ enriched.push({
7198
+ ...clip,
7199
+ entry,
7200
+ targetKey: getGsapAnimationTargetKey(
7201
+ entry.animation,
7202
+ clip.gsapAnimationId
7203
+ )
7204
+ });
7205
+ }
7206
+ const byTarget = /* @__PURE__ */ new Map();
7207
+ for (const item of enriched) {
7208
+ const list = byTarget.get(item.targetKey) ?? [];
7209
+ list.push(item);
7210
+ byTarget.set(item.targetKey, list);
7211
+ }
7212
+ for (const group of byTarget.values()) {
7213
+ const sorted = [...group].sort((a2, b2) => a2.start - b2.start);
7214
+ for (const clip of sorted) {
7215
+ const progress = gsapClipSyncProgress(sequencePosition, clip);
7216
+ const entry = clip.entry;
7217
+ const animation = entry.animation;
7218
+ if (entry.kind === "timeline" && clip.timelineChildren && clip.timelineChildren.length > 0) {
7219
+ applyTimelineChildTimingToGsap(
7220
+ entry.animation,
7221
+ clip.timelineChildren,
7222
+ entry.timelineChildById,
7223
+ entry.onRebuildTimeline
7224
+ );
7225
+ const span = clip.timelineSpan ?? readGsapTweenTimelineDuration(entry.animation);
7226
+ const t2 = progress * Math.max(span, 0.01);
7227
+ if (typeof animation.time === "function") {
7228
+ animation.time(t2, true);
7229
+ } else {
7230
+ animation.progress?.(progress, true);
7231
+ }
7232
+ } else {
7233
+ animation.progress?.(progress, true);
7234
+ }
7235
+ }
7236
+ }
7237
+ }
7238
+ function readGsapTweenTimelineDuration(animation) {
7239
+ const tween = animation;
7240
+ const total = tween.totalDuration?.();
7241
+ if (typeof total === "number" && total > 0) return total;
7242
+ const d2 = tween.duration();
7243
+ return d2 > 0 ? d2 : 1;
7244
+ }
7245
+
7246
+ // shared/src/gsap/gsapAnimationRegistry.ts
7247
+ var DEFAULT_SHEET_INSTANCE_ID2 = "default";
7248
+ var REGISTRY_KEY2 = "__unseenco_theatre_gsap_animationRegistry__";
7249
+ function sheetObjectAddressKeyFromParts(address) {
7250
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID2;
7251
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId, "|").concat(address.objectKey);
7252
+ }
7253
+ function getStore2() {
7254
+ const g2 = globalThis;
7255
+ if (!g2[REGISTRY_KEY2]) {
7256
+ g2[REGISTRY_KEY2] = {
7257
+ bySheetAddress: /* @__PURE__ */ new Map()
7258
+ };
7259
+ }
7260
+ return g2[REGISTRY_KEY2];
7261
+ }
7262
+ function getAnimationEntryBySheetAddressKey(sheetObjectAddressKey, animationId) {
7263
+ return getStore2().bySheetAddress.get(sheetObjectAddressKey)?.get(animationId);
7264
+ }
7265
+
7266
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
7267
+ var import_theatre_dataverse16 = require("@unseenco/theatre-dataverse");
7268
+
7269
+ // shared/src/gsap/syncGsapClipsAtSequencePosition.ts
7270
+ function syncGsapClipsAtSequencePosition(position, clips) {
7271
+ syncRegisteredGsapAnimationsForClips(
7272
+ position,
7273
+ clips
7274
+ );
7275
+ }
7276
+
7277
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
7278
+ function subscribeGsapClipSyncAtPlayhead(source) {
7279
+ const positionPointer = source.pointer.position;
7280
+ const positionPrism = (0, import_theatre_dataverse16.pointerToPrism)(positionPointer);
7281
+ const clipsPrism = (0, import_theatre_dataverse16.prism)(() => source.getGsapClipTimings());
7282
+ const syncNow = () => {
7283
+ const clips = clipsPrism.getValue();
7284
+ if (clips.length === 0) return;
7285
+ syncGsapClipsAtSequencePosition((0, import_theatre_dataverse16.val)(positionPointer), clips);
7286
+ };
7287
+ const untapPosition = positionPrism.onStale(syncNow);
7288
+ const untapClips = clipsPrism.onStale(syncNow);
7289
+ syncNow();
7290
+ return () => {
7291
+ untapPosition();
7292
+ untapClips();
7293
+ };
7294
+ }
7295
+
7296
+ // core/src/gsap/attachGsapSequenceBridge.ts
7297
+ function attachGsapSequenceBridge(sheet) {
7298
+ const sequence = sheet.sequence;
7299
+ const sheetAddress = privateAPI(sheet).address;
7300
+ return subscribeGsapClipSyncAtPlayhead({
7301
+ pointer: sequence.pointer,
7302
+ getGsapClipTimings: () => sequence.__experimental_getGsapClips().map(({ objectKey, clip }) => ({
7303
+ sheetObjectAddressKey: sheetObjectAddressKeyFromParts({
7304
+ projectId: sheetAddress.projectId,
7305
+ sheetId: sheetAddress.sheetId,
7306
+ sheetInstanceId: sheetAddress.sheetInstanceId,
7307
+ objectKey
7308
+ }),
7309
+ gsapAnimationId: clip.gsapAnimationId,
7310
+ start: clip.start,
7311
+ duration: clip.duration,
7312
+ timelineChildren: clip.timelineChildren,
7313
+ timelineSpan: clip.timelineSpan
7314
+ }))
7315
+ });
7316
+ }
7317
+
7318
+ // core/src/sheets/attachSheetScrollDriver.ts
7319
+ var import_theatre_dataverse17 = require("@unseenco/theatre-dataverse");
7320
+ var sheetScrollDrivers = /* @__PURE__ */ new WeakMap();
7321
+ var pageScrollDrivenSequencePositionListeners = /* @__PURE__ */ new Set();
7322
+ function onPageScrollDrivenSequencePosition(listener) {
7323
+ pageScrollDrivenSequencePositionListeners.add(listener);
7324
+ return () => {
7325
+ pageScrollDrivenSequencePositionListeners.delete(listener);
7326
+ };
7327
+ }
7328
+ function notifyPageScrollDrivenSequencePosition(sheet, position) {
7329
+ for (const listener of pageScrollDrivenSequencePositionListeners) {
7330
+ listener(sheet, position);
7331
+ }
7332
+ }
7333
+ function getSheetScrollDriver(sheet) {
7334
+ return sheetScrollDrivers.get(sheet);
7335
+ }
7336
+ function rememberSheetScrollDriver(sheet, driver) {
7337
+ sheetScrollDrivers.set(sheet, driver);
7338
+ }
7339
+ function progressFromScrollPosition(position, max) {
7340
+ if (max <= 0) return 0;
7341
+ if (position <= 0) return 0;
7342
+ if (position >= max - 1) return 1;
7343
+ return position / max;
7344
+ }
7345
+ function getNativeDocumentScrollingElement() {
7346
+ return document.scrollingElement ?? document.documentElement;
7347
+ }
7348
+ function addNativeDocumentScrollListener(handler) {
7349
+ document.addEventListener("scroll", handler, { passive: true, capture: true });
7350
+ return () => document.removeEventListener("scroll", handler, { capture: true });
7351
+ }
7352
+ function createScrollDriverFromElement(getMaxScroll, getScrollPos, setScrollPos, addScrollListener) {
7353
+ let suppressScrollEvents = false;
7354
+ let suppressGeneration = 0;
7355
+ const getProgress = () => {
7356
+ const max = getMaxScroll();
7357
+ return progressFromScrollPosition(getScrollPos(), max);
7358
+ };
7359
+ const setProgress = (progress) => {
7360
+ const max = getMaxScroll();
7361
+ const clamped = Math.max(0, Math.min(1, progress));
7362
+ const gen = ++suppressGeneration;
7363
+ suppressScrollEvents = true;
7364
+ setScrollPos(clamped * max);
7365
+ const release = () => {
7366
+ if (gen === suppressGeneration) {
7367
+ suppressScrollEvents = false;
7368
+ }
7369
+ };
7370
+ requestAnimationFrame(() => requestAnimationFrame(release));
7371
+ };
7372
+ return {
7373
+ getProgress,
7374
+ setProgress,
7375
+ subscribe(onProgressChange) {
7376
+ let rafId = 0;
7377
+ const flush = () => {
7378
+ rafId = 0;
7379
+ if (suppressScrollEvents) return;
7380
+ onProgressChange(getProgress());
7381
+ };
7382
+ const scheduleFlush = () => {
7383
+ if (rafId !== 0) return;
7384
+ rafId = requestAnimationFrame(flush);
7385
+ };
7386
+ const handler = () => scheduleFlush();
7387
+ const removeScroll = addScrollListener(handler);
7388
+ const onResize = () => scheduleFlush();
7389
+ window.addEventListener("resize", onResize);
7390
+ return () => {
7391
+ removeScroll();
7392
+ window.removeEventListener("resize", onResize);
7393
+ if (rafId !== 0) cancelAnimationFrame(rafId);
7394
+ };
7395
+ }
7396
+ };
7397
+ }
7398
+ function createNativeDocumentScrollDriver() {
7399
+ const getMaxScroll = () => {
7400
+ const el = document.documentElement;
7401
+ return Math.max(0, el.scrollHeight - window.innerHeight);
7402
+ };
7403
+ return createScrollDriverFromElement(
7404
+ getMaxScroll,
7405
+ () => window.scrollY,
7406
+ (y2) => window.scrollTo({ top: y2, behavior: "instant" }),
7407
+ addNativeDocumentScrollListener
7408
+ );
7409
+ }
7410
+ function createNativeDocumentHorizontalScrollDriver() {
7411
+ const getMaxScroll = () => {
7412
+ const el = getNativeDocumentScrollingElement();
7413
+ return Math.max(0, el.scrollWidth - el.clientWidth);
7414
+ };
7415
+ const getScrollLeft = () => {
7416
+ const el = getNativeDocumentScrollingElement();
7417
+ return el.scrollLeft;
7418
+ };
7419
+ return createScrollDriverFromElement(
7420
+ getMaxScroll,
7421
+ getScrollLeft,
7422
+ (x2) => {
7423
+ getNativeDocumentScrollingElement().scrollLeft = x2;
7424
+ },
7425
+ addNativeDocumentScrollListener
7426
+ );
7427
+ }
7428
+ function createElementScrollDriver(element) {
7429
+ const getMaxScroll = () => Math.max(0, element.scrollHeight - element.clientHeight);
7430
+ return createScrollDriverFromElement(
7431
+ getMaxScroll,
7432
+ () => element.scrollTop,
7433
+ (y2) => {
7434
+ element.scrollTop = y2;
7435
+ },
7436
+ (handler) => {
7437
+ element.addEventListener("scroll", handler, { passive: true });
7438
+ return () => element.removeEventListener("scroll", handler);
7439
+ }
7440
+ );
7441
+ }
7442
+ function createElementHorizontalScrollDriver(element) {
7443
+ const getMaxScroll = () => Math.max(0, element.scrollWidth - element.clientWidth);
7444
+ return createScrollDriverFromElement(
7445
+ getMaxScroll,
7446
+ () => element.scrollLeft,
7447
+ (x2) => {
7448
+ element.scrollLeft = x2;
7449
+ },
7450
+ (handler) => {
7451
+ element.addEventListener("scroll", handler, { passive: true });
7452
+ return () => element.removeEventListener("scroll", handler);
7453
+ }
7454
+ );
7455
+ }
7456
+ function attachSheetScrollDriver(sheet, driver = createNativeDocumentScrollDriver()) {
7457
+ rememberSheetScrollDriver(sheet, driver);
7458
+ const sequence = sheet.sequence;
7459
+ const syncPositionFromScroll = (progress) => {
7460
+ const length = (0, import_theatre_dataverse17.val)(sequence.pointer.length);
7461
+ if (length <= 0) return;
7462
+ sequence.position = progress * length;
7463
+ };
7464
+ const untapScroll = driver.subscribe((progress) => {
7465
+ syncPositionFromScroll(progress);
7466
+ notifyPageScrollDrivenSequencePosition(sheet, sequence.position);
7467
+ });
7468
+ syncPositionFromScroll(driver.getProgress());
7469
+ return () => {
7470
+ untapScroll();
7471
+ };
7472
+ }
7473
+ function pageScrollProgressFromSequence(sheet) {
7474
+ const length = (0, import_theatre_dataverse17.val)(sheet.sequence.pointer.length);
7475
+ if (length <= 0) return 0;
7476
+ return sheet.sequence.position / length;
7477
+ }
7478
+ function setPageScrollProgress(sheet, progress) {
7479
+ const length = (0, import_theatre_dataverse17.val)(sheet.sequence.pointer.length);
7480
+ if (length <= 0) return;
7481
+ const clamped = Math.max(0, Math.min(1, progress));
7482
+ sheet.sequence.position = clamped * length;
7483
+ }
7484
+ function syncPageScrollToSequencePosition(sheet, driver = getSheetScrollDriver(sheet) ?? createNativeDocumentScrollDriver()) {
7485
+ const progress = pageScrollProgressFromSequence(sheet);
7486
+ driver.setProgress(progress);
7487
+ }
7488
+ function syncNativeDocumentScrollToSequencePosition(sheet) {
7489
+ syncPageScrollToSequencePosition(sheet, createNativeDocumentScrollDriver());
7490
+ }
7491
+
7492
+ // core/src/sheets/Sheet.ts
7493
+ var Sheet = class {
7494
+ constructor(template, instanceId) {
7495
+ this.template = template;
7496
+ this.instanceId = instanceId;
7497
+ __publicField(this, "_objects", new import_theatre_dataverse18.Atom({}));
7498
+ __publicField(this, "_sequences", {});
7499
+ __publicField(this, "_activeSequenceVariant", new import_theatre_dataverse18.Atom(
7500
+ DEFAULT_SEQUENCE_VARIANT
7501
+ ));
7502
+ /**
7503
+ * When Studio is open, it sets this to control which variant is used for
7504
+ * value resolution (preview). User code can still update `_activeSequenceVariant`
7505
+ * via `setActiveSequenceVariant()` without affecting the Studio preview.
7506
+ */
7507
+ __publicField(this, "_studioPreviewVariantOverride", new import_theatre_dataverse18.Atom(void 0));
7508
+ __publicField(this, "_sequenceMode", new import_theatre_dataverse18.Atom("time"));
7509
+ __publicField(this, "sequenceModeP", this._sequenceMode.pointer);
7510
+ __publicField(this, "_pageScrollDisposer");
7511
+ __publicField(this, "_customPageScrollDriver");
7512
+ __publicField(this, "_gsapBridgeDisposer");
7513
+ __publicField(this, "activeSequenceVariantP", this._activeSequenceVariant.pointer);
7514
+ __publicField(this, "effectiveActiveSequenceVariantD");
7515
+ __publicField(this, "address");
7516
+ __publicField(this, "publicApi");
7517
+ __publicField(this, "project");
7518
+ __publicField(this, "objectsP", this._objects.pointer);
7519
+ __publicField(this, "type", "Theatre_Sheet");
7520
+ __publicField(this, "_logger");
6987
7521
  this._logger = template.project._logger.named("Sheet", instanceId);
6988
7522
  this._logger._trace("creating sheet");
6989
7523
  this.project = template.project;
@@ -6992,12 +7526,12 @@ var Sheet = class {
6992
7526
  sheetInstanceId: this.instanceId
6993
7527
  };
6994
7528
  this.publicApi = new TheatreSheet(this);
6995
- this.effectiveActiveSequenceVariantD = (0, import_theatre_dataverse15.prism)(() => {
6996
- const studioOverride = (0, import_theatre_dataverse15.val)(this._studioPreviewVariantOverride.pointer);
7529
+ this.effectiveActiveSequenceVariantD = (0, import_theatre_dataverse18.prism)(() => {
7530
+ const studioOverride = (0, import_theatre_dataverse18.val)(this._studioPreviewVariantOverride.pointer);
6997
7531
  if (studioOverride !== void 0) {
6998
7532
  return studioOverride;
6999
7533
  }
7000
- return (0, import_theatre_dataverse15.val)(this._activeSequenceVariant.pointer);
7534
+ return (0, import_theatre_dataverse18.val)(this._activeSequenceVariant.pointer);
7001
7535
  });
7002
7536
  }
7003
7537
  /**
@@ -7048,6 +7582,7 @@ var Sheet = class {
7048
7582
  * this sheet instance from the project. Persisted state is kept.
7049
7583
  */
7050
7584
  unload() {
7585
+ this.disposeRuntimeIntegrations();
7051
7586
  for (const sequence of Object.values(this._sequences)) {
7052
7587
  sequence.pause();
7053
7588
  }
@@ -7059,10 +7594,13 @@ var Sheet = class {
7059
7594
  this.project._unloadSheetInstance(this);
7060
7595
  }
7061
7596
  getSequence(variant) {
7062
- const variantId = variant ?? (0, import_theatre_dataverse15.val)(this._activeSequenceVariant.pointer);
7597
+ const variantId = variant ?? (0, import_theatre_dataverse18.val)(this._activeSequenceVariant.pointer);
7063
7598
  if (!this._sequences[variantId]) {
7064
- const lengthD = (0, import_theatre_dataverse15.prism)(() => {
7065
- const sheetState = (0, import_theatre_dataverse15.val)(
7599
+ const lengthD = (0, import_theatre_dataverse18.prism)(() => {
7600
+ if ((0, import_theatre_dataverse18.val)(this._sequenceMode.pointer) === "page") {
7601
+ return PAGE_MODE_SEQUENCE_LENGTH;
7602
+ }
7603
+ const sheetState = (0, import_theatre_dataverse18.val)(
7066
7604
  this.project.pointers.historic.sheetsById[this.address.sheetId]
7067
7605
  );
7068
7606
  const unsanitized = getSequenceStateFromSheet(
@@ -7071,8 +7609,11 @@ var Sheet = class {
7071
7609
  )?.length;
7072
7610
  return sanitizeSequenceLength(unsanitized);
7073
7611
  });
7074
- const subUnitsPerUnitD = (0, import_theatre_dataverse15.prism)(() => {
7075
- const sheetState = (0, import_theatre_dataverse15.val)(
7612
+ const subUnitsPerUnitD = (0, import_theatre_dataverse18.prism)(() => {
7613
+ if ((0, import_theatre_dataverse18.val)(this._sequenceMode.pointer) === "page") {
7614
+ return PAGE_MODE_SUB_UNITS_PER_UNIT;
7615
+ }
7616
+ const sheetState = (0, import_theatre_dataverse18.val)(
7076
7617
  this.project.pointers.historic.sheetsById[this.address.sheetId]
7077
7618
  );
7078
7619
  const unsanitized = getSequenceStateFromSheet(
@@ -7124,6 +7665,44 @@ var Sheet = class {
7124
7665
  }
7125
7666
  this._studioPreviewVariantOverride.set(variantId);
7126
7667
  }
7668
+ getSequenceMode() {
7669
+ return this._sequenceMode.get();
7670
+ }
7671
+ setSequenceMode(mode) {
7672
+ if (this._sequenceMode.get() === mode) return;
7673
+ this._sequenceMode.set(mode);
7674
+ this.syncPageScrollDriver();
7675
+ if (this._gsapBridgeDisposer) {
7676
+ this._gsapBridgeDisposer();
7677
+ this._gsapBridgeDisposer = attachGsapSequenceBridge(this.publicApi);
7678
+ }
7679
+ }
7680
+ enableGsapSequenceBridge() {
7681
+ if (this._gsapBridgeDisposer) return;
7682
+ this._gsapBridgeDisposer = attachGsapSequenceBridge(this.publicApi);
7683
+ this.syncPageScrollDriver();
7684
+ }
7685
+ disposeRuntimeIntegrations() {
7686
+ this._pageScrollDisposer?.();
7687
+ this._pageScrollDisposer = void 0;
7688
+ this._gsapBridgeDisposer?.();
7689
+ this._gsapBridgeDisposer = void 0;
7690
+ }
7691
+ syncPageScrollDriver() {
7692
+ this._pageScrollDisposer?.();
7693
+ this._pageScrollDisposer = void 0;
7694
+ if (this.getSequenceMode() === "page") {
7695
+ const driver = this._customPageScrollDriver ?? createNativeDocumentScrollDriver();
7696
+ this._pageScrollDisposer = attachSheetScrollDriver(this.publicApi, driver);
7697
+ }
7698
+ }
7699
+ setPageScrollDriver(driver) {
7700
+ this._customPageScrollDriver = driver;
7701
+ this.syncPageScrollDriver();
7702
+ }
7703
+ getPageScrollDriver() {
7704
+ return this._customPageScrollDriver;
7705
+ }
7127
7706
  };
7128
7707
  var sanitizeSequenceLength = (len) => typeof len === "number" && isFinite(len) && len > 0 ? len : 10;
7129
7708
  var sanitizeSequenceSubUnitsPerUnit = (subs) => typeof subs === "number" && isInteger_default(subs) && subs >= 1 && subs <= 1e3 ? subs : 30;
@@ -7134,13 +7713,13 @@ var SheetTemplate = class {
7134
7713
  this.project = project;
7135
7714
  __publicField(this, "type", "Theatre_SheetTemplate");
7136
7715
  __publicField(this, "address");
7137
- __publicField(this, "_instances", new import_theatre_dataverse16.Atom({}));
7716
+ __publicField(this, "_instances", new import_theatre_dataverse19.Atom({}));
7138
7717
  __publicField(this, "instancesP", this._instances.pointer);
7139
- __publicField(this, "_objectTemplates", new import_theatre_dataverse16.Atom({}));
7718
+ __publicField(this, "_objectTemplates", new import_theatre_dataverse19.Atom({}));
7140
7719
  __publicField(this, "objectTemplatesP", this._objectTemplates.pointer);
7141
7720
  __publicField(this, "_pendingOutlineNamespaces", {});
7142
7721
  __publicField(this, "_sequenceVariants", [DEFAULT_SEQUENCE_VARIANT]);
7143
- __publicField(this, "_visibleInOutline", new import_theatre_dataverse16.Atom(true));
7722
+ __publicField(this, "_visibleInOutline", new import_theatre_dataverse19.Atom(true));
7144
7723
  __publicField(this, "visibleInOutlineP", this._visibleInOutline.pointer);
7145
7724
  this.address = { ...project.address, sheetId };
7146
7725
  }
@@ -7222,8 +7801,8 @@ var SheetTemplate = class {
7222
7801
  };
7223
7802
 
7224
7803
  // core/src/projects/Project.ts
7225
- var import_theatre_dataverse19 = require("@unseenco/theatre-dataverse");
7226
- var import_theatre_dataverse20 = require("@unseenco/theatre-dataverse");
7804
+ var import_theatre_dataverse22 = require("@unseenco/theatre-dataverse");
7805
+ var import_theatre_dataverse23 = require("@unseenco/theatre-dataverse");
7227
7806
 
7228
7807
  // shared/src/utils/delay.ts
7229
7808
  var delay = (dur) => new Promise((resolve) => setTimeout(resolve, dur));
@@ -7658,11 +8237,168 @@ async function initialiseProjectState(studio, project, onDiskState) {
7658
8237
  }
7659
8238
  }
7660
8239
  }
7661
- });
8240
+ });
8241
+ }
8242
+
8243
+ // shared/src/sheets/pageScrollContext.ts
8244
+ var defaultPageScrollContext = {
8245
+ scroller: null,
8246
+ axis: "vertical"
8247
+ };
8248
+ var activePageScrollContext = defaultPageScrollContext;
8249
+ function setActivePageScrollContext(context) {
8250
+ activePageScrollContext = {
8251
+ scroller: context.scroller,
8252
+ axis: context.axis ?? "vertical"
8253
+ };
8254
+ }
8255
+ function getActivePageScrollContext() {
8256
+ return activePageScrollContext;
8257
+ }
8258
+ function resolvePageScrollAxis(context = defaultPageScrollContext) {
8259
+ return context.axis ?? "vertical";
8260
+ }
8261
+ function resolvePageScrollScroller(st, defaultsScroller) {
8262
+ const surface = st;
8263
+ const fromSt = surface.scroller ?? surface.vars?.scroller;
8264
+ if (fromSt != null) {
8265
+ return fromSt;
8266
+ }
8267
+ if (defaultsScroller !== void 0) {
8268
+ return defaultsScroller;
8269
+ }
8270
+ return null;
8271
+ }
8272
+ function isWindowLike(value) {
8273
+ return typeof Window !== "undefined" && (value === window || value instanceof Window);
8274
+ }
8275
+ function isNativeDocumentScroller(scroller) {
8276
+ if (scroller == null) return true;
8277
+ if (isWindowLike(scroller)) return true;
8278
+ if (typeof document === "undefined") return false;
8279
+ return scroller === document.documentElement || scroller === document.body;
8280
+ }
8281
+ function pageScrollScrollersMatch(a2, b2) {
8282
+ if (a2 === b2) return true;
8283
+ if (isNativeDocumentScroller(a2) && isNativeDocumentScroller(b2)) return true;
8284
+ return false;
8285
+ }
8286
+ function isScrollTriggerHorizontal(st) {
8287
+ const surface = st;
8288
+ return surface.horizontal === true || surface.vars?.horizontal === true;
8289
+ }
8290
+ function isPageScrollTrigger(st, context = defaultPageScrollContext) {
8291
+ const axis = resolvePageScrollAxis(context);
8292
+ const stHorizontal = isScrollTriggerHorizontal(st);
8293
+ if (stHorizontal !== (axis === "horizontal")) {
8294
+ return false;
8295
+ }
8296
+ const stScroller = resolvePageScrollScroller(st, context.scroller);
8297
+ return pageScrollScrollersMatch(stScroller, context.scroller);
8298
+ }
8299
+ function isVerticalPageScrollTrigger(st, context = defaultPageScrollContext) {
8300
+ return isPageScrollTrigger(st, {
8301
+ scroller: context.scroller,
8302
+ axis: "vertical"
8303
+ });
8304
+ }
8305
+
8306
+ // shared/src/gsap/scrollTriggerLayout.ts
8307
+ function getNativeDocumentMaxScroll(axis = "vertical") {
8308
+ if (typeof document === "undefined" || typeof window === "undefined") {
8309
+ return 0;
8310
+ }
8311
+ const el = document.documentElement;
8312
+ if (axis === "horizontal") {
8313
+ const scrolling = document.scrollingElement ?? el;
8314
+ return Math.max(0, scrolling.scrollWidth - scrolling.clientWidth);
8315
+ }
8316
+ return Math.max(0, el.scrollHeight - window.innerHeight);
8317
+ }
8318
+ function getMaxScrollForScroller(scroller, axis = "vertical") {
8319
+ if (typeof document === "undefined" || typeof window === "undefined") {
8320
+ return 0;
8321
+ }
8322
+ if (isNativeDocumentScroller(scroller)) {
8323
+ return getNativeDocumentMaxScroll(axis);
8324
+ }
8325
+ const el = scroller;
8326
+ if (axis === "horizontal") {
8327
+ return Math.max(0, el.scrollWidth - el.clientWidth);
8328
+ }
8329
+ return Math.max(0, el.scrollHeight - el.clientHeight);
8330
+ }
8331
+ function getMaxScrollForPageScrollContext(scroller, axis = "vertical") {
8332
+ return getMaxScrollForScroller(scroller, axis);
8333
+ }
8334
+
8335
+ // shared/src/gsap/domElementHighlightTarget.ts
8336
+ function resolveDomElementHighlightTarget(target) {
8337
+ if (typeof document === "undefined") {
8338
+ return null;
8339
+ }
8340
+ if (target.type === "id") {
8341
+ return document.getElementById(target.id);
8342
+ }
8343
+ try {
8344
+ const match = document.querySelector(target.selector);
8345
+ return match instanceof Element ? match : null;
8346
+ } catch {
8347
+ return null;
8348
+ }
8349
+ }
8350
+
8351
+ // shared/src/sheets/remoteDomElementHighlight.ts
8352
+ var listeners = /* @__PURE__ */ new Set();
8353
+ function setRemoteDomElementHighlight(element) {
8354
+ for (const listener of listeners) {
8355
+ listener(element);
8356
+ }
8357
+ }
8358
+
8359
+ // shared/src/sheets/remotePageScrollMetrics.ts
8360
+ var remoteMetrics;
8361
+ var listeners2 = /* @__PURE__ */ new Set();
8362
+ function setRemotePageScrollMetrics(metrics) {
8363
+ const prev = remoteMetrics;
8364
+ remoteMetrics = metrics;
8365
+ if (prev?.maxScroll !== metrics?.maxScroll || prev?.axis !== metrics?.axis) {
8366
+ for (const listener of listeners2) {
8367
+ listener();
8368
+ }
8369
+ }
7662
8370
  }
7663
8371
 
7664
8372
  // core/src/internal/RemoteSync.ts
7665
- var import_theatre_dataverse17 = require("@unseenco/theatre-dataverse");
8373
+ var import_theatre_dataverse20 = require("@unseenco/theatre-dataverse");
8374
+
8375
+ // core/src/internal/createDebouncedCallback.ts
8376
+ function createDebouncedCallback(fn2, delayMs) {
8377
+ let timeoutId;
8378
+ const clearPending = () => {
8379
+ if (timeoutId !== void 0) {
8380
+ clearTimeout(timeoutId);
8381
+ timeoutId = void 0;
8382
+ }
8383
+ };
8384
+ return {
8385
+ schedule() {
8386
+ clearPending();
8387
+ timeoutId = setTimeout(() => {
8388
+ timeoutId = void 0;
8389
+ fn2();
8390
+ }, delayMs);
8391
+ },
8392
+ flush() {
8393
+ if (timeoutId === void 0) return;
8394
+ clearPending();
8395
+ fn2();
8396
+ },
8397
+ cancel() {
8398
+ clearPending();
8399
+ }
8400
+ };
8401
+ }
7666
8402
 
7667
8403
  // core/src/internal/remoteEditor.ts
7668
8404
  function isRemoteEditorWindow() {
@@ -7670,6 +8406,10 @@ function isRemoteEditorWindow() {
7670
8406
  }
7671
8407
 
7672
8408
  // core/src/internal/RemoteSync.ts
8409
+ var REMOTE_HISTORIC_SYNC_DEBOUNCE_MS = 100;
8410
+ function shouldSyncPageScrollWhenApplyingTimelineUpdate(isEditor, sequenceMode) {
8411
+ return !isEditor && sequenceMode === "page";
8412
+ }
7673
8413
  var RemoteSync = class {
7674
8414
  constructor(project) {
7675
8415
  this.project = project;
@@ -7680,34 +8420,37 @@ var RemoteSync = class {
7680
8420
  __publicField(this, "objectUnsubs", /* @__PURE__ */ new Map());
7681
8421
  __publicField(this, "studio");
7682
8422
  __publicField(this, "activeSheet");
8423
+ __publicField(this, "historicSyncDebounce");
8424
+ __publicField(this, "lastBroadcastHistoricFingerprint");
8425
+ __publicField(this, "historicSyncUnsubs", []);
8426
+ __publicField(this, "remoteEditorActive", false);
8427
+ __publicField(this, "suppressTimelineBroadcast", false);
8428
+ __publicField(this, "listenerTimelineUnsub");
8429
+ __publicField(this, "listenerMetricsUnsubs", []);
8430
+ __publicField(this, "broadcastPageScrollMetrics");
7683
8431
  if (typeof BroadcastChannel === "undefined") return;
7684
8432
  this.channel = new BroadcastChannel(
7685
8433
  "theatre-remote:".concat(project.address.projectId)
7686
8434
  );
8435
+ this.channel.onmessage = (event) => {
8436
+ this._handleIncoming(event.data);
8437
+ };
7687
8438
  if (!this.isEditor) {
7688
- this.channel.onmessage = (event) => {
7689
- this._handleIncoming(event.data);
7690
- };
8439
+ this.listenerTimelineUnsub = onPageScrollDrivenSequencePosition(
8440
+ (sheet, position) => {
8441
+ this._broadcastTimelineFromListener(sheet, position);
8442
+ }
8443
+ );
7691
8444
  } else {
7692
8445
  const channel = this.channel;
7693
8446
  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
- }
8447
+ this.historicSyncDebounce?.flush();
8448
+ const data = this._readHistoricSnapshotFromStudio();
8449
+ if (data && this.lastBroadcastHistoricFingerprint === fingerprintHistoricSnapshot(data)) {
8450
+ channel.postMessage({ event: "disconnect", data: {} });
8451
+ return;
7709
8452
  }
7710
- channel.postMessage({ event: "disconnect", data });
8453
+ channel.postMessage({ event: "disconnect", data: data ?? {} });
7711
8454
  });
7712
8455
  }
7713
8456
  }
@@ -7758,8 +8501,13 @@ var RemoteSync = class {
7758
8501
  }
7759
8502
  attachStudio(studio) {
7760
8503
  this.studio = studio;
7761
- if (!this.isEditor || !this.channel) return;
8504
+ if (!this.channel) return;
8505
+ if (!this.isEditor) {
8506
+ this._attachListenerPageScrollMetricsBroadcast();
8507
+ return;
8508
+ }
7762
8509
  const channel = this.channel;
8510
+ channel.postMessage({ event: "editorHello", data: {} });
7763
8511
  const projectId = this.project.address.projectId;
7764
8512
  studio.publicApi.onSelectionChange((selection) => {
7765
8513
  for (const item of selection) {
@@ -7784,7 +8532,7 @@ var RemoteSync = class {
7784
8532
  let lastPosition;
7785
8533
  const ticker = getCoreTicker();
7786
8534
  const pollTimelinePosition = () => {
7787
- if (this.activeSheet) {
8535
+ if (this.activeSheet && !this.suppressTimelineBroadcast) {
7788
8536
  const position = this.activeSheet.publicApi.sequence.position;
7789
8537
  if (position !== lastPosition) {
7790
8538
  lastPosition = position;
@@ -7798,9 +8546,117 @@ var RemoteSync = class {
7798
8546
  ticker.onNextTick(pollTimelinePosition);
7799
8547
  };
7800
8548
  ticker.onNextTick(pollTimelinePosition);
8549
+ this.historicSyncDebounce = createDebouncedCallback(() => {
8550
+ this._broadcastHistoricSnapshot();
8551
+ }, REMOTE_HISTORIC_SYNC_DEBOUNCE_MS);
8552
+ const scheduleHistoricSync = () => {
8553
+ this.historicSyncDebounce?.schedule();
8554
+ };
8555
+ void studio.initialized.then(() => {
8556
+ this.historicSyncUnsubs.push(
8557
+ (0, import_theatre_dataverse20.pointerToPrism)(studio.atomP.historic.coreByProject[projectId]).onChange(
8558
+ studio.ticker,
8559
+ scheduleHistoricSync,
8560
+ true
8561
+ ),
8562
+ (0, import_theatre_dataverse20.pointerToPrism)(
8563
+ studio.atomP.ahistoric.coreByProject[projectId]
8564
+ ).onChange(studio.ticker, scheduleHistoricSync, true)
8565
+ );
8566
+ });
8567
+ }
8568
+ _readHistoricSnapshotFromStudio() {
8569
+ if (!this.studio) return void 0;
8570
+ const projectId = this.project.address.projectId;
8571
+ const historic = (0, import_theatre_dataverse20.val)(
8572
+ this.studio.atomP.historic.coreByProject[projectId]
8573
+ );
8574
+ if (!historic) return void 0;
8575
+ const data = {
8576
+ historic: JSON.parse(JSON.stringify(historic))
8577
+ };
8578
+ const ahistoric = (0, import_theatre_dataverse20.val)(
8579
+ this.studio.atomP.ahistoric.coreByProject[projectId]
8580
+ );
8581
+ if (ahistoric) {
8582
+ data.ahistoric = JSON.parse(JSON.stringify(ahistoric));
8583
+ }
8584
+ return data;
8585
+ }
8586
+ _broadcastHistoricSnapshot(options) {
8587
+ if (!this.channel) return;
8588
+ const data = this._readHistoricSnapshotFromStudio();
8589
+ if (!data) return;
8590
+ const fingerprint = fingerprintHistoricSnapshot(data);
8591
+ if (!options?.force && fingerprint === this.lastBroadcastHistoricFingerprint) {
8592
+ return;
8593
+ }
8594
+ this.lastBroadcastHistoricFingerprint = fingerprint;
8595
+ const message = { event: "updateHistoric", data };
8596
+ this.channel.postMessage(message);
8597
+ }
8598
+ _applyHistoricSnapshot(historic, ahistoric) {
8599
+ if (!this.studio) return;
8600
+ const projectId = this.project.address.projectId;
8601
+ this.studio.transaction(({ drafts }) => {
8602
+ drafts.historic.coreByProject[projectId] = historic;
8603
+ if (ahistoric) {
8604
+ drafts.ahistoric.coreByProject[projectId] = ahistoric;
8605
+ }
8606
+ drafts.ephemeral.coreByProject[projectId].loadingState = {
8607
+ type: "loaded"
8608
+ };
8609
+ });
8610
+ }
8611
+ _broadcastTimelineFromListener(sheet, position) {
8612
+ if (this.isEditor || !this.channel || !this.remoteEditorActive || this.suppressTimelineBroadcast) {
8613
+ return;
8614
+ }
8615
+ const registered = this.sheets.get(sheet.address.sheetId);
8616
+ if (!registered || registered.getSequenceMode() !== "page") return;
8617
+ const message = {
8618
+ event: "updateTimeline",
8619
+ data: { sheet: sheet.address.sheetId, position }
8620
+ };
8621
+ this.channel.postMessage(message);
8622
+ }
8623
+ _postPageScrollMetrics() {
8624
+ if (!this.remoteEditorActive || !this.channel) return;
8625
+ const ctx = getActivePageScrollContext();
8626
+ const axis = resolvePageScrollAxis(ctx);
8627
+ const maxScroll = getMaxScrollForPageScrollContext(ctx.scroller, axis);
8628
+ const message = {
8629
+ event: "pageScrollMetrics",
8630
+ data: { maxScroll, axis }
8631
+ };
8632
+ this.channel.postMessage(message);
8633
+ }
8634
+ _attachListenerPageScrollMetricsBroadcast() {
8635
+ if (this.isEditor || !this.channel) return;
8636
+ const broadcast = () => this._postPageScrollMetrics();
8637
+ this.broadcastPageScrollMetrics = broadcast;
8638
+ const onScroll = () => broadcast();
8639
+ document.addEventListener("scroll", onScroll, { passive: true, capture: true });
8640
+ const onResize = () => broadcast();
8641
+ window.addEventListener("resize", onResize);
8642
+ const ScrollTrigger = globalThis.ScrollTrigger;
8643
+ ScrollTrigger?.addEventListener?.("refresh", broadcast);
8644
+ broadcast();
8645
+ this.listenerMetricsUnsubs.push(() => {
8646
+ document.removeEventListener("scroll", onScroll, { capture: true });
8647
+ window.removeEventListener("resize", onResize);
8648
+ ScrollTrigger?.removeEventListener?.("refresh", broadcast);
8649
+ });
7801
8650
  }
7802
8651
  _handleIncoming(msg) {
7803
8652
  switch (msg.event) {
8653
+ case "editorHello": {
8654
+ if (this.isEditor) break;
8655
+ this.remoteEditorActive = true;
8656
+ this.broadcastPageScrollMetrics?.();
8657
+ this._broadcastHistoricSnapshot({ force: true });
8658
+ break;
8659
+ }
7804
8660
  case "setSheet": {
7805
8661
  const sheet = this.sheets.get(msg.data.sheet);
7806
8662
  if (sheet && this.studio) {
@@ -7825,32 +8681,67 @@ var RemoteSync = class {
7825
8681
  const sheet = this.sheets.get(msg.data.sheet);
7826
8682
  if (sheet) {
7827
8683
  this.activeSheet = sheet;
8684
+ this.suppressTimelineBroadcast = true;
7828
8685
  sheet.publicApi.sequence.position = msg.data.position;
8686
+ if (shouldSyncPageScrollWhenApplyingTimelineUpdate(
8687
+ this.isEditor,
8688
+ sheet.getSequenceMode()
8689
+ )) {
8690
+ syncPageScrollToSequencePosition(sheet.publicApi);
8691
+ }
8692
+ requestAnimationFrame(() => {
8693
+ this.suppressTimelineBroadcast = false;
8694
+ });
8695
+ }
8696
+ break;
8697
+ }
8698
+ case "pageScrollMetrics": {
8699
+ if (!this.isEditor) break;
8700
+ const { maxScroll, axis } = msg.data;
8701
+ setRemotePageScrollMetrics({ maxScroll, axis });
8702
+ break;
8703
+ }
8704
+ case "highlightDomTarget": {
8705
+ if (this.isEditor || !this.remoteEditorActive) break;
8706
+ const target = msg.data.target;
8707
+ const element = resolveDomElementHighlightTarget(target);
8708
+ setRemoteDomElementHighlight(element);
8709
+ break;
8710
+ }
8711
+ case "clearDomHighlight": {
8712
+ if (this.isEditor || !this.remoteEditorActive) break;
8713
+ setRemoteDomElementHighlight(null);
8714
+ break;
8715
+ }
8716
+ case "updateHistoric": {
8717
+ const { historic, ahistoric } = msg.data;
8718
+ if (historic) {
8719
+ this._applyHistoricSnapshot(historic, ahistoric);
7829
8720
  }
7830
8721
  break;
7831
8722
  }
7832
8723
  case "disconnect": {
7833
8724
  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
- });
8725
+ if (historic) {
8726
+ this._applyHistoricSnapshot(historic, ahistoric);
7845
8727
  }
7846
8728
  for (const obj of this.objects.values()) {
7847
8729
  obj.setRemoteOverride({});
7848
8730
  }
8731
+ if (!this.isEditor) {
8732
+ this.remoteEditorActive = false;
8733
+ setRemoteDomElementHighlight(null);
8734
+ } else {
8735
+ setRemotePageScrollMetrics(void 0);
8736
+ }
7849
8737
  break;
7850
8738
  }
7851
8739
  }
7852
8740
  }
7853
8741
  };
8742
+ function fingerprintHistoricSnapshot(data) {
8743
+ return JSON.stringify(data);
8744
+ }
7854
8745
 
7855
8746
  // core/src/_coreLogger.ts
7856
8747
  function noop2() {
@@ -7877,7 +8768,7 @@ function _coreLogger(config) {
7877
8768
  }
7878
8769
 
7879
8770
  // shared/src/utils/assets.ts
7880
- var import_theatre_dataverse18 = require("@unseenco/theatre-dataverse");
8771
+ var import_theatre_dataverse21 = require("@unseenco/theatre-dataverse");
7881
8772
 
7882
8773
  // shared/src/utils/forEachDeep.ts
7883
8774
  function forEachPropDeep(m, fn2, startingPath = []) {
@@ -7947,7 +8838,7 @@ var Project = class {
7947
8838
  __publicField(this, "_studioReadyDeferred");
7948
8839
  __publicField(this, "_assetStorageReadyDeferred");
7949
8840
  __publicField(this, "_readyPromise");
7950
- __publicField(this, "_sheetTemplates", new import_theatre_dataverse20.Atom({}));
8841
+ __publicField(this, "_sheetTemplates", new import_theatre_dataverse23.Atom({}));
7951
8842
  __publicField(this, "sheetTemplatesP", this._sheetTemplates.pointer);
7952
8843
  __publicField(this, "_studio");
7953
8844
  __publicField(this, "_onDiskStateAtom");
@@ -7960,7 +8851,7 @@ var Project = class {
7960
8851
  this._logger.traceDev("creating project");
7961
8852
  this.address = { projectId: id };
7962
8853
  this._remoteSync = new RemoteSync(this);
7963
- const onDiskStateAtom = new import_theatre_dataverse20.Atom({
8854
+ const onDiskStateAtom = new import_theatre_dataverse23.Atom({
7964
8855
  ahistoric: {
7965
8856
  ahistoricStuff: ""
7966
8857
  },
@@ -7986,9 +8877,9 @@ var Project = class {
7986
8877
  }
7987
8878
  };
7988
8879
  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)
8880
+ historic: new import_theatre_dataverse22.PointerProxy(onDiskStateAtom.pointer.historic),
8881
+ ahistoric: new import_theatre_dataverse22.PointerProxy(onDiskStateAtom.pointer.ahistoric),
8882
+ ephemeral: new import_theatre_dataverse22.PointerProxy(onDiskStateAtom.pointer.ephemeral)
7992
8883
  };
7993
8884
  this.pointers = {
7994
8885
  historic: this._pointerProxies.historic.pointer,
@@ -8015,14 +8906,14 @@ var Project = class {
8015
8906
  if (typeof window === "undefined") {
8016
8907
  if (process.env.NODE_ENV === "production") {
8017
8908
  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"
8909
+ '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
8910
  );
8020
8911
  }
8021
8912
  } else {
8022
8913
  setTimeout(() => {
8023
8914
  if (!this._studio) {
8024
8915
  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"
8916
+ '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
8917
  );
8027
8918
  }
8028
8919
  }, 1e3);
@@ -8086,6 +8977,7 @@ var Project = class {
8086
8977
  template.setVisibleInOutline(opts.visible);
8087
8978
  }
8088
8979
  const sheet = template.getInstance(instanceId);
8980
+ applySheetRuntimeOptions(sheet, opts);
8089
8981
  this._remoteSync.registerSheet(sheet);
8090
8982
  return sheet;
8091
8983
  }
@@ -8366,13 +9258,13 @@ var Project = class {
8366
9258
  };
8367
9259
 
8368
9260
  // 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.");
9261
+ var _validateSym = (val13, thingy, range) => {
9262
+ if (typeof val13 !== "string") {
9263
+ return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val13), " given.");
9264
+ } else if (val13.trim().length !== val13.length) {
9265
+ return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val13, "' given.");
9266
+ } else if (val13.length < range[0] || val13.length > range[1]) {
9267
+ return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val13, "' given.");
8376
9268
  }
8377
9269
  };
8378
9270
  var validateName = (name, thingy, shouldThrow = false) => {
@@ -8488,193 +9380,61 @@ var TheatreProject = class {
8488
9380
 
8489
9381
  // core/src/coreExports.ts
8490
9382
  var import_fast_deep_equal3 = __toESM(require_fast_deep_equal());
8491
- var import_theatre_dataverse23 = require("@unseenco/theatre-dataverse");
8492
9383
  var import_theatre_dataverse24 = require("@unseenco/theatre-dataverse");
9384
+ var import_theatre_dataverse25 = require("@unseenco/theatre-dataverse");
8493
9385
 
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;
9386
+ // core/src/sheets/theatrePageScroll.ts
9387
+ var pageScrollConfig = {};
9388
+ function buildPageScrollContextFromConfig() {
9389
+ return {
9390
+ scroller: pageScrollConfig.scroller ?? defaultPageScrollContext.scroller,
9391
+ axis: pageScrollConfig.axis ?? defaultPageScrollContext.axis
9392
+ };
8543
9393
  }
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);
9394
+ function configureTheatrePageScroll(config) {
9395
+ const prev = pageScrollConfig;
9396
+ pageScrollConfig = {
9397
+ scroller: config.scroller ?? prev.scroller,
9398
+ axis: config.axis ?? prev.axis
9399
+ };
9400
+ if (config.scroller !== void 0 || config.axis !== void 0) {
9401
+ setActivePageScrollContext(buildPageScrollContextFromConfig());
8566
9402
  }
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
- }
9403
+ return {
9404
+ reset() {
9405
+ pageScrollConfig = prev;
9406
+ setActivePageScrollContext(
9407
+ prev.scroller !== void 0 || prev.axis !== void 0 ? {
9408
+ scroller: prev.scroller ?? defaultPageScrollContext.scroller,
9409
+ axis: prev.axis ?? defaultPageScrollContext.axis
9410
+ } : defaultPageScrollContext
9411
+ );
8590
9412
  }
8591
- }
9413
+ };
8592
9414
  }
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;
9415
+ function getTheatrePageScrollConfig() {
9416
+ return pageScrollConfig;
8599
9417
  }
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);
9418
+ function getTheatrePageScrollContext() {
9419
+ const ctx = buildPageScrollContextFromConfig();
9420
+ setActivePageScrollContext(ctx);
9421
+ return ctx;
8612
9422
  }
8613
- function getStore() {
8614
- const g2 = globalThis;
8615
- if (!g2[REGISTRY_KEY]) {
8616
- g2[REGISTRY_KEY] = {
8617
- bySheetAddress: /* @__PURE__ */ new Map()
8618
- };
9423
+ function createDefaultPageScrollDriver(scroller = getTheatrePageScrollContext().scroller, axis = resolvePageScrollAxis(getTheatrePageScrollContext())) {
9424
+ if (typeof document !== "undefined" && scroller != null && !isNativeDocumentScroller(scroller) && scroller instanceof HTMLElement) {
9425
+ return axis === "horizontal" ? createElementHorizontalScrollDriver(scroller) : createElementScrollDriver(scroller);
8619
9426
  }
8620
- return g2[REGISTRY_KEY];
9427
+ return axis === "horizontal" ? createNativeDocumentHorizontalScrollDriver() : createNativeDocumentScrollDriver();
8621
9428
  }
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();
9429
+ function attachTheatrePageScroll(sheet, options = {}) {
9430
+ const ctx = getTheatrePageScrollContext();
9431
+ const driver = options.driver ?? createDefaultPageScrollDriver(ctx.scroller, resolvePageScrollAxis(ctx));
9432
+ sheet.setPageScrollDriver(driver);
8650
9433
  return () => {
8651
- untapPosition();
8652
- untapClips();
9434
+ sheet.setPageScrollDriver(void 0);
8653
9435
  };
8654
9436
  }
8655
9437
 
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
9438
  // core/src/coreExports.ts
8679
9439
  function getProject(id, config = {}) {
8680
9440
  const existingProject = projectsSingleton_default.get(id);
@@ -8716,7 +9476,7 @@ var shallowValidateOnDiskState = (projectId, s2) => {
8716
9476
  throw new InvalidArgumentError(
8717
9477
  "Error validating conf.state in Theatre.getProject(".concat(JSON.stringify(
8718
9478
  projectId
8719
- ), ", conf). The state seems to be formatted in a way that is unreadable to Theatre.js. Read more at https://www.theatrejs.com/docs/latest/manual/projects#state")
9479
+ ), ", conf). The state seems to be formatted in a way that is unreadable to Theatre.js. Read more at https://unseen-theatre.netlify.app/docs/guide/manual/projects#state")
8720
9480
  );
8721
9481
  }
8722
9482
  };
@@ -8755,10 +9515,10 @@ var validateProjectIdOrThrow = (value) => {
8755
9515
  };
8756
9516
  function onChange(pointer3, callback, rafDriver) {
8757
9517
  const ticker = rafDriver ? privateAPI(rafDriver).ticker : getCoreTicker();
8758
- if ((0, import_theatre_dataverse23.isPointer)(pointer3)) {
8759
- const pr = (0, import_theatre_dataverse24.pointerToPrism)(pointer3);
9518
+ if ((0, import_theatre_dataverse24.isPointer)(pointer3)) {
9519
+ const pr = (0, import_theatre_dataverse25.pointerToPrism)(pointer3);
8760
9520
  return pr.onChange(ticker, callback, true);
8761
- } else if ((0, import_theatre_dataverse24.isPrism)(pointer3)) {
9521
+ } else if ((0, import_theatre_dataverse25.isPrism)(pointer3)) {
8762
9522
  return pointer3.onChange(ticker, callback, true);
8763
9523
  } else {
8764
9524
  throw new Error(
@@ -8766,9 +9526,9 @@ function onChange(pointer3, callback, rafDriver) {
8766
9526
  );
8767
9527
  }
8768
9528
  }
8769
- function val11(pointer3) {
8770
- if ((0, import_theatre_dataverse23.isPointer)(pointer3)) {
8771
- return (0, import_theatre_dataverse24.pointerToPrism)(pointer3).getValue();
9529
+ function val12(pointer3) {
9530
+ if ((0, import_theatre_dataverse24.isPointer)(pointer3)) {
9531
+ return (0, import_theatre_dataverse25.pointerToPrism)(pointer3).getValue();
8772
9532
  } else {
8773
9533
  throw new Error("Called val(p) where p is not a pointer.");
8774
9534
  }
@@ -8783,7 +9543,7 @@ var CoreBundle = class {
8783
9543
  return "Theatre_CoreBundle";
8784
9544
  }
8785
9545
  get version() {
8786
- return "0.4.3";
9546
+ return "0.5.0";
8787
9547
  }
8788
9548
  getBitsForStudio(studio, callback) {
8789
9549
  if (this._studio) {