@hology/core 0.0.205 → 0.0.207

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/config/project-config.d.ts +4 -0
  2. package/dist/effects/sequence/sequence-data.d.ts +8 -3
  3. package/dist/effects/sequence/sequence-data.js +1 -1
  4. package/dist/effects/sequence/sequence-definitions.js +1 -1
  5. package/dist/effects/sequence/sequence-player.d.ts +2 -0
  6. package/dist/effects/sequence/sequence-player.js +1 -1
  7. package/dist/effects/sequence/sequence-value-lane.js +1 -1
  8. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  9. package/dist/gameplay/actors/factory.d.ts +1 -0
  10. package/dist/gameplay/actors/factory.js +1 -1
  11. package/dist/gameplay/actors/internal/component-init.d.ts +1 -0
  12. package/dist/gameplay/actors/internal/component-init.js +1 -1
  13. package/dist/gameplay/animation/anim-sm.d.ts +2 -0
  14. package/dist/gameplay/animation/anim-sm.js +1 -1
  15. package/dist/gameplay/index.d.ts +1 -0
  16. package/dist/gameplay/index.js +1 -1
  17. package/dist/gameplay/initiate.d.ts +4 -0
  18. package/dist/gameplay/services/asset-loader.d.ts +3 -0
  19. package/dist/gameplay/services/asset-loader.js +1 -1
  20. package/dist/gameplay/services/world.js +1 -1
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +1 -1
  23. package/dist/rendering.d.ts +4 -0
  24. package/dist/rendering.js +1 -1
  25. package/dist/scene/custom-param-deserialize.d.ts +1 -0
  26. package/dist/scene/custom-param-deserialize.js +1 -1
  27. package/dist/scene/custom-param-runtime-types.d.ts +3 -1
  28. package/dist/scene/custom-param-runtime-types.js +1 -1
  29. package/dist/scene/materializer.d.ts +12 -1
  30. package/dist/scene/materializer.js +1 -1
  31. package/dist/scene/model.d.ts +18 -2
  32. package/dist/scene/model.js +1 -1
  33. package/dist/scene/objects/data-asset.d.ts +10 -0
  34. package/dist/scene/objects/data-asset.js +4 -0
  35. package/dist/scene/storage/storage.d.ts +1 -0
  36. package/dist/scene/storage/storage.js +1 -1
  37. package/dist/shader/graph/compiler.js +1 -1
  38. package/dist/shader/parameter.d.ts +64 -3
  39. package/dist/shader/parameter.js +1 -1
  40. package/dist/test/data-asset-definition.test.d.ts +2 -0
  41. package/dist/test/data-asset-definition.test.js +4 -0
  42. package/dist/test/parameter-definition.test.d.ts +2 -0
  43. package/dist/test/parameter-definition.test.js +4 -0
  44. package/dist/test/sequence-property-parameters.test.js +1 -1
  45. package/dist/test/sequence-vfx.test.d.ts +2 -0
  46. package/dist/test/sequence-vfx.test.js +4 -0
  47. package/dist/test/storage-case-collision.test.js +1 -1
  48. package/dist/test/world-lifecycle.test.d.ts +2 -0
  49. package/dist/test/world-lifecycle.test.js +4 -0
  50. package/dist/utils/type.d.ts +1 -1
  51. package/package.json +1 -1
  52. package/tsconfig.tsbuildinfo +1 -1
@@ -19,6 +19,10 @@ export interface ProjectConfig {
19
19
  * Components are reusable pieces of functionality attached to actors.
20
20
  */
21
21
  componentsPath?: string;
22
+ /**
23
+ * Path to data asset definition classes. Defaults to "src/data" if not specified.
24
+ */
25
+ dataDefinitionsPath?: string;
22
26
  play?: {
23
27
  command: string;
24
28
  showTerminal: boolean;
@@ -21,7 +21,8 @@ export interface PropertySubTrackOptions {
21
21
  defaultValue?: CustomParamValue;
22
22
  }
23
23
  export interface MaterialSubTrackOptions {
24
- materialAssetId: AssetId;
24
+ materialAssetId?: AssetId | null;
25
+ materialMatchMode?: MaterialSubTrackMatchMode;
25
26
  parameterName: string;
26
27
  uniformName: string;
27
28
  uniformType: SerializedParamType;
@@ -35,6 +36,7 @@ export interface MaterialSubTrackOptions {
35
36
  stepSize?: number;
36
37
  defaultValue?: CustomParamValue;
37
38
  }
39
+ export type MaterialSubTrackMatchMode = 'asset' | 'parameterName';
38
40
  /**
39
41
  * The main sequence data structure containing all tracks and playback settings.
40
42
  * This is stored as a parameter on SequenceActor or as part of a SequenceAsset.
@@ -289,8 +291,10 @@ export interface PropertySubTrack extends BaseSubTrack {
289
291
  */
290
292
  export interface MaterialSubTrack extends BaseSubTrack {
291
293
  type: 'material';
292
- /** Material asset whose runtime material slots should be controlled */
293
- materialAssetId: AssetId;
294
+ /** How runtime material slots should be matched. Missing means asset matching for older sequence data. */
295
+ materialMatchMode?: MaterialSubTrackMatchMode;
296
+ /** Material asset whose runtime material slots should be controlled when matching by asset */
297
+ materialAssetId?: AssetId | null;
294
298
  /** Source shader/shader graph parameter name */
295
299
  parameterName: string;
296
300
  /** Runtime uniform name to animate */
@@ -635,6 +639,7 @@ export declare function createPropertySubTrack(options?: PropertySubTrackOptions
635
639
  * Creates a new material sub-track
636
640
  */
637
641
  export declare function createMaterialSubTrack(options: MaterialSubTrackOptions): MaterialSubTrack;
642
+ export declare function getMaterialSubTrackMatchMode(subTrack: Pick<MaterialSubTrack | MaterialSubTrackOptions, 'materialMatchMode' | 'materialAssetId'>): MaterialSubTrackMatchMode;
638
643
  /**
639
644
  * Creates a new visibility sub-track
640
645
  */
@@ -1,4 +1,4 @@
1
- import{SerializedParamType as e}from"../../scene/model.js";import{randomString as t}from"../../utils/math.js";import{getAudioParameterDefinition as r}from"./audio-parameters.js";export class Sequence{constructor(e){this.data=e}}export var SequenceRole;!function(e){e.Self="self",e.Target="target",e.Target2="target2",e.Target3="target3",e.Secondary="secondary"}(SequenceRole||(SequenceRole={}));export function createSequenceData(){return{duration:5,loop:!1,playbackRate:1,tracks:[]}}export function createObjectTrack(e="Object Track"){return{id:t(),name:e,type:"object",muted:!1,locked:!1,targetId:null,role:null,subTracks:[]}}export function createCameraTrack(e="Camera Track"){return{id:t(),name:e,type:"camera",muted:!1,locked:!1,parentRole:null,clips:[],cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}export function createCameraShakeTrack(e="Camera Shake"){return{id:t(),name:e,type:"cameraShake",muted:!1,locked:!1,clips:[],subTracks:[]}}export function createPostProcessTrack(e="Post Process"){return{id:t(),name:e,type:"postProcess",muted:!1,locked:!1,clips:[],stage:"beforeOutput",priority:0,subTracks:[]}}export function createCameraClipInstance(e,r){return{id:t(),startTime:e,duration:r,blendInDuration:.2,blendOutDuration:.2,blendInterpolation:"cubic"}}export function createCameraShakeClipInstance(e,r){return{id:t(),startTime:e,duration:r,attack:0,decay:Math.min(Math.max(.35*r,.05),Math.max(r,.05)),frequency:24,positionAmplitude:[0,0,.12],rotationAmplitude:[.015,.02,.01]}}export function createPostProcessClipInstance(e,r){return{id:t(),shaderGraphAssetId:null,shaderGraphParams:{},startTime:e,duration:r,fadeInDuration:Math.min(.15,Math.max(.25*r,0)),fadeOutDuration:Math.min(.15,Math.max(.25*r,0))}}export function createAudioTrack(e="Audio Track"){return{id:t(),name:e,type:"audio",muted:!1,locked:!1,clips:[],subTracks:[],volume:1,spatial:!1}}export function createVfxTrack(e="VFX Track"){return{id:t(),name:e,type:"vfx",muted:!1,locked:!1,clips:[],position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],subTracks:[]}}export function createSpawnTrack(e="Spawn Track"){return{id:t(),name:e,type:"spawn",muted:!1,locked:!1,spawnType:"mesh",role:null,clips:[],subTracks:[]}}export function createSpawnClipInstance(e,r){return{id:t(),startTime:e,duration:r}}export function createGroupTrack(e="Group"){return{id:t(),name:e,type:"group",muted:!1,locked:!1,collapsed:!1,childTracks:[],subTracks:[]}}export function createTransformSubTrack(){return{id:t(),name:"Transform",type:"transform",muted:!1,components:{position:!0,rotation:!0,scale:!0},keyframes:[]}}export function createAnimationSubTrack(e="Animation"){return{id:t(),name:e,type:"animation",muted:!1,clips:[]}}export function createAudioParameterSubTrack(e="volume"){const a=r(e);return{id:t(),name:a.displayName,type:"audioParameter",muted:!1,parameter:e,keyframes:[]}}export function createPropertySubTrack(r="",a=e.Number){const n="string"==typeof r?{propertyPath:r,propertyType:a}:r;return{id:t(),name:n.name??n.label??n.propertyPath??"Property",type:"property",muted:!1,propertyPath:n.propertyPath,propertyType:n.propertyType,label:n.label,group:n.group,help:n.help,range:n.range,precision:n.precision,stepSize:n.stepSize,options:n.options,editorInput:n.editorInput,defaultValue:n.defaultValue,keyframes:[]}}export function createMaterialSubTrack(e){return{id:t(),name:e.name??e.label??e.parameterName??"Material",type:"material",muted:!1,materialAssetId:e.materialAssetId,parameterName:e.parameterName,uniformName:e.uniformName,uniformType:e.uniformType,valueType:e.valueType,label:e.label,group:e.group,help:e.help,range:e.range,precision:e.precision,stepSize:e.stepSize,defaultValue:e.defaultValue,keyframes:[]}}export function createVisibilitySubTrack(e="Visibility"){return{id:t(),name:e,type:"visibility",muted:!1,keyframes:[]}}export function createTransformKeyframe(e){return{id:t(),time:e,position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],interpolation:"cubic"}}export function createPropertyKeyframe(r,a={type:e.Number,value:0}){return{id:t(),time:r,value:a,interpolation:"linear"}}export function createAnimationClipInstance(e,r,a){return{id:t(),animationClipAssetId:e,startTime:r,duration:a,clipStartOffset:0,clipEndOffset:0,playbackRate:1,fadeInDuration:.2,retiming:void 0,rootMotion:!1}}export function createAnimationClipRetimingPoint(e=.35,r=.55){return{id:t(),clipProgress:e,sourceProgress:r}}export function createAnimationClipRetiming(e="impact",t=("uniform"===e?[]:[createAnimationClipRetimingPoint()])){return{mode:e,points:t}}export function createAudioClipInstance(e,r,a){return{id:t(),audioAssetId:e,startTime:r,duration:a,clipStartOffset:0,playbackRate:1,volume:1,fadeInDuration:0,fadeOutDuration:0,volumeRandomization:0,pitchRandomization:0}}export function createVfxClipInstance(e,r,a){return{id:t(),vfxAssetId:e,startTime:r,duration:a,endBehavior:"finish",expireWithinSeconds:.25}}export function createEventSubTrack(e="Events"){return{id:t(),name:e,type:"event",muted:!1,events:[]}}export function createSequenceEventData(e,r=""){return{id:t(),time:e,editorOnly:!1,functionName:r,arguments:[]}}export function createLocatorTrack(e="Locator"){return{id:t(),name:e,type:"locator",muted:!1,locked:!1,subTracks:[]}}/*
1
+ import{SerializedParamType as e}from"../../scene/model.js";import{randomString as t}from"../../utils/math.js";import{getAudioParameterDefinition as r}from"./audio-parameters.js";export class Sequence{constructor(e){this.data=e}}export var SequenceRole;!function(e){e.Self="self",e.Target="target",e.Target2="target2",e.Target3="target3",e.Secondary="secondary"}(SequenceRole||(SequenceRole={}));export function createSequenceData(){return{duration:5,loop:!1,playbackRate:1,tracks:[]}}export function createObjectTrack(e="Object Track"){return{id:t(),name:e,type:"object",muted:!1,locked:!1,targetId:null,role:null,subTracks:[]}}export function createCameraTrack(e="Camera Track"){return{id:t(),name:e,type:"camera",muted:!1,locked:!1,parentRole:null,clips:[],cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}export function createCameraShakeTrack(e="Camera Shake"){return{id:t(),name:e,type:"cameraShake",muted:!1,locked:!1,clips:[],subTracks:[]}}export function createPostProcessTrack(e="Post Process"){return{id:t(),name:e,type:"postProcess",muted:!1,locked:!1,clips:[],stage:"beforeOutput",priority:0,subTracks:[]}}export function createCameraClipInstance(e,r){return{id:t(),startTime:e,duration:r,blendInDuration:.2,blendOutDuration:.2,blendInterpolation:"cubic"}}export function createCameraShakeClipInstance(e,r){return{id:t(),startTime:e,duration:r,attack:0,decay:Math.min(Math.max(.35*r,.05),Math.max(r,.05)),frequency:24,positionAmplitude:[0,0,.12],rotationAmplitude:[.015,.02,.01]}}export function createPostProcessClipInstance(e,r){return{id:t(),shaderGraphAssetId:null,shaderGraphParams:{},startTime:e,duration:r,fadeInDuration:Math.min(.15,Math.max(.25*r,0)),fadeOutDuration:Math.min(.15,Math.max(.25*r,0))}}export function createAudioTrack(e="Audio Track"){return{id:t(),name:e,type:"audio",muted:!1,locked:!1,clips:[],subTracks:[],volume:1,spatial:!1}}export function createVfxTrack(e="VFX Track"){return{id:t(),name:e,type:"vfx",muted:!1,locked:!1,clips:[],position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],subTracks:[]}}export function createSpawnTrack(e="Spawn Track"){return{id:t(),name:e,type:"spawn",muted:!1,locked:!1,spawnType:"mesh",role:null,clips:[],subTracks:[]}}export function createSpawnClipInstance(e,r){return{id:t(),startTime:e,duration:r}}export function createGroupTrack(e="Group"){return{id:t(),name:e,type:"group",muted:!1,locked:!1,collapsed:!1,childTracks:[],subTracks:[]}}export function createTransformSubTrack(){return{id:t(),name:"Transform",type:"transform",muted:!1,components:{position:!0,rotation:!0,scale:!0},keyframes:[]}}export function createAnimationSubTrack(e="Animation"){return{id:t(),name:e,type:"animation",muted:!1,clips:[]}}export function createAudioParameterSubTrack(e="volume"){const a=r(e);return{id:t(),name:a.displayName,type:"audioParameter",muted:!1,parameter:e,keyframes:[]}}export function createPropertySubTrack(r="",a=e.Number){const n="string"==typeof r?{propertyPath:r,propertyType:a}:r;return{id:t(),name:n.name??n.label??n.propertyPath??"Property",type:"property",muted:!1,propertyPath:n.propertyPath,propertyType:n.propertyType,label:n.label,group:n.group,help:n.help,range:n.range,precision:n.precision,stepSize:n.stepSize,options:n.options,editorInput:n.editorInput,defaultValue:n.defaultValue,keyframes:[]}}export function createMaterialSubTrack(e){const r=e.materialMatchMode??(e.materialAssetId?"asset":"parameterName");return{id:t(),name:e.name??e.label??e.parameterName??"Material",type:"material",muted:!1,materialMatchMode:r,materialAssetId:e.materialAssetId??null,parameterName:e.parameterName,uniformName:e.uniformName,uniformType:e.uniformType,valueType:e.valueType,label:e.label,group:e.group,help:e.help,range:e.range,precision:e.precision,stepSize:e.stepSize,defaultValue:e.defaultValue,keyframes:[]}}export function getMaterialSubTrackMatchMode(e){return e.materialMatchMode??(e.materialAssetId?"asset":"parameterName")}export function createVisibilitySubTrack(e="Visibility"){return{id:t(),name:e,type:"visibility",muted:!1,keyframes:[]}}export function createTransformKeyframe(e){return{id:t(),time:e,position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],interpolation:"cubic"}}export function createPropertyKeyframe(r,a={type:e.Number,value:0}){return{id:t(),time:r,value:a,interpolation:"linear"}}export function createAnimationClipInstance(e,r,a){return{id:t(),animationClipAssetId:e,startTime:r,duration:a,clipStartOffset:0,clipEndOffset:0,playbackRate:1,fadeInDuration:.2,retiming:void 0,rootMotion:!1}}export function createAnimationClipRetimingPoint(e=.35,r=.55){return{id:t(),clipProgress:e,sourceProgress:r}}export function createAnimationClipRetiming(e="impact",t=("uniform"===e?[]:[createAnimationClipRetimingPoint()])){return{mode:e,points:t}}export function createAudioClipInstance(e,r,a){return{id:t(),audioAssetId:e,startTime:r,duration:a,clipStartOffset:0,playbackRate:1,volume:1,fadeInDuration:0,fadeOutDuration:0,volumeRandomization:0,pitchRandomization:0}}export function createVfxClipInstance(e,r,a){return{id:t(),vfxAssetId:e,startTime:r,duration:a,endBehavior:"finish",expireWithinSeconds:.25}}export function createEventSubTrack(e="Events"){return{id:t(),name:e,type:"event",muted:!1,events:[]}}export function createSequenceEventData(e,r=""){return{id:t(),time:e,editorOnly:!1,functionName:r,arguments:[]}}export function createLocatorTrack(e="Locator"){return{id:t(),name:e,type:"locator",muted:!1,locked:!1,subTracks:[]}}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{createAnimationClipInstance as e,createAnimationSubTrack as r,createAudioClipInstance as a,createAudioParameterSubTrack as t,createAudioTrack as o,createCameraClipInstance as i,createCameraShakeClipInstance as n,createCameraShakeTrack as p,createCameraTrack as l,createEventSubTrack as c,createGroupTrack as s,createLocatorTrack as u,createMaterialSubTrack as m,createObjectTrack as d,createPostProcessClipInstance as T,createPostProcessTrack as y,createPropertySubTrack as b,createSpawnClipInstance as k,createSpawnTrack as f,createTransformSubTrack as v,createVfxClipInstance as E,createVfxTrack as S,createVisibilitySubTrack as x}from"./sequence-data.js";import{SerializedParamType as P}from"../../scene/model.js";const w=[{type:"object",label:"Object Track",icon:"mdil-hexagon",runtimeEvaluator:"object",createTrack:()=>d(),allowedSubTrackTypes:["transform","animation","property","material","visibility","event"],supportsParenting:!0,exposedInEditor:!1},{type:"locator",label:"Locator",icon:"mdil-map-marker",runtimeEvaluator:"locator",createTrack:()=>u(),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"camera",label:"Camera Track",icon:"mdil-camcorder",runtimeEvaluator:"camera",createTrack:(e=0,r=2)=>{const a=l();return a.clips.push(i(e,r)),a.subTracks.push(v()),a},createDirectClip:(e=0,r=2)=>i(e,r),allowedSubTrackTypes:["transform","property"],exposedInEditor:!0},{type:"cameraShake",label:"Camera Shake",icon:"mdil-camera",runtimeEvaluator:"cameraShake",createTrack:(e=0,r=.35)=>{const a=p();return a.clips.push(n(e,r)),a},createDirectClip:(e=0,r=.35)=>n(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"postProcess",label:"Post Process",icon:"mdil-television",runtimeEvaluator:"postProcess",createTrack:(e=0,r=2)=>{const a=y();return a.clips.push(T(e,r)),a},createDirectClip:(e=0,r=2)=>T(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"audio",label:"Audio Track",icon:"mdil-volume-high",runtimeEvaluator:"audio",createTrack:(e=0,r=2)=>{const t=o();return t.clips.push(a(null,e,r)),t},createDirectClip:(e=0,r=2)=>a(null,e,r),allowedSubTrackTypes:["audioParameter"],supportsParenting:!0,exposedInEditor:!0},{type:"vfx",label:"VFX Track",icon:"mdil-star",runtimeEvaluator:"vfx",createTrack:(e=0,r=2)=>{const a=S();return a.clips.push(E(null,e,r)),a},createDirectClip:(e=0,r=2)=>E(null,e,r),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"spawn",label:"Spawn Track",icon:"mdil-plus-box",runtimeEvaluator:"spawn",createTrack:(e=0,r=2)=>{const a=f();return a.clips.push(k(e,r)),a},createDirectClip:(e=0,r=2)=>k(e,r),allowedSubTrackTypes:["transform","animation","property","material","event"],supportsParenting:!0,exposedInEditor:!0},{type:"group",label:"Group",icon:"mdil-folder",runtimeEvaluator:"group",createTrack:()=>s(),allowedSubTrackTypes:[],exposedInEditor:!1}],h=[{type:"transform",label:"Transform",icon:"mdil-move-resize",laneKind:"keyframes",runtimeEvaluator:"transform",createSubTrack:()=>v(),supportedTrackTypes:["object","locator","camera","spawn","vfx"],exposedInEditor:!0},{type:"animation",label:"Animation",icon:"mdil-run",laneKind:"clips",runtimeEvaluator:"animation",createSubTrack:()=>r(),createClip:(r=0,a=2)=>e(null,r,a),supportedTrackTypes:["object","camera","spawn"],exposedInEditor:!0},{type:"property",label:"Property",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>b(e?.property??{propertyPath:e?.propertyPath??"",propertyType:e?.propertyType??P.Number}),supportedTrackTypes:["object","camera","spawn"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"customParam"}},{type:"material",label:"Material",icon:"mdil-palette",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>m(e.material),supportedTrackTypes:["object","spawn"],exposedInEditor:!1,valueLane:{kind:"customParam"}},{type:"visibility",label:"Visibility",icon:"mdil-eye",laneKind:"keyframes",runtimeEvaluator:"visibility",createSubTrack:()=>x(),supportedTrackTypes:["object","spawn","vfx"],exposedInEditor:!1},{type:"event",label:"Events",icon:"mdil-flash-outline",laneKind:"events",runtimeEvaluator:"event",createSubTrack:()=>c(),supportedTrackTypes:["object","spawn"],exposedInEditor:!0},{type:"audioParameter",label:"Audio Parameter",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>t(e?.parameter),supportedTrackTypes:["audio"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"number"}}];export const audioParameterSubTrackOptions=[{parameter:"volume",label:"Volume",icon:"mdil-tune"},{parameter:"detune",label:"Detune",icon:"mdil-music-note"},{parameter:"pan",label:"Pan",icon:"mdil-panorama-horizontal"},{parameter:"spatialBlend",label:"Spatial Blend",icon:"mdil-cube-outline"},{parameter:"lowpass",label:"Low Pass Filter",icon:"mdil-filter-variant"},{parameter:"highpass",label:"High Pass Filter",icon:"mdil-filter-variant"}];export const cameraPropertySubTrackOptions=[{name:"FOV",label:"FOV",propertyPath:"fov",propertyType:P.Number,group:"Camera",help:"Camera field of view in degrees.",range:[1,179],precision:1,stepSize:.1,defaultValue:{type:P.Number,value:60}}];const g=new Map(w.map(e=>[e.type,e])),I=new Map(h.map(e=>[e.type,e]));export function getSequenceTrackDefinitions(){return w}export function getSequenceSubTrackDefinitions(){return h}export function getSequenceTrackDefinition(e){return g.get(e)}export function getSequenceSubTrackDefinition(e){return I.get(e)}export function getEditorSequenceTrackDefinitions(){return w.filter(e=>!1!==e.exposedInEditor)}export function getEditorSequenceSubTrackDefinitions(e){return h.filter(r=>!1!==r.exposedInEditor&&r.supportedTrackTypes.some(r=>r===e.type))}export function canTrackAddSubTrack(e,r,a){if(e.locked)return!1;const t=getSequenceSubTrackDefinition(r);if(!t.supportedTrackTypes.some(r=>r===e.type))return!1;if("audioParameter"===r)return!!a?.parameter&&!e.subTracks.some(e=>"audioParameter"===e.type&&e.parameter===a.parameter);if("property"===r){const r=a?.property?.propertyPath??a?.propertyPath;return!!r&&!e.subTracks.some(e=>"property"===e.type&&e.propertyPath===r)}if("material"===r){const r=a?.material;return!(!r?.materialAssetId||!r.parameterName)&&!e.subTracks.some(e=>"material"===e.type&&e.materialAssetId===r.materialAssetId&&e.parameterName===r.parameterName)}return!!t.allowMultiple||!e.subTracks.some(e=>e.type===r)}/*
1
+ import{createAnimationClipInstance as e,createAnimationSubTrack as r,createAudioClipInstance as a,createAudioParameterSubTrack as t,createAudioTrack as o,createCameraClipInstance as i,createCameraShakeClipInstance as n,createCameraShakeTrack as p,createCameraTrack as l,createEventSubTrack as c,createGroupTrack as s,createLocatorTrack as u,createMaterialSubTrack as m,createObjectTrack as d,createPostProcessClipInstance as T,createPostProcessTrack as y,createPropertySubTrack as b,createSpawnClipInstance as k,createSpawnTrack as f,createTransformSubTrack as v,createVfxClipInstance as E,createVfxTrack as S,createVisibilitySubTrack as x,getMaterialSubTrackMatchMode as P}from"./sequence-data.js";import{SerializedParamType as w}from"../../scene/model.js";const h=[{type:"object",label:"Object Track",icon:"mdil-hexagon",runtimeEvaluator:"object",createTrack:()=>d(),allowedSubTrackTypes:["transform","animation","property","material","visibility","event"],supportsParenting:!0,exposedInEditor:!1},{type:"locator",label:"Locator",icon:"mdil-map-marker",runtimeEvaluator:"locator",createTrack:()=>u(),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"camera",label:"Camera Track",icon:"mdil-camcorder",runtimeEvaluator:"camera",createTrack:(e=0,r=2)=>{const a=l();return a.clips.push(i(e,r)),a.subTracks.push(v()),a},createDirectClip:(e=0,r=2)=>i(e,r),allowedSubTrackTypes:["transform","property"],exposedInEditor:!0},{type:"cameraShake",label:"Camera Shake",icon:"mdil-camera",runtimeEvaluator:"cameraShake",createTrack:(e=0,r=.35)=>{const a=p();return a.clips.push(n(e,r)),a},createDirectClip:(e=0,r=.35)=>n(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"postProcess",label:"Post Process",icon:"mdil-television",runtimeEvaluator:"postProcess",createTrack:(e=0,r=2)=>{const a=y();return a.clips.push(T(e,r)),a},createDirectClip:(e=0,r=2)=>T(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"audio",label:"Audio Track",icon:"mdil-volume-high",runtimeEvaluator:"audio",createTrack:(e=0,r=2)=>{const t=o();return t.clips.push(a(null,e,r)),t},createDirectClip:(e=0,r=2)=>a(null,e,r),allowedSubTrackTypes:["audioParameter"],supportsParenting:!0,exposedInEditor:!0},{type:"vfx",label:"VFX Track",icon:"mdil-star",runtimeEvaluator:"vfx",createTrack:(e=0,r=2)=>{const a=S();return a.clips.push(E(null,e,r)),a},createDirectClip:(e=0,r=2)=>E(null,e,r),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"spawn",label:"Spawn Track",icon:"mdil-plus-box",runtimeEvaluator:"spawn",createTrack:(e=0,r=2)=>{const a=f();return a.clips.push(k(e,r)),a},createDirectClip:(e=0,r=2)=>k(e,r),allowedSubTrackTypes:["transform","animation","property","material","event"],supportsParenting:!0,exposedInEditor:!0},{type:"group",label:"Group",icon:"mdil-folder",runtimeEvaluator:"group",createTrack:()=>s(),allowedSubTrackTypes:[],exposedInEditor:!1}],g=[{type:"transform",label:"Transform",icon:"mdil-move-resize",laneKind:"keyframes",runtimeEvaluator:"transform",createSubTrack:()=>v(),supportedTrackTypes:["object","locator","camera","spawn","vfx"],exposedInEditor:!0},{type:"animation",label:"Animation",icon:"mdil-run",laneKind:"clips",runtimeEvaluator:"animation",createSubTrack:()=>r(),createClip:(r=0,a=2)=>e(null,r,a),supportedTrackTypes:["object","camera","spawn"],exposedInEditor:!0},{type:"property",label:"Property",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>b(e?.property??{propertyPath:e?.propertyPath??"",propertyType:e?.propertyType??w.Number}),supportedTrackTypes:["object","camera","spawn"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"customParam"}},{type:"material",label:"Material",icon:"mdil-palette",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>m(e.material),supportedTrackTypes:["object","spawn"],exposedInEditor:!1,valueLane:{kind:"customParam"}},{type:"visibility",label:"Visibility",icon:"mdil-eye",laneKind:"keyframes",runtimeEvaluator:"visibility",createSubTrack:()=>x(),supportedTrackTypes:["object","spawn","vfx"],exposedInEditor:!1},{type:"event",label:"Events",icon:"mdil-flash-outline",laneKind:"events",runtimeEvaluator:"event",createSubTrack:()=>c(),supportedTrackTypes:["object","spawn"],exposedInEditor:!0},{type:"audioParameter",label:"Audio Parameter",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>t(e?.parameter),supportedTrackTypes:["audio"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"number"}}];export const audioParameterSubTrackOptions=[{parameter:"volume",label:"Volume",icon:"mdil-tune"},{parameter:"detune",label:"Detune",icon:"mdil-music-note"},{parameter:"pan",label:"Pan",icon:"mdil-panorama-horizontal"},{parameter:"spatialBlend",label:"Spatial Blend",icon:"mdil-cube-outline"},{parameter:"lowpass",label:"Low Pass Filter",icon:"mdil-filter-variant"},{parameter:"highpass",label:"High Pass Filter",icon:"mdil-filter-variant"}];export const cameraPropertySubTrackOptions=[{name:"FOV",label:"FOV",propertyPath:"fov",propertyType:w.Number,group:"Camera",help:"Camera field of view in degrees.",range:[1,179],precision:1,stepSize:.1,defaultValue:{type:w.Number,value:60}}];const I=new Map(h.map(e=>[e.type,e])),D=new Map(g.map(e=>[e.type,e]));export function getSequenceTrackDefinitions(){return h}export function getSequenceSubTrackDefinitions(){return g}export function getSequenceTrackDefinition(e){return I.get(e)}export function getSequenceSubTrackDefinition(e){return D.get(e)}export function getEditorSequenceTrackDefinitions(){return h.filter(e=>!1!==e.exposedInEditor)}export function getEditorSequenceSubTrackDefinitions(e){return g.filter(r=>!1!==r.exposedInEditor&&r.supportedTrackTypes.some(r=>r===e.type))}export function canTrackAddSubTrack(e,r,a){if(e.locked)return!1;const t=getSequenceSubTrackDefinition(r);if(!t.supportedTrackTypes.some(r=>r===e.type))return!1;if("audioParameter"===r)return!!a?.parameter&&!e.subTracks.some(e=>"audioParameter"===e.type&&e.parameter===a.parameter);if("property"===r){const r=a?.property?.propertyPath??a?.propertyPath;return!!r&&!e.subTracks.some(e=>"property"===e.type&&e.propertyPath===r)}if("material"===r){const r=a?.material;return!!r?.parameterName&&(!("asset"===P(r)&&!r.materialAssetId)&&!e.subTracks.some(e=>"material"===e.type&&function(e,r){if(e.parameterName!==r.parameterName)return!1;const a=P(e),t=P(r);if("parameterName"===a||"parameterName"===t)return!0;return e.materialAssetId===r.materialAssetId}(e,r)))}return!!t.allowMultiple||!e.subTracks.some(e=>e.type===r)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -353,6 +353,8 @@ export declare class SequencePlayer implements SequenceLocatorReader {
353
353
  private stopAllAudio;
354
354
  private evaluateVfxTrack;
355
355
  private getVfxClipKey;
356
+ private isVfxClipActiveAtTime;
357
+ private resetVfxForTimeReset;
356
358
  private applyInactiveVfxClipBehavior;
357
359
  /**
358
360
  * Ensure VFX actor exists for a clip (create if needed, reuse if exists)
@@ -1,4 +1,4 @@
1
- import{BehaviorSubject as e,Subject as t}from"rxjs";import*as a from"three";import{AnimationMixer as s,Color as r,Euler as i,Object3D as n,Quaternion as o,Vector2 as l,Vector3 as c,Vector4 as h}from"three";import{VisualEffect as u}from"../../effects/vfx/vfx-param.js";import{BaseActor as p}from"../../gameplay/actors/actor.js";import d from"../../gameplay/actors/builtin/index.js";import{Prefab as f,PrefabOf as m}from"../../scene/objects/prefab.js";import{SerializedParamType as y}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as C,deserializeCustomParamValue as g,deserializeCustomParamValueSync as v}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as A}from"./audio-parameters.js";import{Sequence as S}from"./sequence-data.js";import{getSequenceSubTrackDefinition as w,getSequenceTrackDefinition as P}from"./sequence-definitions.js";import{applyInterpolation as b,evaluateCustomParamValueKeyframes as k,evaluateNumericKeyframes as x,findKeyframeSpan as T}from"./sequence-value-lane.js";import{buildRetimedAnimationClip as I,getAnimationClipRetimingSignature as B,isAnimationClipUsingRetiming as M}from"./sequence-animation-retiming.js";import{SkeletonUtils as q}from"three-stdlib";import{CharacterAnimationComponent as O,CharacterMovementComponent as F}from"../../gameplay/actors/index.js";import{RootMotionClip as E}from"../../gameplay/animation/root-motion.js";import{hashCameraShakeSeed as j}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as L,shaderGraphPostProcessWeightUniformName as _}from"../../shader/graph/index.js";export var SequencePlaybackState;!function(e){e.Stopped="stopped",e.Playing="playing",e.Paused="paused"}(SequencePlaybackState||(SequencePlaybackState={}));export class SequencePlayer{constructor(){this._state=new e(SequencePlaybackState.Stopped),this._time=new e(0),this._duration=0,this._timescale=1,this._loop=!1,this._externalTimeControl=!1,this._inEditor=!1,this.bindings=new Map,this.roleBindings=new Map,this.sequenceData=null,this.onComplete=new t,this.onLoop=new t,this.onTimeUpdate=this._time.asObservable(),this.onStateChange=this._state.asObservable(),this.loopCount=0,this.viewController=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.sequenceCameras=new Map,this.cameraPlayables=new Map,this.cameraBlendCamera=null,this.cameraBlendSource=null,this.cameraBlendOutSource=null,this.cameraOverrideHandle=null,this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null,this.activeCameraShakeClipKeys=new Set,this.nextCameraShakeClipKeys=new Set,this.activePostProcessClips=new Map,this.nextPostProcessClipKeys=new Set,this.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,this.audioByClip=new Map,this.activeAudioClips=new Set,this.audioGainNodes=new Map,this.audioStartInFlight=new Map,this.lastAudioStartAttemptTime=new Map,this.audioStartRetryIntervalSeconds=.25,this.world=null,this.assetLoader=null,this.actorFactory=null,this.vfxService=null,this.spawnedInstances=new Map,this.activeClips=new Set,this.pendingSpawns=new Set,this.vfxActors=new Map,this.activeVfxClips=new Set,this.locatorMarkers=new Map,this.clearCounter=0,this.propertyPathSegments=new Map,this.propertyResolutionCache=new Map,this.propertySnapshots=new Map,this.materialResolutionCache=new Map,this.materialSnapshots=new Map,this.audioFilters=new Map,this.audioPannerNodes=new Map,this.firedEvents=new Set,this.sequenceEventSyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e)},this.sequenceEventAsyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e),texture:e=>this.assetLoader?.getTextureByAssetId(e)??null,sampler2DNode:e=>this.assetLoader?.getTextureByAssetId(e)??null,object3D:async e=>{const t=await(this.assetLoader?.getModelByAssetId(e));return t?.scene??null},material:e=>this.assetLoader?.getMaterialByAssetId(e)??null,audioBuffer:e=>this.assetLoader?.getAudioByAssetId(e)??null,visualEffect:async e=>{if(!this.assetLoader||!this.actorFactory)return null;const t=await this.assetLoader.getAsset(e);return t?new u(this.actorFactory,t):null},prefab:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new f(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(new f(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,a)=>{t&&this.evaluateObjectTrack(e,t,a)},locator:(e,t,a)=>{t&&this.evaluateLocatorTrack(e,t,a)},camera:(e,t,a)=>this.evaluateCameraTrack(e,a),cameraShake:(e,t,a)=>this.evaluateCameraShakeTrack(e,a),postProcess:(e,t,a)=>this.evaluatePostProcessTrack(e,a),audio:(e,t,a)=>this.evaluateAudioTrack(e,a),vfx:(e,t,a)=>this.evaluateVfxTrack(e,a),spawn:(e,t,a)=>this.evaluateSpawnTrack(e,t,a),group:(e,t,a)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,a)}},this.subTrackRuntimeEvaluators={transform:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateTransformSubTrack(e,s,a)},animation:(e,t,a)=>this.evaluateAnimationSubTrack(e,t,a),visibility:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateVisibilitySubTrack(e,s,a)},parameter:(e,t,a)=>this.evaluateParameterSubTrack(e,t.target||null,a),event:(e,t,a)=>this.evaluateEventSubTrack(e,t.target||null,a)}}get state(){return this._state.value}get time(){return this._time.value}get duration(){return this._duration}get timescale(){return this._timescale}set timescale(e){this._timescale=Math.max(.01,e)}get loop(){return this._loop}set loop(e){this._loop=e}get externalTimeControl(){return this._externalTimeControl}set externalTimeControl(e){this._externalTimeControl=e}get inEditor(){return this._inEditor}set inEditor(e){this._inEditor=e,this.updateLocatorMarkerVisibility()}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,e||this.releaseCameraOverride()}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId!==e&&(this._cameraControlTrackId=e,this.releaseCameraOverride())}setViewController(e){this.viewController&&this.viewController!==e&&this.viewController.clearCameraShakeContributionsForOwner(this),this.viewController=e}setWorld(e){this.world!==e&&(this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.world=e,this.clearCounter++,this.vfxActors.clear(),this.spawnedInstances.clear(),this.bindings.clear(),this.activeClips.clear(),this.activeVfxClips.clear(),this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear(),this.loadingAudioBuffers.clear(),this.audioFilters.clear(),this.audioPannerNodes.clear(),this.pendingSpawns.clear(),this.propertyResolutionCache.clear(),this.materialResolutionCache.clear(),this.clearRetimedAnimationClipCache(),this._state.next(SequencePlaybackState.Stopped),this.sequenceData&&this.initializeLocatorBindings())}setAudioListener(e){this.audioListener=e}setAssetLoader(e){if(this.assetLoader=e,this.sequenceData){const e=this.clearCounter;this.preloadSequenceResources(this.sequenceData,e)}}setActorFactory(e){this.actorFactory=e}setVfxService(e){this.vfxService=e}load(e){if(this.stop(),this.clearCounter++,this.clearLocatorBindings(),this.clearSequenceCameras(),this.sequenceData=e,this._duration=e.duration,this._loop=e.loop,this._timescale=e.playbackRate,this.clearRetimedAnimationClipCache(),this.bindings.clear(),this.initializeLocatorBindings(),this.loopCount=0,this.assetLoader){const t=this.clearCounter;this.preloadSequenceResources(e,t)}}preloadSequenceResources(e,t){return Promise.all([this.preloadAudioBuffersForSequence(e,t),this.preloadAnimationClipsForSequence(e,t)]).then(()=>{})}getAudioAssetIdsForSequence(e){const t=new Set;for(const a of e.tracks){if("audio"!==a.type)continue;const e=a;for(const a of e.clips??[])a.audioAssetId&&t.add(a.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const a=this.getAudioAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let a=this.loadingAudioBuffers.get(e);a||(a=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,a));try{const s=await a;if(t!==this.clearCounter)return;this.audioBuffers.set(e,s)}catch(e){}finally{this.loadingAudioBuffers.get(e)===a&&this.loadingAudioBuffers.delete(e)}}))}getAnimationClipAssetIdsForSequence(e){const t=new Set;for(const a of z(e.tracks))if("subTracks"in a)for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips)a.animationClipAssetId&&t.add(a.animationClipAssetId);return[...t]}async preloadAnimationClipsForSequence(e,t){if(!this.assetLoader)return;const a=this.getAnimationClipAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{t===this.clearCounter&&await this.ensureAnimationClip(e)}))}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const a of this.sequenceData.tracks)"object"===a.type&&a.targetId===e&&this.createBinding(a,t)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=H(e);if(!t||!this.sequenceData)return[];const a=[];for(const e of z(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(H(e.bindingId)!==t)continue;const s=this.bindings.get(e.id),r=s?this.getPlayableObject(s):null;r&&(r.updateWorldMatrix(!0,!1),a.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:r.getWorldPosition(new c),rotation:r.getWorldQuaternion(new o),scale:r.getWorldScale(new c)}))}return a}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of z(this.sequenceData.tracks)){if("locator"!==e.type||this.bindings.has(e.id))continue;const t=new n;t.name=e.name||"Locator",t.userData.sequenceLocatorTrackId=e.id,this.world?.scene&&null==t.parent&&this.world.scene.add(t);const a=J(e.name);a.visible=this._inEditor,t.add(a),this.locatorMarkers.set(e.id,a),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())ee(e);for(const e of this.bindings.values()){if("locator"!==e.track.type)continue;const t=this.getPlayableObject(e);t?.parent&&t.removeFromParent()}this.locatorMarkers.clear()}updateLocatorMarkerVisibility(){for(const e of this.locatorMarkers.values())e.visible=this._inEditor}disableLocatorInteraction(e){e.traverse(e=>{e.raycast=()=>{}})}resolveTrackBinding(e){if("object"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("spawn"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("group"===e.type)for(const t of e.childTracks)this.resolveTrackBinding(t)}createBinding(e,t){const a=t instanceof p?t.object:t,r=this.bindings.get(e.id),i=null!=r?r.target instanceof p?r.target.object:r.target:null,n=null!=r&&r.target===t&&i===a,o=e.subTracks.some(e=>"animation"===e.type);if(null!=r&&!n){for(const e of r.activeActions.values())e.stop();r.activeActions.clear(),r.mixer?.stopAllAction(),r.charAnimComponent?.stopSequenceAnimation(),r.charAnimComponent=void 0,r.charAnimActionKeys?.clear()}const l=n?r:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,l.originalTransform={position:a.position.clone(),rotation:a.rotation.clone(),scale:a.scale.clone()},l.originalParent=a.parent,o&&null==l.mixer?l.mixer=new s(a):o||(l.mixer=void 0),this.bindings.set(e.id,l)}play(){this._state.value!==SequencePlaybackState.Playing&&this.sequenceData&&(this._state.value===SequencePlaybackState.Stopped&&(this._time.next(0),this.loopCount=0,this.resolveBindings(),this.captureOriginalTransforms()),this._state.next(SequencePlaybackState.Playing),this.evaluate(this._time.value),this.resumeVfx())}pause(){this._state.value===SequencePlaybackState.Playing&&(this._state.next(SequencePlaybackState.Paused),this.pauseAudio(),this.pauseVfx())}pauseAudio(){for(const e of this.audioByClip.values())e.pause()}pauseVfx(){for(const e of this.vfxActors.values())e.pause()}resumeVfx(){for(const[e,t]of this.vfxActors.entries())(this.activeVfxClips.has(e)||t.getParticleCount()>0)&&t.play()}cancel(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}restart(){this.stop(),this.play()}seek(e){const t=Math.max(0,Math.min(e,this._duration));this._time.next(t),this.evaluate(t)}update(e){if(this._state.value!==SequencePlaybackState.Playing)return;if(!this.sequenceData)return;if(this._externalTimeControl){for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale);return}const t=this._time.value+e*this._timescale;if(t>=this._duration){if(!this._loop)return this._time.next(this._duration),this.evaluate(this._duration),this.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this._state.next(SequencePlaybackState.Stopped),void this.onComplete.next();this.loopCount++,this._time.next(t%this._duration),this.firedEvents.clear(),this.onLoop.next(this.loopCount)}else this._time.next(t);this.evaluate(this._time.value);for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale)}evaluate(e){if(this.sequenceData){this.nextCameraShakeClipKeys.clear(),this.nextPostProcessClipKeys.clear();for(const t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===t.type||"spawn"===t.type||"vfx"===t.type)){const e=this.bindings.get(t.id);this.updateTrackParenting(t,e)}this.evaluateTrack(t,e)}this.updateCameraControl(e),this.syncCameraShakeContributions(),this.syncPostProcessEffects()}}evaluateTrack(e,t){if(e.muted)return;const a=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[P(e.type).runtimeEvaluator])(e,a,t)}evaluateObjectTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}evaluateLocatorTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=z(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,a){for(const s of e){if(s.muted)continue;(0,this.subTrackRuntimeEvaluators[w(s.type).runtimeEvaluator])(s,t,a)}}evaluateTransformSubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;const{prev:r,next:i,t:n}=T(s,a);if(r)if(i&&r!==i){const a=b(n,r.interpolation);e.components.position&&r.position&&i.position&&t.position.lerpVectors(te.fromArray(r.position),ae.fromArray(i.position),a),e.components.rotation&&r.rotation&&i.rotation&&(re.setFromEuler(ne.fromArray([...r.rotation,"XYZ"])),ie.setFromEuler(oe.fromArray([...i.rotation,"XYZ"])),t.quaternion.slerpQuaternions(re,ie,a)),e.components.scale&&r.scale&&i.scale&&t.scale.lerpVectors(te.fromArray(r.scale),ae.fromArray(i.scale),a)}else e.components.position&&r.position&&t.position.fromArray(r.position),e.components.rotation&&r.rotation&&t.rotation.fromArray([...r.rotation,"XYZ"]),e.components.scale&&r.scale&&t.scale.fromArray(r.scale)}evaluateAnimationSubTrack(e,t,s){if(!t.mixer||!t.activeActions)return;if(t.target instanceof p?t.target.object:t.target)for(const r of e.clips){const i=r.startTime+r.duration,n=s>=r.startTime&&s<i,o=`${e.id}-${r.id}`;let l=t.activeActions.get(o),c=!1;if(n){if(!l){c=!0;const e=r.animationClipAssetId;if(null==e)continue;const s=this.animationClips.get(e);if(null==s){this.ensureAnimationClip(e);continue}const i=this.prepareAnimationPlayback(e,s,r),n=t;let h=!1;if(t.target instanceof p){n.charAnimComponent||(n.charAnimComponent=t.target.getComponent(O)??void 0);const a=n.charAnimComponent;if(null!=a){const c=r.rootMotion?M(r)?this.getPlayableAnimationClip(e,s,r,!0):E.fromClip(i.clip,!1):i.clip;if(this._externalTimeControl)l=a.beginExternalAnimationControl(c,{timeScale:i.timeScale});else if(a.play(c,{inPlace:!r.rootMotion,loop:!1,priority:20,timeScale:i.timeScale,fadeTime:r.fadeInDuration??.2,offset:i.startOffset}),l=a.getFullBodyAction(),r.rootMotion){const e=t.target.getComponent(F);e&&e.setRootMotionAction(l,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(o,l),n.charAnimActionKeys||(n.charAnimActionKeys=new Set),n.charAnimActionKeys.add(o),h=!0}}h||(l=t.mixer.clipAction(i.clip),l.setLoop(a.LoopOnce,1),l.clampWhenFinished=!0,l.timeScale=i.timeScale,i.startOffset>0&&(l.time=i.startOffset),t.activeActions.set(o,l),l.play())}if(l){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const a=this.getAnimationPlaybackLocalTime(r,s),i=Math.min(a,l.getClip().duration);(c||Math.abs(l.time-i)>.001)&&(l.time=i,l.paused=!1,l.play(),e.charAnimComponent?e.charAnimComponent.getMixer()?.update(0):t.mixer&&t.mixer.update(0))}else e.charAnimComponent?.endExternalControl()}}else if(l){t.activeActions.delete(o);const e=t;e.charAnimActionKeys?.has(o)?(e.charAnimActionKeys.delete(o),l.stop(),0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0)):(l.stop(),this._externalTimeControl&&t.mixer&&t.mixer.update(0))}}}evaluateVisibilitySubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;let r=s[0];for(const e of s){if(!(e.time<=a))break;r=e}t.visible=r.visible}evaluatePropertySubTrack(e,t,a){const s=k(e.keyframes,a,{min:e.range?.[0],max:e.range?.[1],stepOnly:R(e)});s&&this.applyResolvedPropertyValue(e,t,s)}evaluateParameterSubTrack(e,t,a){if("audioParameter"===e.type)return;const s=k(e.keyframes,a,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:R(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)}:{});s&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,s):this.applyResolvedPropertyValue(e,t,s))}evaluateEventSubTrack(e,t,a){if(t instanceof p&&this._state.value===SequencePlaybackState.Playing)for(const s of e.events){const r=`${e.id}-${s.id}`;if(a>=s.time&&!this.firedEvents.has(r)){if(this.firedEvents.add(r),s.editorOnly&&!this._inEditor)continue;if(!s.functionName)continue;const e=t[s.functionName];"function"==typeof e?this.invokeSequenceEvent(t,s.functionName,e,s.arguments??[]):console.warn(`Sequence event method '${s.functionName}' not found on actor`)}else s.time>a&&this.firedEvents.delete(r)}}evaluateCameraTrack(e,t){const a=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,a),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,a),t),a.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const a of e.clips??[]){if(!this.isCameraShakeClipActive(a,t))continue;const e=t-a.startTime,s=a.id;this.nextCameraShakeClipKeys.add(s),this.viewController.setCameraShakeContribution(this,s,a,e,a.seed??j(a.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader)for(const a of e.clips??[]){if(!this.isPostProcessClipActive(a,t))continue;const s=this.getPostProcessClipKey(e,a);this.nextPostProcessClipKeys.add(s),this.ensurePostProcessClipEffect(e,a,s);const r=this.activePostProcessClips.get(s);r?.handle&&(r.handle.stage=e.stage,r.handle.priority=e.priority,r.handle.enabled=!0,this.applyPostProcessClipWeight(r.handle,a,t))}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,a){const s=t.shaderGraphAssetId;if(!s)return void this.releasePostProcessClipEffect(a);const r=JSON.stringify(t.shaderGraphParams??{}),i=this.activePostProcessClips.get(a);if(i?.assetId===s&&i.paramsSignature===r)return;this.releasePostProcessClipEffect(a);const n={key:a,trackId:e.id,clipId:t.id,assetId:s,paramsSignature:r,version:this.clearCounter};this.activePostProcessClips.set(a,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,a){if(this.assetLoader&&this.viewController)try{const s=await this.assetLoader.getShaderGraphByAssetId(a.assetId);if(!this.isPostProcessClipEntryCurrent(a))return;if("postProcess"!==s.target)return console.warn(`Sequence post-process clip references shader graph "${a.assetId}" with target "${s.target}"`),void this.releasePostProcessClipEffect(a.key);const r=await this.assetLoader.prepareShaderGraphParameters(s,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(a))return;const i=L(s,{parameters:r});if(!this.isPostProcessClipEntryCurrent(a))return void i.dispose();a.handle=this.viewController.addPostProcessEffect(i,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(a.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(a)&&this.releasePostProcessClipEffect(a.key),console.error(`Failed to create post-process effect for clip ${t.id}:`,e)}}isPostProcessClipEntryCurrent(e){return this.clearCounter===e.version&&this.activePostProcessClips.get(e.key)===e}applyPostProcessClipWeight(e,t,a){const s=e.material.uniforms?.[_];null!=s&&(s.value=this.getPostProcessClipWeight(t,a),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const a=Math.max(0,t-e.startTime),s=Math.max(0,e.startTime+e.duration-t);let r=1;const i=Math.max(0,e.fadeInDuration??0);i>0&&(r=Math.min(r,a/i));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(r=Math.min(r,s/n)),Math.max(0,Math.min(1,r))}syncPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.nextPostProcessClipKeys.has(e)||this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}clearPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}releasePostProcessClipEffect(e){const t=this.activePostProcessClips.get(e);if(t&&(this.activePostProcessClips.delete(e),t.handle)){const e=t.handle.material;t.handle.dispose(),e.dispose()}}getCameraPlayable(e,t){let a=this.cameraPlayables.get(e.id);return a?a.target=t:(a={target:t},this.cameraPlayables.set(e.id,a)),a}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new a.PerspectiveCamera(s.fov??60,this.getCurrentCameraAspect(),s.near??.1,s.far??1e3),t.name=e.name||"Sequence Camera",t.userData.sequenceCameraTrackId=e.id,t.layers.mask=this.viewController?.getBaseCamera().layers.mask??t.layers.mask,this.sequenceCameras.set(e.id,t),this.world?.scene.add(t)}return t}clearSequenceCameras(){this.releaseCameraOverride();for(const e of this.sequenceCameras.values())e.removeFromParent();this.sequenceCameras.clear(),this.cameraPlayables.clear()}applyCameraTrackSettings(e,t){const a=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=a.fov??60,t.near=a.near??.1,t.far=a.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof a.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof a.PerspectiveCamera&&Number.isFinite(t.aspect)&&t.aspect>0?t.aspect:1}updateCameraControl(e){if(!this._cameraControlEnabled||!this.viewController||!this.sequenceData)return void this.releaseCameraOverride();const t=this.findActiveCameraShot(e);if(t)return void this.updateActiveCameraShot(t,e);const a=this.findBlendOutCameraShot(e);a?this.updateCameraBlendOut(a,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of z(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s)this.isCameraClipActive(r,e)&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of z(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s){const s=Math.max(0,r.blendOutDuration??0);if(s<=0)continue;const i=this.getCameraClipEnd(r);e>=i&&e<i+s&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const s=Math.max(0,e.clip.blendInDuration??0),r=s<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/s,e.clip);r>=1?this.copyCameraState(e.camera,a):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,a,r),a.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();if(this.cameraBlendOutClipKey!==e.key){const t=this.activeCameraClipKey===e.key?this.viewController.getSourceCamera():e.camera;this.copyCameraState(t,this.ensureCameraBlendOutSource()),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=e.key}const s=this.getCameraClipEnd(e.clip),r=Math.max(0,e.clip.blendOutDuration??0),i=r<=0?1:this.evaluateCameraBlendAlpha((t-s)/r,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),a,i),a.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new a.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new a.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new a.PerspectiveCamera),this.cameraBlendOutSource}ensureCameraOverride(){this.viewController&&!this.cameraOverrideHandle&&(this.cameraOverrideHandle=this.viewController.pushCameraOverride(this.ensureCameraBlendCamera(),this))}releaseCameraOverride(){this.cameraOverrideHandle?.release(),this.cameraOverrideHandle=null,this.viewController?.releaseCameraOverridesForOwner(this),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null}isCameraClipActive(e,t){return t>=e.startTime&&t<this.getCameraClipEnd(e)}getCameraClipEnd(e){return e.startTime+Math.max(0,e.duration)}isCameraShakeClipActive(e,t){return t>=e.startTime&&t<this.getCameraShakeClipEnd(e)}getCameraShakeClipEnd(e){return e.startTime+Math.max(0,e.duration)}getCameraClipKey(e,t){return`${e.id}-${t.id}`}evaluateCameraBlendAlpha(e,t){return b(Math.max(0,Math.min(1,e)),t.blendInterpolation??"cubic")}syncCameraShakeContributions(){if(!this.viewController)return this.activeCameraShakeClipKeys.clear(),void this.nextCameraShakeClipKeys.clear();for(const e of this.activeCameraShakeClipKeys)this.nextCameraShakeClipKeys.has(e)||this.viewController.removeCameraShakeContribution(this,e);this.activeCameraShakeClipKeys.clear();for(const e of this.nextCameraShakeClipKeys)this.activeCameraShakeClipKeys.add(e);this.nextCameraShakeClipKeys.clear()}clearCameraShakeContributions(){this.activeCameraShakeClipKeys.clear(),this.nextCameraShakeClipKeys.clear(),this.viewController?.clearCameraShakeContributionsForOwner(this)}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(te)),t.quaternion.copy(e.getWorldQuaternion(re)),t.scale.copy(e.getWorldScale(ae)),e instanceof a.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect):t.aspect=this.getCurrentCameraAspect(),t.layers.mask=e.layers.mask}blendCameraState(e,t,s,r){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),s.position.lerpVectors(e.getWorldPosition(te),t.getWorldPosition(ae),r),s.quaternion.slerpQuaternions(e.getWorldQuaternion(re),t.getWorldQuaternion(ie),r),s.scale.lerpVectors(e.getWorldScale(te),t.getWorldScale(ae),r),e instanceof a.PerspectiveCamera&&t instanceof a.PerspectiveCamera?(s.fov=e.fov+(t.fov-e.fov)*r,s.near=e.near+(t.near-e.near)*r,s.far=e.far+(t.far-e.far)*r,s.aspect=t.aspect):t instanceof a.PerspectiveCamera?(s.fov=t.fov,s.near=t.near,s.far=t.far,s.aspect=t.aspect):s.aspect=this.getCurrentCameraAspect(),s.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const a=this._state.value===SequencePlaybackState.Playing,s=this.evaluateAudioSubTracks(e,t);e.volume;for(const r of e.clips){const i=r.startTime+r.duration,n=t>=r.startTime&&t<i,o=`${e.id}-${r.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),a){const a=this.audioByClip.get(o);a&&a.isPlaying||this.tryStartAudioClip(e,r,o,t,s)}const i=this.audioByClip.get(o);i&&this.applyAudioParameters(i,e,r,o,t,s)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,a,s,r){if(this.audioStartInFlight.has(a))return;const i=this.lastAudioStartAttemptTime.get(a);if(void 0!==i&&s-i<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(a,s);const n=this.playAudioClip(e,t,a,s,r).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(a)===n&&this.audioStartInFlight.delete(a)});this.audioStartInFlight.set(a,n)}applyAudioParameters(e,t,s,r,i,n){const o=n.volume??1,l=this.stringToRandom(r+t.id),c=s.volumeRandomization?(2*l-1)*s.volumeRandomization:0;let h=1;const u=i-s.startTime;u<s.fadeInDuration&&s.fadeInDuration>0?h=u/s.fadeInDuration:u>s.duration-s.fadeOutDuration&&s.fadeOutDuration>0&&(h=(s.duration-u)/s.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(s.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(s.pitchRandomization){d+=(2*this.stringToRandom(r+"_pitch")-1)*s.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(s.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const s=this.audioListener.context,i=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(r);if(void 0!==o||void 0!==l)c||(c=s.createBiquadFilter(),this.audioFilters.set(r,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),i.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(r)}const h=n.pan;if(!t.spatial&&e instanceof a.Audio&&void 0!==h&&"function"==typeof s.createStereoPanner){let e=this.audioPannerNodes.get(r);e||(e=s.createStereoPanner(),this.audioPannerNodes.set(r,e)),e.pan.value=h,i.push(e)}else{const e=this.audioPannerNodes.get(r);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(r)}}e.setFilters(i)}t.spatial&&e instanceof a.PositionalAudio?this.updatePositionalAudioTransform(e,t,s,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,s,r){let i=null,n=null;const o=s.attachedToTrackId||t.parent?.trackId,l=s.attachmentSocketName||t.parent?.socketName;if(o){const e=this.sequenceData?.tracks.find(e=>e.id===o);if(e){const t=this.getActiveObjectsForTrack(e);if(t.length>0){const e=t[0];if(i=te,n=re,e.getWorldPosition(i),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(i),t.getWorldQuaternion(n))}}}}if(i&&n){const t="number"==typeof r?a.MathUtils.clamp(r,0,1):1;if(t<1&&this.audioListener){const e=se;this.audioListener.getWorldPosition(e),i=i.clone().lerp(e,1-t)}e.position.copy(i),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,s,r,i){if(!this.assetLoader||!t.audioAssetId||null==this.audioListener)return;if("suspended"===this.audioListener.context.state)try{await this.audioListener.context.resume()}catch(e){return void console.warn("Failed to resume audio context:",e)}this.stopAudioClip(s);const n=this.clearCounter;try{let r=this.audioBuffers.get(t.audioAssetId);if(!r){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{r=await e,this.audioBuffers.set(t.audioAssetId,r)}finally{this.loadingAudioBuffers.delete(t.audioAssetId)}}if(n!==this.clearCounter)return;const o=this._time.value,l=t.startTime+t.duration;if(!(o>=t.startTime&&o<l))return;const c=Math.max(0,o-t.startTime),h=t.clipStartOffset+c*t.playbackRate;if(h>=r.duration||c>=t.duration)return;let u=this.audioByClip.get(s);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(s),u=void 0),!u){if(p){const e=new a.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new a.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(s,u)}Math.min((t.duration-c)/t.playbackRate,(r.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,r.duration)),u.setLoop(!0),u.setBuffer(r),this.applyAudioParameters(u,e,t,s,o,i),u.isPlaying||u.play()}catch(e){console.error(`Failed to play audio clip ${t.id}:`,e)}}stopAudioClip(e){const t=this.audioByClip.get(e);if(t){try{t.isPlaying&&t.stop()}catch(e){}t.parent&&t.parent.remove(t),this.audioByClip.delete(e)}const a=this.audioGainNodes.get(e);a&&(a.disconnect(),this.audioGainNodes.delete(e));const s=this.audioFilters.get(e);if(s){try{s.disconnect()}catch{}this.audioFilters.delete(e)}const r=this.audioPannerNodes.get(e);if(r){try{r.disconnect()}catch{}this.audioPannerNodes.delete(e)}}stopAllAudio(){for(const e of this.audioByClip.keys())this.stopAudioClip(e);this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear()}evaluateVfxTrack(e,t){if(!this.vfxService||!this.world||!e.clips||0===e.clips.length)return;const a=new Set,s=new Map;for(const r of e.clips){const i=this.getVfxClipKey(e,r);s.set(i,r);const n=r.startTime+r.duration;t>=r.startTime&&t<n&&a.add(i)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(a.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[r,i]of s.entries()){const s=this.vfxActors.get(r);a.has(r)&&!this.activeVfxClips.has(r)?(this.activeVfxClips.add(r),this.ensureVfxActor(e,i,r)):a.has(r)&&s?(this.updateVfxTransform(e,s,t),this._state.value===SequencePlaybackState.Playing&&s.play()):s&&this.applyInactiveVfxClipBehavior(i,s,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}applyInactiveVfxClipBehavior(e,t,a){const s=e.endBehavior??"finish";if("finish"===s)return void t.stop();if("kill"===s)return void t.applyClipEndBehavior(s);const r=e.startTime+e.duration,i=Math.max(a-r,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-i);t.applyClipEndBehavior(s,o)}async ensureVfxActor(e,t,a){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(a)){const e=this.vfxActors.get(a);return e.restart(),void e.play()}const s=this.clearCounter;try{const r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene);if(s!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:i,rotation:n,scale:o}=this.getVfxTransform(e,t.startTime);r.object.position.copy(i),r.object.rotation.copy(n),r.object.scale.copy(o),this.vfxActors.set(a,r),this._state.value===SequencePlaybackState.Playing&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const a=new c,s=new i,r=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:i,t:l}=T(n.keyframes,t);if(e&&(e.position&&a.fromArray(e.position),e.rotation&&s.fromArray([...e.rotation,"XYZ"]),e.scale&&r.fromArray(e.scale)),i&&e!==i&&e.time!==i.time){const t=b(l,e.interpolation);if(e.position&&i.position&&a.lerpVectors(te.fromArray(e.position),ae.fromArray(i.position),t),e.rotation&&i.rotation){re.setFromEuler(ne.fromArray([...e.rotation,"XYZ"])),ie.setFromEuler(oe.fromArray([...i.rotation,"XYZ"]));const a=new o;a.slerpQuaternions(re,ie,t),s.setFromQuaternion(a)}e.scale&&i.scale&&r.lerpVectors(te.fromArray(e.scale),ae.fromArray(i.scale),t)}}else a.fromArray(e.position),s.fromArray([...e.rotation,"XYZ"]),r.fromArray(e.scale);return{position:a,rotation:s,scale:r}}updateVfxTransform(e,t,a){const{position:s,rotation:r,scale:i}=this.getVfxTransform(e,a);t.object.position.copy(s),t.object.rotation.copy(r),t.object.scale.copy(i)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const a=d[e];return a||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,a,s){if(!this.world||!e.actorType)return null;const r=this.resolveActorType(e.actorType);if(!r)return null;try{return await this.world.spawnActor(r,a,s)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.prefabId)return null;try{const t=await this.assetLoader.getPrefabById(e.prefabId);if(!t)return null;return await this.world.spawnPrefab(t,a,s)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),r=await this.assetLoader.getModelByAssetId(e.meshId),i=q.clone(r.scene);if(i.position.copy(a),i.rotation.copy(s),t){await this.assetLoader.applyMaterials(t,i);const e=t.mesh?.rescale;null!=e&&1!==e&&i.scale.multiplyScalar(e)}return this.world.scene.add(i),i}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(this.restorePropertySnapshotsForInstance(e),this.restoreMaterialSnapshotsForInstance(e),this.world)switch(e?.type){case"actor":this.world.removeActor(e.instance);break;case"prefab":this.world.removePrefab(e.instance);break;case"mesh":this.world.scene.remove(e.instance)}}despawnAll(){for(const e of this.spawnedInstances.values())this.despawnInstance(e);this.spawnedInstances.clear(),this.activeClips.clear(),this.pendingSpawns.clear()}getInitialTransform(e,t,a){const s=new c,r=new i,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e}=T(n.keyframes,a);e&&(e.position&&s.fromArray(e.position),e.rotation&&r.fromArray([...e.rotation,"XYZ"]))}else t.initialPosition&&s.fromArray(t.initialPosition),t.initialRotation&&r.fromArray([...t.initialRotation,"XYZ"]);return{position:s,rotation:r}}evaluateSpawnTrack(e,t,a){if(!e.clips||0===e.clips.length)return;const s=t||this.bindings.get(e.id);if(s&&s.target)for(const t of e.clips){const r=t.startTime+t.duration,i=a>=t.startTime&&a<r,n=`${e.id}-${t.id}`;if(i){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:s.target}));(s.target instanceof p?s.target.object:s.target)&&this.evaluateSubTracks(e.subTracks,s,a)}else this.activeClips.has(n)&&(this.restorePropertySnapshotsForTarget(s.target),this.restoreMaterialSnapshotsForTarget(s.target),this.activeClips.delete(n),this.spawnedInstances.delete(n))}else for(const t of e.clips){const s=t.startTime+t.duration,r=a>=t.startTime&&a<s,i=`${e.id}-${t.id}`,n=this.spawnedInstances.has(i),o=this.pendingSpawns.has(i);if(!r||n||o){if(r&&n){const t=this.spawnedInstances.get(i);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,a)}else if(!r&&n){const e=this.spawnedInstances.get(i);e&&(this.despawnInstance(e),this.spawnedInstances.delete(i),this.activeClips.delete(i))}}else{const{position:a,rotation:s}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(i),this.spawnForClip(e,t,a,s,i)}}}getInstanceObject(e){switch(e.type){case"actor":return e.instance.object;case"prefab":return e.instance.mainActor?.object||e.instance.object;case"mesh":return e.instance;case"proxy":return e.target instanceof p?e.target.object:e.target;default:return null}}async spawnForClip(e,t,a,r,i){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const s=await this.spawnActorForClip(e,t,a,r);s&&(o={type:"actor",instance:s});break;case"prefab":const i=await this.spawnPrefabForClip(e,t,a,r);i&&(o={type:"prefab",instance:i});break;case"mesh":const n=await this.spawnMeshForClip(e,t,a,r);n&&(o={type:"mesh",instance:n})}if(n!==this.clearCounter)return void(o&&this.despawnInstance(o));const l=this._time.value,c=l>=t.startTime&&l<t.startTime+t.duration;if(o&&c){const t=this.getInstanceObject(o);"proxy"===o.type||("actor"===o.type?o.target=o.instance:"prefab"===o.type?o.target=o.instance.mainActor||o.instance.object:o.target=t);e.subTracks.some(e=>"animation"===e.type)&&t&&(o.mixer=new s(t),o.activeActions=new Map),this.spawnedInstances.set(i,o),this.activeClips.add(i)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(i)}}getPlayableObject(e){return e.target instanceof p?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,a){if(!t||!e.propertyPath)return;const s=this.getPropertyResolution(t,e);if(!s)return;const r=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,r,s);const n=function(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return $(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return N(e,t.value);case y.Euler:return function(e,t){const a=X(t,3);if(!a)return{applied:!1};const s=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof i)return e.set(a[0],a[1],a[2],s),{applied:!0,value:e};return{applied:!0,value:new i(a[0],a[1],a[2],s)}}(e,t.value);case y.Color:return W(e,t.value);default:return{applied:!1}}}(s.owner[s.key],a);n.applied&&(s.owner[s.key]=n.value)}getPropertyResolution(e,t){const a=e,s=this.getPropertySnapshotKey(t);let r=this.propertyResolutionCache.get(a);if(r||(r=new Map,this.propertyResolutionCache.set(a,r)),r.has(s))return r.get(s)??null;const i=this.getPropertyPathSegments(t.propertyPath);if(0===i.length)return r.set(s,null),null;let n=e;for(let e=0;e<i.length-1;e++){if(!D(n))return r.set(s,null),null;n=n[i[e]]}if(!D(n))return r.set(s,null),null;const o={owner:n,key:i[i.length-1]};return r.set(s,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const a=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,a),a}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,a){const s=e;let r=this.propertySnapshots.get(s);if(r||(r=new Map,this.propertySnapshots.set(s,r)),r.has(t))return;const i=a.owner[a.key];r.set(t,{resolution:a,hadOwnProperty:Object.prototype.hasOwnProperty.call(a.owner,a.key),value:i,valueSnapshot:Y(i)})}restorePropertySnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restorePropertySnapshotsForTarget(e.instance);break;case"prefab":this.restorePropertySnapshotsForTarget(e.target??null),this.restorePropertySnapshotsForTarget(e.instance.mainActor??null),this.restorePropertySnapshotsForTarget(e.instance.object);break;case"proxy":this.restorePropertySnapshotsForTarget(e.target)}}restorePropertySnapshotsForTarget(e){if(!e)return;const t=e,a=this.propertySnapshots.get(t);if(a){for(const e of a.values())Z(e);this.propertySnapshots.delete(t),this.propertyResolutionCache.delete(t)}}restoreAllPropertySnapshots(){for(const e of Array.from(this.propertySnapshots.keys()))this.restorePropertySnapshotsForTarget(e)}restoreMaterialSnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restoreMaterialSnapshotsForTarget(e.instance);break;case"prefab":this.restoreMaterialSnapshotsForTarget(e.target??null),this.restoreMaterialSnapshotsForTarget(e.instance.mainActor??null),this.restoreMaterialSnapshotsForTarget(e.instance.object);break;case"proxy":this.restoreMaterialSnapshotsForTarget(e.target)}}restoreMaterialSnapshotsForTarget(e){if(!e)return;const t=e;this.materialResolutionCache.delete(t);const a=this.materialSnapshots.get(t);if(a){for(const e of a.values())null==e.materialIndex?e.owner.material=e.originalMaterial:Array.isArray(e.owner.material)&&(e.owner.material[e.materialIndex]=e.originalMaterial),e.controlledMaterial!==e.originalMaterial&&e.controlledMaterial.dispose();this.materialSnapshots.delete(t)}}restoreAllMaterialSnapshots(){for(const e of Array.from(this.materialSnapshots.keys()))this.restoreMaterialSnapshotsForTarget(e)}applyResolvedMaterialValue(e,t,a){if(!t||!e.materialAssetId||!e.uniformName)return;const s=this.getMaterialSlotResolutions(t,e);for(const r of s){const s=this.ensureSequenceControlledMaterial(t,r),i=s.uniforms?.[e.uniformName];if(!i)continue;const n=K(i.value,a);n.applied&&(i.value=n.value,s.uniformsNeedUpdate=!0)}}getMaterialSlotResolutions(e,t){const a=e,s=`${t.id}:${t.materialAssetId}`;let r=this.materialResolutionCache.get(a);r||(r=new Map,this.materialResolutionCache.set(a,r));const i=r.get(s);if(i)return i;const n=e instanceof p?e.object:e,o=[];return n.traverse(e=>{const a=e.material;if(Array.isArray(a))for(let s=0;s<a.length;s++){const r=a[s];G(r,t)&&o.push({owner:e,materialIndex:s,material:r,key:`${e.uuid}:${s}`})}else G(a,t)&&o.push({owner:e,materialIndex:null,material:a,key:`${e.uuid}:material`})}),r.set(s,o),o}ensureSequenceControlledMaterial(e,t){const a=e;let s=this.materialSnapshots.get(a);s||(s=new Map,this.materialSnapshots.set(a,s));const r=s.get(t.key);if(r)return r.controlledMaterial;const i=t.material.clone();return null==t.materialIndex?t.owner.material=i:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=i),s.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:i}),i}async ensureAnimationClip(e){if(!this.assetLoader)return null;const t=this.animationClips.get(e);if(t)return t;const a=this.loadingAnimationClips.get(e);if(a)return a;const s=(async()=>{try{const t=await this.assetLoader.getAnimationClipByAssetId(e);return t&&this.animationClips.set(e,t),t}catch(t){return console.error(`Failed to load animation clip for asset ${e}:`,t),null}finally{this.loadingAnimationClips.get(e)===s&&this.loadingAnimationClips.delete(e)}})();return this.loadingAnimationClips.set(e,s),s}prepareAnimationPlayback(e,t,a){if(!M(a)){let e=t;return a.clipEndOffset>0&&(e=e.clone(),e.duration=Math.max(0,e.duration-a.clipEndOffset)),{clip:e,timeScale:a.playbackRate,startOffset:a.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,a,!1),timeScale:1,startOffset:0}}getPlayableAnimationClip(e,t,a,s){if(!M(a))return s?E.fromClip(t,!1):t;const r=`${a.id}:${s?"root":"base"}`,i=`${B(a)}|${s?"root":"base"}`,n=this.retimedAnimationClips.get(r);if(n&&n.assetId===e&&n.signature===i)return n.clip;const o=I(t,a),l=s?E.fromClip(o,!1):o;return this.retimedAnimationClips.set(r,{assetId:e,signature:i,clip:l}),l}getAnimationPlaybackLocalTime(e,t){const a=Math.max(0,t-e.startTime);return M(e)?a:a*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,a]of this.retimedAnimationClips.entries())a.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof p?e.target.object:e.target;t&&(e.originalTransform={position:t.position.clone(),rotation:t.rotation.clone(),scale:t.scale.clone()})}}restoreOriginalTransforms(){for(const e of this.bindings.values())if(e.originalTransform){const t=e.target instanceof p?e.target.object:e.target;t&&(t.position.copy(e.originalTransform.position),t.rotation.copy(e.originalTransform.rotation),t.scale.copy(e.originalTransform.scale))}}stopAllAnimations(){for(const e of this.bindings.values()){for(const t of e.activeActions.values())t.stop();e.activeActions.clear(),e.mixer&&e.mixer.stopAllAction(),e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0),e.charAnimActionKeys?.clear()}}stopAllVfx(){for(const e of this.vfxActors.values())e.paused||e.stop();this.activeVfxClips.clear()}dispose(){if(this.stop(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.bindings.clear(),this.roleBindings.clear(),this.sequenceData=null,this.world)for(const e of this.vfxActors.values())this.world.removeActor(e);this.vfxActors.clear(),this.stopAllAudio(),this.audioBuffers.clear(),this.loadingAudioBuffers.clear(),this.animationClips.clear(),this.loadingAnimationClips.clear(),this.clearRetimedAnimationClipCache(),this.audioByClip.clear()}updateTrackParenting(e,t){const a=this.getActiveObjectsForTrack(e);if(0===a.length)return;let s=null;const r=e.parent?.trackId;if(r){const t=this.sequenceData?z(this.sequenceData.tracks).find(e=>e.id===r):void 0;if(t){const a=this.getActiveObjectsForTrack(t);if(a.length>0&&(s=a[0],e.parent?.socketName)){const t=this.findSocket(s,e.parent.socketName);t&&(s=t)}}}if(!s&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const t=this.roleBindings.get(e.parentRole);if(s=t instanceof p?t.object:t,e.parentRoleSocketName){const t=this.findSocket(s,e.parentRoleSocketName);t&&(s=t)}}for(const r of a)s?r.parent!==s&&(s.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=s)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&this.world?.scene.add(r)}findSocket(e,t){if(e.name===t)return e;if(e instanceof a.SkinnedMesh){const a=e.skeleton.bones.find(e=>e.name===t);if(a)return a}return e.getObjectByName(t)||null}getActiveObjectsForTrack(e){if("object"===e.type){const t=this.bindings.get(e.id);if(t&&t.target)return[t.target instanceof p?t.target.object:t.target]}else if("locator"===e.type){const t=this.bindings.get(e.id);if(t&&t.target instanceof n)return[t.target]}else{if("camera"===e.type)return[this.ensureSequenceCamera(e)];if("spawn"===e.type){const t=[];for(const[a,s]of this.spawnedInstances)if(a.startsWith(e.id+"-")&&this.activeClips.has(a)){const e=this.getInstanceObject(s);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const a of this.activeVfxClips)if(a.startsWith(e.id+"-")){const e=this.vfxActors.get(a);e&&t.push(e.object)}return t}}return[]}restoreObjectParent(e,t){e.originalParent?e.originalParent.add(t):this.world&&this.world.scene.add(t),e.currentParent=void 0}restoreOriginalParents(){for(const e of this.bindings.values())if(e.currentParent){const t=e.target instanceof p?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const a={};for(const s of e.subTracks)if("audioParameter"===s.type){const e=s,r=A(e.parameter),i=x(e.keyframes,t,{min:r.min,max:r.max});void 0!==i&&(a[e.parameter]=i)}return a}stringToRandom(e){let t=0;for(let a=0;a<e.length;a++){t=(t<<5)-t+e.charCodeAt(a),t&=t}const a=1e4*Math.sin(t);return a-Math.floor(a)}async refreshAsset(e){let t=!1;this.assetLoader?.clearCacheById(e),this.animationClips.delete(e),this.loadingAnimationClips.delete(e),this.clearRetimedAnimationClipCache(e),this.vfxService?.clearPool(e),t=this.refreshVfxActorsForAssetIds(new Set([e]))||t;for(const[a,s]of this.activePostProcessClips.entries())s.assetId===e&&(this.releasePostProcessClipEffect(a),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const a=await this.getAssetOrNull(e);return"shaderGraph"===a?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[a,s]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(a,e)&&(this.world&&this.world.removeActor(s),this.vfxActors.delete(a),this.activeVfxClips.delete(a),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const a of t)if(e.endsWith(`-${a}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[a,s]of this.spawnedInstances.entries())e.has(a)&&(this.despawnInstance(s),this.spawnedInstances.delete(a),this.activeClips.delete(a),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const a of z(this.sequenceData.tracks))if("spawn"===a.type&&(a.prefabId===e||a.meshId===e))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const a=this.refreshVfxActorsForAssetIds(t),s=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return a||s}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of z(this.sequenceData.tracks))if("vfx"===s.type)for(const r of s.clips)null==r.vfxAssetId||t.has(r.vfxAssetId)||await this.assetUsesShaderGraph(r.vfxAssetId,e,a)&&t.add(r.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of z(this.sequenceData.tracks))if("spawn"===s.type&&await this.spawnTrackUsesShaderGraph(s,e,a))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,a){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,a))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,a))return!0;for(const s of e.subTracks??[])if("material"===s.type&&null!=s.materialAssetId&&await this.assetUsesShaderGraph(s.materialAssetId,t,a))return!0;return!1}assetUsesShaderGraph(e,t,a,s=new Set){if(e===t)return Promise.resolve(!0);if(s.has(e))return Promise.resolve(!1);if(a.has(e))return a.get(e);const r=this.assetUsesShaderGraphUncached(e,t,a,s);return a.set(e,r),r}async assetUsesShaderGraphUncached(e,t,a,s){if(s.has(e))return!1;const r=await this.getAssetOrNull(e);if(null==r)return!1;const i=new Set(s);return i.add(e),!!this.materialAssetUsesShaderGraph(r,t)||("mesh"===r.type?this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,i):"prefab"===r.type?this.sceneObjectsUseShaderGraph(r.prefab?.objects,t,a,i):"vfx"===r.type&&this.vfxAssetUsesShaderGraph(r,t,a,i))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,a,s){for(const r of e??[])if(null!=r.materialId&&"null"!==r.materialId&&await this.assetUsesShaderGraph(r.materialId,t,a,s))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,a,s){for(const r of e??[]){if(await this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,s))return!0;if(null!=r.assetId&&("asset_mesh"===r.type||"prefab"===r.type||"vfx"===r.type)&&await this.assetUsesShaderGraph(r.assetId,t,a,s))return!0;if(await this.sceneObjectsUseShaderGraph(r.children,t,a,s))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,a,s){for(const r of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterUsesShaderGraph(e,t,a,s){if(await this.emitterOutputUsesShaderGraph(e.output,t,a,s))return!0;for(const r of e.children??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,a,s){const r=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===r&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==r||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,a,s))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,a,s){let r=!1;for(let e=0;e<s.length;e++)if(C(s[e])){r=!0;break}if(r)try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=g(s[e],this.sequenceEventAsyncResolvers);const r=await Promise.all(t);await a.call(e,...r)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=v(s[e],this.sequenceEventSyncResolvers);a.call(e,...t)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}}resolveSequenceEventActorReference(e){if(!this.world||null==e)return null;const t=e,a="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==a)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===a)return e}return null}resolveSequenceEventSequence(e){return function(e){return"object"==typeof e&&null!=e&&"duration"in e&&"tracks"in e}(e)?new S(e):this.assetLoader&&"string"==typeof e?this.assetLoader.getSequenceById(e):null}async resolveSequenceEventAnimationClip(e){const t="string"==typeof e?e:"object"==typeof e&&null!=e?e.assetId??null:null;return null!=t&&this.assetLoader?this.assetLoader.getAnimationClipByAssetId(t):null}}function R(e){return e.options?.length>0||e.propertyType===y.Boolean||e.propertyType===y.String}function V(e){return e.valueType===y.Boolean||e.valueType===y.String}function D(e){return"object"==typeof e&&null!=e||"function"==typeof e}function K(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return $(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return N(e,t.value);case y.Color:return function(e,t){if(e instanceof c){const a=le.set(0);return Q(a,t)?(e.set(a.r,a.g,a.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const a=le.set(0);return Q(a,t)?(e.set(a.r,a.g,a.b,e.w),{applied:!0,value:e}):{applied:!1}}return W(e,t)}(e,t.value);default:return{applied:!1}}}function G(e,t){return function(e){return e instanceof a.Material||!0===e?.isMaterial}(e)&&e.userData?.assetId===t.materialAssetId&&null!=e.uniforms?.[t.uniformName]}function $(e,t){const a=X(t,2);return a?e instanceof l?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new l(a[0],a[1])}:{applied:!1}}function U(e,t){const a=X(t,3);return a?e instanceof c?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new c(a[0],a[1],a[2])}:{applied:!1}}function N(e,t){const a=X(t,4);return a?e instanceof h?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new h(a[0],a[1],a[2],a[3])}:{applied:!1}}function W(e,t){if(e instanceof r)return Q(e,t)?{applied:!0,value:e}:{applied:!1};const a=new r;return Q(a,t)?{applied:!0,value:a}:{applied:!1}}function X(e,t){if(!Array.isArray(e)||e.length<t)return null;const a=new Array(t);for(let s=0;s<t;s++){if("number"!=typeof e[s])return null;a[s]=e[s]}return a}function Q(e,t){return t instanceof r||"string"==typeof t||"number"==typeof t?(e.set(t),!0):!!(Array.isArray(t)&&t.length>=3)&&(e.setRGB("number"==typeof t[0]?t[0]:0,"number"==typeof t[1]?t[1]:0,"number"==typeof t[2]?t[2]:0),!0)}function Y(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof r||e instanceof i)return e.clone()}function Z(e){const{owner:t,key:a}=e.resolution;e.hadOwnProperty?(!function(e,t){if(e instanceof l&&t instanceof l)return e.copy(t),!0;if(e instanceof c&&t instanceof c)return e.copy(t),!0;if(e instanceof h&&t instanceof h)return e.copy(t),!0;if(e instanceof r&&t instanceof r)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0}(e.value,e.valueSnapshot),t[a]=e.value):delete t[a]}function z(e){const t=[];for(const a of e)t.push(a),"group"===a.type&&t.push(...z(a.childTracks));return t}function H(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function J(e){const t=new a.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const s=new a.AxesHelper(.35);s.renderOrder=1e3;const r=Array.isArray(s.material)?s.material:[s.material];for(const e of r)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(s);const i=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const s=t.getContext("2d");if(!s)return null;s.clearRect(0,0,t.width,t.height),s.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,a,s,r,i){const n=t+s,o=a+r;e.beginPath(),e.moveTo(t+i,a),e.lineTo(n-i,a),e.quadraticCurveTo(n,a,n,a+i),e.lineTo(n,o-i),e.quadraticCurveTo(n,o,n-i,o),e.lineTo(t+i,o),e.quadraticCurveTo(t,o,t,o-i),e.lineTo(t,a+i),e.quadraticCurveTo(t,a,t+i,a),e.closePath()}(s,0,8,t.width,48,8),s.fill(),s.font="24px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillStyle="#f8fafc",s.fillText(e||"Locator",t.width/2,t.height/2);const r=new a.CanvasTexture(t);r.needsUpdate=!0;const i=new a.SpriteMaterial({map:r,transparent:!0,depthTest:!1});i.toneMapped=!1;const n=new a.Sprite(i);return n.scale.set(.9,.225,1),n}(e);return i&&(i.position.set(0,.45,0),i.renderOrder=1001,t.add(i)),t.traverse(e=>{e.raycast=()=>{}}),t}function ee(e){e.traverse(e=>{const t=e.material;if(Array.isArray(t))for(const e of t)e?.dispose?.(),e?.map?.dispose?.();else t?.dispose?.(),t?.map?.dispose?.()})}const te=new c,ae=new c,se=new c,re=new o,ie=new o,ne=new i,oe=new i,le=new r;/*
1
+ import{BehaviorSubject as e,Subject as t}from"rxjs";import*as a from"three";import{AnimationMixer as s,Color as r,Euler as i,Object3D as n,Quaternion as o,Vector2 as l,Vector3 as c,Vector4 as h}from"three";import{VisualEffect as u}from"../../effects/vfx/vfx-param.js";import{BaseActor as p}from"../../gameplay/actors/actor.js";import d from"../../gameplay/actors/builtin/index.js";import{Prefab as f,PrefabOf as m}from"../../scene/objects/prefab.js";import{SerializedParamType as y}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as C,deserializeCustomParamValue as v,deserializeCustomParamValueSync as g}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as A}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as S,Sequence as w}from"./sequence-data.js";import{getSequenceSubTrackDefinition as P,getSequenceTrackDefinition as b}from"./sequence-definitions.js";import{applyInterpolation as k,evaluateCustomParamValueKeyframes as x,evaluateNumericKeyframes as T,findKeyframeSpan as I}from"./sequence-value-lane.js";import{buildRetimedAnimationClip as q,getAnimationClipRetimingSignature as B,isAnimationClipUsingRetiming as M}from"./sequence-animation-retiming.js";import{SkeletonUtils as O}from"three-stdlib";import{CharacterAnimationComponent as F,CharacterMovementComponent as E}from"../../gameplay/actors/index.js";import{RootMotionClip as j}from"../../gameplay/animation/root-motion.js";import{hashCameraShakeSeed as _}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as L,shaderGraphPostProcessWeightUniformName as R}from"../../shader/graph/index.js";export var SequencePlaybackState;!function(e){e.Stopped="stopped",e.Playing="playing",e.Paused="paused"}(SequencePlaybackState||(SequencePlaybackState={}));export class SequencePlayer{constructor(){this._state=new e(SequencePlaybackState.Stopped),this._time=new e(0),this._duration=0,this._timescale=1,this._loop=!1,this._externalTimeControl=!1,this._inEditor=!1,this.bindings=new Map,this.roleBindings=new Map,this.sequenceData=null,this.onComplete=new t,this.onLoop=new t,this.onTimeUpdate=this._time.asObservable(),this.onStateChange=this._state.asObservable(),this.loopCount=0,this.viewController=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.sequenceCameras=new Map,this.cameraPlayables=new Map,this.cameraBlendCamera=null,this.cameraBlendSource=null,this.cameraBlendOutSource=null,this.cameraOverrideHandle=null,this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null,this.activeCameraShakeClipKeys=new Set,this.nextCameraShakeClipKeys=new Set,this.activePostProcessClips=new Map,this.nextPostProcessClipKeys=new Set,this.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,this.audioByClip=new Map,this.activeAudioClips=new Set,this.audioGainNodes=new Map,this.audioStartInFlight=new Map,this.lastAudioStartAttemptTime=new Map,this.audioStartRetryIntervalSeconds=.25,this.world=null,this.assetLoader=null,this.actorFactory=null,this.vfxService=null,this.spawnedInstances=new Map,this.activeClips=new Set,this.pendingSpawns=new Set,this.vfxActors=new Map,this.activeVfxClips=new Set,this.locatorMarkers=new Map,this.clearCounter=0,this.propertyPathSegments=new Map,this.propertyResolutionCache=new Map,this.propertySnapshots=new Map,this.materialResolutionCache=new Map,this.materialSnapshots=new Map,this.audioFilters=new Map,this.audioPannerNodes=new Map,this.firedEvents=new Set,this.sequenceEventSyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e)},this.sequenceEventAsyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e),texture:e=>this.assetLoader?.getTextureByAssetId(e)??null,sampler2DNode:e=>this.assetLoader?.getTextureByAssetId(e)??null,object3D:async e=>{const t=await(this.assetLoader?.getModelByAssetId(e));return t?.scene??null},material:e=>this.assetLoader?.getMaterialByAssetId(e)??null,audioBuffer:e=>this.assetLoader?.getAudioByAssetId(e)??null,visualEffect:async e=>{if(!this.assetLoader||!this.actorFactory)return null;const t=await this.assetLoader.getAsset(e);return t?new u(this.actorFactory,t):null},prefab:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new f(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(new f(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,a)=>{t&&this.evaluateObjectTrack(e,t,a)},locator:(e,t,a)=>{t&&this.evaluateLocatorTrack(e,t,a)},camera:(e,t,a)=>this.evaluateCameraTrack(e,a),cameraShake:(e,t,a)=>this.evaluateCameraShakeTrack(e,a),postProcess:(e,t,a)=>this.evaluatePostProcessTrack(e,a),audio:(e,t,a)=>this.evaluateAudioTrack(e,a),vfx:(e,t,a)=>this.evaluateVfxTrack(e,a),spawn:(e,t,a)=>this.evaluateSpawnTrack(e,t,a),group:(e,t,a)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,a)}},this.subTrackRuntimeEvaluators={transform:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateTransformSubTrack(e,s,a)},animation:(e,t,a)=>this.evaluateAnimationSubTrack(e,t,a),visibility:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateVisibilitySubTrack(e,s,a)},parameter:(e,t,a)=>this.evaluateParameterSubTrack(e,t.target||null,a),event:(e,t,a)=>this.evaluateEventSubTrack(e,t.target||null,a)}}get state(){return this._state.value}get time(){return this._time.value}get duration(){return this._duration}get timescale(){return this._timescale}set timescale(e){this._timescale=Math.max(.01,e)}get loop(){return this._loop}set loop(e){this._loop=e}get externalTimeControl(){return this._externalTimeControl}set externalTimeControl(e){this._externalTimeControl=e}get inEditor(){return this._inEditor}set inEditor(e){this._inEditor=e,this.updateLocatorMarkerVisibility()}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,e||this.releaseCameraOverride()}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId!==e&&(this._cameraControlTrackId=e,this.releaseCameraOverride())}setViewController(e){this.viewController&&this.viewController!==e&&this.viewController.clearCameraShakeContributionsForOwner(this),this.viewController=e}setWorld(e){this.world!==e&&(this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.world=e,this.clearCounter++,this.vfxActors.clear(),this.spawnedInstances.clear(),this.bindings.clear(),this.activeClips.clear(),this.activeVfxClips.clear(),this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear(),this.loadingAudioBuffers.clear(),this.audioFilters.clear(),this.audioPannerNodes.clear(),this.pendingSpawns.clear(),this.propertyResolutionCache.clear(),this.materialResolutionCache.clear(),this.clearRetimedAnimationClipCache(),this._state.next(SequencePlaybackState.Stopped),this.sequenceData&&this.initializeLocatorBindings())}setAudioListener(e){this.audioListener=e}setAssetLoader(e){if(this.assetLoader=e,this.sequenceData){const e=this.clearCounter;this.preloadSequenceResources(this.sequenceData,e)}}setActorFactory(e){this.actorFactory=e}setVfxService(e){this.vfxService=e}load(e){if(this.stop(),this.clearCounter++,this.clearLocatorBindings(),this.clearSequenceCameras(),this.sequenceData=e,this._duration=e.duration,this._loop=e.loop,this._timescale=e.playbackRate,this.clearRetimedAnimationClipCache(),this.bindings.clear(),this.initializeLocatorBindings(),this.loopCount=0,this.assetLoader){const t=this.clearCounter;this.preloadSequenceResources(e,t)}}preloadSequenceResources(e,t){return Promise.all([this.preloadAudioBuffersForSequence(e,t),this.preloadAnimationClipsForSequence(e,t)]).then(()=>{})}getAudioAssetIdsForSequence(e){const t=new Set;for(const a of e.tracks){if("audio"!==a.type)continue;const e=a;for(const a of e.clips??[])a.audioAssetId&&t.add(a.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const a=this.getAudioAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let a=this.loadingAudioBuffers.get(e);a||(a=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,a));try{const s=await a;if(t!==this.clearCounter)return;this.audioBuffers.set(e,s)}catch(e){}finally{this.loadingAudioBuffers.get(e)===a&&this.loadingAudioBuffers.delete(e)}}))}getAnimationClipAssetIdsForSequence(e){const t=new Set;for(const a of H(e.tracks))if("subTracks"in a)for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips)a.animationClipAssetId&&t.add(a.animationClipAssetId);return[...t]}async preloadAnimationClipsForSequence(e,t){if(!this.assetLoader)return;const a=this.getAnimationClipAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{t===this.clearCounter&&await this.ensureAnimationClip(e)}))}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const a of this.sequenceData.tracks)"object"===a.type&&a.targetId===e&&this.createBinding(a,t)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=J(e);if(!t||!this.sequenceData)return[];const a=[];for(const e of H(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(J(e.bindingId)!==t)continue;const s=this.bindings.get(e.id),r=s?this.getPlayableObject(s):null;r&&(r.updateWorldMatrix(!0,!1),a.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:r.getWorldPosition(new c),rotation:r.getWorldQuaternion(new o),scale:r.getWorldScale(new c)}))}return a}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of H(this.sequenceData.tracks)){if("locator"!==e.type||this.bindings.has(e.id))continue;const t=new n;t.name=e.name||"Locator",t.userData.sequenceLocatorTrackId=e.id,this.world?.scene&&null==t.parent&&this.world.scene.add(t);const a=ee(e.name);a.visible=this._inEditor,t.add(a),this.locatorMarkers.set(e.id,a),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())te(e);for(const e of this.bindings.values()){if("locator"!==e.track.type)continue;const t=this.getPlayableObject(e);t?.parent&&t.removeFromParent()}this.locatorMarkers.clear()}updateLocatorMarkerVisibility(){for(const e of this.locatorMarkers.values())e.visible=this._inEditor}disableLocatorInteraction(e){e.traverse(e=>{e.raycast=()=>{}})}resolveTrackBinding(e){if("object"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("spawn"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("group"===e.type)for(const t of e.childTracks)this.resolveTrackBinding(t)}createBinding(e,t){const a=t instanceof p?t.object:t,r=this.bindings.get(e.id),i=null!=r?r.target instanceof p?r.target.object:r.target:null,n=null!=r&&r.target===t&&i===a,o=e.subTracks.some(e=>"animation"===e.type);if(null!=r&&!n){for(const e of r.activeActions.values())e.stop();r.activeActions.clear(),r.mixer?.stopAllAction(),r.charAnimComponent?.stopSequenceAnimation(),r.charAnimComponent=void 0,r.charAnimActionKeys?.clear()}const l=n?r:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,l.originalTransform={position:a.position.clone(),rotation:a.rotation.clone(),scale:a.scale.clone()},l.originalParent=a.parent,o&&null==l.mixer?l.mixer=new s(a):o||(l.mixer=void 0),this.bindings.set(e.id,l)}play(){this._state.value!==SequencePlaybackState.Playing&&this.sequenceData&&(this._state.value===SequencePlaybackState.Stopped&&(this._time.next(0),this.loopCount=0,this.resolveBindings(),this.captureOriginalTransforms()),this._state.next(SequencePlaybackState.Playing),this.evaluate(this._time.value),this.resumeVfx())}pause(){this._state.value===SequencePlaybackState.Playing&&(this._state.next(SequencePlaybackState.Paused),this.pauseAudio(),this.pauseVfx())}pauseAudio(){for(const e of this.audioByClip.values())e.pause()}pauseVfx(){for(const e of this.vfxActors.values())e.pause()}resumeVfx(){for(const[e,t]of this.vfxActors.entries())(this.activeVfxClips.has(e)||t.getParticleCount()>0)&&t.play()}cancel(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}restart(){this.stop(),this.play()}seek(e){const t=Math.max(0,Math.min(e,this._duration));t<this._time.value&&this.resetVfxForTimeReset(t),this._time.next(t),this.evaluate(t)}update(e){if(this._state.value!==SequencePlaybackState.Playing)return;if(!this.sequenceData)return;if(this._externalTimeControl){for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale);return}const t=this._time.value+e*this._timescale;if(t>=this._duration){if(!this._loop)return this._time.next(this._duration),this.evaluate(this._duration),this.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this._state.next(SequencePlaybackState.Stopped),void this.onComplete.next();{this.loopCount++;const e=t%this._duration;this.resetVfxForTimeReset(e),this._time.next(e),this.firedEvents.clear(),this.onLoop.next(this.loopCount)}}else this._time.next(t);this.evaluate(this._time.value);for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale)}evaluate(e){if(this.sequenceData){this.nextCameraShakeClipKeys.clear(),this.nextPostProcessClipKeys.clear();for(const t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===t.type||"spawn"===t.type||"vfx"===t.type)){const e=this.bindings.get(t.id);this.updateTrackParenting(t,e)}this.evaluateTrack(t,e)}this.updateCameraControl(e),this.syncCameraShakeContributions(),this.syncPostProcessEffects()}}evaluateTrack(e,t){if(e.muted)return;const a=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[b(e.type).runtimeEvaluator])(e,a,t)}evaluateObjectTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}evaluateLocatorTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=H(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,a){for(const s of e){if(s.muted)continue;(0,this.subTrackRuntimeEvaluators[P(s.type).runtimeEvaluator])(s,t,a)}}evaluateTransformSubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;const{prev:r,next:i,t:n}=I(s,a);if(r)if(i&&r!==i){const a=k(n,r.interpolation);e.components.position&&r.position&&i.position&&t.position.lerpVectors(ae.fromArray(r.position),se.fromArray(i.position),a),e.components.rotation&&r.rotation&&i.rotation&&(ie.setFromEuler(oe.fromArray([...r.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"])),t.quaternion.slerpQuaternions(ie,ne,a)),e.components.scale&&r.scale&&i.scale&&t.scale.lerpVectors(ae.fromArray(r.scale),se.fromArray(i.scale),a)}else e.components.position&&r.position&&t.position.fromArray(r.position),e.components.rotation&&r.rotation&&t.rotation.fromArray([...r.rotation,"XYZ"]),e.components.scale&&r.scale&&t.scale.fromArray(r.scale)}evaluateAnimationSubTrack(e,t,s){if(!t.mixer||!t.activeActions)return;if(t.target instanceof p?t.target.object:t.target)for(const r of e.clips){const i=r.startTime+r.duration,n=s>=r.startTime&&s<i,o=`${e.id}-${r.id}`;let l=t.activeActions.get(o),c=!1;if(n){if(!l){c=!0;const e=r.animationClipAssetId;if(null==e)continue;const s=this.animationClips.get(e);if(null==s){this.ensureAnimationClip(e);continue}const i=this.prepareAnimationPlayback(e,s,r),n=t;let h=!1;if(t.target instanceof p){n.charAnimComponent||(n.charAnimComponent=t.target.getComponent(F)??void 0);const a=n.charAnimComponent;if(null!=a){const c=r.rootMotion?M(r)?this.getPlayableAnimationClip(e,s,r,!0):j.fromClip(i.clip,!1):i.clip;if(this._externalTimeControl)l=a.beginExternalAnimationControl(c,{timeScale:i.timeScale});else if(a.play(c,{inPlace:!r.rootMotion,loop:!1,priority:20,timeScale:i.timeScale,fadeTime:r.fadeInDuration??.2,offset:i.startOffset}),l=a.getFullBodyAction(),r.rootMotion){const e=t.target.getComponent(E);e&&e.setRootMotionAction(l,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(o,l),n.charAnimActionKeys||(n.charAnimActionKeys=new Set),n.charAnimActionKeys.add(o),h=!0}}h||(l=t.mixer.clipAction(i.clip),l.setLoop(a.LoopOnce,1),l.clampWhenFinished=!0,l.timeScale=i.timeScale,i.startOffset>0&&(l.time=i.startOffset),t.activeActions.set(o,l),l.play())}if(l){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const a=this.getAnimationPlaybackLocalTime(r,s),i=Math.min(a,l.getClip().duration);(c||Math.abs(l.time-i)>.001)&&(l.time=i,l.paused=!1,l.play(),e.charAnimComponent?e.charAnimComponent.getMixer()?.update(0):t.mixer&&t.mixer.update(0))}else e.charAnimComponent?.endExternalControl()}}else if(l){t.activeActions.delete(o);const e=t;e.charAnimActionKeys?.has(o)?(e.charAnimActionKeys.delete(o),l.stop(),0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0)):(l.stop(),this._externalTimeControl&&t.mixer&&t.mixer.update(0))}}}evaluateVisibilitySubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;let r=s[0];for(const e of s){if(!(e.time<=a))break;r=e}t.visible=r.visible}evaluatePropertySubTrack(e,t,a){const s=x(e.keyframes,a,{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)});s&&this.applyResolvedPropertyValue(e,t,s)}evaluateParameterSubTrack(e,t,a){if("audioParameter"===e.type)return;const s=x(e.keyframes,a,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:D(e)}:{});s&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,s):this.applyResolvedPropertyValue(e,t,s))}evaluateEventSubTrack(e,t,a){if(t instanceof p&&this._state.value===SequencePlaybackState.Playing)for(const s of e.events){const r=`${e.id}-${s.id}`;if(a>=s.time&&!this.firedEvents.has(r)){if(this.firedEvents.add(r),s.editorOnly&&!this._inEditor)continue;if(!s.functionName)continue;const e=t[s.functionName];"function"==typeof e?this.invokeSequenceEvent(t,s.functionName,e,s.arguments??[]):console.warn(`Sequence event method '${s.functionName}' not found on actor`)}else s.time>a&&this.firedEvents.delete(r)}}evaluateCameraTrack(e,t){const a=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,a),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,a),t),a.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const a of e.clips??[]){if(!this.isCameraShakeClipActive(a,t))continue;const e=t-a.startTime,s=a.id;this.nextCameraShakeClipKeys.add(s),this.viewController.setCameraShakeContribution(this,s,a,e,a.seed??_(a.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader)for(const a of e.clips??[]){if(!this.isPostProcessClipActive(a,t))continue;const s=this.getPostProcessClipKey(e,a);this.nextPostProcessClipKeys.add(s),this.ensurePostProcessClipEffect(e,a,s);const r=this.activePostProcessClips.get(s);r?.handle&&(r.handle.stage=e.stage,r.handle.priority=e.priority,r.handle.enabled=!0,this.applyPostProcessClipWeight(r.handle,a,t))}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,a){const s=t.shaderGraphAssetId;if(!s)return void this.releasePostProcessClipEffect(a);const r=JSON.stringify(t.shaderGraphParams??{}),i=this.activePostProcessClips.get(a);if(i?.assetId===s&&i.paramsSignature===r)return;this.releasePostProcessClipEffect(a);const n={key:a,trackId:e.id,clipId:t.id,assetId:s,paramsSignature:r,version:this.clearCounter};this.activePostProcessClips.set(a,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,a){if(this.assetLoader&&this.viewController)try{const s=await this.assetLoader.getShaderGraphByAssetId(a.assetId);if(!this.isPostProcessClipEntryCurrent(a))return;if("postProcess"!==s.target)return console.warn(`Sequence post-process clip references shader graph "${a.assetId}" with target "${s.target}"`),void this.releasePostProcessClipEffect(a.key);const r=await this.assetLoader.prepareShaderGraphParameters(s,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(a))return;const i=L(s,{parameters:r});if(!this.isPostProcessClipEntryCurrent(a))return void i.dispose();a.handle=this.viewController.addPostProcessEffect(i,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(a.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(a)&&this.releasePostProcessClipEffect(a.key),console.error(`Failed to create post-process effect for clip ${t.id}:`,e)}}isPostProcessClipEntryCurrent(e){return this.clearCounter===e.version&&this.activePostProcessClips.get(e.key)===e}applyPostProcessClipWeight(e,t,a){const s=e.material.uniforms?.[R];null!=s&&(s.value=this.getPostProcessClipWeight(t,a),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const a=Math.max(0,t-e.startTime),s=Math.max(0,e.startTime+e.duration-t);let r=1;const i=Math.max(0,e.fadeInDuration??0);i>0&&(r=Math.min(r,a/i));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(r=Math.min(r,s/n)),Math.max(0,Math.min(1,r))}syncPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.nextPostProcessClipKeys.has(e)||this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}clearPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}releasePostProcessClipEffect(e){const t=this.activePostProcessClips.get(e);if(t&&(this.activePostProcessClips.delete(e),t.handle)){const e=t.handle.material;t.handle.dispose(),e.dispose()}}getCameraPlayable(e,t){let a=this.cameraPlayables.get(e.id);return a?a.target=t:(a={target:t},this.cameraPlayables.set(e.id,a)),a}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new a.PerspectiveCamera(s.fov??60,this.getCurrentCameraAspect(),s.near??.1,s.far??1e3),t.name=e.name||"Sequence Camera",t.userData.sequenceCameraTrackId=e.id,t.layers.mask=this.viewController?.getBaseCamera().layers.mask??t.layers.mask,this.sequenceCameras.set(e.id,t),this.world?.scene.add(t)}return t}clearSequenceCameras(){this.releaseCameraOverride();for(const e of this.sequenceCameras.values())e.removeFromParent();this.sequenceCameras.clear(),this.cameraPlayables.clear()}applyCameraTrackSettings(e,t){const a=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=a.fov??60,t.near=a.near??.1,t.far=a.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof a.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof a.PerspectiveCamera&&Number.isFinite(t.aspect)&&t.aspect>0?t.aspect:1}updateCameraControl(e){if(!this._cameraControlEnabled||!this.viewController||!this.sequenceData)return void this.releaseCameraOverride();const t=this.findActiveCameraShot(e);if(t)return void this.updateActiveCameraShot(t,e);const a=this.findBlendOutCameraShot(e);a?this.updateCameraBlendOut(a,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s)this.isCameraClipActive(r,e)&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s){const s=Math.max(0,r.blendOutDuration??0);if(s<=0)continue;const i=this.getCameraClipEnd(r);e>=i&&e<i+s&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const s=Math.max(0,e.clip.blendInDuration??0),r=s<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/s,e.clip);r>=1?this.copyCameraState(e.camera,a):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,a,r),a.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();if(this.cameraBlendOutClipKey!==e.key){const t=this.activeCameraClipKey===e.key?this.viewController.getSourceCamera():e.camera;this.copyCameraState(t,this.ensureCameraBlendOutSource()),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=e.key}const s=this.getCameraClipEnd(e.clip),r=Math.max(0,e.clip.blendOutDuration??0),i=r<=0?1:this.evaluateCameraBlendAlpha((t-s)/r,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),a,i),a.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new a.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new a.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new a.PerspectiveCamera),this.cameraBlendOutSource}ensureCameraOverride(){this.viewController&&!this.cameraOverrideHandle&&(this.cameraOverrideHandle=this.viewController.pushCameraOverride(this.ensureCameraBlendCamera(),this))}releaseCameraOverride(){this.cameraOverrideHandle?.release(),this.cameraOverrideHandle=null,this.viewController?.releaseCameraOverridesForOwner(this),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null}isCameraClipActive(e,t){return t>=e.startTime&&t<this.getCameraClipEnd(e)}getCameraClipEnd(e){return e.startTime+Math.max(0,e.duration)}isCameraShakeClipActive(e,t){return t>=e.startTime&&t<this.getCameraShakeClipEnd(e)}getCameraShakeClipEnd(e){return e.startTime+Math.max(0,e.duration)}getCameraClipKey(e,t){return`${e.id}-${t.id}`}evaluateCameraBlendAlpha(e,t){return k(Math.max(0,Math.min(1,e)),t.blendInterpolation??"cubic")}syncCameraShakeContributions(){if(!this.viewController)return this.activeCameraShakeClipKeys.clear(),void this.nextCameraShakeClipKeys.clear();for(const e of this.activeCameraShakeClipKeys)this.nextCameraShakeClipKeys.has(e)||this.viewController.removeCameraShakeContribution(this,e);this.activeCameraShakeClipKeys.clear();for(const e of this.nextCameraShakeClipKeys)this.activeCameraShakeClipKeys.add(e);this.nextCameraShakeClipKeys.clear()}clearCameraShakeContributions(){this.activeCameraShakeClipKeys.clear(),this.nextCameraShakeClipKeys.clear(),this.viewController?.clearCameraShakeContributionsForOwner(this)}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(ae)),t.quaternion.copy(e.getWorldQuaternion(ie)),t.scale.copy(e.getWorldScale(se)),e instanceof a.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect):t.aspect=this.getCurrentCameraAspect(),t.layers.mask=e.layers.mask}blendCameraState(e,t,s,r){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),s.position.lerpVectors(e.getWorldPosition(ae),t.getWorldPosition(se),r),s.quaternion.slerpQuaternions(e.getWorldQuaternion(ie),t.getWorldQuaternion(ne),r),s.scale.lerpVectors(e.getWorldScale(ae),t.getWorldScale(se),r),e instanceof a.PerspectiveCamera&&t instanceof a.PerspectiveCamera?(s.fov=e.fov+(t.fov-e.fov)*r,s.near=e.near+(t.near-e.near)*r,s.far=e.far+(t.far-e.far)*r,s.aspect=t.aspect):t instanceof a.PerspectiveCamera?(s.fov=t.fov,s.near=t.near,s.far=t.far,s.aspect=t.aspect):s.aspect=this.getCurrentCameraAspect(),s.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const a=this._state.value===SequencePlaybackState.Playing,s=this.evaluateAudioSubTracks(e,t);e.volume;for(const r of e.clips){const i=r.startTime+r.duration,n=t>=r.startTime&&t<i,o=`${e.id}-${r.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),a){const a=this.audioByClip.get(o);a&&a.isPlaying||this.tryStartAudioClip(e,r,o,t,s)}const i=this.audioByClip.get(o);i&&this.applyAudioParameters(i,e,r,o,t,s)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,a,s,r){if(this.audioStartInFlight.has(a))return;const i=this.lastAudioStartAttemptTime.get(a);if(void 0!==i&&s-i<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(a,s);const n=this.playAudioClip(e,t,a,s,r).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(a)===n&&this.audioStartInFlight.delete(a)});this.audioStartInFlight.set(a,n)}applyAudioParameters(e,t,s,r,i,n){const o=n.volume??1,l=this.stringToRandom(r+t.id),c=s.volumeRandomization?(2*l-1)*s.volumeRandomization:0;let h=1;const u=i-s.startTime;u<s.fadeInDuration&&s.fadeInDuration>0?h=u/s.fadeInDuration:u>s.duration-s.fadeOutDuration&&s.fadeOutDuration>0&&(h=(s.duration-u)/s.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(s.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(s.pitchRandomization){d+=(2*this.stringToRandom(r+"_pitch")-1)*s.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(s.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const s=this.audioListener.context,i=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(r);if(void 0!==o||void 0!==l)c||(c=s.createBiquadFilter(),this.audioFilters.set(r,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),i.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(r)}const h=n.pan;if(!t.spatial&&e instanceof a.Audio&&void 0!==h&&"function"==typeof s.createStereoPanner){let e=this.audioPannerNodes.get(r);e||(e=s.createStereoPanner(),this.audioPannerNodes.set(r,e)),e.pan.value=h,i.push(e)}else{const e=this.audioPannerNodes.get(r);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(r)}}e.setFilters(i)}t.spatial&&e instanceof a.PositionalAudio?this.updatePositionalAudioTransform(e,t,s,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,s,r){let i=null,n=null;const o=s.attachedToTrackId||t.parent?.trackId,l=s.attachmentSocketName||t.parent?.socketName;if(o){const e=this.sequenceData?.tracks.find(e=>e.id===o);if(e){const t=this.getActiveObjectsForTrack(e);if(t.length>0){const e=t[0];if(i=ae,n=ie,e.getWorldPosition(i),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(i),t.getWorldQuaternion(n))}}}}if(i&&n){const t="number"==typeof r?a.MathUtils.clamp(r,0,1):1;if(t<1&&this.audioListener){const e=re;this.audioListener.getWorldPosition(e),i=i.clone().lerp(e,1-t)}e.position.copy(i),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,s,r,i){if(!this.assetLoader||!t.audioAssetId||null==this.audioListener)return;if("suspended"===this.audioListener.context.state)try{await this.audioListener.context.resume()}catch(e){return void console.warn("Failed to resume audio context:",e)}this.stopAudioClip(s);const n=this.clearCounter;try{let r=this.audioBuffers.get(t.audioAssetId);if(!r){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{r=await e,this.audioBuffers.set(t.audioAssetId,r)}finally{this.loadingAudioBuffers.delete(t.audioAssetId)}}if(n!==this.clearCounter)return;const o=this._time.value,l=t.startTime+t.duration;if(!(o>=t.startTime&&o<l))return;const c=Math.max(0,o-t.startTime),h=t.clipStartOffset+c*t.playbackRate;if(h>=r.duration||c>=t.duration)return;let u=this.audioByClip.get(s);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(s),u=void 0),!u){if(p){const e=new a.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new a.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(s,u)}Math.min((t.duration-c)/t.playbackRate,(r.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,r.duration)),u.setLoop(!0),u.setBuffer(r),this.applyAudioParameters(u,e,t,s,o,i),u.isPlaying||u.play()}catch(e){console.error(`Failed to play audio clip ${t.id}:`,e)}}stopAudioClip(e){const t=this.audioByClip.get(e);if(t){try{t.isPlaying&&t.stop()}catch(e){}t.parent&&t.parent.remove(t),this.audioByClip.delete(e)}const a=this.audioGainNodes.get(e);a&&(a.disconnect(),this.audioGainNodes.delete(e));const s=this.audioFilters.get(e);if(s){try{s.disconnect()}catch{}this.audioFilters.delete(e)}const r=this.audioPannerNodes.get(e);if(r){try{r.disconnect()}catch{}this.audioPannerNodes.delete(e)}}stopAllAudio(){for(const e of this.audioByClip.keys())this.stopAudioClip(e);this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear()}evaluateVfxTrack(e,t){if(!this.vfxService||!this.world||!e.clips||0===e.clips.length)return;const a=new Set,s=new Map;for(const r of e.clips){const i=this.getVfxClipKey(e,r);s.set(i,r),this.isVfxClipActiveAtTime(r,t)&&a.add(i)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(a.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[r,i]of s.entries()){const s=this.vfxActors.get(r);a.has(r)&&!this.activeVfxClips.has(r)?(this.activeVfxClips.add(r),this.ensureVfxActor(e,i,r)):a.has(r)&&s?(this.updateVfxTransform(e,s,t),this._state.value===SequencePlaybackState.Playing&&s.play()):s&&this.applyInactiveVfxClipBehavior(i,s,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const a=e.startTime+e.duration;return t>=e.startTime&&t<a}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const a of H(this.sequenceData.tracks))if("vfx"===a.type)for(const s of a.clips??[])this.isVfxClipActiveAtTime(s,e)&&t.add(this.getVfxClipKey(a,s));this.activeVfxClips.clear();for(const[e,a]of this.vfxActors.entries())t.has(e)||(a.restart(),a.stop(),a.pause())}applyInactiveVfxClipBehavior(e,t,a){const s=e.endBehavior??"finish";if("finish"===s)return void t.stop();if("kill"===s)return void t.applyClipEndBehavior(s);const r=e.startTime+e.duration,i=Math.max(a-r,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-i);t.applyClipEndBehavior(s,o)}async ensureVfxActor(e,t,a){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(a)){const e=this.vfxActors.get(a);return e.restart(),void e.play()}const s=this.clearCounter;try{const r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene);if(s!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:i,rotation:n,scale:o}=this.getVfxTransform(e,t.startTime);r.object.position.copy(i),r.object.rotation.copy(n),r.object.scale.copy(o),this.vfxActors.set(a,r),this._state.value===SequencePlaybackState.Playing&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const a=new c,s=new i,r=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:i,t:l}=I(n.keyframes,t);if(e&&(e.position&&a.fromArray(e.position),e.rotation&&s.fromArray([...e.rotation,"XYZ"]),e.scale&&r.fromArray(e.scale)),i&&e!==i&&e.time!==i.time){const t=k(l,e.interpolation);if(e.position&&i.position&&a.lerpVectors(ae.fromArray(e.position),se.fromArray(i.position),t),e.rotation&&i.rotation){ie.setFromEuler(oe.fromArray([...e.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"]));const a=new o;a.slerpQuaternions(ie,ne,t),s.setFromQuaternion(a)}e.scale&&i.scale&&r.lerpVectors(ae.fromArray(e.scale),se.fromArray(i.scale),t)}}else a.fromArray(e.position),s.fromArray([...e.rotation,"XYZ"]),r.fromArray(e.scale);return{position:a,rotation:s,scale:r}}updateVfxTransform(e,t,a){const{position:s,rotation:r,scale:i}=this.getVfxTransform(e,a);t.object.position.copy(s),t.object.rotation.copy(r),t.object.scale.copy(i)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const a=d[e];return a||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,a,s){if(!this.world||!e.actorType)return null;const r=this.resolveActorType(e.actorType);if(!r)return null;try{return await this.world.spawnActor(r,a,s)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.prefabId)return null;try{const t=await this.assetLoader.getPrefabById(e.prefabId);if(!t)return null;return await this.world.spawnPrefab(t,a,s)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),r=await this.assetLoader.getModelByAssetId(e.meshId),i=O.clone(r.scene);if(i.position.copy(a),i.rotation.copy(s),t){await this.assetLoader.applyMaterials(t,i);const e=t.mesh?.rescale;null!=e&&1!==e&&i.scale.multiplyScalar(e)}return this.world.scene.add(i),i}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(this.restorePropertySnapshotsForInstance(e),this.restoreMaterialSnapshotsForInstance(e),this.world)switch(e?.type){case"actor":this.world.removeActor(e.instance);break;case"prefab":this.world.removePrefab(e.instance);break;case"mesh":this.world.scene.remove(e.instance)}}despawnAll(){for(const e of this.spawnedInstances.values())this.despawnInstance(e);this.spawnedInstances.clear(),this.activeClips.clear(),this.pendingSpawns.clear()}getInitialTransform(e,t,a){const s=new c,r=new i,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e}=I(n.keyframes,a);e&&(e.position&&s.fromArray(e.position),e.rotation&&r.fromArray([...e.rotation,"XYZ"]))}else t.initialPosition&&s.fromArray(t.initialPosition),t.initialRotation&&r.fromArray([...t.initialRotation,"XYZ"]);return{position:s,rotation:r}}evaluateSpawnTrack(e,t,a){if(!e.clips||0===e.clips.length)return;const s=t||this.bindings.get(e.id);if(s&&s.target)for(const t of e.clips){const r=t.startTime+t.duration,i=a>=t.startTime&&a<r,n=`${e.id}-${t.id}`;if(i){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:s.target}));(s.target instanceof p?s.target.object:s.target)&&this.evaluateSubTracks(e.subTracks,s,a)}else this.activeClips.has(n)&&(this.restorePropertySnapshotsForTarget(s.target),this.restoreMaterialSnapshotsForTarget(s.target),this.activeClips.delete(n),this.spawnedInstances.delete(n))}else for(const t of e.clips){const s=t.startTime+t.duration,r=a>=t.startTime&&a<s,i=`${e.id}-${t.id}`,n=this.spawnedInstances.has(i),o=this.pendingSpawns.has(i);if(!r||n||o){if(r&&n){const t=this.spawnedInstances.get(i);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,a)}else if(!r&&n){const e=this.spawnedInstances.get(i);e&&(this.despawnInstance(e),this.spawnedInstances.delete(i),this.activeClips.delete(i))}}else{const{position:a,rotation:s}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(i),this.spawnForClip(e,t,a,s,i)}}}getInstanceObject(e){switch(e.type){case"actor":return e.instance.object;case"prefab":return e.instance.mainActor?.object||e.instance.object;case"mesh":return e.instance;case"proxy":return e.target instanceof p?e.target.object:e.target;default:return null}}async spawnForClip(e,t,a,r,i){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const s=await this.spawnActorForClip(e,t,a,r);s&&(o={type:"actor",instance:s});break;case"prefab":const i=await this.spawnPrefabForClip(e,t,a,r);i&&(o={type:"prefab",instance:i});break;case"mesh":const n=await this.spawnMeshForClip(e,t,a,r);n&&(o={type:"mesh",instance:n})}if(n!==this.clearCounter)return void(o&&this.despawnInstance(o));const l=this._time.value,c=l>=t.startTime&&l<t.startTime+t.duration;if(o&&c){const t=this.getInstanceObject(o);"proxy"===o.type||("actor"===o.type?o.target=o.instance:"prefab"===o.type?o.target=o.instance.mainActor||o.instance.object:o.target=t);e.subTracks.some(e=>"animation"===e.type)&&t&&(o.mixer=new s(t),o.activeActions=new Map),this.spawnedInstances.set(i,o),this.activeClips.add(i)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(i)}}getPlayableObject(e){return e.target instanceof p?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,a){if(!t||!e.propertyPath)return;const s=this.getPropertyResolution(t,e);if(!s)return;const r=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,r,s);const n=function(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Euler:return function(e,t){const a=Q(t,3);if(!a)return{applied:!1};const s=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof i)return e.set(a[0],a[1],a[2],s),{applied:!0,value:e};return{applied:!0,value:new i(a[0],a[1],a[2],s)}}(e,t.value);case y.Color:return X(e,t.value);default:return{applied:!1}}}(s.owner[s.key],a);n.applied&&(s.owner[s.key]=n.value)}getPropertyResolution(e,t){const a=e,s=this.getPropertySnapshotKey(t);let r=this.propertyResolutionCache.get(a);if(r||(r=new Map,this.propertyResolutionCache.set(a,r)),r.has(s))return r.get(s)??null;const i=this.getPropertyPathSegments(t.propertyPath);if(0===i.length)return r.set(s,null),null;let n=e;for(let e=0;e<i.length-1;e++){if(!K(n))return r.set(s,null),null;n=n[i[e]]}if(!K(n))return r.set(s,null),null;const o={owner:n,key:i[i.length-1]};return r.set(s,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const a=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,a),a}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,a){const s=e;let r=this.propertySnapshots.get(s);if(r||(r=new Map,this.propertySnapshots.set(s,r)),r.has(t))return;const i=a.owner[a.key];r.set(t,{resolution:a,hadOwnProperty:Object.prototype.hasOwnProperty.call(a.owner,a.key),value:i,valueSnapshot:Z(i)})}restorePropertySnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restorePropertySnapshotsForTarget(e.instance);break;case"prefab":this.restorePropertySnapshotsForTarget(e.target??null),this.restorePropertySnapshotsForTarget(e.instance.mainActor??null),this.restorePropertySnapshotsForTarget(e.instance.object);break;case"proxy":this.restorePropertySnapshotsForTarget(e.target)}}restorePropertySnapshotsForTarget(e){if(!e)return;const t=e,a=this.propertySnapshots.get(t);if(a){for(const e of a.values())z(e);this.propertySnapshots.delete(t),this.propertyResolutionCache.delete(t)}}restoreAllPropertySnapshots(){for(const e of Array.from(this.propertySnapshots.keys()))this.restorePropertySnapshotsForTarget(e)}restoreMaterialSnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restoreMaterialSnapshotsForTarget(e.instance);break;case"prefab":this.restoreMaterialSnapshotsForTarget(e.target??null),this.restoreMaterialSnapshotsForTarget(e.instance.mainActor??null),this.restoreMaterialSnapshotsForTarget(e.instance.object);break;case"proxy":this.restoreMaterialSnapshotsForTarget(e.target)}}restoreMaterialSnapshotsForTarget(e){if(!e)return;const t=e;this.materialResolutionCache.delete(t);const a=this.materialSnapshots.get(t);if(a){for(const e of a.values())null==e.materialIndex?e.owner.material=e.originalMaterial:Array.isArray(e.owner.material)&&(e.owner.material[e.materialIndex]=e.originalMaterial),e.controlledMaterial!==e.originalMaterial&&e.controlledMaterial.dispose();this.materialSnapshots.delete(t)}}restoreAllMaterialSnapshots(){for(const e of Array.from(this.materialSnapshots.keys()))this.restoreMaterialSnapshotsForTarget(e)}applyResolvedMaterialValue(e,t,a){if(!t||!e.uniformName)return;if("asset"===S(e)&&!e.materialAssetId)return;const s=this.getMaterialSlotResolutions(t,e);for(const r of s){const s=this.ensureSequenceControlledMaterial(t,r),i=s.uniforms?.[e.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,s.uniformsNeedUpdate=!0)}}getMaterialSlotResolutions(e,t){const a=e,s=S(t),r=`${t.id}:${s}:${t.materialAssetId??""}:${t.uniformName}`;let i=this.materialResolutionCache.get(a);i||(i=new Map,this.materialResolutionCache.set(a,i));const n=i.get(r);if(n)return n;const o=e instanceof p?e.object:e,l=[];return o.traverse(e=>{const a=e.material;if(Array.isArray(a))for(let s=0;s<a.length;s++){const r=a[s];$(r,t)&&l.push({owner:e,materialIndex:s,material:r,key:`${e.uuid}:${s}`})}else $(a,t)&&l.push({owner:e,materialIndex:null,material:a,key:`${e.uuid}:material`})}),i.set(r,l),l}ensureSequenceControlledMaterial(e,t){const a=e;let s=this.materialSnapshots.get(a);s||(s=new Map,this.materialSnapshots.set(a,s));const r=s.get(t.key);if(r)return r.controlledMaterial;const i=t.material.clone();return null==t.materialIndex?t.owner.material=i:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=i),s.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:i}),i}async ensureAnimationClip(e){if(!this.assetLoader)return null;const t=this.animationClips.get(e);if(t)return t;const a=this.loadingAnimationClips.get(e);if(a)return a;const s=(async()=>{try{const t=await this.assetLoader.getAnimationClipByAssetId(e);return t&&this.animationClips.set(e,t),t}catch(t){return console.error(`Failed to load animation clip for asset ${e}:`,t),null}finally{this.loadingAnimationClips.get(e)===s&&this.loadingAnimationClips.delete(e)}})();return this.loadingAnimationClips.set(e,s),s}prepareAnimationPlayback(e,t,a){if(!M(a)){let e=t;return a.clipEndOffset>0&&(e=e.clone(),e.duration=Math.max(0,e.duration-a.clipEndOffset)),{clip:e,timeScale:a.playbackRate,startOffset:a.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,a,!1),timeScale:1,startOffset:0}}getPlayableAnimationClip(e,t,a,s){if(!M(a))return s?j.fromClip(t,!1):t;const r=`${a.id}:${s?"root":"base"}`,i=`${B(a)}|${s?"root":"base"}`,n=this.retimedAnimationClips.get(r);if(n&&n.assetId===e&&n.signature===i)return n.clip;const o=q(t,a),l=s?j.fromClip(o,!1):o;return this.retimedAnimationClips.set(r,{assetId:e,signature:i,clip:l}),l}getAnimationPlaybackLocalTime(e,t){const a=Math.max(0,t-e.startTime);return M(e)?a:a*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,a]of this.retimedAnimationClips.entries())a.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof p?e.target.object:e.target;t&&(e.originalTransform={position:t.position.clone(),rotation:t.rotation.clone(),scale:t.scale.clone()})}}restoreOriginalTransforms(){for(const e of this.bindings.values())if(e.originalTransform){const t=e.target instanceof p?e.target.object:e.target;t&&(t.position.copy(e.originalTransform.position),t.rotation.copy(e.originalTransform.rotation),t.scale.copy(e.originalTransform.scale))}}stopAllAnimations(){for(const e of this.bindings.values()){for(const t of e.activeActions.values())t.stop();e.activeActions.clear(),e.mixer&&e.mixer.stopAllAction(),e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0),e.charAnimActionKeys?.clear()}}stopAllVfx(){for(const e of this.vfxActors.values())e.paused||e.stop();this.activeVfxClips.clear()}dispose(){if(this.stop(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.bindings.clear(),this.roleBindings.clear(),this.sequenceData=null,this.world)for(const e of this.vfxActors.values())this.world.removeActor(e);this.vfxActors.clear(),this.stopAllAudio(),this.audioBuffers.clear(),this.loadingAudioBuffers.clear(),this.animationClips.clear(),this.loadingAnimationClips.clear(),this.clearRetimedAnimationClipCache(),this.audioByClip.clear()}updateTrackParenting(e,t){const a=this.getActiveObjectsForTrack(e);if(0===a.length)return;let s=null;const r=e.parent?.trackId;if(r){const t=this.sequenceData?H(this.sequenceData.tracks).find(e=>e.id===r):void 0;if(t){const a=this.getActiveObjectsForTrack(t);if(a.length>0&&(s=a[0],e.parent?.socketName)){const t=this.findSocket(s,e.parent.socketName);t&&(s=t)}}}if(!s&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const t=this.roleBindings.get(e.parentRole);if(s=t instanceof p?t.object:t,e.parentRoleSocketName){const t=this.findSocket(s,e.parentRoleSocketName);t&&(s=t)}}for(const r of a)s?r.parent!==s&&(s.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=s)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&this.world?.scene.add(r)}findSocket(e,t){if(e.name===t)return e;if(e instanceof a.SkinnedMesh){const a=e.skeleton.bones.find(e=>e.name===t);if(a)return a}return e.getObjectByName(t)||null}getActiveObjectsForTrack(e){if("object"===e.type){const t=this.bindings.get(e.id);if(t&&t.target)return[t.target instanceof p?t.target.object:t.target]}else if("locator"===e.type){const t=this.bindings.get(e.id);if(t&&t.target instanceof n)return[t.target]}else{if("camera"===e.type)return[this.ensureSequenceCamera(e)];if("spawn"===e.type){const t=[];for(const[a,s]of this.spawnedInstances)if(a.startsWith(e.id+"-")&&this.activeClips.has(a)){const e=this.getInstanceObject(s);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const a of this.activeVfxClips)if(a.startsWith(e.id+"-")){const e=this.vfxActors.get(a);e&&t.push(e.object)}return t}}return[]}restoreObjectParent(e,t){e.originalParent?e.originalParent.add(t):this.world&&this.world.scene.add(t),e.currentParent=void 0}restoreOriginalParents(){for(const e of this.bindings.values())if(e.currentParent){const t=e.target instanceof p?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const a={};for(const s of e.subTracks)if("audioParameter"===s.type){const e=s,r=A(e.parameter),i=T(e.keyframes,t,{min:r.min,max:r.max});void 0!==i&&(a[e.parameter]=i)}return a}stringToRandom(e){let t=0;for(let a=0;a<e.length;a++){t=(t<<5)-t+e.charCodeAt(a),t&=t}const a=1e4*Math.sin(t);return a-Math.floor(a)}async refreshAsset(e){let t=!1;this.assetLoader?.clearCacheById(e),this.animationClips.delete(e),this.loadingAnimationClips.delete(e),this.clearRetimedAnimationClipCache(e),this.vfxService?.clearPool(e),t=this.refreshVfxActorsForAssetIds(new Set([e]))||t;for(const[a,s]of this.activePostProcessClips.entries())s.assetId===e&&(this.releasePostProcessClipEffect(a),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const a=await this.getAssetOrNull(e);return"shaderGraph"===a?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[a,s]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(a,e)&&(this.world&&this.world.removeActor(s),this.vfxActors.delete(a),this.activeVfxClips.delete(a),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const a of t)if(e.endsWith(`-${a}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[a,s]of this.spawnedInstances.entries())e.has(a)&&(this.despawnInstance(s),this.spawnedInstances.delete(a),this.activeClips.delete(a),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const a of H(this.sequenceData.tracks))if("spawn"===a.type&&(a.prefabId===e||a.meshId===e))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const a=this.refreshVfxActorsForAssetIds(t),s=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return a||s}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("vfx"===s.type)for(const r of s.clips)null==r.vfxAssetId||t.has(r.vfxAssetId)||await this.assetUsesShaderGraph(r.vfxAssetId,e,a)&&t.add(r.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("spawn"===s.type&&await this.spawnTrackUsesShaderGraph(s,e,a))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,a){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,a))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,a))return!0;for(const s of e.subTracks??[])if("material"===s.type&&null!=s.materialAssetId&&await this.assetUsesShaderGraph(s.materialAssetId,t,a))return!0;return!1}assetUsesShaderGraph(e,t,a,s=new Set){if(e===t)return Promise.resolve(!0);if(s.has(e))return Promise.resolve(!1);if(a.has(e))return a.get(e);const r=this.assetUsesShaderGraphUncached(e,t,a,s);return a.set(e,r),r}async assetUsesShaderGraphUncached(e,t,a,s){if(s.has(e))return!1;const r=await this.getAssetOrNull(e);if(null==r)return!1;const i=new Set(s);return i.add(e),!!this.materialAssetUsesShaderGraph(r,t)||("mesh"===r.type?this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,i):"prefab"===r.type?this.sceneObjectsUseShaderGraph(r.prefab?.objects,t,a,i):"vfx"===r.type&&this.vfxAssetUsesShaderGraph(r,t,a,i))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,a,s){for(const r of e??[])if(null!=r.materialId&&"null"!==r.materialId&&await this.assetUsesShaderGraph(r.materialId,t,a,s))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,a,s){for(const r of e??[]){if(await this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,s))return!0;if(null!=r.assetId&&("asset_mesh"===r.type||"prefab"===r.type||"vfx"===r.type)&&await this.assetUsesShaderGraph(r.assetId,t,a,s))return!0;if(await this.sceneObjectsUseShaderGraph(r.children,t,a,s))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,a,s){for(const r of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterUsesShaderGraph(e,t,a,s){if(await this.emitterOutputUsesShaderGraph(e.output,t,a,s))return!0;for(const r of e.children??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,a,s){const r=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===r&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==r||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,a,s))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,a,s){let r=!1;for(let e=0;e<s.length;e++)if(C(s[e])){r=!0;break}if(r)try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=v(s[e],this.sequenceEventAsyncResolvers);const r=await Promise.all(t);await a.call(e,...r)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=g(s[e],this.sequenceEventSyncResolvers);a.call(e,...t)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}}resolveSequenceEventActorReference(e){if(!this.world||null==e)return null;const t=e,a="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==a)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===a)return e}return null}resolveSequenceEventSequence(e){return function(e){return"object"==typeof e&&null!=e&&"duration"in e&&"tracks"in e}(e)?new w(e):this.assetLoader&&"string"==typeof e?this.assetLoader.getSequenceById(e):null}async resolveSequenceEventAnimationClip(e){const t="string"==typeof e?e:"object"==typeof e&&null!=e?e.assetId??null:null;return null!=t&&this.assetLoader?this.assetLoader.getAnimationClipByAssetId(t):null}}function V(e){return e.options?.length>0||e.propertyType===y.Boolean||e.propertyType===y.String}function D(e){return e.valueType===y.Boolean||e.valueType===y.String}function K(e){return"object"==typeof e&&null!=e||"function"==typeof e}function G(e,t){switch(t.type){case y.Number:return function(e){if("number"==typeof e)return Number.isFinite(e)?{applied:!0,value:e}:{applied:!1};if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?{applied:!0,value:t}:{applied:!1}}return{applied:!1}}(t.value);case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Color:return function(e,t){if(e instanceof c){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b,e.w),{applied:!0,value:e}):{applied:!1}}return X(e,t)}(e,t.value);default:return{applied:!1}}}function $(e,t){const s=S(t);return function(e){return e instanceof a.Material||!0===e?.isMaterial}(e)&&null!=e.uniforms?.[t.uniformName]&&("parameterName"===s||e.userData?.assetId===t.materialAssetId)}function N(e,t){const a=Q(t,2);return a?e instanceof l?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new l(a[0],a[1])}:{applied:!1}}function U(e,t){const a=Q(t,3);return a?e instanceof c?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new c(a[0],a[1],a[2])}:{applied:!1}}function W(e,t){const a=Q(t,4);return a?e instanceof h?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new h(a[0],a[1],a[2],a[3])}:{applied:!1}}function X(e,t){if(e instanceof r)return Y(e,t)?{applied:!0,value:e}:{applied:!1};const a=new r;return Y(a,t)?{applied:!0,value:a}:{applied:!1}}function Q(e,t){if(!Array.isArray(e)||e.length<t)return null;const a=new Array(t);for(let s=0;s<t;s++){if("number"!=typeof e[s])return null;a[s]=e[s]}return a}function Y(e,t){return t instanceof r||"string"==typeof t||"number"==typeof t?(e.set(t),!0):!!(Array.isArray(t)&&t.length>=3)&&(e.setRGB("number"==typeof t[0]?t[0]:0,"number"==typeof t[1]?t[1]:0,"number"==typeof t[2]?t[2]:0),!0)}function Z(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof r||e instanceof i)return e.clone()}function z(e){const{owner:t,key:a}=e.resolution;e.hadOwnProperty?(!function(e,t){if(e instanceof l&&t instanceof l)return e.copy(t),!0;if(e instanceof c&&t instanceof c)return e.copy(t),!0;if(e instanceof h&&t instanceof h)return e.copy(t),!0;if(e instanceof r&&t instanceof r)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0}(e.value,e.valueSnapshot),t[a]=e.value):delete t[a]}function H(e){const t=[];for(const a of e)t.push(a),"group"===a.type&&t.push(...H(a.childTracks));return t}function J(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function ee(e){const t=new a.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const s=new a.AxesHelper(.35);s.renderOrder=1e3;const r=Array.isArray(s.material)?s.material:[s.material];for(const e of r)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(s);const i=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const s=t.getContext("2d");if(!s)return null;s.clearRect(0,0,t.width,t.height),s.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,a,s,r,i){const n=t+s,o=a+r;e.beginPath(),e.moveTo(t+i,a),e.lineTo(n-i,a),e.quadraticCurveTo(n,a,n,a+i),e.lineTo(n,o-i),e.quadraticCurveTo(n,o,n-i,o),e.lineTo(t+i,o),e.quadraticCurveTo(t,o,t,o-i),e.lineTo(t,a+i),e.quadraticCurveTo(t,a,t+i,a),e.closePath()}(s,0,8,t.width,48,8),s.fill(),s.font="24px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillStyle="#f8fafc",s.fillText(e||"Locator",t.width/2,t.height/2);const r=new a.CanvasTexture(t);r.needsUpdate=!0;const i=new a.SpriteMaterial({map:r,transparent:!0,depthTest:!1});i.toneMapped=!1;const n=new a.Sprite(i);return n.scale.set(.9,.225,1),n}(e);return i&&(i.position.set(0,.45,0),i.renderOrder=1001,t.add(i)),t.traverse(e=>{e.raycast=()=>{}}),t}function te(e){e.traverse(e=>{const t=e.material;if(Array.isArray(t))for(const e of t)e?.dispose?.(),e?.map?.dispose?.();else t?.dispose?.(),t?.map?.dispose?.()})}const ae=new c,se=new c,re=new c,ie=new o,ne=new o,oe=new i,le=new i,ce=new r;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{SerializedParamType as e}from"../../scene/model.js";import{Color as t}from"three";export function sortTimedSequenceItems(e){return[...e].sort((e,t)=>e.time-t.time)}export function findKeyframeSpan(e,t){if(0===e.length)return{prev:null,next:null,t:0};let r=null,n=null;for(let u=0;u<e.length;u++)if(e[u].time<=t&&(r=e[u]),e[u].time>t&&!n){n=e[u];break}if(r||(r=e[0]),n||(n=e[e.length-1]),r===n||r.time===n.time)return{prev:r,next:r,t:0};return{prev:r,next:n,t:(t-r.time)/(n.time-r.time)}}export function applyInterpolation(e,t){switch(t){case"linear":case"catmullRom":default:return e;case"step":return 0;case"cubic":return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}export function clampNumericValue(e,t={}){const r=t.min,n=t.max;let u=e;return"number"==typeof r&&(u=Math.max(r,u)),"number"==typeof n&&(u=Math.min(n,u)),u}export function evaluateNumericKeyframes(e,t,n={}){if(0===e.length)return;const{prev:u,next:l,t:a}=findKeyframeSpan(e,t);if(!u)return;const o=r(u.value);if("number"!=typeof o)return;let i=o;if(l&&l!==u){const e=r(l.value);"number"==typeof e&&(i="step"===u.interpolation?o:o+(e-o)*applyInterpolation(a,u.interpolation))}return clampNumericValue(i,n)}export function evaluateCustomParamValueKeyframes(t,r,f={}){if(0===t.length)return null;const{prev:c,next:m,t:s}=findKeyframeSpan(t,r);if(!c)return null;const y=c.value;if(!m||m===c)return n(y,f);if(!f.stepOnly&&"step"!==c.interpolation){const t=function(t,r,n,f){if(t?.type!==r?.type)return null;if(t.type===e.Number&&r.type===e.Number)return"number"!=typeof t.value||"number"!=typeof r.value?null:{type:e.Number,value:clampNumericValue(t.value+(r.value-t.value)*n,f)};const c=u(t.type);if(c>0){const u=l(t.value,c),o=l(r.value,c);if(!u||!o)return null;const i=new Array(c);for(let e=0;e<c;e++)i[e]=clampNumericValue(u[e]+(o[e]-u[e])*n,f);return t.type===e.Euler&&(i[3]=a(t.value)??a(r.value)??"XYZ"),{type:t.type,value:i}}if(t.type===e.Color){const u=function(e,t,r){try{return o(i,e),o(p,t),i.lerp(p,r),`#${i.getHexString()}`}catch{return null}}(t.value,r.value,n);return null==u?null:{type:e.Color,value:u}}return null}(y,m.value,applyInterpolation(s,c.interpolation),f);if(t)return t}return n(y,f)}function r(t){if(t?.type===e.Number)return"number"==typeof t.value?t.value:void 0}function n(t,r){if(t?.type===e.Number&&"number"==typeof t.value)return{...t,value:clampNumericValue(t.value,r)};const n=u(t?.type);if(n>0){const e=t.value;if(!Array.isArray(e))return t;const u=e.slice();for(let e=0;e<Math.min(n,u.length);e++)"number"==typeof u[e]&&(u[e]=clampNumericValue(u[e],r));return{...t,value:u}}return t}function u(t){switch(t){case e.Vector2:return 2;case e.Vector3:return 3;case e.Vector4:return 4;case e.Euler:return 3;default:return 0}}function l(e,t){if(!Array.isArray(e)||e.length<t)return null;const r=new Array(t);for(let n=0;n<t;n++){if("number"!=typeof e[n])return null;r[n]=e[n]}return r}function a(e){return Array.isArray(e)&&"string"==typeof e[3]?e[3]:void 0}function o(e,r){if(r instanceof t||"string"==typeof r||"number"==typeof r)e.set(r);else{if(!(Array.isArray(r)&&r.length>=3))throw new Error("Unsupported color value");e.setRGB(Number(r[0])||0,Number(r[1])||0,Number(r[2])||0)}}const i=new t,p=new t;/*
1
+ import{SerializedParamType as e}from"../../scene/model.js";import{Color as t}from"three";export function sortTimedSequenceItems(e){return[...e].sort((e,t)=>e.time-t.time)}export function findKeyframeSpan(e,t){if(0===e.length)return{prev:null,next:null,t:0};let r=null,n=null;for(let u=0;u<e.length;u++)if(e[u].time<=t&&(r=e[u]),e[u].time>t&&!n){n=e[u];break}if(r||(r=e[0]),n||(n=e[e.length-1]),r===n||r.time===n.time)return{prev:r,next:r,t:0};return{prev:r,next:n,t:(t-r.time)/(n.time-r.time)}}export function applyInterpolation(e,t){switch(t){case"linear":case"catmullRom":default:return e;case"step":return 0;case"cubic":return e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2}}export function clampNumericValue(e,t={}){const r=t.min,n=t.max;let u=e;return"number"==typeof r&&(u=Math.max(r,u)),"number"==typeof n&&(u=Math.min(n,u)),u}export function evaluateNumericKeyframes(e,t,n={}){if(0===e.length)return;const{prev:u,next:l,t:i}=findKeyframeSpan(e,t);if(!u)return;const a=r(u.value);if("number"!=typeof a)return;let o=a;if(l&&l!==u){const e=r(l.value);"number"==typeof e&&(o="step"===u.interpolation?a:a+(e-a)*applyInterpolation(i,u.interpolation))}return clampNumericValue(o,n)}export function evaluateCustomParamValueKeyframes(t,r,p={}){if(0===t.length)return null;const{prev:m,next:s,t:y}=findKeyframeSpan(t,r);if(!m)return null;const v=m.value;if(!s||s===m)return n(v,p);if(!p.stepOnly&&"step"!==m.interpolation){const t=function(t,r,n,p){if(t?.type!==r?.type)return null;if(t.type===e.Number&&r.type===e.Number){const u=i(t.value),l=i(r.value);return null==u||null==l?null:{type:e.Number,value:clampNumericValue(u+(l-u)*n,p)}}const m=u(t.type);if(m>0){const u=l(t.value,m),i=l(r.value,m);if(!u||!i)return null;const o=new Array(m);for(let e=0;e<m;e++)o[e]=clampNumericValue(u[e]+(i[e]-u[e])*n,p);return t.type===e.Euler&&(o[3]=a(t.value)??a(r.value)??"XYZ"),{type:t.type,value:o}}if(t.type===e.Color){const u=function(e,t,r){try{return o(c,e),o(f,t),c.lerp(f,r),`#${c.getHexString()}`}catch{return null}}(t.value,r.value,n);return null==u?null:{type:e.Color,value:u}}return null}(v,s.value,applyInterpolation(y,m.interpolation),p);if(t)return t}return n(v,p)}function r(t){if(t?.type===e.Number)return i(t.value)??void 0}function n(t,r){if(t?.type===e.Number&&"number"==typeof t.value)return{...t,value:clampNumericValue(t.value,r)};if(t?.type===e.Number){const e=i(t.value);if(null!=e)return{...t,value:clampNumericValue(e,r)}}const n=u(t?.type);if(n>0){const e=t.value;if(!Array.isArray(e))return t;const u=e.slice();for(let e=0;e<Math.min(n,u.length);e++){const t=i(u[e]);null!=t&&(u[e]=clampNumericValue(t,r))}return{...t,value:u}}return t}function u(t){switch(t){case e.Vector2:return 2;case e.Vector3:return 3;case e.Vector4:return 4;case e.Euler:return 3;default:return 0}}function l(e,t){if(!Array.isArray(e)||e.length<t)return null;const r=new Array(t);for(let n=0;n<t;n++){const t=i(e[n]);if(null==t)return null;r[n]=t}return r}function i(e){if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?t:null}return null}function a(e){return Array.isArray(e)&&"string"==typeof e[3]?e[3]:void 0}function o(e,r){if(r instanceof t||"string"==typeof r||"number"==typeof r)e.set(r);else{if(!(Array.isArray(r)&&r.length>=3))throw new Error("Unsupported color value");e.setRGB(Number(r[0])||0,Number(r[1])||0,Number(r[2])||0)}}const c=new t,f=new t;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */