@luma.gl/engine 9.0.0-alpha.33 → 9.0.0-alpha.34

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 (39) hide show
  1. package/dist/animation/key-frames.js +6 -7
  2. package/dist/animation/key-frames.js.map +1 -1
  3. package/dist/animation/timeline.js +5 -6
  4. package/dist/animation/timeline.js.map +1 -1
  5. package/dist/animation-loop/animation-loop.js +18 -19
  6. package/dist/animation-loop/animation-loop.js.map +1 -1
  7. package/dist/dist.dev.js +88 -96
  8. package/dist/geometries/ico-sphere-geometry.js +1 -1
  9. package/dist/geometries/ico-sphere-geometry.js.map +1 -1
  10. package/dist/geometries/plane-geometry.js +4 -4
  11. package/dist/geometries/plane-geometry.js.map +1 -1
  12. package/dist/geometry/geometry.js +8 -9
  13. package/dist/geometry/geometry.js.map +1 -1
  14. package/dist/geometry/gpu-geometry.d.ts +4 -15
  15. package/dist/geometry/gpu-geometry.d.ts.map +1 -1
  16. package/dist/geometry/gpu-geometry.js +27 -62
  17. package/dist/geometry/gpu-geometry.js.map +1 -1
  18. package/dist/index.cjs +28 -44
  19. package/dist/lib/clip-space.js +16 -3
  20. package/dist/lib/clip-space.js.map +1 -1
  21. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  22. package/dist/lib/pipeline-factory.js +15 -11
  23. package/dist/lib/pipeline-factory.js.map +1 -1
  24. package/dist/model/model.d.ts.map +1 -1
  25. package/dist/model/model.js +27 -34
  26. package/dist/model/model.js.map +1 -1
  27. package/dist/scenegraph/group-node.js +1 -2
  28. package/dist/scenegraph/group-node.js.map +1 -1
  29. package/dist/scenegraph/model-node.js +3 -4
  30. package/dist/scenegraph/model-node.js.map +1 -1
  31. package/dist/scenegraph/scenegraph-node.js +9 -10
  32. package/dist/scenegraph/scenegraph-node.js.map +1 -1
  33. package/dist/transform/transform.js +4 -5
  34. package/dist/transform/transform.js.map +1 -1
  35. package/dist.min.js +75 -75
  36. package/package.json +6 -6
  37. package/src/geometry/gpu-geometry.ts +18 -52
  38. package/src/lib/pipeline-factory.ts +13 -10
  39. package/src/model/model.ts +3 -12
@@ -1,12 +1,11 @@
1
- import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
1
  export class KeyFrames {
3
2
  constructor(keyFrames) {
4
- _defineProperty(this, "startIndex", -1);
5
- _defineProperty(this, "endIndex", -1);
6
- _defineProperty(this, "factor", 0);
7
- _defineProperty(this, "times", []);
8
- _defineProperty(this, "values", []);
9
- _defineProperty(this, "_lastTime", -1);
3
+ this.startIndex = -1;
4
+ this.endIndex = -1;
5
+ this.factor = 0;
6
+ this.times = [];
7
+ this.values = [];
8
+ this._lastTime = -1;
10
9
  this.setKeyFrames(keyFrames);
11
10
  this.setTime(0);
12
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"key-frames.js","names":["KeyFrames","constructor","keyFrames","_defineProperty","setKeyFrames","setTime","numKeys","length","times","values","i","_calculateKeys","_lastTime","time","Math","max","getStartTime","startIndex","getEndTime","endIndex","getStartData","getEndData","index","startTime","endTime","factor","min"],"sources":["../../src/animation/key-frames.ts"],"sourcesContent":["// keyframes\nexport type KeyFrame<T> = [number, T];\n\n/** Holds a list of key frames (timestamped values) */\nexport class KeyFrames<T = number> {\n startIndex: number = -1;\n endIndex: number = -1;\n factor: number = 0;\n times: number[] = [];\n values: T[] = [];\n private _lastTime = -1;\n\n constructor(keyFrames: KeyFrame<T>[]) {\n this.setKeyFrames(keyFrames);\n this.setTime(0);\n }\n\n setKeyFrames(keyFrames: KeyFrame<T>[]): void {\n const numKeys = keyFrames.length;\n this.times.length = numKeys;\n this.values.length = numKeys;\n\n for (let i = 0; i < numKeys; ++i) {\n this.times[i] = keyFrames[i][0];\n this.values[i] = keyFrames[i][1];\n }\n\n this._calculateKeys(this._lastTime);\n }\n\n setTime(time: number): void {\n time = Math.max(0, time);\n\n if (time !== this._lastTime) {\n this._calculateKeys(time);\n this._lastTime = time;\n }\n }\n\n getStartTime(): number {\n return this.times[this.startIndex];\n }\n\n getEndTime(): number {\n return this.times[this.endIndex];\n }\n\n getStartData(): T {\n return this.values[this.startIndex];\n }\n\n getEndData(): T {\n return this.values[this.endIndex];\n }\n\n _calculateKeys(time: number): void {\n let index = 0;\n const numKeys = this.times.length;\n\n for (index = 0; index < numKeys - 2; ++index) {\n if (this.times[index + 1] > time) {\n break;\n }\n }\n\n this.startIndex = index;\n this.endIndex = index + 1;\n\n const startTime = this.times[this.startIndex];\n const endTime = this.times[this.endIndex];\n this.factor = Math.min(Math.max(0, (time - startTime) / (endTime - startTime)), 1);\n }\n}\n"],"mappings":";AAIA,OAAO,MAAMA,SAAS,CAAa;EAQjCC,WAAWA,CAACC,SAAwB,EAAE;IAAAC,eAAA,qBAPjB,CAAC,CAAC;IAAAA,eAAA,mBACJ,CAAC,CAAC;IAAAA,eAAA,iBACJ,CAAC;IAAAA,eAAA,gBACA,EAAE;IAAAA,eAAA,iBACN,EAAE;IAAAA,eAAA,oBACI,CAAC,CAAC;IAGpB,IAAI,CAACC,YAAY,CAACF,SAAS,CAAC;IAC5B,IAAI,CAACG,OAAO,CAAC,CAAC,CAAC;EACjB;EAEAD,YAAYA,CAACF,SAAwB,EAAQ;IAC3C,MAAMI,OAAO,GAAGJ,SAAS,CAACK,MAAM;IAChC,IAAI,CAACC,KAAK,CAACD,MAAM,GAAGD,OAAO;IAC3B,IAAI,CAACG,MAAM,CAACF,MAAM,GAAGD,OAAO;IAE5B,KAAK,IAAII,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,OAAO,EAAE,EAAEI,CAAC,EAAE;MAChC,IAAI,CAACF,KAAK,CAACE,CAAC,CAAC,GAAGR,SAAS,CAACQ,CAAC,CAAC,CAAC,CAAC,CAAC;MAC/B,IAAI,CAACD,MAAM,CAACC,CAAC,CAAC,GAAGR,SAAS,CAACQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC;IAEA,IAAI,CAACC,cAAc,CAAC,IAAI,CAACC,SAAS,CAAC;EACrC;EAEAP,OAAOA,CAACQ,IAAY,EAAQ;IAC1BA,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEF,IAAI,CAAC;IAExB,IAAIA,IAAI,KAAK,IAAI,CAACD,SAAS,EAAE;MAC3B,IAAI,CAACD,cAAc,CAACE,IAAI,CAAC;MACzB,IAAI,CAACD,SAAS,GAAGC,IAAI;IACvB;EACF;EAEAG,YAAYA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACR,KAAK,CAAC,IAAI,CAACS,UAAU,CAAC;EACpC;EAEAC,UAAUA,CAAA,EAAW;IACnB,OAAO,IAAI,CAACV,KAAK,CAAC,IAAI,CAACW,QAAQ,CAAC;EAClC;EAEAC,YAAYA,CAAA,EAAM;IAChB,OAAO,IAAI,CAACX,MAAM,CAAC,IAAI,CAACQ,UAAU,CAAC;EACrC;EAEAI,UAAUA,CAAA,EAAM;IACd,OAAO,IAAI,CAACZ,MAAM,CAAC,IAAI,CAACU,QAAQ,CAAC;EACnC;EAEAR,cAAcA,CAACE,IAAY,EAAQ;IACjC,IAAIS,KAAK,GAAG,CAAC;IACb,MAAMhB,OAAO,GAAG,IAAI,CAACE,KAAK,CAACD,MAAM;IAEjC,KAAKe,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGhB,OAAO,GAAG,CAAC,EAAE,EAAEgB,KAAK,EAAE;MAC5C,IAAI,IAAI,CAACd,KAAK,CAACc,KAAK,GAAG,CAAC,CAAC,GAAGT,IAAI,EAAE;QAChC;MACF;IACF;IAEA,IAAI,CAACI,UAAU,GAAGK,KAAK;IACvB,IAAI,CAACH,QAAQ,GAAGG,KAAK,GAAG,CAAC;IAEzB,MAAMC,SAAS,GAAG,IAAI,CAACf,KAAK,CAAC,IAAI,CAACS,UAAU,CAAC;IAC7C,MAAMO,OAAO,GAAG,IAAI,CAAChB,KAAK,CAAC,IAAI,CAACW,QAAQ,CAAC;IACzC,IAAI,CAACM,MAAM,GAAGX,IAAI,CAACY,GAAG,CAACZ,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE,CAACF,IAAI,GAAGU,SAAS,KAAKC,OAAO,GAAGD,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;EACpF;AACF"}
1
+ {"version":3,"file":"key-frames.js","names":["KeyFrames","constructor","keyFrames","startIndex","endIndex","factor","times","values","_lastTime","setKeyFrames","setTime","numKeys","length","i","_calculateKeys","time","Math","max","getStartTime","getEndTime","getStartData","getEndData","index","startTime","endTime","min"],"sources":["../../src/animation/key-frames.ts"],"sourcesContent":["// keyframes\nexport type KeyFrame<T> = [number, T];\n\n/** Holds a list of key frames (timestamped values) */\nexport class KeyFrames<T = number> {\n startIndex: number = -1;\n endIndex: number = -1;\n factor: number = 0;\n times: number[] = [];\n values: T[] = [];\n private _lastTime = -1;\n\n constructor(keyFrames: KeyFrame<T>[]) {\n this.setKeyFrames(keyFrames);\n this.setTime(0);\n }\n\n setKeyFrames(keyFrames: KeyFrame<T>[]): void {\n const numKeys = keyFrames.length;\n this.times.length = numKeys;\n this.values.length = numKeys;\n\n for (let i = 0; i < numKeys; ++i) {\n this.times[i] = keyFrames[i][0];\n this.values[i] = keyFrames[i][1];\n }\n\n this._calculateKeys(this._lastTime);\n }\n\n setTime(time: number): void {\n time = Math.max(0, time);\n\n if (time !== this._lastTime) {\n this._calculateKeys(time);\n this._lastTime = time;\n }\n }\n\n getStartTime(): number {\n return this.times[this.startIndex];\n }\n\n getEndTime(): number {\n return this.times[this.endIndex];\n }\n\n getStartData(): T {\n return this.values[this.startIndex];\n }\n\n getEndData(): T {\n return this.values[this.endIndex];\n }\n\n _calculateKeys(time: number): void {\n let index = 0;\n const numKeys = this.times.length;\n\n for (index = 0; index < numKeys - 2; ++index) {\n if (this.times[index + 1] > time) {\n break;\n }\n }\n\n this.startIndex = index;\n this.endIndex = index + 1;\n\n const startTime = this.times[this.startIndex];\n const endTime = this.times[this.endIndex];\n this.factor = Math.min(Math.max(0, (time - startTime) / (endTime - startTime)), 1);\n }\n}\n"],"mappings":"AAIA,OAAO,MAAMA,SAAS,CAAa;EAQjCC,WAAWA,CAACC,SAAwB,EAAE;IAAA,KAPtCC,UAAU,GAAW,CAAC,CAAC;IAAA,KACvBC,QAAQ,GAAW,CAAC,CAAC;IAAA,KACrBC,MAAM,GAAW,CAAC;IAAA,KAClBC,KAAK,GAAa,EAAE;IAAA,KACpBC,MAAM,GAAQ,EAAE;IAAA,KACRC,SAAS,GAAG,CAAC,CAAC;IAGpB,IAAI,CAACC,YAAY,CAACP,SAAS,CAAC;IAC5B,IAAI,CAACQ,OAAO,CAAC,CAAC,CAAC;EACjB;EAEAD,YAAYA,CAACP,SAAwB,EAAQ;IAC3C,MAAMS,OAAO,GAAGT,SAAS,CAACU,MAAM;IAChC,IAAI,CAACN,KAAK,CAACM,MAAM,GAAGD,OAAO;IAC3B,IAAI,CAACJ,MAAM,CAACK,MAAM,GAAGD,OAAO;IAE5B,KAAK,IAAIE,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,OAAO,EAAE,EAAEE,CAAC,EAAE;MAChC,IAAI,CAACP,KAAK,CAACO,CAAC,CAAC,GAAGX,SAAS,CAACW,CAAC,CAAC,CAAC,CAAC,CAAC;MAC/B,IAAI,CAACN,MAAM,CAACM,CAAC,CAAC,GAAGX,SAAS,CAACW,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC;IAEA,IAAI,CAACC,cAAc,CAAC,IAAI,CAACN,SAAS,CAAC;EACrC;EAEAE,OAAOA,CAACK,IAAY,EAAQ;IAC1BA,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEF,IAAI,CAAC;IAExB,IAAIA,IAAI,KAAK,IAAI,CAACP,SAAS,EAAE;MAC3B,IAAI,CAACM,cAAc,CAACC,IAAI,CAAC;MACzB,IAAI,CAACP,SAAS,GAAGO,IAAI;IACvB;EACF;EAEAG,YAAYA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACZ,KAAK,CAAC,IAAI,CAACH,UAAU,CAAC;EACpC;EAEAgB,UAAUA,CAAA,EAAW;IACnB,OAAO,IAAI,CAACb,KAAK,CAAC,IAAI,CAACF,QAAQ,CAAC;EAClC;EAEAgB,YAAYA,CAAA,EAAM;IAChB,OAAO,IAAI,CAACb,MAAM,CAAC,IAAI,CAACJ,UAAU,CAAC;EACrC;EAEAkB,UAAUA,CAAA,EAAM;IACd,OAAO,IAAI,CAACd,MAAM,CAAC,IAAI,CAACH,QAAQ,CAAC;EACnC;EAEAU,cAAcA,CAACC,IAAY,EAAQ;IACjC,IAAIO,KAAK,GAAG,CAAC;IACb,MAAMX,OAAO,GAAG,IAAI,CAACL,KAAK,CAACM,MAAM;IAEjC,KAAKU,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGX,OAAO,GAAG,CAAC,EAAE,EAAEW,KAAK,EAAE;MAC5C,IAAI,IAAI,CAAChB,KAAK,CAACgB,KAAK,GAAG,CAAC,CAAC,GAAGP,IAAI,EAAE;QAChC;MACF;IACF;IAEA,IAAI,CAACZ,UAAU,GAAGmB,KAAK;IACvB,IAAI,CAAClB,QAAQ,GAAGkB,KAAK,GAAG,CAAC;IAEzB,MAAMC,SAAS,GAAG,IAAI,CAACjB,KAAK,CAAC,IAAI,CAACH,UAAU,CAAC;IAC7C,MAAMqB,OAAO,GAAG,IAAI,CAAClB,KAAK,CAAC,IAAI,CAACF,QAAQ,CAAC;IACzC,IAAI,CAACC,MAAM,GAAGW,IAAI,CAACS,GAAG,CAACT,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE,CAACF,IAAI,GAAGQ,SAAS,KAAKC,OAAO,GAAGD,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;EACpF;AACF"}
@@ -1,13 +1,12 @@
1
- import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
1
  let channelHandles = 1;
3
2
  let animationHandles = 1;
4
3
  export class Timeline {
5
4
  constructor() {
6
- _defineProperty(this, "time", 0);
7
- _defineProperty(this, "channels", new Map());
8
- _defineProperty(this, "animations", new Map());
9
- _defineProperty(this, "playing", false);
10
- _defineProperty(this, "lastEngineTime", -1);
5
+ this.time = 0;
6
+ this.channels = new Map();
7
+ this.animations = new Map();
8
+ this.playing = false;
9
+ this.lastEngineTime = -1;
11
10
  }
12
11
  addChannel(props) {
13
12
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.js","names":["channelHandles","animationHandles","Timeline","constructor","_defineProperty","Map","addChannel","props","delay","duration","Number","POSITIVE_INFINITY","rate","repeat","handle","channel","time","_setChannelTime","channels","set","removeChannel","delete","animationHandle","animation","animations","detachAnimation","isFinished","get","undefined","getTime","setTime","Math","max","values","animationData","play","playing","pause","lastEngineTime","reset","attachAnimation","channelHandle","update","engineTime","offsetTime","totalDuration"],"sources":["../../src/animation/timeline.ts"],"sourcesContent":["// luma.gl, MIT license\n\n/**\n * Timeline channel properties\n * @param delay = 0;\n * @param duration = Number.POSITIVE_INFINITY;\n * @param rate = 1\n * @param repeat = 1\n */\nexport type ChannelOptions = {\n delay?: number\n duration?: number\n rate?: number\n repeat?: number\n}\n\nexport type AnimationOptions = {\n setTime: (time: number) => void\n}\n\n type Channel = {\n time: number\n delay: number\n duration: number\n rate: number\n repeat: number\n}\n\ntype Animation = {\n channel?: number;\n animation: {\n setTime: (time: number) => void\n }\n}\n\nlet channelHandles = 1;\nlet animationHandles = 1;\n\nexport class Timeline {\n time: number = 0;\n channels = new Map<number, Channel>();\n animations = new Map<number, Animation>();\n playing: boolean = false;\n lastEngineTime: number = -1;\n\n constructor() {\n }\n\n addChannel(props: ChannelOptions): number {\n const {delay = 0, duration = Number.POSITIVE_INFINITY, rate = 1, repeat = 1} = props;\n\n const handle = channelHandles++;\n const channel: Channel = {\n time: 0,\n delay,\n duration,\n rate,\n repeat\n };\n this._setChannelTime(channel, this.time);\n this.channels.set(handle, channel);\n\n return handle;\n }\n\n removeChannel(handle: number): void {\n this.channels.delete(handle);\n\n for (const [animationHandle, animation] of this.animations) {\n if (animation.channel === handle) {\n this.detachAnimation(animationHandle);\n }\n }\n }\n\n isFinished(handle: number): boolean {\n const channel = this.channels.get(handle);\n if (channel === undefined) {\n return false;\n }\n\n return this.time >= channel.delay + channel.duration * channel.repeat;\n }\n\n getTime(handle?: number): number {\n if (handle === undefined) {\n return this.time;\n }\n\n const channel = this.channels.get(handle);\n\n if (channel === undefined) {\n return -1;\n }\n\n return channel.time;\n }\n\n setTime(time: number): void {\n this.time = Math.max(0, time);\n\n const channels = this.channels.values();\n for (const channel of channels) {\n this._setChannelTime(channel, this.time);\n }\n\n const animations = this.animations.values();\n for (const animationData of animations) {\n const {animation, channel} = animationData;\n animation.setTime(this.getTime(channel));\n }\n }\n\n play(): void {\n this.playing = true;\n }\n\n pause(): void {\n this.playing = false;\n this.lastEngineTime = -1;\n }\n\n reset(): void {\n this.setTime(0);\n }\n\n attachAnimation(animation: AnimationOptions, channelHandle?: number): number {\n const animationHandle = animationHandles++;\n\n this.animations.set(animationHandle, {\n animation,\n channel: channelHandle\n });\n\n animation.setTime(this.getTime(channelHandle));\n\n return animationHandle;\n }\n\n detachAnimation(handle: number): void {\n this.animations.delete(handle);\n }\n\n update(engineTime: number): void {\n if (this.playing) {\n if (this.lastEngineTime === -1) {\n this.lastEngineTime = engineTime;\n }\n this.setTime(this.time + (engineTime - this.lastEngineTime));\n this.lastEngineTime = engineTime;\n }\n }\n\n _setChannelTime(channel: Channel, time: number): void {\n const offsetTime = time - channel.delay;\n const totalDuration = channel.duration * channel.repeat;\n // Note(Tarek): Don't loop on final repeat.\n if (offsetTime >= totalDuration) {\n channel.time = channel.duration * channel.rate;\n } else {\n channel.time = Math.max(0, offsetTime) % channel.duration;\n channel.time *= channel.rate;\n }\n }\n}\n"],"mappings":";AAmCA,IAAIA,cAAc,GAAG,CAAC;AACtB,IAAIC,gBAAgB,GAAG,CAAC;AAExB,OAAO,MAAMC,QAAQ,CAAC;EAOpBC,WAAWA,CAAA,EAAG;IAAAC,eAAA,eANC,CAAC;IAAAA,eAAA,mBACL,IAAIC,GAAG,CAAkB,CAAC;IAAAD,eAAA,qBACxB,IAAIC,GAAG,CAAoB,CAAC;IAAAD,eAAA,kBACtB,KAAK;IAAAA,eAAA,yBACC,CAAC,CAAC;EAG3B;EAEAE,UAAUA,CAACC,KAAqB,EAAU;IACxC,MAAM;MAACC,KAAK,GAAG,CAAC;MAAEC,QAAQ,GAAGC,MAAM,CAACC,iBAAiB;MAAEC,IAAI,GAAG,CAAC;MAAEC,MAAM,GAAG;IAAC,CAAC,GAAGN,KAAK;IAEpF,MAAMO,MAAM,GAAGd,cAAc,EAAE;IAC/B,MAAMe,OAAgB,GAAG;MACvBC,IAAI,EAAE,CAAC;MACPR,KAAK;MACLC,QAAQ;MACRG,IAAI;MACJC;IACF,CAAC;IACD,IAAI,CAACI,eAAe,CAACF,OAAO,EAAE,IAAI,CAACC,IAAI,CAAC;IACxC,IAAI,CAACE,QAAQ,CAACC,GAAG,CAACL,MAAM,EAAEC,OAAO,CAAC;IAElC,OAAOD,MAAM;EACf;EAEAM,aAAaA,CAACN,MAAc,EAAQ;IAClC,IAAI,CAACI,QAAQ,CAACG,MAAM,CAACP,MAAM,CAAC;IAE5B,KAAK,MAAM,CAACQ,eAAe,EAAEC,SAAS,CAAC,IAAI,IAAI,CAACC,UAAU,EAAE;MAC1D,IAAID,SAAS,CAACR,OAAO,KAAKD,MAAM,EAAE;QAChC,IAAI,CAACW,eAAe,CAACH,eAAe,CAAC;MACvC;IACF;EACF;EAEAI,UAAUA,CAACZ,MAAc,EAAW;IAClC,MAAMC,OAAO,GAAG,IAAI,CAACG,QAAQ,CAACS,GAAG,CAACb,MAAM,CAAC;IACzC,IAAIC,OAAO,KAAKa,SAAS,EAAE;MACzB,OAAO,KAAK;IACd;IAEA,OAAO,IAAI,CAACZ,IAAI,IAAID,OAAO,CAACP,KAAK,GAAGO,OAAO,CAACN,QAAQ,GAAGM,OAAO,CAACF,MAAM;EACvE;EAEAgB,OAAOA,CAACf,MAAe,EAAU;IAC/B,IAAIA,MAAM,KAAKc,SAAS,EAAE;MACxB,OAAO,IAAI,CAACZ,IAAI;IAClB;IAEA,MAAMD,OAAO,GAAG,IAAI,CAACG,QAAQ,CAACS,GAAG,CAACb,MAAM,CAAC;IAEzC,IAAIC,OAAO,KAAKa,SAAS,EAAE;MACzB,OAAO,CAAC,CAAC;IACX;IAEA,OAAOb,OAAO,CAACC,IAAI;EACrB;EAEAc,OAAOA,CAACd,IAAY,EAAQ;IAC1B,IAAI,CAACA,IAAI,GAAGe,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEhB,IAAI,CAAC;IAE7B,MAAME,QAAQ,GAAG,IAAI,CAACA,QAAQ,CAACe,MAAM,CAAC,CAAC;IACvC,KAAK,MAAMlB,OAAO,IAAIG,QAAQ,EAAE;MAC9B,IAAI,CAACD,eAAe,CAACF,OAAO,EAAE,IAAI,CAACC,IAAI,CAAC;IAC1C;IAEA,MAAMQ,UAAU,GAAG,IAAI,CAACA,UAAU,CAACS,MAAM,CAAC,CAAC;IAC3C,KAAK,MAAMC,aAAa,IAAIV,UAAU,EAAE;MACtC,MAAM;QAACD,SAAS;QAAER;MAAO,CAAC,GAAGmB,aAAa;MAC1CX,SAAS,CAACO,OAAO,CAAC,IAAI,CAACD,OAAO,CAACd,OAAO,CAAC,CAAC;IAC1C;EACF;EAEAoB,IAAIA,CAAA,EAAS;IACX,IAAI,CAACC,OAAO,GAAG,IAAI;EACrB;EAEAC,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACD,OAAO,GAAG,KAAK;IACpB,IAAI,CAACE,cAAc,GAAG,CAAC,CAAC;EAC1B;EAEAC,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACT,OAAO,CAAC,CAAC,CAAC;EACjB;EAEAU,eAAeA,CAACjB,SAA2B,EAAEkB,aAAsB,EAAU;IAC3E,MAAMnB,eAAe,GAAGrB,gBAAgB,EAAE;IAE1C,IAAI,CAACuB,UAAU,CAACL,GAAG,CAACG,eAAe,EAAE;MACnCC,SAAS;MACTR,OAAO,EAAE0B;IACX,CAAC,CAAC;IAEFlB,SAAS,CAACO,OAAO,CAAC,IAAI,CAACD,OAAO,CAACY,aAAa,CAAC,CAAC;IAE9C,OAAOnB,eAAe;EACxB;EAEAG,eAAeA,CAACX,MAAc,EAAQ;IACpC,IAAI,CAACU,UAAU,CAACH,MAAM,CAACP,MAAM,CAAC;EAChC;EAEA4B,MAAMA,CAACC,UAAkB,EAAQ;IAC/B,IAAI,IAAI,CAACP,OAAO,EAAE;MAChB,IAAI,IAAI,CAACE,cAAc,KAAK,CAAC,CAAC,EAAE;QAC9B,IAAI,CAACA,cAAc,GAAGK,UAAU;MAClC;MACA,IAAI,CAACb,OAAO,CAAC,IAAI,CAACd,IAAI,IAAI2B,UAAU,GAAG,IAAI,CAACL,cAAc,CAAC,CAAC;MAC5D,IAAI,CAACA,cAAc,GAAGK,UAAU;IAClC;EACF;EAEA1B,eAAeA,CAACF,OAAgB,EAAEC,IAAY,EAAQ;IACpD,MAAM4B,UAAU,GAAG5B,IAAI,GAAGD,OAAO,CAACP,KAAK;IACvC,MAAMqC,aAAa,GAAG9B,OAAO,CAACN,QAAQ,GAAGM,OAAO,CAACF,MAAM;IAEvD,IAAI+B,UAAU,IAAIC,aAAa,EAAE;MAC/B9B,OAAO,CAACC,IAAI,GAAGD,OAAO,CAACN,QAAQ,GAAGM,OAAO,CAACH,IAAI;IAChD,CAAC,MAAM;MACLG,OAAO,CAACC,IAAI,GAAGe,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEY,UAAU,CAAC,GAAG7B,OAAO,CAACN,QAAQ;MACzDM,OAAO,CAACC,IAAI,IAAID,OAAO,CAACH,IAAI;IAC9B;EACF;AACF"}
1
+ {"version":3,"file":"timeline.js","names":["channelHandles","animationHandles","Timeline","constructor","time","channels","Map","animations","playing","lastEngineTime","addChannel","props","delay","duration","Number","POSITIVE_INFINITY","rate","repeat","handle","channel","_setChannelTime","set","removeChannel","delete","animationHandle","animation","detachAnimation","isFinished","get","undefined","getTime","setTime","Math","max","values","animationData","play","pause","reset","attachAnimation","channelHandle","update","engineTime","offsetTime","totalDuration"],"sources":["../../src/animation/timeline.ts"],"sourcesContent":["// luma.gl, MIT license\n\n/**\n * Timeline channel properties\n * @param delay = 0;\n * @param duration = Number.POSITIVE_INFINITY;\n * @param rate = 1\n * @param repeat = 1\n */\nexport type ChannelOptions = {\n delay?: number\n duration?: number\n rate?: number\n repeat?: number\n}\n\nexport type AnimationOptions = {\n setTime: (time: number) => void\n}\n\n type Channel = {\n time: number\n delay: number\n duration: number\n rate: number\n repeat: number\n}\n\ntype Animation = {\n channel?: number;\n animation: {\n setTime: (time: number) => void\n }\n}\n\nlet channelHandles = 1;\nlet animationHandles = 1;\n\nexport class Timeline {\n time: number = 0;\n channels = new Map<number, Channel>();\n animations = new Map<number, Animation>();\n playing: boolean = false;\n lastEngineTime: number = -1;\n\n constructor() {\n }\n\n addChannel(props: ChannelOptions): number {\n const {delay = 0, duration = Number.POSITIVE_INFINITY, rate = 1, repeat = 1} = props;\n\n const handle = channelHandles++;\n const channel: Channel = {\n time: 0,\n delay,\n duration,\n rate,\n repeat\n };\n this._setChannelTime(channel, this.time);\n this.channels.set(handle, channel);\n\n return handle;\n }\n\n removeChannel(handle: number): void {\n this.channels.delete(handle);\n\n for (const [animationHandle, animation] of this.animations) {\n if (animation.channel === handle) {\n this.detachAnimation(animationHandle);\n }\n }\n }\n\n isFinished(handle: number): boolean {\n const channel = this.channels.get(handle);\n if (channel === undefined) {\n return false;\n }\n\n return this.time >= channel.delay + channel.duration * channel.repeat;\n }\n\n getTime(handle?: number): number {\n if (handle === undefined) {\n return this.time;\n }\n\n const channel = this.channels.get(handle);\n\n if (channel === undefined) {\n return -1;\n }\n\n return channel.time;\n }\n\n setTime(time: number): void {\n this.time = Math.max(0, time);\n\n const channels = this.channels.values();\n for (const channel of channels) {\n this._setChannelTime(channel, this.time);\n }\n\n const animations = this.animations.values();\n for (const animationData of animations) {\n const {animation, channel} = animationData;\n animation.setTime(this.getTime(channel));\n }\n }\n\n play(): void {\n this.playing = true;\n }\n\n pause(): void {\n this.playing = false;\n this.lastEngineTime = -1;\n }\n\n reset(): void {\n this.setTime(0);\n }\n\n attachAnimation(animation: AnimationOptions, channelHandle?: number): number {\n const animationHandle = animationHandles++;\n\n this.animations.set(animationHandle, {\n animation,\n channel: channelHandle\n });\n\n animation.setTime(this.getTime(channelHandle));\n\n return animationHandle;\n }\n\n detachAnimation(handle: number): void {\n this.animations.delete(handle);\n }\n\n update(engineTime: number): void {\n if (this.playing) {\n if (this.lastEngineTime === -1) {\n this.lastEngineTime = engineTime;\n }\n this.setTime(this.time + (engineTime - this.lastEngineTime));\n this.lastEngineTime = engineTime;\n }\n }\n\n _setChannelTime(channel: Channel, time: number): void {\n const offsetTime = time - channel.delay;\n const totalDuration = channel.duration * channel.repeat;\n // Note(Tarek): Don't loop on final repeat.\n if (offsetTime >= totalDuration) {\n channel.time = channel.duration * channel.rate;\n } else {\n channel.time = Math.max(0, offsetTime) % channel.duration;\n channel.time *= channel.rate;\n }\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
1
  import { luma } from '@luma.gl/core';
3
2
  import { requestAnimationFrame, cancelAnimationFrame } from '@luma.gl/core';
4
3
  import { Stats } from '@probe.gl/stats';
@@ -12,30 +11,30 @@ const DEFAULT_ANIMATION_LOOP_PROPS = {
12
11
  onRender: () => {},
13
12
  onFinalize: () => {},
14
13
  onError: error => console.error(error),
15
- stats: luma.stats.get("animation-loop-".concat(statIdCounter++)),
14
+ stats: luma.stats.get(`animation-loop-${statIdCounter++}`),
16
15
  useDevicePixels: true,
17
16
  autoResizeViewport: false,
18
17
  autoResizeDrawingBuffer: false
19
18
  };
20
19
  export class AnimationLoop {
21
20
  constructor(props) {
22
- _defineProperty(this, "device", null);
23
- _defineProperty(this, "canvas", null);
24
- _defineProperty(this, "props", void 0);
25
- _defineProperty(this, "animationProps", null);
26
- _defineProperty(this, "timeline", null);
27
- _defineProperty(this, "stats", void 0);
28
- _defineProperty(this, "cpuTime", void 0);
29
- _defineProperty(this, "gpuTime", void 0);
30
- _defineProperty(this, "frameRate", void 0);
31
- _defineProperty(this, "display", void 0);
32
- _defineProperty(this, "needsRedraw", 'initialized');
33
- _defineProperty(this, "_initialized", false);
34
- _defineProperty(this, "_running", false);
35
- _defineProperty(this, "_animationFrameId", null);
36
- _defineProperty(this, "_nextFramePromise", null);
37
- _defineProperty(this, "_resolveNextFrame", null);
38
- _defineProperty(this, "_cpuStartTime", 0);
21
+ this.device = null;
22
+ this.canvas = null;
23
+ this.props = void 0;
24
+ this.animationProps = null;
25
+ this.timeline = null;
26
+ this.stats = void 0;
27
+ this.cpuTime = void 0;
28
+ this.gpuTime = void 0;
29
+ this.frameRate = void 0;
30
+ this.display = void 0;
31
+ this.needsRedraw = 'initialized';
32
+ this._initialized = false;
33
+ this._running = false;
34
+ this._animationFrameId = null;
35
+ this._nextFramePromise = null;
36
+ this._resolveNextFrame = null;
37
+ this._cpuStartTime = 0;
39
38
  this.props = {
40
39
  ...DEFAULT_ANIMATION_LOOP_PROPS,
41
40
  ...props
@@ -1 +1 @@
1
- {"version":3,"file":"animation-loop.js","names":["luma","requestAnimationFrame","cancelAnimationFrame","Stats","statIdCounter","DEFAULT_ANIMATION_LOOP_PROPS","device","onAddHTML","onInitialize","onRender","onFinalize","onError","error","console","stats","get","concat","useDevicePixels","autoResizeViewport","autoResizeDrawingBuffer","AnimationLoop","constructor","props","_defineProperty","Error","id","cpuTime","gpuTime","frameRate","setProps","start","bind","stop","_onMousemove","_onMouseleave","destroy","_setDisplay","delete","setNeedsRedraw","reason","needsRedraw","_running","appContext","_initialized","_initDevice","_initialize","_getAnimationProps","_cancelAnimationFrame","_requestAnimationFrame","err","redraw","_this$device","isLost","_beginTimers","_setupFrame","_updateAnimationProps","_renderFrame","_clearNeedsRedraw","_resolveNextFrame","_nextFramePromise","_endTimers","animationProps","attachTimeline","timeline","detachTimeline","waitForRender","Promise","resolve","toDataURL","canvas","HTMLCanvasElement","_startEventHandling","_initializeAnimationProps","_resizeCanvasDrawingBuffer","_resizeViewport","display","animationLoop","_animationFrameId","_animationFrame","_this$device2","canvasContext","renderPass","getDefaultRenderPass","width","height","aspect","time","startTime","Date","now","engineTime","tick","tock","_mousePosition","_getSizeAndAspect","update","Math","floor","getTime","_this$device$canvasCo","_createInfoDiv","wrapperDiv","document","createElement","body","appendChild","style","position","div","left","bottom","background","html","innerHTML","_this$device3","_this$device4","getPixelSize","clientHeight","clientWidth","gl","viewport","drawingBufferWidth","drawingBufferHeight","_this$device5","resize","timeEnd","timeStart","addEventListener","event","MouseEvent","offsetX","offsetY"],"sources":["../../src/animation-loop/animation-loop.ts"],"sourcesContent":["// luma.gl, MIT license\n\nimport {luma, Device} from '@luma.gl/core';\nimport {requestAnimationFrame, cancelAnimationFrame} from '@luma.gl/core';\nimport {Timeline} from '../animation/timeline';\nimport {AnimationProps} from './animation-props';\nimport {Stats, Stat} from '@probe.gl/stats';\n\nlet statIdCounter = 0;\n\n/** AnimationLoop properties */\nexport type AnimationLoopProps = {\n device: Device | Promise<Device>;\n\n onAddHTML?: (div: HTMLDivElement) => string; // innerHTML\n onInitialize?: (animationProps: AnimationProps) => Promise<unknown>;\n onRender?: (animationProps: AnimationProps) => unknown;\n onFinalize?: (animationProps: AnimationProps) => void;\n onError?: (reason: Error) => void;\n\n stats?: Stats;\n\n // view parameters - TODO move to CanvasContext?\n autoResizeViewport?: boolean;\n autoResizeDrawingBuffer?: boolean;\n useDevicePixels?: number | boolean;\n};\n\nexport type MutableAnimationLoopProps = {\n // view parameters\n autoResizeViewport?: boolean;\n autoResizeDrawingBuffer?: boolean;\n useDevicePixels?: number | boolean;\n}\n\n\nconst DEFAULT_ANIMATION_LOOP_PROPS: Required<AnimationLoopProps> = {\n device: null!,\n\n onAddHTML: () => '',\n onInitialize: async () => { return null; },\n onRender: () => {},\n onFinalize: () => {},\n onError: (error) => console.error(error), // eslint-disable-line no-console\n\n stats: luma.stats.get(`animation-loop-${statIdCounter++}`),\n\n // view parameters\n useDevicePixels: true,\n autoResizeViewport: false,\n autoResizeDrawingBuffer: false,\n};\n\n/** Convenient animation loop */\nexport class AnimationLoop {\n device: Device | null = null;\n canvas: HTMLCanvasElement | OffscreenCanvas | null = null;\n\n props: Required<AnimationLoopProps>;\n animationProps: AnimationProps | null = null;\n timeline: Timeline | null = null;\n stats: Stats;\n cpuTime: Stat;\n gpuTime: Stat;\n frameRate: Stat;\n\n display: any;\n\n needsRedraw: string | false = 'initialized';\n\n _initialized: boolean = false;\n _running: boolean = false;\n _animationFrameId: any = null;\n _nextFramePromise: Promise<AnimationLoop> | null = null;\n _resolveNextFrame: ((animationLoop: AnimationLoop) => void) | null = null;\n _cpuStartTime: number = 0;\n\n // _gpuTimeQuery: Query | null = null;\n\n /*\n * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context\n */\n constructor(props: AnimationLoopProps) {\n this.props = {...DEFAULT_ANIMATION_LOOP_PROPS, ...props};\n props = this.props;\n\n if (!props.device) {\n throw new Error('No device provided');\n }\n\n const {useDevicePixels = true} = this.props;\n\n // state\n this.stats = props.stats || new Stats({id: 'animation-loop-stats'});\n this.cpuTime = this.stats.get('CPU Time');\n this.gpuTime = this.stats.get('GPU Time');\n this.frameRate = this.stats.get('Frame Rate');\n\n this.setProps({\n autoResizeViewport: props.autoResizeViewport,\n autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,\n useDevicePixels\n });\n\n // Bind methods\n this.start = this.start.bind(this);\n this.stop = this.stop.bind(this);\n\n this._onMousemove = this._onMousemove.bind(this);\n this._onMouseleave = this._onMouseleave.bind(this);\n }\n\n destroy(): void {\n this.stop();\n this._setDisplay(null);\n }\n\n /** @deprecated Use .destroy() */\n delete(): void {\n this.destroy();\n }\n\n setNeedsRedraw(reason: string): this {\n this.needsRedraw = this.needsRedraw || reason;\n return this;\n }\n\n // TODO - move to CanvasContext\n setProps(props: MutableAnimationLoopProps): this {\n if ('autoResizeViewport' in props) {\n this.props.autoResizeViewport = props.autoResizeViewport || false;\n }\n if ('autoResizeDrawingBuffer' in props) {\n this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;\n }\n if ('useDevicePixels' in props) {\n this.props.useDevicePixels = props.useDevicePixels || false;\n }\n return this;\n }\n\n /** Starts a render loop if not already running */\n async start() {\n if (this._running) {\n return this;\n }\n this._running = true;\n\n try {\n // check that we haven't been stopped\n if (!this._running) {\n return null;\n }\n\n let appContext;\n if (!this._initialized) {\n this._initialized = true;\n // Create the WebGL context\n await this._initDevice();\n this._initialize();\n\n // Note: onIntialize can return a promise (e.g. in case app needs to load resources)\n await this.props.onInitialize(this._getAnimationProps());\n }\n\n // check that we haven't been stopped\n if (!this._running) {\n return null;\n }\n\n // Start the loop\n if (appContext !== false) {\n // cancel any pending renders to ensure only one loop can ever run\n this._cancelAnimationFrame();\n this._requestAnimationFrame();\n }\n\n return this;\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error('Unknown error')\n this.props.onError(error);\n // this._running = false; // TODO\n throw error;\n }\n }\n\n /** Explicitly draw a frame */\n redraw(): this {\n if (this.device?.isLost) {\n return this;\n }\n\n this._beginTimers();\n\n this._setupFrame();\n this._updateAnimationProps();\n\n this._renderFrame(this._getAnimationProps());\n\n // clear needsRedraw flag\n this._clearNeedsRedraw();\n\n if (this._resolveNextFrame) {\n this._resolveNextFrame(this);\n this._nextFramePromise = null;\n this._resolveNextFrame = null;\n }\n\n this._endTimers();\n\n return this;\n }\n\n // Stops a render loop if already running, finalizing\n stop() {\n // console.debug(`Stopping ${this.constructor.name}`);\n if (this._running) {\n // call callback\n // If stop is called immediately, we can end up in a state where props haven't been initialized...\n if (this.animationProps) {\n this.props.onFinalize(this.animationProps);\n }\n\n this._cancelAnimationFrame();\n this._nextFramePromise = null;\n this._resolveNextFrame = null;\n this._running = false;\n }\n return this;\n }\n\n attachTimeline(timeline: Timeline): Timeline {\n this.timeline = timeline;\n return this.timeline;\n }\n\n detachTimeline(): void {\n this.timeline = null;\n }\n\n waitForRender(): Promise<AnimationLoop> {\n this.setNeedsRedraw('waitForRender');\n\n if (!this._nextFramePromise) {\n this._nextFramePromise = new Promise((resolve) => {\n this._resolveNextFrame = resolve;\n });\n }\n return this._nextFramePromise;\n }\n\n async toDataURL(): Promise<string> {\n this.setNeedsRedraw('toDataURL');\n await this.waitForRender();\n if (this.canvas instanceof HTMLCanvasElement) {\n return this.canvas.toDataURL();\n }\n throw new Error('OffscreenCanvas');\n }\n\n // PRIVATE METHODS\n\n _initialize() {\n this._startEventHandling();\n\n // Initialize the callback data\n this._initializeAnimationProps();\n this._updateAnimationProps();\n\n // Default viewport setup, in case onInitialize wants to render\n this._resizeCanvasDrawingBuffer();\n this._resizeViewport();\n\n // this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;\n }\n\n _setDisplay(display: any) {\n if (this.display) {\n this.display.destroy();\n this.display.animationLoop = null;\n }\n\n // store animation loop on the display\n if (display) {\n display.animationLoop = this;\n }\n\n this.display = display;\n }\n\n _requestAnimationFrame() {\n if (!this._running) {\n return;\n }\n\n // VR display has a separate animation frame to sync with headset\n // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/\n // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame\n // if (this.display && this.display.requestAnimationFrame) {\n // this._animationFrameId = this.display.requestAnimationFrame(this._animationFrame.bind(this));\n // }\n this._animationFrameId = requestAnimationFrame(this._animationFrame.bind(this));\n }\n\n _cancelAnimationFrame() {\n if (this._animationFrameId !== null) {\n return;\n }\n\n // VR display has a separate animation frame to sync with headset\n // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/\n // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame\n // if (this.display && this.display.cancelAnimationFrame) {\n // this.display.cancelAnimationFrame(this._animationFrameId);\n // }\n cancelAnimationFrame(this._animationFrameId);\n this._animationFrameId = null;\n }\n\n _animationFrame() {\n if (!this._running) {\n return;\n }\n this.redraw();\n this._requestAnimationFrame();\n }\n\n // Called on each frame, can be overridden to call onRender multiple times\n // to support e.g. stereoscopic rendering\n _renderFrame(animationProps: AnimationProps) {\n // Allow e.g. VR display to render multiple frames.\n if (this.display) {\n this.display._renderFrame(animationProps);\n return;\n }\n\n // call callback\n this.props.onRender(this._getAnimationProps());\n // end callback\n }\n\n _clearNeedsRedraw() {\n this.needsRedraw = false;\n }\n\n _setupFrame() {\n this._resizeCanvasDrawingBuffer();\n this._resizeViewport();\n }\n\n // Initialize the object that will be passed to app callbacks\n _initializeAnimationProps() {\n if (!this.device) {\n throw new Error('loop');\n }\n this.animationProps = {\n animationLoop: this,\n\n device: this.device,\n canvas: this.device?.canvasContext?.canvas,\n renderPass: this.device.getDefaultRenderPass(),\n timeline: this.timeline,\n\n // Initial values\n useDevicePixels: this.props.useDevicePixels,\n needsRedraw: false,\n\n // Placeholders\n width: 1,\n height: 1,\n aspect: 1,\n\n // Animation props\n time: 0,\n startTime: Date.now(),\n engineTime: 0,\n tick: 0,\n tock: 0,\n\n // Experimental\n _mousePosition: null // Event props\n };\n }\n\n _getAnimationProps(): AnimationProps {\n if (!this.animationProps) {\n throw new Error('animationProps');\n }\n return this.animationProps;\n }\n\n // Update the context object that will be passed to app callbacks\n _updateAnimationProps(): void {\n if (!this.animationProps) {\n return;\n }\n\n this.animationProps.renderPass = this.device.getDefaultRenderPass();\n\n const {width, height, aspect} = this._getSizeAndAspect();\n if (width !== this.animationProps.width || height !== this.animationProps.height) {\n this.setNeedsRedraw('drawing buffer resized');\n }\n if (aspect !== this.animationProps.aspect) {\n this.setNeedsRedraw('drawing buffer aspect changed');\n }\n\n this.animationProps.width = width;\n this.animationProps.height = height;\n this.animationProps.aspect = aspect;\n\n this.animationProps.needsRedraw = this.needsRedraw;\n\n // Update time properties\n this.animationProps.engineTime = Date.now() - this.animationProps.startTime;\n\n if (this.timeline) {\n this.timeline.update(this.animationProps.engineTime);\n }\n\n this.animationProps.tick = Math.floor((this.animationProps.time / 1000) * 60);\n this.animationProps.tock++;\n\n // For back compatibility\n this.animationProps.time = this.timeline\n ? this.timeline.getTime()\n : this.animationProps.engineTime;\n }\n\n /** Wait for supplied device */\n async _initDevice() {\n this.device = await this.props.device;\n if (!this.device) {\n throw new Error('No device provided');\n }\n this.canvas = this.device.canvasContext?.canvas || null;\n // this._createInfoDiv();\n }\n\n _createInfoDiv() {\n if (this.canvas && this.props.onAddHTML) {\n const wrapperDiv = document.createElement('div');\n document.body.appendChild(wrapperDiv);\n wrapperDiv.style.position = 'relative';\n const div = document.createElement('div');\n div.style.position = 'absolute';\n div.style.left = '10px';\n div.style.bottom = '10px';\n div.style.width = '300px';\n div.style.background = 'white';\n if (this.canvas instanceof HTMLCanvasElement) {\n wrapperDiv.appendChild(this.canvas);\n }\n wrapperDiv.appendChild(div);\n const html = this.props.onAddHTML(div);\n if (html) {\n div.innerHTML = html;\n }\n }\n }\n\n _getSizeAndAspect(): {width: number; height: number; aspect: number} {\n if (!this.device) {\n return {width: 1, height: 1, aspect: 1};\n }\n // https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html\n const [width, height] = this.device?.canvasContext?.getPixelSize() || [1, 1];\n\n // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html\n let aspect = 1;\n const canvas = this.device?.canvasContext?.canvas;\n\n // @ts-expect-error\n if (canvas && canvas.clientHeight) {\n // @ts-expect-error\n aspect = canvas.clientWidth / canvas.clientHeight;\n } else if (width > 0 && height > 0) {\n aspect = width / height;\n }\n\n return {width, height, aspect};\n }\n\n /** Default viewport setup */\n _resizeViewport() {\n // @ts-expect-error Expose on canvasContext\n if (this.props.autoResizeViewport && this.device.gl) {\n // @ts-expect-error Expose canvasContext\n this.device.gl.viewport(0, 0, this.device.gl.drawingBufferWidth, this.device.gl.drawingBufferHeight);\n }\n }\n\n /**\n * Resize the render buffer of the canvas to match canvas client size\n * Optionally multiplying with devicePixel ratio\n */\n _resizeCanvasDrawingBuffer() {\n if (this.props.autoResizeDrawingBuffer) {\n this.device?.canvasContext?.resize({useDevicePixels: this.props.useDevicePixels});\n }\n }\n\n _beginTimers() {\n this.frameRate.timeEnd();\n this.frameRate.timeStart();\n\n // Check if timer for last frame has completed.\n // GPU timer results are never available in the same\n // frame they are captured.\n // if (\n // this._gpuTimeQuery &&\n // this._gpuTimeQuery.isResultAvailable() &&\n // !this._gpuTimeQuery.isTimerDisjoint()\n // ) {\n // this.stats.get('GPU Time').addTime(this._gpuTimeQuery.getTimerMilliseconds());\n // }\n\n // if (this._gpuTimeQuery) {\n // // GPU time query start\n // this._gpuTimeQuery.beginTimeElapsedQuery();\n // }\n\n // this.cpuTime.timeStart();\n }\n\n _endTimers() {\n this.cpuTime.timeEnd();\n\n // if (this._gpuTimeQuery) {\n // // GPU time query end. Results will be available on next frame.\n // this._gpuTimeQuery.end();\n // }\n }\n\n // Event handling\n\n _startEventHandling() {\n if (this.canvas) {\n this.canvas.addEventListener('mousemove', this._onMousemove.bind(this));\n this.canvas.addEventListener('mouseleave', this._onMouseleave.bind(this));\n }\n }\n\n _onMousemove(event: Event) {\n if (event instanceof MouseEvent) {\n this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];\n }\n }\n\n _onMouseleave(event: Event) {\n this._getAnimationProps()._mousePosition = null;\n }\n}\n"],"mappings":";AAEA,SAAQA,IAAI,QAAe,eAAe;AAC1C,SAAQC,qBAAqB,EAAEC,oBAAoB,QAAO,eAAe;AAGzE,SAAQC,KAAK,QAAa,iBAAiB;AAE3C,IAAIC,aAAa,GAAG,CAAC;AA4BrB,MAAMC,4BAA0D,GAAG;EACjEC,MAAM,EAAE,IAAK;EAEbC,SAAS,EAAEA,CAAA,KAAM,EAAE;EACnBC,YAAY,EAAE,MAAAA,CAAA,KAAY;IAAE,OAAO,IAAI;EAAE,CAAC;EAC1CC,QAAQ,EAAEA,CAAA,KAAM,CAAC,CAAC;EAClBC,UAAU,EAAEA,CAAA,KAAM,CAAC,CAAC;EACpBC,OAAO,EAAGC,KAAK,IAAKC,OAAO,CAACD,KAAK,CAACA,KAAK,CAAC;EAExCE,KAAK,EAAEd,IAAI,CAACc,KAAK,CAACC,GAAG,mBAAAC,MAAA,CAAmBZ,aAAa,EAAE,CAAE,CAAC;EAG1Da,eAAe,EAAE,IAAI;EACrBC,kBAAkB,EAAE,KAAK;EACzBC,uBAAuB,EAAE;AAC3B,CAAC;AAGD,OAAO,MAAMC,aAAa,CAAC;EA4BzBC,WAAWA,CAACC,KAAyB,EAAE;IAAAC,eAAA,iBA3Bf,IAAI;IAAAA,eAAA,iBACyB,IAAI;IAAAA,eAAA;IAAAA,eAAA,yBAGjB,IAAI;IAAAA,eAAA,mBAChB,IAAI;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA,sBAQF,aAAa;IAAAA,eAAA,uBAEnB,KAAK;IAAAA,eAAA,mBACT,KAAK;IAAAA,eAAA,4BACA,IAAI;IAAAA,eAAA,4BACsB,IAAI;IAAAA,eAAA,4BACc,IAAI;IAAAA,eAAA,wBACjD,CAAC;IAQvB,IAAI,CAACD,KAAK,GAAG;MAAC,GAAGjB,4BAA4B;MAAE,GAAGiB;IAAK,CAAC;IACxDA,KAAK,GAAG,IAAI,CAACA,KAAK;IAElB,IAAI,CAACA,KAAK,CAAChB,MAAM,EAAE;MACjB,MAAM,IAAIkB,KAAK,CAAC,oBAAoB,CAAC;IACvC;IAEA,MAAM;MAACP,eAAe,GAAG;IAAI,CAAC,GAAG,IAAI,CAACK,KAAK;IAG3C,IAAI,CAACR,KAAK,GAAGQ,KAAK,CAACR,KAAK,IAAI,IAAIX,KAAK,CAAC;MAACsB,EAAE,EAAE;IAAsB,CAAC,CAAC;IACnE,IAAI,CAACC,OAAO,GAAG,IAAI,CAACZ,KAAK,CAACC,GAAG,CAAC,UAAU,CAAC;IACzC,IAAI,CAACY,OAAO,GAAG,IAAI,CAACb,KAAK,CAACC,GAAG,CAAC,UAAU,CAAC;IACzC,IAAI,CAACa,SAAS,GAAG,IAAI,CAACd,KAAK,CAACC,GAAG,CAAC,YAAY,CAAC;IAE7C,IAAI,CAACc,QAAQ,CAAC;MACZX,kBAAkB,EAAEI,KAAK,CAACJ,kBAAkB;MAC5CC,uBAAuB,EAAEG,KAAK,CAACH,uBAAuB;MACtDF;IACF,CAAC,CAAC;IAGF,IAAI,CAACa,KAAK,GAAG,IAAI,CAACA,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC;IAClC,IAAI,CAACC,IAAI,GAAG,IAAI,CAACA,IAAI,CAACD,IAAI,CAAC,IAAI,CAAC;IAEhC,IAAI,CAACE,YAAY,GAAG,IAAI,CAACA,YAAY,CAACF,IAAI,CAAC,IAAI,CAAC;IAChD,IAAI,CAACG,aAAa,GAAG,IAAI,CAACA,aAAa,CAACH,IAAI,CAAC,IAAI,CAAC;EACpD;EAEAI,OAAOA,CAAA,EAAS;IACd,IAAI,CAACH,IAAI,CAAC,CAAC;IACX,IAAI,CAACI,WAAW,CAAC,IAAI,CAAC;EACxB;EAGAC,MAAMA,CAAA,EAAS;IACb,IAAI,CAACF,OAAO,CAAC,CAAC;EAChB;EAEAG,cAAcA,CAACC,MAAc,EAAQ;IACnC,IAAI,CAACC,WAAW,GAAG,IAAI,CAACA,WAAW,IAAID,MAAM;IAC7C,OAAO,IAAI;EACb;EAGAV,QAAQA,CAACP,KAAgC,EAAQ;IAC/C,IAAI,oBAAoB,IAAIA,KAAK,EAAE;MACjC,IAAI,CAACA,KAAK,CAACJ,kBAAkB,GAAGI,KAAK,CAACJ,kBAAkB,IAAI,KAAK;IACnE;IACA,IAAI,yBAAyB,IAAII,KAAK,EAAE;MACtC,IAAI,CAACA,KAAK,CAACH,uBAAuB,GAAGG,KAAK,CAACH,uBAAuB,IAAI,KAAK;IAC7E;IACA,IAAI,iBAAiB,IAAIG,KAAK,EAAE;MAC9B,IAAI,CAACA,KAAK,CAACL,eAAe,GAAGK,KAAK,CAACL,eAAe,IAAI,KAAK;IAC7D;IACA,OAAO,IAAI;EACb;EAGA,MAAMa,KAAKA,CAAA,EAAG;IACZ,IAAI,IAAI,CAACW,QAAQ,EAAE;MACjB,OAAO,IAAI;IACb;IACA,IAAI,CAACA,QAAQ,GAAG,IAAI;IAEpB,IAAI;MAEF,IAAI,CAAC,IAAI,CAACA,QAAQ,EAAE;QAClB,OAAO,IAAI;MACb;MAEA,IAAIC,UAAU;MACd,IAAI,CAAC,IAAI,CAACC,YAAY,EAAE;QACtB,IAAI,CAACA,YAAY,GAAG,IAAI;QAExB,MAAM,IAAI,CAACC,WAAW,CAAC,CAAC;QACxB,IAAI,CAACC,WAAW,CAAC,CAAC;QAGlB,MAAM,IAAI,CAACvB,KAAK,CAACd,YAAY,CAAC,IAAI,CAACsC,kBAAkB,CAAC,CAAC,CAAC;MAC1D;MAGA,IAAI,CAAC,IAAI,CAACL,QAAQ,EAAE;QAClB,OAAO,IAAI;MACb;MAGA,IAAIC,UAAU,KAAK,KAAK,EAAE;QAExB,IAAI,CAACK,qBAAqB,CAAC,CAAC;QAC5B,IAAI,CAACC,sBAAsB,CAAC,CAAC;MAC/B;MAEA,OAAO,IAAI;IACb,CAAC,CAAC,OAAOC,GAAY,EAAE;MACrB,MAAMrC,KAAK,GAAGqC,GAAG,YAAYzB,KAAK,GAAGyB,GAAG,GAAG,IAAIzB,KAAK,CAAC,eAAe,CAAC;MACrE,IAAI,CAACF,KAAK,CAACX,OAAO,CAACC,KAAK,CAAC;MAEzB,MAAMA,KAAK;IACb;EACF;EAGAsC,MAAMA,CAAA,EAAS;IAAA,IAAAC,YAAA;IACb,KAAAA,YAAA,GAAI,IAAI,CAAC7C,MAAM,cAAA6C,YAAA,eAAXA,YAAA,CAAaC,MAAM,EAAE;MACvB,OAAO,IAAI;IACb;IAEA,IAAI,CAACC,YAAY,CAAC,CAAC;IAEnB,IAAI,CAACC,WAAW,CAAC,CAAC;IAClB,IAAI,CAACC,qBAAqB,CAAC,CAAC;IAE5B,IAAI,CAACC,YAAY,CAAC,IAAI,CAACV,kBAAkB,CAAC,CAAC,CAAC;IAG5C,IAAI,CAACW,iBAAiB,CAAC,CAAC;IAExB,IAAI,IAAI,CAACC,iBAAiB,EAAE;MAC1B,IAAI,CAACA,iBAAiB,CAAC,IAAI,CAAC;MAC5B,IAAI,CAACC,iBAAiB,GAAG,IAAI;MAC7B,IAAI,CAACD,iBAAiB,GAAG,IAAI;IAC/B;IAEA,IAAI,CAACE,UAAU,CAAC,CAAC;IAEjB,OAAO,IAAI;EACb;EAGA5B,IAAIA,CAAA,EAAG;IAEL,IAAI,IAAI,CAACS,QAAQ,EAAE;MAGjB,IAAI,IAAI,CAACoB,cAAc,EAAE;QACvB,IAAI,CAACvC,KAAK,CAACZ,UAAU,CAAC,IAAI,CAACmD,cAAc,CAAC;MAC5C;MAEA,IAAI,CAACd,qBAAqB,CAAC,CAAC;MAC5B,IAAI,CAACY,iBAAiB,GAAG,IAAI;MAC7B,IAAI,CAACD,iBAAiB,GAAG,IAAI;MAC7B,IAAI,CAACjB,QAAQ,GAAG,KAAK;IACvB;IACA,OAAO,IAAI;EACb;EAEAqB,cAAcA,CAACC,QAAkB,EAAY;IAC3C,IAAI,CAACA,QAAQ,GAAGA,QAAQ;IACxB,OAAO,IAAI,CAACA,QAAQ;EACtB;EAEAC,cAAcA,CAAA,EAAS;IACrB,IAAI,CAACD,QAAQ,GAAG,IAAI;EACtB;EAEAE,aAAaA,CAAA,EAA2B;IACtC,IAAI,CAAC3B,cAAc,CAAC,eAAe,CAAC;IAEpC,IAAI,CAAC,IAAI,CAACqB,iBAAiB,EAAE;MAC3B,IAAI,CAACA,iBAAiB,GAAG,IAAIO,OAAO,CAAEC,OAAO,IAAK;QAChD,IAAI,CAACT,iBAAiB,GAAGS,OAAO;MAClC,CAAC,CAAC;IACJ;IACA,OAAO,IAAI,CAACR,iBAAiB;EAC/B;EAEA,MAAMS,SAASA,CAAA,EAAoB;IACjC,IAAI,CAAC9B,cAAc,CAAC,WAAW,CAAC;IAChC,MAAM,IAAI,CAAC2B,aAAa,CAAC,CAAC;IAC1B,IAAI,IAAI,CAACI,MAAM,YAAYC,iBAAiB,EAAE;MAC5C,OAAO,IAAI,CAACD,MAAM,CAACD,SAAS,CAAC,CAAC;IAChC;IACA,MAAM,IAAI5C,KAAK,CAAC,iBAAiB,CAAC;EACpC;EAIAqB,WAAWA,CAAA,EAAG;IACZ,IAAI,CAAC0B,mBAAmB,CAAC,CAAC;IAG1B,IAAI,CAACC,yBAAyB,CAAC,CAAC;IAChC,IAAI,CAACjB,qBAAqB,CAAC,CAAC;IAG5B,IAAI,CAACkB,0BAA0B,CAAC,CAAC;IACjC,IAAI,CAACC,eAAe,CAAC,CAAC;EAGxB;EAEAtC,WAAWA,CAACuC,OAAY,EAAE;IACxB,IAAI,IAAI,CAACA,OAAO,EAAE;MAChB,IAAI,CAACA,OAAO,CAACxC,OAAO,CAAC,CAAC;MACtB,IAAI,CAACwC,OAAO,CAACC,aAAa,GAAG,IAAI;IACnC;IAGA,IAAID,OAAO,EAAE;MACXA,OAAO,CAACC,aAAa,GAAG,IAAI;IAC9B;IAEA,IAAI,CAACD,OAAO,GAAGA,OAAO;EACxB;EAEA3B,sBAAsBA,CAAA,EAAG;IACvB,IAAI,CAAC,IAAI,CAACP,QAAQ,EAAE;MAClB;IACF;IAQA,IAAI,CAACoC,iBAAiB,GAAG5E,qBAAqB,CAAC,IAAI,CAAC6E,eAAe,CAAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;EACjF;EAEAgB,qBAAqBA,CAAA,EAAG;IACtB,IAAI,IAAI,CAAC8B,iBAAiB,KAAK,IAAI,EAAE;MACnC;IACF;IAQA3E,oBAAoB,CAAC,IAAI,CAAC2E,iBAAiB,CAAC;IAC5C,IAAI,CAACA,iBAAiB,GAAG,IAAI;EAC/B;EAEAC,eAAeA,CAAA,EAAG;IAChB,IAAI,CAAC,IAAI,CAACrC,QAAQ,EAAE;MAClB;IACF;IACA,IAAI,CAACS,MAAM,CAAC,CAAC;IACb,IAAI,CAACF,sBAAsB,CAAC,CAAC;EAC/B;EAIAQ,YAAYA,CAACK,cAA8B,EAAE;IAE3C,IAAI,IAAI,CAACc,OAAO,EAAE;MAChB,IAAI,CAACA,OAAO,CAACnB,YAAY,CAACK,cAAc,CAAC;MACzC;IACF;IAGA,IAAI,CAACvC,KAAK,CAACb,QAAQ,CAAC,IAAI,CAACqC,kBAAkB,CAAC,CAAC,CAAC;EAEhD;EAEAW,iBAAiBA,CAAA,EAAG;IAClB,IAAI,CAACjB,WAAW,GAAG,KAAK;EAC1B;EAEAc,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACmB,0BAA0B,CAAC,CAAC;IACjC,IAAI,CAACC,eAAe,CAAC,CAAC;EACxB;EAGAF,yBAAyBA,CAAA,EAAG;IAAA,IAAAO,aAAA;IAC1B,IAAI,CAAC,IAAI,CAACzE,MAAM,EAAE;MAChB,MAAM,IAAIkB,KAAK,CAAC,MAAM,CAAC;IACzB;IACA,IAAI,CAACqC,cAAc,GAAG;MACpBe,aAAa,EAAE,IAAI;MAEnBtE,MAAM,EAAE,IAAI,CAACA,MAAM;MACnB+D,MAAM,GAAAU,aAAA,GAAE,IAAI,CAACzE,MAAM,cAAAyE,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAaC,aAAa,cAAAD,aAAA,uBAA1BA,aAAA,CAA4BV,MAAM;MAC1CY,UAAU,EAAE,IAAI,CAAC3E,MAAM,CAAC4E,oBAAoB,CAAC,CAAC;MAC9CnB,QAAQ,EAAE,IAAI,CAACA,QAAQ;MAGvB9C,eAAe,EAAE,IAAI,CAACK,KAAK,CAACL,eAAe;MAC3CuB,WAAW,EAAE,KAAK;MAGlB2C,KAAK,EAAE,CAAC;MACRC,MAAM,EAAE,CAAC;MACTC,MAAM,EAAE,CAAC;MAGTC,IAAI,EAAE,CAAC;MACPC,SAAS,EAAEC,IAAI,CAACC,GAAG,CAAC,CAAC;MACrBC,UAAU,EAAE,CAAC;MACbC,IAAI,EAAE,CAAC;MACPC,IAAI,EAAE,CAAC;MAGPC,cAAc,EAAE;IAClB,CAAC;EACH;EAEA/C,kBAAkBA,CAAA,EAAmB;IACnC,IAAI,CAAC,IAAI,CAACe,cAAc,EAAE;MACxB,MAAM,IAAIrC,KAAK,CAAC,gBAAgB,CAAC;IACnC;IACA,OAAO,IAAI,CAACqC,cAAc;EAC5B;EAGAN,qBAAqBA,CAAA,EAAS;IAC5B,IAAI,CAAC,IAAI,CAACM,cAAc,EAAE;MACxB;IACF;IAEA,IAAI,CAACA,cAAc,CAACoB,UAAU,GAAG,IAAI,CAAC3E,MAAM,CAAC4E,oBAAoB,CAAC,CAAC;IAEnE,MAAM;MAACC,KAAK;MAAEC,MAAM;MAAEC;IAAM,CAAC,GAAG,IAAI,CAACS,iBAAiB,CAAC,CAAC;IACxD,IAAIX,KAAK,KAAK,IAAI,CAACtB,cAAc,CAACsB,KAAK,IAAIC,MAAM,KAAK,IAAI,CAACvB,cAAc,CAACuB,MAAM,EAAE;MAChF,IAAI,CAAC9C,cAAc,CAAC,wBAAwB,CAAC;IAC/C;IACA,IAAI+C,MAAM,KAAK,IAAI,CAACxB,cAAc,CAACwB,MAAM,EAAE;MACzC,IAAI,CAAC/C,cAAc,CAAC,+BAA+B,CAAC;IACtD;IAEA,IAAI,CAACuB,cAAc,CAACsB,KAAK,GAAGA,KAAK;IACjC,IAAI,CAACtB,cAAc,CAACuB,MAAM,GAAGA,MAAM;IACnC,IAAI,CAACvB,cAAc,CAACwB,MAAM,GAAGA,MAAM;IAEnC,IAAI,CAACxB,cAAc,CAACrB,WAAW,GAAG,IAAI,CAACA,WAAW;IAGlD,IAAI,CAACqB,cAAc,CAAC6B,UAAU,GAAGF,IAAI,CAACC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC5B,cAAc,CAAC0B,SAAS;IAE3E,IAAI,IAAI,CAACxB,QAAQ,EAAE;MACjB,IAAI,CAACA,QAAQ,CAACgC,MAAM,CAAC,IAAI,CAAClC,cAAc,CAAC6B,UAAU,CAAC;IACtD;IAEA,IAAI,CAAC7B,cAAc,CAAC8B,IAAI,GAAGK,IAAI,CAACC,KAAK,CAAE,IAAI,CAACpC,cAAc,CAACyB,IAAI,GAAG,IAAI,GAAI,EAAE,CAAC;IAC7E,IAAI,CAACzB,cAAc,CAAC+B,IAAI,EAAE;IAG1B,IAAI,CAAC/B,cAAc,CAACyB,IAAI,GAAG,IAAI,CAACvB,QAAQ,GACpC,IAAI,CAACA,QAAQ,CAACmC,OAAO,CAAC,CAAC,GACvB,IAAI,CAACrC,cAAc,CAAC6B,UAAU;EACpC;EAGA,MAAM9C,WAAWA,CAAA,EAAG;IAAA,IAAAuD,qBAAA;IAClB,IAAI,CAAC7F,MAAM,GAAG,MAAM,IAAI,CAACgB,KAAK,CAAChB,MAAM;IACrC,IAAI,CAAC,IAAI,CAACA,MAAM,EAAE;MAChB,MAAM,IAAIkB,KAAK,CAAC,oBAAoB,CAAC;IACvC;IACA,IAAI,CAAC6C,MAAM,GAAG,EAAA8B,qBAAA,OAAI,CAAC7F,MAAM,CAAC0E,aAAa,cAAAmB,qBAAA,uBAAzBA,qBAAA,CAA2B9B,MAAM,KAAI,IAAI;EAEzD;EAEA+B,cAAcA,CAAA,EAAG;IACf,IAAI,IAAI,CAAC/B,MAAM,IAAI,IAAI,CAAC/C,KAAK,CAACf,SAAS,EAAE;MACvC,MAAM8F,UAAU,GAAGC,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;MAChDD,QAAQ,CAACE,IAAI,CAACC,WAAW,CAACJ,UAAU,CAAC;MACrCA,UAAU,CAACK,KAAK,CAACC,QAAQ,GAAG,UAAU;MACtC,MAAMC,GAAG,GAAGN,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;MACzCK,GAAG,CAACF,KAAK,CAACC,QAAQ,GAAG,UAAU;MAC/BC,GAAG,CAACF,KAAK,CAACG,IAAI,GAAG,MAAM;MACvBD,GAAG,CAACF,KAAK,CAACI,MAAM,GAAG,MAAM;MACzBF,GAAG,CAACF,KAAK,CAACvB,KAAK,GAAG,OAAO;MACzByB,GAAG,CAACF,KAAK,CAACK,UAAU,GAAG,OAAO;MAC9B,IAAI,IAAI,CAAC1C,MAAM,YAAYC,iBAAiB,EAAE;QAC5C+B,UAAU,CAACI,WAAW,CAAC,IAAI,CAACpC,MAAM,CAAC;MACrC;MACAgC,UAAU,CAACI,WAAW,CAACG,GAAG,CAAC;MAC3B,MAAMI,IAAI,GAAG,IAAI,CAAC1F,KAAK,CAACf,SAAS,CAACqG,GAAG,CAAC;MACtC,IAAII,IAAI,EAAE;QACRJ,GAAG,CAACK,SAAS,GAAGD,IAAI;MACtB;IACF;EACF;EAEAlB,iBAAiBA,CAAA,EAAqD;IAAA,IAAAoB,aAAA,EAAAC,aAAA;IACpE,IAAI,CAAC,IAAI,CAAC7G,MAAM,EAAE;MAChB,OAAO;QAAC6E,KAAK,EAAE,CAAC;QAAEC,MAAM,EAAE,CAAC;QAAEC,MAAM,EAAE;MAAC,CAAC;IACzC;IAEA,MAAM,CAACF,KAAK,EAAEC,MAAM,CAAC,GAAG,EAAA8B,aAAA,OAAI,CAAC5G,MAAM,cAAA4G,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAalC,aAAa,cAAAkC,aAAA,uBAA1BA,aAAA,CAA4BE,YAAY,CAAC,CAAC,KAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAG5E,IAAI/B,MAAM,GAAG,CAAC;IACd,MAAMhB,MAAM,IAAA8C,aAAA,GAAG,IAAI,CAAC7G,MAAM,cAAA6G,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAanC,aAAa,cAAAmC,aAAA,uBAA1BA,aAAA,CAA4B9C,MAAM;IAGjD,IAAIA,MAAM,IAAIA,MAAM,CAACgD,YAAY,EAAE;MAEjChC,MAAM,GAAGhB,MAAM,CAACiD,WAAW,GAAGjD,MAAM,CAACgD,YAAY;IACnD,CAAC,MAAM,IAAIlC,KAAK,GAAG,CAAC,IAAIC,MAAM,GAAG,CAAC,EAAE;MAClCC,MAAM,GAAGF,KAAK,GAAGC,MAAM;IACzB;IAEA,OAAO;MAACD,KAAK;MAAEC,MAAM;MAAEC;IAAM,CAAC;EAChC;EAGAX,eAAeA,CAAA,EAAG;IAEhB,IAAI,IAAI,CAACpD,KAAK,CAACJ,kBAAkB,IAAI,IAAI,CAACZ,MAAM,CAACiH,EAAE,EAAE;MAEnD,IAAI,CAACjH,MAAM,CAACiH,EAAE,CAACC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAClH,MAAM,CAACiH,EAAE,CAACE,kBAAkB,EAAE,IAAI,CAACnH,MAAM,CAACiH,EAAE,CAACG,mBAAmB,CAAC;IACtG;EACF;EAMAjD,0BAA0BA,CAAA,EAAG;IAC3B,IAAI,IAAI,CAACnD,KAAK,CAACH,uBAAuB,EAAE;MAAA,IAAAwG,aAAA;MACtC,CAAAA,aAAA,OAAI,CAACrH,MAAM,cAAAqH,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAa3C,aAAa,cAAA2C,aAAA,uBAA1BA,aAAA,CAA4BC,MAAM,CAAC;QAAC3G,eAAe,EAAE,IAAI,CAACK,KAAK,CAACL;MAAe,CAAC,CAAC;IACnF;EACF;EAEAoC,YAAYA,CAAA,EAAG;IACb,IAAI,CAACzB,SAAS,CAACiG,OAAO,CAAC,CAAC;IACxB,IAAI,CAACjG,SAAS,CAACkG,SAAS,CAAC,CAAC;EAmB5B;EAEAlE,UAAUA,CAAA,EAAG;IACX,IAAI,CAAClC,OAAO,CAACmG,OAAO,CAAC,CAAC;EAMxB;EAIAtD,mBAAmBA,CAAA,EAAG;IACpB,IAAI,IAAI,CAACF,MAAM,EAAE;MACf,IAAI,CAACA,MAAM,CAAC0D,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC9F,YAAY,CAACF,IAAI,CAAC,IAAI,CAAC,CAAC;MACvE,IAAI,CAACsC,MAAM,CAAC0D,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC7F,aAAa,CAACH,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E;EACF;EAEAE,YAAYA,CAAC+F,KAAY,EAAE;IACzB,IAAIA,KAAK,YAAYC,UAAU,EAAE;MAC/B,IAAI,CAACnF,kBAAkB,CAAC,CAAC,CAAC+C,cAAc,GAAG,CAACmC,KAAK,CAACE,OAAO,EAAEF,KAAK,CAACG,OAAO,CAAC;IAC3E;EACF;EAEAjG,aAAaA,CAAC8F,KAAY,EAAE;IAC1B,IAAI,CAAClF,kBAAkB,CAAC,CAAC,CAAC+C,cAAc,GAAG,IAAI;EACjD;AACF"}
1
+ {"version":3,"file":"animation-loop.js","names":["luma","requestAnimationFrame","cancelAnimationFrame","Stats","statIdCounter","DEFAULT_ANIMATION_LOOP_PROPS","device","onAddHTML","onInitialize","onRender","onFinalize","onError","error","console","stats","get","useDevicePixels","autoResizeViewport","autoResizeDrawingBuffer","AnimationLoop","constructor","props","canvas","animationProps","timeline","cpuTime","gpuTime","frameRate","display","needsRedraw","_initialized","_running","_animationFrameId","_nextFramePromise","_resolveNextFrame","_cpuStartTime","Error","id","setProps","start","bind","stop","_onMousemove","_onMouseleave","destroy","_setDisplay","delete","setNeedsRedraw","reason","appContext","_initDevice","_initialize","_getAnimationProps","_cancelAnimationFrame","_requestAnimationFrame","err","redraw","_this$device","isLost","_beginTimers","_setupFrame","_updateAnimationProps","_renderFrame","_clearNeedsRedraw","_endTimers","attachTimeline","detachTimeline","waitForRender","Promise","resolve","toDataURL","HTMLCanvasElement","_startEventHandling","_initializeAnimationProps","_resizeCanvasDrawingBuffer","_resizeViewport","animationLoop","_animationFrame","_this$device2","canvasContext","renderPass","getDefaultRenderPass","width","height","aspect","time","startTime","Date","now","engineTime","tick","tock","_mousePosition","_getSizeAndAspect","update","Math","floor","getTime","_this$device$canvasCo","_createInfoDiv","wrapperDiv","document","createElement","body","appendChild","style","position","div","left","bottom","background","html","innerHTML","_this$device3","_this$device4","getPixelSize","clientHeight","clientWidth","gl","viewport","drawingBufferWidth","drawingBufferHeight","_this$device5","resize","timeEnd","timeStart","addEventListener","event","MouseEvent","offsetX","offsetY"],"sources":["../../src/animation-loop/animation-loop.ts"],"sourcesContent":["// luma.gl, MIT license\n\nimport {luma, Device} from '@luma.gl/core';\nimport {requestAnimationFrame, cancelAnimationFrame} from '@luma.gl/core';\nimport {Timeline} from '../animation/timeline';\nimport {AnimationProps} from './animation-props';\nimport {Stats, Stat} from '@probe.gl/stats';\n\nlet statIdCounter = 0;\n\n/** AnimationLoop properties */\nexport type AnimationLoopProps = {\n device: Device | Promise<Device>;\n\n onAddHTML?: (div: HTMLDivElement) => string; // innerHTML\n onInitialize?: (animationProps: AnimationProps) => Promise<unknown>;\n onRender?: (animationProps: AnimationProps) => unknown;\n onFinalize?: (animationProps: AnimationProps) => void;\n onError?: (reason: Error) => void;\n\n stats?: Stats;\n\n // view parameters - TODO move to CanvasContext?\n autoResizeViewport?: boolean;\n autoResizeDrawingBuffer?: boolean;\n useDevicePixels?: number | boolean;\n};\n\nexport type MutableAnimationLoopProps = {\n // view parameters\n autoResizeViewport?: boolean;\n autoResizeDrawingBuffer?: boolean;\n useDevicePixels?: number | boolean;\n}\n\n\nconst DEFAULT_ANIMATION_LOOP_PROPS: Required<AnimationLoopProps> = {\n device: null!,\n\n onAddHTML: () => '',\n onInitialize: async () => { return null; },\n onRender: () => {},\n onFinalize: () => {},\n onError: (error) => console.error(error), // eslint-disable-line no-console\n\n stats: luma.stats.get(`animation-loop-${statIdCounter++}`),\n\n // view parameters\n useDevicePixels: true,\n autoResizeViewport: false,\n autoResizeDrawingBuffer: false,\n};\n\n/** Convenient animation loop */\nexport class AnimationLoop {\n device: Device | null = null;\n canvas: HTMLCanvasElement | OffscreenCanvas | null = null;\n\n props: Required<AnimationLoopProps>;\n animationProps: AnimationProps | null = null;\n timeline: Timeline | null = null;\n stats: Stats;\n cpuTime: Stat;\n gpuTime: Stat;\n frameRate: Stat;\n\n display: any;\n\n needsRedraw: string | false = 'initialized';\n\n _initialized: boolean = false;\n _running: boolean = false;\n _animationFrameId: any = null;\n _nextFramePromise: Promise<AnimationLoop> | null = null;\n _resolveNextFrame: ((animationLoop: AnimationLoop) => void) | null = null;\n _cpuStartTime: number = 0;\n\n // _gpuTimeQuery: Query | null = null;\n\n /*\n * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context\n */\n constructor(props: AnimationLoopProps) {\n this.props = {...DEFAULT_ANIMATION_LOOP_PROPS, ...props};\n props = this.props;\n\n if (!props.device) {\n throw new Error('No device provided');\n }\n\n const {useDevicePixels = true} = this.props;\n\n // state\n this.stats = props.stats || new Stats({id: 'animation-loop-stats'});\n this.cpuTime = this.stats.get('CPU Time');\n this.gpuTime = this.stats.get('GPU Time');\n this.frameRate = this.stats.get('Frame Rate');\n\n this.setProps({\n autoResizeViewport: props.autoResizeViewport,\n autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,\n useDevicePixels\n });\n\n // Bind methods\n this.start = this.start.bind(this);\n this.stop = this.stop.bind(this);\n\n this._onMousemove = this._onMousemove.bind(this);\n this._onMouseleave = this._onMouseleave.bind(this);\n }\n\n destroy(): void {\n this.stop();\n this._setDisplay(null);\n }\n\n /** @deprecated Use .destroy() */\n delete(): void {\n this.destroy();\n }\n\n setNeedsRedraw(reason: string): this {\n this.needsRedraw = this.needsRedraw || reason;\n return this;\n }\n\n // TODO - move to CanvasContext\n setProps(props: MutableAnimationLoopProps): this {\n if ('autoResizeViewport' in props) {\n this.props.autoResizeViewport = props.autoResizeViewport || false;\n }\n if ('autoResizeDrawingBuffer' in props) {\n this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;\n }\n if ('useDevicePixels' in props) {\n this.props.useDevicePixels = props.useDevicePixels || false;\n }\n return this;\n }\n\n /** Starts a render loop if not already running */\n async start() {\n if (this._running) {\n return this;\n }\n this._running = true;\n\n try {\n // check that we haven't been stopped\n if (!this._running) {\n return null;\n }\n\n let appContext;\n if (!this._initialized) {\n this._initialized = true;\n // Create the WebGL context\n await this._initDevice();\n this._initialize();\n\n // Note: onIntialize can return a promise (e.g. in case app needs to load resources)\n await this.props.onInitialize(this._getAnimationProps());\n }\n\n // check that we haven't been stopped\n if (!this._running) {\n return null;\n }\n\n // Start the loop\n if (appContext !== false) {\n // cancel any pending renders to ensure only one loop can ever run\n this._cancelAnimationFrame();\n this._requestAnimationFrame();\n }\n\n return this;\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error('Unknown error')\n this.props.onError(error);\n // this._running = false; // TODO\n throw error;\n }\n }\n\n /** Explicitly draw a frame */\n redraw(): this {\n if (this.device?.isLost) {\n return this;\n }\n\n this._beginTimers();\n\n this._setupFrame();\n this._updateAnimationProps();\n\n this._renderFrame(this._getAnimationProps());\n\n // clear needsRedraw flag\n this._clearNeedsRedraw();\n\n if (this._resolveNextFrame) {\n this._resolveNextFrame(this);\n this._nextFramePromise = null;\n this._resolveNextFrame = null;\n }\n\n this._endTimers();\n\n return this;\n }\n\n // Stops a render loop if already running, finalizing\n stop() {\n // console.debug(`Stopping ${this.constructor.name}`);\n if (this._running) {\n // call callback\n // If stop is called immediately, we can end up in a state where props haven't been initialized...\n if (this.animationProps) {\n this.props.onFinalize(this.animationProps);\n }\n\n this._cancelAnimationFrame();\n this._nextFramePromise = null;\n this._resolveNextFrame = null;\n this._running = false;\n }\n return this;\n }\n\n attachTimeline(timeline: Timeline): Timeline {\n this.timeline = timeline;\n return this.timeline;\n }\n\n detachTimeline(): void {\n this.timeline = null;\n }\n\n waitForRender(): Promise<AnimationLoop> {\n this.setNeedsRedraw('waitForRender');\n\n if (!this._nextFramePromise) {\n this._nextFramePromise = new Promise((resolve) => {\n this._resolveNextFrame = resolve;\n });\n }\n return this._nextFramePromise;\n }\n\n async toDataURL(): Promise<string> {\n this.setNeedsRedraw('toDataURL');\n await this.waitForRender();\n if (this.canvas instanceof HTMLCanvasElement) {\n return this.canvas.toDataURL();\n }\n throw new Error('OffscreenCanvas');\n }\n\n // PRIVATE METHODS\n\n _initialize() {\n this._startEventHandling();\n\n // Initialize the callback data\n this._initializeAnimationProps();\n this._updateAnimationProps();\n\n // Default viewport setup, in case onInitialize wants to render\n this._resizeCanvasDrawingBuffer();\n this._resizeViewport();\n\n // this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;\n }\n\n _setDisplay(display: any) {\n if (this.display) {\n this.display.destroy();\n this.display.animationLoop = null;\n }\n\n // store animation loop on the display\n if (display) {\n display.animationLoop = this;\n }\n\n this.display = display;\n }\n\n _requestAnimationFrame() {\n if (!this._running) {\n return;\n }\n\n // VR display has a separate animation frame to sync with headset\n // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/\n // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame\n // if (this.display && this.display.requestAnimationFrame) {\n // this._animationFrameId = this.display.requestAnimationFrame(this._animationFrame.bind(this));\n // }\n this._animationFrameId = requestAnimationFrame(this._animationFrame.bind(this));\n }\n\n _cancelAnimationFrame() {\n if (this._animationFrameId !== null) {\n return;\n }\n\n // VR display has a separate animation frame to sync with headset\n // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/\n // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame\n // if (this.display && this.display.cancelAnimationFrame) {\n // this.display.cancelAnimationFrame(this._animationFrameId);\n // }\n cancelAnimationFrame(this._animationFrameId);\n this._animationFrameId = null;\n }\n\n _animationFrame() {\n if (!this._running) {\n return;\n }\n this.redraw();\n this._requestAnimationFrame();\n }\n\n // Called on each frame, can be overridden to call onRender multiple times\n // to support e.g. stereoscopic rendering\n _renderFrame(animationProps: AnimationProps) {\n // Allow e.g. VR display to render multiple frames.\n if (this.display) {\n this.display._renderFrame(animationProps);\n return;\n }\n\n // call callback\n this.props.onRender(this._getAnimationProps());\n // end callback\n }\n\n _clearNeedsRedraw() {\n this.needsRedraw = false;\n }\n\n _setupFrame() {\n this._resizeCanvasDrawingBuffer();\n this._resizeViewport();\n }\n\n // Initialize the object that will be passed to app callbacks\n _initializeAnimationProps() {\n if (!this.device) {\n throw new Error('loop');\n }\n this.animationProps = {\n animationLoop: this,\n\n device: this.device,\n canvas: this.device?.canvasContext?.canvas,\n renderPass: this.device.getDefaultRenderPass(),\n timeline: this.timeline,\n\n // Initial values\n useDevicePixels: this.props.useDevicePixels,\n needsRedraw: false,\n\n // Placeholders\n width: 1,\n height: 1,\n aspect: 1,\n\n // Animation props\n time: 0,\n startTime: Date.now(),\n engineTime: 0,\n tick: 0,\n tock: 0,\n\n // Experimental\n _mousePosition: null // Event props\n };\n }\n\n _getAnimationProps(): AnimationProps {\n if (!this.animationProps) {\n throw new Error('animationProps');\n }\n return this.animationProps;\n }\n\n // Update the context object that will be passed to app callbacks\n _updateAnimationProps(): void {\n if (!this.animationProps) {\n return;\n }\n\n this.animationProps.renderPass = this.device.getDefaultRenderPass();\n\n const {width, height, aspect} = this._getSizeAndAspect();\n if (width !== this.animationProps.width || height !== this.animationProps.height) {\n this.setNeedsRedraw('drawing buffer resized');\n }\n if (aspect !== this.animationProps.aspect) {\n this.setNeedsRedraw('drawing buffer aspect changed');\n }\n\n this.animationProps.width = width;\n this.animationProps.height = height;\n this.animationProps.aspect = aspect;\n\n this.animationProps.needsRedraw = this.needsRedraw;\n\n // Update time properties\n this.animationProps.engineTime = Date.now() - this.animationProps.startTime;\n\n if (this.timeline) {\n this.timeline.update(this.animationProps.engineTime);\n }\n\n this.animationProps.tick = Math.floor((this.animationProps.time / 1000) * 60);\n this.animationProps.tock++;\n\n // For back compatibility\n this.animationProps.time = this.timeline\n ? this.timeline.getTime()\n : this.animationProps.engineTime;\n }\n\n /** Wait for supplied device */\n async _initDevice() {\n this.device = await this.props.device;\n if (!this.device) {\n throw new Error('No device provided');\n }\n this.canvas = this.device.canvasContext?.canvas || null;\n // this._createInfoDiv();\n }\n\n _createInfoDiv() {\n if (this.canvas && this.props.onAddHTML) {\n const wrapperDiv = document.createElement('div');\n document.body.appendChild(wrapperDiv);\n wrapperDiv.style.position = 'relative';\n const div = document.createElement('div');\n div.style.position = 'absolute';\n div.style.left = '10px';\n div.style.bottom = '10px';\n div.style.width = '300px';\n div.style.background = 'white';\n if (this.canvas instanceof HTMLCanvasElement) {\n wrapperDiv.appendChild(this.canvas);\n }\n wrapperDiv.appendChild(div);\n const html = this.props.onAddHTML(div);\n if (html) {\n div.innerHTML = html;\n }\n }\n }\n\n _getSizeAndAspect(): {width: number; height: number; aspect: number} {\n if (!this.device) {\n return {width: 1, height: 1, aspect: 1};\n }\n // https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html\n const [width, height] = this.device?.canvasContext?.getPixelSize() || [1, 1];\n\n // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html\n let aspect = 1;\n const canvas = this.device?.canvasContext?.canvas;\n\n // @ts-expect-error\n if (canvas && canvas.clientHeight) {\n // @ts-expect-error\n aspect = canvas.clientWidth / canvas.clientHeight;\n } else if (width > 0 && height > 0) {\n aspect = width / height;\n }\n\n return {width, height, aspect};\n }\n\n /** Default viewport setup */\n _resizeViewport() {\n // @ts-expect-error Expose on canvasContext\n if (this.props.autoResizeViewport && this.device.gl) {\n // @ts-expect-error Expose canvasContext\n this.device.gl.viewport(0, 0, this.device.gl.drawingBufferWidth, this.device.gl.drawingBufferHeight);\n }\n }\n\n /**\n * Resize the render buffer of the canvas to match canvas client size\n * Optionally multiplying with devicePixel ratio\n */\n _resizeCanvasDrawingBuffer() {\n if (this.props.autoResizeDrawingBuffer) {\n this.device?.canvasContext?.resize({useDevicePixels: this.props.useDevicePixels});\n }\n }\n\n _beginTimers() {\n this.frameRate.timeEnd();\n this.frameRate.timeStart();\n\n // Check if timer for last frame has completed.\n // GPU timer results are never available in the same\n // frame they are captured.\n // if (\n // this._gpuTimeQuery &&\n // this._gpuTimeQuery.isResultAvailable() &&\n // !this._gpuTimeQuery.isTimerDisjoint()\n // ) {\n // this.stats.get('GPU Time').addTime(this._gpuTimeQuery.getTimerMilliseconds());\n // }\n\n // if (this._gpuTimeQuery) {\n // // GPU time query start\n // this._gpuTimeQuery.beginTimeElapsedQuery();\n // }\n\n // this.cpuTime.timeStart();\n }\n\n _endTimers() {\n this.cpuTime.timeEnd();\n\n // if (this._gpuTimeQuery) {\n // // GPU time query end. Results will be available on next frame.\n // this._gpuTimeQuery.end();\n // }\n }\n\n // Event handling\n\n _startEventHandling() {\n if (this.canvas) {\n this.canvas.addEventListener('mousemove', this._onMousemove.bind(this));\n this.canvas.addEventListener('mouseleave', this._onMouseleave.bind(this));\n }\n }\n\n _onMousemove(event: Event) {\n if (event instanceof MouseEvent) {\n this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];\n }\n }\n\n _onMouseleave(event: Event) {\n this._getAnimationProps()._mousePosition = null;\n }\n}\n"],"mappings":"AAEA,SAAQA,IAAI,QAAe,eAAe;AAC1C,SAAQC,qBAAqB,EAAEC,oBAAoB,QAAO,eAAe;AAGzE,SAAQC,KAAK,QAAa,iBAAiB;AAE3C,IAAIC,aAAa,GAAG,CAAC;AA4BrB,MAAMC,4BAA0D,GAAG;EACjEC,MAAM,EAAE,IAAK;EAEbC,SAAS,EAAEA,CAAA,KAAM,EAAE;EACnBC,YAAY,EAAE,MAAAA,CAAA,KAAY;IAAE,OAAO,IAAI;EAAE,CAAC;EAC1CC,QAAQ,EAAEA,CAAA,KAAM,CAAC,CAAC;EAClBC,UAAU,EAAEA,CAAA,KAAM,CAAC,CAAC;EACpBC,OAAO,EAAGC,KAAK,IAAKC,OAAO,CAACD,KAAK,CAACA,KAAK,CAAC;EAExCE,KAAK,EAAEd,IAAI,CAACc,KAAK,CAACC,GAAG,CAAE,kBAAiBX,aAAa,EAAG,EAAC,CAAC;EAG1DY,eAAe,EAAE,IAAI;EACrBC,kBAAkB,EAAE,KAAK;EACzBC,uBAAuB,EAAE;AAC3B,CAAC;AAGD,OAAO,MAAMC,aAAa,CAAC;EA4BzBC,WAAWA,CAACC,KAAyB,EAAE;IAAA,KA3BvCf,MAAM,GAAkB,IAAI;IAAA,KAC5BgB,MAAM,GAA+C,IAAI;IAAA,KAEzDD,KAAK;IAAA,KACLE,cAAc,GAA0B,IAAI;IAAA,KAC5CC,QAAQ,GAAoB,IAAI;IAAA,KAChCV,KAAK;IAAA,KACLW,OAAO;IAAA,KACPC,OAAO;IAAA,KACPC,SAAS;IAAA,KAETC,OAAO;IAAA,KAEPC,WAAW,GAAmB,aAAa;IAAA,KAE3CC,YAAY,GAAY,KAAK;IAAA,KAC7BC,QAAQ,GAAY,KAAK;IAAA,KACzBC,iBAAiB,GAAQ,IAAI;IAAA,KAC7BC,iBAAiB,GAAkC,IAAI;IAAA,KACvDC,iBAAiB,GAAoD,IAAI;IAAA,KACzEC,aAAa,GAAW,CAAC;IAQvB,IAAI,CAACd,KAAK,GAAG;MAAC,GAAGhB,4BAA4B;MAAE,GAAGgB;IAAK,CAAC;IACxDA,KAAK,GAAG,IAAI,CAACA,KAAK;IAElB,IAAI,CAACA,KAAK,CAACf,MAAM,EAAE;MACjB,MAAM,IAAI8B,KAAK,CAAC,oBAAoB,CAAC;IACvC;IAEA,MAAM;MAACpB,eAAe,GAAG;IAAI,CAAC,GAAG,IAAI,CAACK,KAAK;IAG3C,IAAI,CAACP,KAAK,GAAGO,KAAK,CAACP,KAAK,IAAI,IAAIX,KAAK,CAAC;MAACkC,EAAE,EAAE;IAAsB,CAAC,CAAC;IACnE,IAAI,CAACZ,OAAO,GAAG,IAAI,CAACX,KAAK,CAACC,GAAG,CAAC,UAAU,CAAC;IACzC,IAAI,CAACW,OAAO,GAAG,IAAI,CAACZ,KAAK,CAACC,GAAG,CAAC,UAAU,CAAC;IACzC,IAAI,CAACY,SAAS,GAAG,IAAI,CAACb,KAAK,CAACC,GAAG,CAAC,YAAY,CAAC;IAE7C,IAAI,CAACuB,QAAQ,CAAC;MACZrB,kBAAkB,EAAEI,KAAK,CAACJ,kBAAkB;MAC5CC,uBAAuB,EAAEG,KAAK,CAACH,uBAAuB;MACtDF;IACF,CAAC,CAAC;IAGF,IAAI,CAACuB,KAAK,GAAG,IAAI,CAACA,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC;IAClC,IAAI,CAACC,IAAI,GAAG,IAAI,CAACA,IAAI,CAACD,IAAI,CAAC,IAAI,CAAC;IAEhC,IAAI,CAACE,YAAY,GAAG,IAAI,CAACA,YAAY,CAACF,IAAI,CAAC,IAAI,CAAC;IAChD,IAAI,CAACG,aAAa,GAAG,IAAI,CAACA,aAAa,CAACH,IAAI,CAAC,IAAI,CAAC;EACpD;EAEAI,OAAOA,CAAA,EAAS;IACd,IAAI,CAACH,IAAI,CAAC,CAAC;IACX,IAAI,CAACI,WAAW,CAAC,IAAI,CAAC;EACxB;EAGAC,MAAMA,CAAA,EAAS;IACb,IAAI,CAACF,OAAO,CAAC,CAAC;EAChB;EAEAG,cAAcA,CAACC,MAAc,EAAQ;IACnC,IAAI,CAACnB,WAAW,GAAG,IAAI,CAACA,WAAW,IAAImB,MAAM;IAC7C,OAAO,IAAI;EACb;EAGAV,QAAQA,CAACjB,KAAgC,EAAQ;IAC/C,IAAI,oBAAoB,IAAIA,KAAK,EAAE;MACjC,IAAI,CAACA,KAAK,CAACJ,kBAAkB,GAAGI,KAAK,CAACJ,kBAAkB,IAAI,KAAK;IACnE;IACA,IAAI,yBAAyB,IAAII,KAAK,EAAE;MACtC,IAAI,CAACA,KAAK,CAACH,uBAAuB,GAAGG,KAAK,CAACH,uBAAuB,IAAI,KAAK;IAC7E;IACA,IAAI,iBAAiB,IAAIG,KAAK,EAAE;MAC9B,IAAI,CAACA,KAAK,CAACL,eAAe,GAAGK,KAAK,CAACL,eAAe,IAAI,KAAK;IAC7D;IACA,OAAO,IAAI;EACb;EAGA,MAAMuB,KAAKA,CAAA,EAAG;IACZ,IAAI,IAAI,CAACR,QAAQ,EAAE;MACjB,OAAO,IAAI;IACb;IACA,IAAI,CAACA,QAAQ,GAAG,IAAI;IAEpB,IAAI;MAEF,IAAI,CAAC,IAAI,CAACA,QAAQ,EAAE;QAClB,OAAO,IAAI;MACb;MAEA,IAAIkB,UAAU;MACd,IAAI,CAAC,IAAI,CAACnB,YAAY,EAAE;QACtB,IAAI,CAACA,YAAY,GAAG,IAAI;QAExB,MAAM,IAAI,CAACoB,WAAW,CAAC,CAAC;QACxB,IAAI,CAACC,WAAW,CAAC,CAAC;QAGlB,MAAM,IAAI,CAAC9B,KAAK,CAACb,YAAY,CAAC,IAAI,CAAC4C,kBAAkB,CAAC,CAAC,CAAC;MAC1D;MAGA,IAAI,CAAC,IAAI,CAACrB,QAAQ,EAAE;QAClB,OAAO,IAAI;MACb;MAGA,IAAIkB,UAAU,KAAK,KAAK,EAAE;QAExB,IAAI,CAACI,qBAAqB,CAAC,CAAC;QAC5B,IAAI,CAACC,sBAAsB,CAAC,CAAC;MAC/B;MAEA,OAAO,IAAI;IACb,CAAC,CAAC,OAAOC,GAAY,EAAE;MACrB,MAAM3C,KAAK,GAAG2C,GAAG,YAAYnB,KAAK,GAAGmB,GAAG,GAAG,IAAInB,KAAK,CAAC,eAAe,CAAC;MACrE,IAAI,CAACf,KAAK,CAACV,OAAO,CAACC,KAAK,CAAC;MAEzB,MAAMA,KAAK;IACb;EACF;EAGA4C,MAAMA,CAAA,EAAS;IAAA,IAAAC,YAAA;IACb,KAAAA,YAAA,GAAI,IAAI,CAACnD,MAAM,cAAAmD,YAAA,eAAXA,YAAA,CAAaC,MAAM,EAAE;MACvB,OAAO,IAAI;IACb;IAEA,IAAI,CAACC,YAAY,CAAC,CAAC;IAEnB,IAAI,CAACC,WAAW,CAAC,CAAC;IAClB,IAAI,CAACC,qBAAqB,CAAC,CAAC;IAE5B,IAAI,CAACC,YAAY,CAAC,IAAI,CAACV,kBAAkB,CAAC,CAAC,CAAC;IAG5C,IAAI,CAACW,iBAAiB,CAAC,CAAC;IAExB,IAAI,IAAI,CAAC7B,iBAAiB,EAAE;MAC1B,IAAI,CAACA,iBAAiB,CAAC,IAAI,CAAC;MAC5B,IAAI,CAACD,iBAAiB,GAAG,IAAI;MAC7B,IAAI,CAACC,iBAAiB,GAAG,IAAI;IAC/B;IAEA,IAAI,CAAC8B,UAAU,CAAC,CAAC;IAEjB,OAAO,IAAI;EACb;EAGAvB,IAAIA,CAAA,EAAG;IAEL,IAAI,IAAI,CAACV,QAAQ,EAAE;MAGjB,IAAI,IAAI,CAACR,cAAc,EAAE;QACvB,IAAI,CAACF,KAAK,CAACX,UAAU,CAAC,IAAI,CAACa,cAAc,CAAC;MAC5C;MAEA,IAAI,CAAC8B,qBAAqB,CAAC,CAAC;MAC5B,IAAI,CAACpB,iBAAiB,GAAG,IAAI;MAC7B,IAAI,CAACC,iBAAiB,GAAG,IAAI;MAC7B,IAAI,CAACH,QAAQ,GAAG,KAAK;IACvB;IACA,OAAO,IAAI;EACb;EAEAkC,cAAcA,CAACzC,QAAkB,EAAY;IAC3C,IAAI,CAACA,QAAQ,GAAGA,QAAQ;IACxB,OAAO,IAAI,CAACA,QAAQ;EACtB;EAEA0C,cAAcA,CAAA,EAAS;IACrB,IAAI,CAAC1C,QAAQ,GAAG,IAAI;EACtB;EAEA2C,aAAaA,CAAA,EAA2B;IACtC,IAAI,CAACpB,cAAc,CAAC,eAAe,CAAC;IAEpC,IAAI,CAAC,IAAI,CAACd,iBAAiB,EAAE;MAC3B,IAAI,CAACA,iBAAiB,GAAG,IAAImC,OAAO,CAAEC,OAAO,IAAK;QAChD,IAAI,CAACnC,iBAAiB,GAAGmC,OAAO;MAClC,CAAC,CAAC;IACJ;IACA,OAAO,IAAI,CAACpC,iBAAiB;EAC/B;EAEA,MAAMqC,SAASA,CAAA,EAAoB;IACjC,IAAI,CAACvB,cAAc,CAAC,WAAW,CAAC;IAChC,MAAM,IAAI,CAACoB,aAAa,CAAC,CAAC;IAC1B,IAAI,IAAI,CAAC7C,MAAM,YAAYiD,iBAAiB,EAAE;MAC5C,OAAO,IAAI,CAACjD,MAAM,CAACgD,SAAS,CAAC,CAAC;IAChC;IACA,MAAM,IAAIlC,KAAK,CAAC,iBAAiB,CAAC;EACpC;EAIAe,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACqB,mBAAmB,CAAC,CAAC;IAG1B,IAAI,CAACC,yBAAyB,CAAC,CAAC;IAChC,IAAI,CAACZ,qBAAqB,CAAC,CAAC;IAG5B,IAAI,CAACa,0BAA0B,CAAC,CAAC;IACjC,IAAI,CAACC,eAAe,CAAC,CAAC;EAGxB;EAEA9B,WAAWA,CAACjB,OAAY,EAAE;IACxB,IAAI,IAAI,CAACA,OAAO,EAAE;MAChB,IAAI,CAACA,OAAO,CAACgB,OAAO,CAAC,CAAC;MACtB,IAAI,CAAChB,OAAO,CAACgD,aAAa,GAAG,IAAI;IACnC;IAGA,IAAIhD,OAAO,EAAE;MACXA,OAAO,CAACgD,aAAa,GAAG,IAAI;IAC9B;IAEA,IAAI,CAAChD,OAAO,GAAGA,OAAO;EACxB;EAEA0B,sBAAsBA,CAAA,EAAG;IACvB,IAAI,CAAC,IAAI,CAACvB,QAAQ,EAAE;MAClB;IACF;IAQA,IAAI,CAACC,iBAAiB,GAAG/B,qBAAqB,CAAC,IAAI,CAAC4E,eAAe,CAACrC,IAAI,CAAC,IAAI,CAAC,CAAC;EACjF;EAEAa,qBAAqBA,CAAA,EAAG;IACtB,IAAI,IAAI,CAACrB,iBAAiB,KAAK,IAAI,EAAE;MACnC;IACF;IAQA9B,oBAAoB,CAAC,IAAI,CAAC8B,iBAAiB,CAAC;IAC5C,IAAI,CAACA,iBAAiB,GAAG,IAAI;EAC/B;EAEA6C,eAAeA,CAAA,EAAG;IAChB,IAAI,CAAC,IAAI,CAAC9C,QAAQ,EAAE;MAClB;IACF;IACA,IAAI,CAACyB,MAAM,CAAC,CAAC;IACb,IAAI,CAACF,sBAAsB,CAAC,CAAC;EAC/B;EAIAQ,YAAYA,CAACvC,cAA8B,EAAE;IAE3C,IAAI,IAAI,CAACK,OAAO,EAAE;MAChB,IAAI,CAACA,OAAO,CAACkC,YAAY,CAACvC,cAAc,CAAC;MACzC;IACF;IAGA,IAAI,CAACF,KAAK,CAACZ,QAAQ,CAAC,IAAI,CAAC2C,kBAAkB,CAAC,CAAC,CAAC;EAEhD;EAEAW,iBAAiBA,CAAA,EAAG;IAClB,IAAI,CAAClC,WAAW,GAAG,KAAK;EAC1B;EAEA+B,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACc,0BAA0B,CAAC,CAAC;IACjC,IAAI,CAACC,eAAe,CAAC,CAAC;EACxB;EAGAF,yBAAyBA,CAAA,EAAG;IAAA,IAAAK,aAAA;IAC1B,IAAI,CAAC,IAAI,CAACxE,MAAM,EAAE;MAChB,MAAM,IAAI8B,KAAK,CAAC,MAAM,CAAC;IACzB;IACA,IAAI,CAACb,cAAc,GAAG;MACpBqD,aAAa,EAAE,IAAI;MAEnBtE,MAAM,EAAE,IAAI,CAACA,MAAM;MACnBgB,MAAM,GAAAwD,aAAA,GAAE,IAAI,CAACxE,MAAM,cAAAwE,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAaC,aAAa,cAAAD,aAAA,uBAA1BA,aAAA,CAA4BxD,MAAM;MAC1C0D,UAAU,EAAE,IAAI,CAAC1E,MAAM,CAAC2E,oBAAoB,CAAC,CAAC;MAC9CzD,QAAQ,EAAE,IAAI,CAACA,QAAQ;MAGvBR,eAAe,EAAE,IAAI,CAACK,KAAK,CAACL,eAAe;MAC3Ca,WAAW,EAAE,KAAK;MAGlBqD,KAAK,EAAE,CAAC;MACRC,MAAM,EAAE,CAAC;MACTC,MAAM,EAAE,CAAC;MAGTC,IAAI,EAAE,CAAC;MACPC,SAAS,EAAEC,IAAI,CAACC,GAAG,CAAC,CAAC;MACrBC,UAAU,EAAE,CAAC;MACbC,IAAI,EAAE,CAAC;MACPC,IAAI,EAAE,CAAC;MAGPC,cAAc,EAAE;IAClB,CAAC;EACH;EAEAxC,kBAAkBA,CAAA,EAAmB;IACnC,IAAI,CAAC,IAAI,CAAC7B,cAAc,EAAE;MACxB,MAAM,IAAIa,KAAK,CAAC,gBAAgB,CAAC;IACnC;IACA,OAAO,IAAI,CAACb,cAAc;EAC5B;EAGAsC,qBAAqBA,CAAA,EAAS;IAC5B,IAAI,CAAC,IAAI,CAACtC,cAAc,EAAE;MACxB;IACF;IAEA,IAAI,CAACA,cAAc,CAACyD,UAAU,GAAG,IAAI,CAAC1E,MAAM,CAAC2E,oBAAoB,CAAC,CAAC;IAEnE,MAAM;MAACC,KAAK;MAAEC,MAAM;MAAEC;IAAM,CAAC,GAAG,IAAI,CAACS,iBAAiB,CAAC,CAAC;IACxD,IAAIX,KAAK,KAAK,IAAI,CAAC3D,cAAc,CAAC2D,KAAK,IAAIC,MAAM,KAAK,IAAI,CAAC5D,cAAc,CAAC4D,MAAM,EAAE;MAChF,IAAI,CAACpC,cAAc,CAAC,wBAAwB,CAAC;IAC/C;IACA,IAAIqC,MAAM,KAAK,IAAI,CAAC7D,cAAc,CAAC6D,MAAM,EAAE;MACzC,IAAI,CAACrC,cAAc,CAAC,+BAA+B,CAAC;IACtD;IAEA,IAAI,CAACxB,cAAc,CAAC2D,KAAK,GAAGA,KAAK;IACjC,IAAI,CAAC3D,cAAc,CAAC4D,MAAM,GAAGA,MAAM;IACnC,IAAI,CAAC5D,cAAc,CAAC6D,MAAM,GAAGA,MAAM;IAEnC,IAAI,CAAC7D,cAAc,CAACM,WAAW,GAAG,IAAI,CAACA,WAAW;IAGlD,IAAI,CAACN,cAAc,CAACkE,UAAU,GAAGF,IAAI,CAACC,GAAG,CAAC,CAAC,GAAG,IAAI,CAACjE,cAAc,CAAC+D,SAAS;IAE3E,IAAI,IAAI,CAAC9D,QAAQ,EAAE;MACjB,IAAI,CAACA,QAAQ,CAACsE,MAAM,CAAC,IAAI,CAACvE,cAAc,CAACkE,UAAU,CAAC;IACtD;IAEA,IAAI,CAAClE,cAAc,CAACmE,IAAI,GAAGK,IAAI,CAACC,KAAK,CAAE,IAAI,CAACzE,cAAc,CAAC8D,IAAI,GAAG,IAAI,GAAI,EAAE,CAAC;IAC7E,IAAI,CAAC9D,cAAc,CAACoE,IAAI,EAAE;IAG1B,IAAI,CAACpE,cAAc,CAAC8D,IAAI,GAAG,IAAI,CAAC7D,QAAQ,GACpC,IAAI,CAACA,QAAQ,CAACyE,OAAO,CAAC,CAAC,GACvB,IAAI,CAAC1E,cAAc,CAACkE,UAAU;EACpC;EAGA,MAAMvC,WAAWA,CAAA,EAAG;IAAA,IAAAgD,qBAAA;IAClB,IAAI,CAAC5F,MAAM,GAAG,MAAM,IAAI,CAACe,KAAK,CAACf,MAAM;IACrC,IAAI,CAAC,IAAI,CAACA,MAAM,EAAE;MAChB,MAAM,IAAI8B,KAAK,CAAC,oBAAoB,CAAC;IACvC;IACA,IAAI,CAACd,MAAM,GAAG,EAAA4E,qBAAA,OAAI,CAAC5F,MAAM,CAACyE,aAAa,cAAAmB,qBAAA,uBAAzBA,qBAAA,CAA2B5E,MAAM,KAAI,IAAI;EAEzD;EAEA6E,cAAcA,CAAA,EAAG;IACf,IAAI,IAAI,CAAC7E,MAAM,IAAI,IAAI,CAACD,KAAK,CAACd,SAAS,EAAE;MACvC,MAAM6F,UAAU,GAAGC,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;MAChDD,QAAQ,CAACE,IAAI,CAACC,WAAW,CAACJ,UAAU,CAAC;MACrCA,UAAU,CAACK,KAAK,CAACC,QAAQ,GAAG,UAAU;MACtC,MAAMC,GAAG,GAAGN,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;MACzCK,GAAG,CAACF,KAAK,CAACC,QAAQ,GAAG,UAAU;MAC/BC,GAAG,CAACF,KAAK,CAACG,IAAI,GAAG,MAAM;MACvBD,GAAG,CAACF,KAAK,CAACI,MAAM,GAAG,MAAM;MACzBF,GAAG,CAACF,KAAK,CAACvB,KAAK,GAAG,OAAO;MACzByB,GAAG,CAACF,KAAK,CAACK,UAAU,GAAG,OAAO;MAC9B,IAAI,IAAI,CAACxF,MAAM,YAAYiD,iBAAiB,EAAE;QAC5C6B,UAAU,CAACI,WAAW,CAAC,IAAI,CAAClF,MAAM,CAAC;MACrC;MACA8E,UAAU,CAACI,WAAW,CAACG,GAAG,CAAC;MAC3B,MAAMI,IAAI,GAAG,IAAI,CAAC1F,KAAK,CAACd,SAAS,CAACoG,GAAG,CAAC;MACtC,IAAII,IAAI,EAAE;QACRJ,GAAG,CAACK,SAAS,GAAGD,IAAI;MACtB;IACF;EACF;EAEAlB,iBAAiBA,CAAA,EAAqD;IAAA,IAAAoB,aAAA,EAAAC,aAAA;IACpE,IAAI,CAAC,IAAI,CAAC5G,MAAM,EAAE;MAChB,OAAO;QAAC4E,KAAK,EAAE,CAAC;QAAEC,MAAM,EAAE,CAAC;QAAEC,MAAM,EAAE;MAAC,CAAC;IACzC;IAEA,MAAM,CAACF,KAAK,EAAEC,MAAM,CAAC,GAAG,EAAA8B,aAAA,OAAI,CAAC3G,MAAM,cAAA2G,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAalC,aAAa,cAAAkC,aAAA,uBAA1BA,aAAA,CAA4BE,YAAY,CAAC,CAAC,KAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAG5E,IAAI/B,MAAM,GAAG,CAAC;IACd,MAAM9D,MAAM,IAAA4F,aAAA,GAAG,IAAI,CAAC5G,MAAM,cAAA4G,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAanC,aAAa,cAAAmC,aAAA,uBAA1BA,aAAA,CAA4B5F,MAAM;IAGjD,IAAIA,MAAM,IAAIA,MAAM,CAAC8F,YAAY,EAAE;MAEjChC,MAAM,GAAG9D,MAAM,CAAC+F,WAAW,GAAG/F,MAAM,CAAC8F,YAAY;IACnD,CAAC,MAAM,IAAIlC,KAAK,GAAG,CAAC,IAAIC,MAAM,GAAG,CAAC,EAAE;MAClCC,MAAM,GAAGF,KAAK,GAAGC,MAAM;IACzB;IAEA,OAAO;MAACD,KAAK;MAAEC,MAAM;MAAEC;IAAM,CAAC;EAChC;EAGAT,eAAeA,CAAA,EAAG;IAEhB,IAAI,IAAI,CAACtD,KAAK,CAACJ,kBAAkB,IAAI,IAAI,CAACX,MAAM,CAACgH,EAAE,EAAE;MAEnD,IAAI,CAAChH,MAAM,CAACgH,EAAE,CAACC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAACjH,MAAM,CAACgH,EAAE,CAACE,kBAAkB,EAAE,IAAI,CAAClH,MAAM,CAACgH,EAAE,CAACG,mBAAmB,CAAC;IACtG;EACF;EAMA/C,0BAA0BA,CAAA,EAAG;IAC3B,IAAI,IAAI,CAACrD,KAAK,CAACH,uBAAuB,EAAE;MAAA,IAAAwG,aAAA;MACtC,CAAAA,aAAA,OAAI,CAACpH,MAAM,cAAAoH,aAAA,gBAAAA,aAAA,GAAXA,aAAA,CAAa3C,aAAa,cAAA2C,aAAA,uBAA1BA,aAAA,CAA4BC,MAAM,CAAC;QAAC3G,eAAe,EAAE,IAAI,CAACK,KAAK,CAACL;MAAe,CAAC,CAAC;IACnF;EACF;EAEA2C,YAAYA,CAAA,EAAG;IACb,IAAI,CAAChC,SAAS,CAACiG,OAAO,CAAC,CAAC;IACxB,IAAI,CAACjG,SAAS,CAACkG,SAAS,CAAC,CAAC;EAmB5B;EAEA7D,UAAUA,CAAA,EAAG;IACX,IAAI,CAACvC,OAAO,CAACmG,OAAO,CAAC,CAAC;EAMxB;EAIApD,mBAAmBA,CAAA,EAAG;IACpB,IAAI,IAAI,CAAClD,MAAM,EAAE;MACf,IAAI,CAACA,MAAM,CAACwG,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAACpF,YAAY,CAACF,IAAI,CAAC,IAAI,CAAC,CAAC;MACvE,IAAI,CAAClB,MAAM,CAACwG,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAACnF,aAAa,CAACH,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E;EACF;EAEAE,YAAYA,CAACqF,KAAY,EAAE;IACzB,IAAIA,KAAK,YAAYC,UAAU,EAAE;MAC/B,IAAI,CAAC5E,kBAAkB,CAAC,CAAC,CAACwC,cAAc,GAAG,CAACmC,KAAK,CAACE,OAAO,EAAEF,KAAK,CAACG,OAAO,CAAC;IAC3E;EACF;EAEAvF,aAAaA,CAACoF,KAAY,EAAE;IAC1B,IAAI,CAAC3E,kBAAkB,CAAC,CAAC,CAACwC,cAAc,GAAG,IAAI;EACjD;AACF"}
package/dist/dist.dev.js CHANGED
@@ -1369,7 +1369,7 @@ var __exports__ = (() => {
1369
1369
  // Resource creation helpers
1370
1370
  _getBufferProps(props) {
1371
1371
  if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1372
- return {
1372
+ props = {
1373
1373
  data: props
1374
1374
  };
1375
1375
  }
@@ -1381,6 +1381,8 @@ var __exports__ = (() => {
1381
1381
  newProps.indexType = "uint32";
1382
1382
  } else if (props.data instanceof Uint16Array) {
1383
1383
  newProps.indexType = "uint16";
1384
+ } else {
1385
+ log.warn("indices buffer content must be of integer type")();
1384
1386
  }
1385
1387
  }
1386
1388
  return newProps;
@@ -2456,8 +2458,8 @@ var __exports__ = (() => {
2456
2458
  const vertexFormat = bufferMapping?.vertexFormat || attributeTypeInfo.defaultVertexFormat;
2457
2459
  const vertexFormatInfo = decodeVertexFormat(vertexFormat);
2458
2460
  return {
2459
- name: name2,
2460
- bufferName: bufferMapping?.name || name2,
2461
+ attributeName: bufferMapping?.attributeName || shaderDeclaration.name,
2462
+ bufferName: bufferMapping?.bufferName || shaderDeclaration.name,
2461
2463
  location: shaderDeclaration.location,
2462
2464
  shaderType: shaderDeclaration.type,
2463
2465
  shaderDataType: attributeTypeInfo.dataType,
@@ -2481,38 +2483,63 @@ var __exports__ = (() => {
2481
2483
  }
2482
2484
  return attribute || null;
2483
2485
  }
2484
- function getAttributeFromBufferLayout(bufferLayout, name2) {
2485
- for (const bufferMapping of bufferLayout) {
2486
- if (bufferMapping.name === name2) {
2486
+ function getAttributeFromBufferLayout(bufferLayouts, name2) {
2487
+ checkBufferLayouts(bufferLayouts);
2488
+ let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name2);
2489
+ if (bufferLayoutInfo) {
2490
+ return bufferLayoutInfo;
2491
+ }
2492
+ bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name2);
2493
+ if (bufferLayoutInfo) {
2494
+ return bufferLayoutInfo;
2495
+ }
2496
+ log.warn(`layout for attribute "${name2}" not present in buffer layout`);
2497
+ return null;
2498
+ }
2499
+ function checkBufferLayouts(bufferLayouts) {
2500
+ for (const bufferLayout of bufferLayouts) {
2501
+ if (bufferLayout.attributes && bufferLayout.format || !bufferLayout.attributes && !bufferLayout.format) {
2502
+ log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`);
2503
+ }
2504
+ }
2505
+ }
2506
+ function getAttributeFromShortHand(bufferLayouts, name2) {
2507
+ for (const bufferLayout of bufferLayouts) {
2508
+ if (bufferLayout.format && bufferLayout.name === name2) {
2487
2509
  return {
2488
- name: bufferMapping.name,
2510
+ attributeName: bufferLayout.name,
2489
2511
  bufferName: name2,
2490
- vertexFormat: bufferMapping.format,
2491
- byteOffset: bufferMapping.byteOffset || 0,
2492
- byteStride: bufferMapping.byteStride || 0
2512
+ stepMode: bufferLayout.stepMode,
2513
+ vertexFormat: bufferLayout.format,
2514
+ // If offset is needed, use `attributes` field.
2515
+ byteOffset: 0,
2516
+ byteStride: bufferLayout.byteStride || 0
2493
2517
  };
2494
2518
  }
2495
- let nextByteOffset = bufferMapping.byteOffset || 0;
2496
- let byteStride = 0;
2497
- for (const interleavedMapping of bufferMapping.attributes || []) {
2498
- const info = decodeVertexFormat(interleavedMapping.format);
2499
- byteStride += info.byteLength;
2500
- }
2501
- for (const interleavedMapping of bufferMapping.attributes || []) {
2502
- const byteOffset = nextByteOffset;
2503
- nextByteOffset += interleavedMapping?.byteStrideOffset || decodeVertexFormat(interleavedMapping.format).byteLength;
2504
- if (interleavedMapping.name === name2) {
2505
- return {
2506
- name: bufferMapping.name,
2507
- bufferName: name2,
2508
- vertexFormat: interleavedMapping.format,
2509
- byteOffset,
2510
- byteStride: bufferMapping.byteStride || byteStride
2511
- };
2519
+ }
2520
+ return null;
2521
+ }
2522
+ function getAttributeFromAttributesList(bufferLayouts, name2) {
2523
+ for (const bufferLayout of bufferLayouts) {
2524
+ let byteStride = bufferLayout.byteStride;
2525
+ if (typeof bufferLayout.byteStride !== "number") {
2526
+ for (const attributeMapping2 of bufferLayout.attributes || []) {
2527
+ const info = decodeVertexFormat(attributeMapping2.format);
2528
+ byteStride += info.byteLength;
2512
2529
  }
2513
2530
  }
2531
+ const attributeMapping = bufferLayout.attributes?.find((mapping) => mapping.attribute === name2);
2532
+ if (attributeMapping) {
2533
+ return {
2534
+ attributeName: attributeMapping.attribute,
2535
+ bufferName: bufferLayout.name,
2536
+ stepMode: bufferLayout.stepMode,
2537
+ vertexFormat: attributeMapping.format,
2538
+ byteOffset: attributeMapping.byteOffset,
2539
+ byteStride
2540
+ };
2541
+ }
2514
2542
  }
2515
- log.warn(`layout for attribute "${name2}" not present in buffer layout`);
2516
2543
  return null;
2517
2544
  }
2518
2545
  function mergeShaderLayout(baseLayout, overrideLayout) {
@@ -5991,30 +6018,6 @@ void main() {
5991
6018
  this.attributes = props.attributes;
5992
6019
  this.vertexCount = props.vertexCount;
5993
6020
  this.bufferLayout = props.bufferLayout || [];
5994
- if (!this.bufferLayout.find((layout) => layout.name === "positions")) {
5995
- this.bufferLayout.push({
5996
- name: "positions",
5997
- format: "float32x3"
5998
- });
5999
- }
6000
- if (this.attributes.normals && !this.bufferLayout.find((layout) => layout.name === "normals")) {
6001
- this.bufferLayout.push({
6002
- name: "normals",
6003
- format: "float32x3"
6004
- });
6005
- }
6006
- if (this.attributes.texCoords && !this.bufferLayout.find((layout) => layout.name === "texCoords")) {
6007
- this.bufferLayout.push({
6008
- name: "texCoords",
6009
- format: "float32x2"
6010
- });
6011
- }
6012
- if (this.attributes.colors && !this.bufferLayout.find((layout) => layout.name === "colors")) {
6013
- this.bufferLayout.push({
6014
- name: "colors",
6015
- format: "float32x3"
6016
- });
6017
- }
6018
6021
  if (this.indices) {
6019
6022
  assert2(this.indices.usage === Buffer2.INDEX);
6020
6023
  }
@@ -6062,44 +6065,34 @@ void main() {
6062
6065
  return void 0;
6063
6066
  }
6064
6067
  const data = geometry.indices.value;
6065
- assert2(data instanceof Uint16Array || data instanceof Uint32Array, 'attribute array for "indices" must be of integer type');
6066
6068
  return device.createBuffer({
6067
6069
  usage: Buffer2.INDEX,
6068
6070
  data
6069
6071
  });
6070
6072
  }
6071
6073
  function getAttributeBuffersFromGeometry(device, geometry) {
6072
- const positions = geometry.attributes.positions || geometry.attributes.POSITION;
6073
- const normals = geometry.attributes.normals || geometry.attributes.NORMAL;
6074
- const texCoords = geometry.attributes.texCoords || geometry.attributes.TEXCOORD_0;
6075
- const attributes = {
6076
- positions: device.createBuffer({
6077
- data: positions.value,
6078
- id: "positions-buffer"
6079
- })
6080
- };
6081
- const bufferLayout = [{
6082
- name: "positions",
6083
- format: `float32x${positions.size}`
6084
- }];
6085
- if (normals) {
6086
- attributes.normals = device.createBuffer({
6087
- data: normals.value,
6088
- id: "normals-buffer"
6089
- });
6090
- bufferLayout.push({
6091
- name: "normals",
6092
- format: `float32x${normals.size}`
6093
- });
6094
- }
6095
- if (texCoords) {
6096
- attributes.texCoords = device.createBuffer({
6097
- data: texCoords.value,
6098
- id: "texCoords-buffer"
6074
+ const bufferLayout = [];
6075
+ const attributes = {};
6076
+ for (const [attributeName, attribute] of Object.entries(geometry.attributes)) {
6077
+ let name2 = attributeName;
6078
+ switch (attributeName) {
6079
+ case "POSITION":
6080
+ name2 = "positions";
6081
+ break;
6082
+ case "NORMAL":
6083
+ name2 = "normals";
6084
+ break;
6085
+ case "TEXCOORD_0":
6086
+ name2 = "texCoords";
6087
+ break;
6088
+ }
6089
+ attributes[name2] = device.createBuffer({
6090
+ data: attribute.value,
6091
+ id: `${attributeName}-buffer`
6099
6092
  });
6100
6093
  bufferLayout.push({
6101
- name: "texCoords",
6102
- format: `float32x${texCoords.size}`
6094
+ name: name2,
6095
+ format: `float32x${attribute.size}`
6103
6096
  });
6104
6097
  }
6105
6098
  const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices);
@@ -6181,10 +6174,15 @@ void main() {
6181
6174
  _hashRenderPipeline(props) {
6182
6175
  const vsHash = this._getHash(props.vs);
6183
6176
  const fsHash = props.fs ? this._getHash(props.fs) : 0;
6184
- const parameterHash = this._getHash(JSON.stringify(props.parameters));
6185
- const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
6186
6177
  const varyingHash = "-";
6187
- return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}}`;
6178
+ switch (this.device.info.type) {
6179
+ case "webgpu":
6180
+ const parameterHash = this._getHash(JSON.stringify(props.parameters));
6181
+ const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
6182
+ return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}}`;
6183
+ default:
6184
+ return `${vsHash}/${fsHash}V${varyingHash}`;
6185
+ }
6188
6186
  }
6189
6187
  _getHash(key) {
6190
6188
  if (this._hashes[key] === void 0) {
@@ -6318,9 +6316,7 @@ void main() {
6318
6316
  setTopology(topology) {
6319
6317
  if (topology !== this.topology) {
6320
6318
  this.topology = topology;
6321
- if (this.device.info.type === "webgpu") {
6322
- this._setPipelineNeedsUpdate("topology");
6323
- }
6319
+ this._setPipelineNeedsUpdate("topology");
6324
6320
  }
6325
6321
  }
6326
6322
  /**
@@ -6330,9 +6326,7 @@ void main() {
6330
6326
  setBufferLayout(bufferLayout) {
6331
6327
  if (bufferLayout !== this.bufferLayout) {
6332
6328
  this.bufferLayout = bufferLayout;
6333
- if (this.device.info.type === "webgpu") {
6334
- this._setPipelineNeedsUpdate("bufferLayout");
6335
- }
6329
+ this._setPipelineNeedsUpdate("bufferLayout");
6336
6330
  }
6337
6331
  }
6338
6332
  /**
@@ -6343,9 +6337,7 @@ void main() {
6343
6337
  setParameters(parameters) {
6344
6338
  if (!deepEqual(parameters, this.parameters, 2)) {
6345
6339
  this.parameters = parameters;
6346
- if (this.device.info.type === "webgpu") {
6347
- this._setPipelineNeedsUpdate("parameters");
6348
- }
6340
+ this._setPipelineNeedsUpdate("parameters");
6349
6341
  }
6350
6342
  }
6351
6343
  // Update dynamic fields
@@ -13112,8 +13104,8 @@ ${formattedLog}`)();
13112
13104
  }
13113
13105
  const webglBuffer = cast(buffer);
13114
13106
  const glType = getGLFromVertexType(attributeInfo.bufferDataType);
13115
- log.log(1, {
13116
- setAttribute: attributeInfo.name,
13107
+ log.log(2, {
13108
+ setAttribute: attributeInfo.attributeName,
13117
13109
  toBuffer: bufferName,
13118
13110
  size: attributeInfo.bufferComponents,
13119
13111
  type: glType,
@@ -42,7 +42,7 @@ function tesselateIcosaHedron(props) {
42
42
  i2 *= 3;
43
43
  const mini = i1 < i2 ? i1 : i2;
44
44
  const maxi = i1 > i2 ? i1 : i2;
45
- const key = "".concat(mini, "|").concat(maxi);
45
+ const key = `${mini}|${maxi}`;
46
46
  if (key in pointMemo) {
47
47
  return pointMemo[key];
48
48
  }