@uptimizr/replay 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/AGENTS.md +57 -0
  2. package/LICENSE +201 -0
  3. package/README.md +96 -0
  4. package/dist/drivers/babylon-lite.d.ts +134 -0
  5. package/dist/drivers/babylon-lite.d.ts.map +1 -0
  6. package/dist/drivers/babylon-lite.js +167 -0
  7. package/dist/drivers/babylon-lite.js.map +1 -0
  8. package/dist/drivers/babylon.d.ts +99 -0
  9. package/dist/drivers/babylon.d.ts.map +1 -0
  10. package/dist/drivers/babylon.js +176 -0
  11. package/dist/drivers/babylon.js.map +1 -0
  12. package/dist/drivers/playcanvas.d.ts +122 -0
  13. package/dist/drivers/playcanvas.d.ts.map +1 -0
  14. package/dist/drivers/playcanvas.js +206 -0
  15. package/dist/drivers/playcanvas.js.map +1 -0
  16. package/dist/drivers/three.d.ts +127 -0
  17. package/dist/drivers/three.d.ts.map +1 -0
  18. package/dist/drivers/three.js +194 -0
  19. package/dist/drivers/three.js.map +1 -0
  20. package/dist/fetchSession.d.ts +43 -0
  21. package/dist/fetchSession.d.ts.map +1 -0
  22. package/dist/fetchSession.js +103 -0
  23. package/dist/fetchSession.js.map +1 -0
  24. package/dist/global.d.ts +62 -0
  25. package/dist/global.d.ts.map +1 -0
  26. package/dist/global.js +95 -0
  27. package/dist/global.js.map +1 -0
  28. package/dist/index.d.ts +14 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +11 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/player.d.ts +35 -0
  33. package/dist/player.d.ts.map +1 -0
  34. package/dist/player.js +104 -0
  35. package/dist/player.js.map +1 -0
  36. package/dist/reconstruct.d.ts +74 -0
  37. package/dist/reconstruct.d.ts.map +1 -0
  38. package/dist/reconstruct.js +266 -0
  39. package/dist/reconstruct.js.map +1 -0
  40. package/dist/types.d.ts +39 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +2 -0
  43. package/dist/types.js.map +1 -0
  44. package/dist/uptimizr-replay.global.js +71 -0
  45. package/llms.txt +17 -0
  46. package/package.json +100 -0
package/dist/global.js ADDED
@@ -0,0 +1,95 @@
1
+ import { createBabylonReplayDriver } from "./drivers/babylon.js";
2
+ import { fetchSessionEvents, fetchSessionEventsStream } from "./fetchSession.js";
3
+ import { ReplayPlayer } from "./player.js";
4
+ const LOG_PREFIX = "[UptimizrReplay]";
5
+ /**
6
+ * Fetch a captured session from the collector and play it back in `scene`,
7
+ * starting immediately. Returns the {@link ReplayHandle} so callers can
8
+ * pause/seek/stop. The collector must have raw-session retention enabled for the
9
+ * session-events endpoint to return data (ADR 0003).
10
+ *
11
+ * Emits a concise console summary (and, with `debug: true`, per-step logs) so it
12
+ * is clear whether playback is running. The common "nothing happens" causes —
13
+ * an empty session, a session with no `camera_sample` events, or a scene with no
14
+ * active camera — are surfaced as console warnings.
15
+ */
16
+ export async function replayInScene(options) {
17
+ const debug = options.debug ?? false;
18
+ const log = (...args) => {
19
+ if (debug)
20
+ console.info(LOG_PREFIX, ...args);
21
+ };
22
+ log(`fetching session "${options.sessionId}" from ${options.endpoint}`);
23
+ let events;
24
+ try {
25
+ // Stream the session (NDJSON when the collector supports it) and accumulate
26
+ // into an array for the full-session player. Streaming keeps server memory
27
+ // bounded and validates per line, with a transparent JSON-array fallback for
28
+ // older collectors (ADR 0015).
29
+ events = [];
30
+ let malformed = 0;
31
+ for await (const event of fetchSessionEventsStream({
32
+ endpoint: options.endpoint,
33
+ apiKey: options.apiKey,
34
+ sessionId: options.sessionId,
35
+ onMalformedLine: (count) => {
36
+ malformed = count;
37
+ },
38
+ })) {
39
+ events.push(event);
40
+ }
41
+ if (malformed > 0) {
42
+ console.warn(`${LOG_PREFIX} skipped ${malformed} malformed event line(s) while streaming the session.`);
43
+ }
44
+ }
45
+ catch (err) {
46
+ // Surface fetch failures (e.g. 403 when raw retention is disabled, 401 for a
47
+ // bad key) instead of letting them vanish into an unhandled rejection.
48
+ console.error(`${LOG_PREFIX} failed to fetch session events:`, err);
49
+ throw err;
50
+ }
51
+ const cameraSamples = events.filter((e) => e.type === "camera_sample").length;
52
+ if (events.length === 0) {
53
+ // A 200 with an empty array almost always means the API key belongs to a
54
+ // different project than the session. Reads are scoped to the key's project
55
+ // (the collector filters by project_id), so a valid session id looked up
56
+ // with another project's key returns no rows. Lead with that cause.
57
+ console.error(`${LOG_PREFIX} session "${options.sessionId}" returned 0 events — nothing to replay. ` +
58
+ `Most likely the API key belongs to a different project than this session: ` +
59
+ `copy the session id and the API key from the SAME dashboard project. ` +
60
+ `Other causes: a mistyped session id, or the collector not having ` +
61
+ `ENABLE_RAW_SESSION_RETENTION=true.`);
62
+ }
63
+ else if (cameraSamples === 0) {
64
+ console.warn(`${LOG_PREFIX} session has ${events.length} events but no camera_sample events, ` +
65
+ `so the camera won't move. Pointer/mesh/custom callbacks will still fire.`);
66
+ }
67
+ const activeCamera = options.camera ?? options.scene.activeCamera;
68
+ if (!activeCamera) {
69
+ console.warn(`${LOG_PREFIX} scene has no active camera and none was provided — camera pose ` +
70
+ `won't be applied. Pass a \`camera\`, or set \`scene.activeCamera\` before replaying.`);
71
+ }
72
+ const driver = createBabylonReplayDriver({
73
+ scene: options.scene,
74
+ camera: options.camera,
75
+ onPointer: options.onPointer,
76
+ onMeshInteraction: options.onMeshInteraction,
77
+ onCustom: options.onCustom,
78
+ onLifecycle: options.onLifecycle,
79
+ onError: options.onError,
80
+ });
81
+ const player = new ReplayPlayer(events, driver, {
82
+ speed: options.speed ?? 1,
83
+ onProgress: options.onProgress,
84
+ onComplete: () => {
85
+ log("playback complete");
86
+ options.onComplete?.();
87
+ },
88
+ });
89
+ log(`loaded ${events.length} events (${cameraSamples} camera_sample), ` +
90
+ `duration ${Math.round(player.durationMs)}ms — playing at ${options.speed ?? 1}x`);
91
+ player.play();
92
+ return player;
93
+ }
94
+ export { createBabylonReplayDriver, fetchSessionEvents, fetchSessionEventsStream, ReplayPlayer };
95
+ //# sourceMappingURL=global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.js","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@uptimizr/replay` — re-drive a captured session in the user's own 3D scene.
3
+ *
4
+ * The core (`ReplayPlayer`, `fetchSessionEvents`) is framework-agnostic. Engine
5
+ * drivers live behind subpaths, e.g. `@uptimizr/replay/babylon`. A replay driver
6
+ * only reads/writes the scene — it never emits analytics events (ADR 0006).
7
+ */
8
+ export { ReplayPlayer } from "./player.js";
9
+ export { fetchSessionEvents, fetchSessionEventsStream } from "./fetchSession.js";
10
+ export type { FetchSessionOptions, StreamSessionOptions } from "./fetchSession.js";
11
+ export type { ReplayDriver, ReplayOptions, ReplayHandle, PlayerEnv } from "./types.js";
12
+ export { reconstructRigidSubtree } from "./reconstruct.js";
13
+ export type { ReconstructRigidSubtreeOptions, ReconstructedMesh, RigidTransform, RootTransform, Vec3 as ReconstructVec3, Quat as ReconstructQuat, } from "./reconstruct.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EACV,8BAA8B,EAC9B,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,IAAI,IAAI,eAAe,EACvB,IAAI,IAAI,eAAe,GACxB,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `@uptimizr/replay` — re-drive a captured session in the user's own 3D scene.
3
+ *
4
+ * The core (`ReplayPlayer`, `fetchSessionEvents`) is framework-agnostic. Engine
5
+ * drivers live behind subpaths, e.g. `@uptimizr/replay/babylon`. A replay driver
6
+ * only reads/writes the scene — it never emits analytics events (ADR 0006).
7
+ */
8
+ export { ReplayPlayer } from "./player.js";
9
+ export { fetchSessionEvents, fetchSessionEventsStream } from "./fetchSession.js";
10
+ export { reconstructRigidSubtree } from "./reconstruct.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { AnyEvent } from "@uptimizr/schema";
2
+ import type { PlayerEnv, ReplayDriver, ReplayHandle, ReplayOptions } from "./types.js";
3
+ /**
4
+ * Drives an ordered session stream through a {@link ReplayDriver}, reconstructing
5
+ * the session in the host's own scene.
6
+ *
7
+ * The core is the pure {@link update} method (apply everything up to a relative
8
+ * elapsed time); {@link play} simply ticks it from an animation loop. Seeking
9
+ * backward resets the driver and replays from the start — replay is deterministic.
10
+ */
11
+ export declare class ReplayPlayer implements ReplayHandle {
12
+ private readonly driver;
13
+ private readonly options;
14
+ private readonly env;
15
+ private readonly events;
16
+ private readonly baseTs;
17
+ readonly durationMs: number;
18
+ private cursor;
19
+ private elapsed;
20
+ private playing;
21
+ private completed;
22
+ private rafId;
23
+ private startWall;
24
+ private startElapsed;
25
+ constructor(events: readonly AnyEvent[], driver: ReplayDriver, options?: ReplayOptions, env?: PlayerEnv);
26
+ get isPlaying(): boolean;
27
+ private rel;
28
+ /** Apply all events up to `elapsedMs` (relative to the first event). */
29
+ update(elapsedMs: number): void;
30
+ seek(elapsedMs: number): void;
31
+ play(): void;
32
+ pause(): void;
33
+ stop(): void;
34
+ }
35
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAYvF;;;;;;;GAOG;AACH,qBAAa,YAAa,YAAW,YAAY;IAe7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAhBtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,YAAY,CAAK;gBAGvB,MAAM,EAAE,SAAS,QAAQ,EAAE,EACV,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,aAAkB,EAC3B,GAAG,GAAE,SAAwB;IAQhD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,CAAC,GAAG;IAIX,wEAAwE;IACxE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAqB/B,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,IAAI,IAAI;IAmBZ,KAAK,IAAI,IAAI;IAQb,IAAI,IAAI,IAAI;CAOb"}
package/dist/player.js ADDED
@@ -0,0 +1,104 @@
1
+ function defaultEnv() {
2
+ const hasRaf = typeof requestAnimationFrame === "function";
3
+ return {
4
+ now: () => (typeof performance !== "undefined" ? performance.now() : Date.now()),
5
+ requestFrame: (cb) => hasRaf ? requestAnimationFrame(cb) : setTimeout(cb, 16),
6
+ cancelFrame: (id) => (hasRaf ? cancelAnimationFrame(id) : clearTimeout(id)),
7
+ };
8
+ }
9
+ /**
10
+ * Drives an ordered session stream through a {@link ReplayDriver}, reconstructing
11
+ * the session in the host's own scene.
12
+ *
13
+ * The core is the pure {@link update} method (apply everything up to a relative
14
+ * elapsed time); {@link play} simply ticks it from an animation loop. Seeking
15
+ * backward resets the driver and replays from the start — replay is deterministic.
16
+ */
17
+ export class ReplayPlayer {
18
+ driver;
19
+ options;
20
+ env;
21
+ events;
22
+ baseTs;
23
+ durationMs;
24
+ cursor = 0;
25
+ elapsed = 0;
26
+ playing = false;
27
+ completed = false;
28
+ rafId = null;
29
+ startWall = 0;
30
+ startElapsed = 0;
31
+ constructor(events, driver, options = {}, env = defaultEnv()) {
32
+ this.driver = driver;
33
+ this.options = options;
34
+ this.env = env;
35
+ this.events = [...events].sort((a, b) => a.ts - b.ts);
36
+ this.baseTs = this.events.length > 0 ? this.events[0].ts : 0;
37
+ this.durationMs =
38
+ this.events.length > 0 ? this.events[this.events.length - 1].ts - this.baseTs : 0;
39
+ }
40
+ get isPlaying() {
41
+ return this.playing;
42
+ }
43
+ rel(event) {
44
+ return event.ts - this.baseTs;
45
+ }
46
+ /** Apply all events up to `elapsedMs` (relative to the first event). */
47
+ update(elapsedMs) {
48
+ const clamped = Math.max(0, elapsedMs);
49
+ if (clamped < this.elapsed) {
50
+ this.driver.reset();
51
+ this.cursor = 0;
52
+ this.completed = false;
53
+ }
54
+ while (this.cursor < this.events.length && this.rel(this.events[this.cursor]) <= clamped) {
55
+ this.driver.apply(this.events[this.cursor]);
56
+ this.cursor++;
57
+ }
58
+ this.elapsed = clamped;
59
+ this.options.onProgress?.(Math.min(clamped, this.durationMs), this.durationMs);
60
+ if (!this.completed && this.cursor >= this.events.length && clamped >= this.durationMs) {
61
+ this.completed = true;
62
+ this.pause();
63
+ this.options.onComplete?.();
64
+ }
65
+ }
66
+ seek(elapsedMs) {
67
+ this.update(elapsedMs);
68
+ }
69
+ play() {
70
+ if (this.playing || this.events.length === 0)
71
+ return;
72
+ if (this.completed) {
73
+ this.update(0);
74
+ }
75
+ this.playing = true;
76
+ this.startWall = this.env.now();
77
+ this.startElapsed = this.elapsed;
78
+ const speed = this.options.speed ?? 1;
79
+ const loop = () => {
80
+ if (!this.playing)
81
+ return;
82
+ const wall = this.env.now();
83
+ this.update(this.startElapsed + (wall - this.startWall) * speed);
84
+ if (this.playing)
85
+ this.rafId = this.env.requestFrame(loop);
86
+ };
87
+ this.rafId = this.env.requestFrame(loop);
88
+ }
89
+ pause() {
90
+ this.playing = false;
91
+ if (this.rafId !== null) {
92
+ this.env.cancelFrame(this.rafId);
93
+ this.rafId = null;
94
+ }
95
+ }
96
+ stop() {
97
+ this.pause();
98
+ this.driver.reset();
99
+ this.cursor = 0;
100
+ this.elapsed = 0;
101
+ this.completed = false;
102
+ }
103
+ }
104
+ //# sourceMappingURL=player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.js","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAGA,SAAS,UAAU;IACjB,MAAM,MAAM,GAAG,OAAO,qBAAqB,KAAK,UAAU,CAAC;IAC3D,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAChF,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE,CACnB,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,UAAU,CAAC,EAAE,EAAE,EAAE,CAAuB;QAChF,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IAeJ;IACA;IACA;IAhBF,MAAM,CAAa;IACnB,MAAM,CAAS;IACvB,UAAU,CAAS;IAEpB,MAAM,GAAG,CAAC,CAAC;IACX,OAAO,GAAG,CAAC,CAAC;IACZ,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,GAAG,KAAK,CAAC;IAClB,KAAK,GAAkB,IAAI,CAAC;IAC5B,SAAS,GAAG,CAAC,CAAC;IACd,YAAY,GAAG,CAAC,CAAC;IAEzB,YACE,MAA2B,EACV,MAAoB,EACpB,UAAyB,EAAE,EAC3B,MAAiB,UAAU,EAAE;QAF7B,WAAM,GAAN,MAAM,CAAc;QACpB,YAAO,GAAP,OAAO,CAAoB;QAC3B,QAAG,GAAH,GAAG,CAA0B;QAE9C,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU;YACb,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAEO,GAAG,CAAC,KAAe;QACzB,OAAO,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,wEAAwE;IACxE,MAAM,CAAC,SAAiB;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YAChB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAE,CAAC,IAAI,OAAO,EAAE,CAAC;YAC1F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAE/E,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACvF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAiB;QACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAO;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC;YACjE,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Proxy-driven **rigid** reconstruction (ADR 0033 §3).
3
+ *
4
+ * When an actor is captured Tier-1 root-only (one `node_transform` stream, no
5
+ * `childPath`) and a scene proxy ({@link ../../schema} `sceneProxySchema`) carries
6
+ * per-mesh hierarchy (`path`) plus a scan-time world transform (`world`), replay
7
+ * can move the actor's whole sub-assembly **rigidly** with the recorded root —
8
+ * reproducing "parenting just works" without capturing or listing any child:
9
+ *
10
+ * ```
11
+ * childWorld(t) = rootWorld(t) · rootWorld(t0)⁻¹ · childWorldAtScan
12
+ * ```
13
+ *
14
+ * This is **rigid only**: it reproduces motion that is rigid w.r.t. the root. It
15
+ * must never be used to fake internal articulation — for that, the developer opts
16
+ * into Tier-1 subtree capture (ADR 0033 §1) and replay drives each captured
17
+ * `childPath` directly. Callers MUST prefer a captured `childPath` sample over a
18
+ * reconstructed transform whenever one exists.
19
+ *
20
+ * The math here is pure, engine-agnostic, column-major 4×4 (the three.js layout,
21
+ * matching the connector decompose path) and operates entirely in the canonical
22
+ * frame (ADR 0018), so it is independent of the source engine's handedness.
23
+ */
24
+ import type { MeshTransform, SceneProxy } from "@uptimizr/schema";
25
+ export type Vec3 = [number, number, number];
26
+ export type Quat = [number, number, number, number];
27
+ /** A fully-specified world transform (position, rotation quaternion, scale). */
28
+ export interface RigidTransform {
29
+ position: Vec3;
30
+ rotation: Quat;
31
+ scale: Vec3;
32
+ }
33
+ /** A recorded or current root world transform; scale defaults to identity. */
34
+ export interface RootTransform {
35
+ position: Vec3;
36
+ rotation: Quat;
37
+ scale?: Vec3;
38
+ }
39
+ /** A reconstructed descendant: its proxy name/path and the world transform at `t`. */
40
+ export interface ReconstructedMesh {
41
+ name: string;
42
+ path: string;
43
+ world: RigidTransform;
44
+ }
45
+ /** Options for {@link reconstructRigidSubtree}. */
46
+ export interface ReconstructRigidSubtreeOptions {
47
+ /** The scene proxy carrying per-mesh `path` + scan-time `world` (ADR 0033 §3). */
48
+ proxy: SceneProxy;
49
+ /**
50
+ * The proxy node path of the actor's root, e.g. `"Machine_root"`. Descendant
51
+ * meshes are those whose `path` is `rootPath/...`. Matched by exact path prefix.
52
+ */
53
+ rootPath: string;
54
+ /** The actor's **current** (time-`t`) root world transform, from the recorded stream. */
55
+ rootWorld: RootTransform;
56
+ /**
57
+ * The actor's root world transform at scan time (`t0`). Defaults to the proxy
58
+ * mesh whose `path` equals `rootPath`. Reconstruction is unavailable (returns
59
+ * `[]`) when neither is present.
60
+ */
61
+ rootWorldAtScan?: MeshTransform;
62
+ }
63
+ /**
64
+ * Reconstruct the world transforms of an actor's rigid sub-assembly at time `t`
65
+ * from a single recorded root transform and the scene proxy's scan-time snapshot.
66
+ * Returns one entry per descendant proxy mesh that carries `path` + `world`;
67
+ * meshes without those fields, and the root itself, are skipped. Returns `[]` when
68
+ * the proxy has no usable scan-time root transform.
69
+ *
70
+ * Callers MUST prefer a captured `childPath` sample over these reconstructed
71
+ * transforms (ADR 0033 §3): use this only for descendants with no captured stream.
72
+ */
73
+ export declare function reconstructRigidSubtree(options: ReconstructRigidSubtreeOptions): ReconstructedMesh[];
74
+ //# sourceMappingURL=reconstruct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconstruct.d.ts","sourceRoot":"","sources":["../src/reconstruct.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC5C,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,IAAI,CAAC;IACf,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,IAAI,CAAC;CACb;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,IAAI,CAAC;IACf,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,IAAI,CAAC;CACd;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;CACvB;AAoSD,mDAAmD;AACnD,MAAM,WAAW,8BAA8B;IAC7C,kFAAkF;IAClF,KAAK,EAAE,UAAU,CAAC;IAClB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,SAAS,EAAE,aAAa,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,iBAAiB,EAAE,CAsBrB"}
@@ -0,0 +1,266 @@
1
+ /** Compose a column-major 4×4 from position / rotation quaternion / scale. */
2
+ function compose(position, q, scale) {
3
+ const [x, y, z, w] = q;
4
+ const x2 = x + x, y2 = y + y, z2 = z + z;
5
+ const xx = x * x2, xy = x * y2, xz = x * z2;
6
+ const yy = y * y2, yz = y * z2, zz = z * z2;
7
+ const wx = w * x2, wy = w * y2, wz = w * z2;
8
+ const [sx, sy, sz] = scale;
9
+ return [
10
+ (1 - (yy + zz)) * sx,
11
+ (xy + wz) * sx,
12
+ (xz - wy) * sx,
13
+ 0,
14
+ (xy - wz) * sy,
15
+ (1 - (xx + zz)) * sy,
16
+ (yz + wx) * sy,
17
+ 0,
18
+ (xz + wy) * sz,
19
+ (yz - wx) * sz,
20
+ (1 - (xx + yy)) * sz,
21
+ 0,
22
+ position[0],
23
+ position[1],
24
+ position[2],
25
+ 1,
26
+ ];
27
+ }
28
+ /** Column-major matrix product `a · b`. */
29
+ function multiply(a, b) {
30
+ const a11 = a[0], a12 = a[4], a13 = a[8], a14 = a[12];
31
+ const a21 = a[1], a22 = a[5], a23 = a[9], a24 = a[13];
32
+ const a31 = a[2], a32 = a[6], a33 = a[10], a34 = a[14];
33
+ const a41 = a[3], a42 = a[7], a43 = a[11], a44 = a[15];
34
+ const b11 = b[0], b12 = b[4], b13 = b[8], b14 = b[12];
35
+ const b21 = b[1], b22 = b[5], b23 = b[9], b24 = b[13];
36
+ const b31 = b[2], b32 = b[6], b33 = b[10], b34 = b[14];
37
+ const b41 = b[3], b42 = b[7], b43 = b[11], b44 = b[15];
38
+ return [
39
+ a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41,
40
+ a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41,
41
+ a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41,
42
+ a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41,
43
+ a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42,
44
+ a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42,
45
+ a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42,
46
+ a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42,
47
+ a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43,
48
+ a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43,
49
+ a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43,
50
+ a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43,
51
+ a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44,
52
+ a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44,
53
+ a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44,
54
+ a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44,
55
+ ];
56
+ }
57
+ /** Inverse of a column-major 4×4 (three.js `Matrix4.invert`); `null` if singular. */
58
+ function invert(m) {
59
+ const n11 = m[0], n21 = m[1], n31 = m[2], n41 = m[3];
60
+ const n12 = m[4], n22 = m[5], n32 = m[6], n42 = m[7];
61
+ const n13 = m[8], n23 = m[9], n33 = m[10], n43 = m[11];
62
+ const n14 = m[12], n24 = m[13], n34 = m[14], n44 = m[15];
63
+ const t11 = n23 * n34 * n42 -
64
+ n24 * n33 * n42 +
65
+ n24 * n32 * n43 -
66
+ n22 * n34 * n43 -
67
+ n23 * n32 * n44 +
68
+ n22 * n33 * n44;
69
+ const t12 = n14 * n33 * n42 -
70
+ n13 * n34 * n42 -
71
+ n14 * n32 * n43 +
72
+ n12 * n34 * n43 +
73
+ n13 * n32 * n44 -
74
+ n12 * n33 * n44;
75
+ const t13 = n13 * n24 * n42 -
76
+ n14 * n23 * n42 +
77
+ n14 * n22 * n43 -
78
+ n12 * n24 * n43 -
79
+ n13 * n22 * n44 +
80
+ n12 * n23 * n44;
81
+ const t14 = n14 * n23 * n32 -
82
+ n13 * n24 * n32 -
83
+ n14 * n22 * n33 +
84
+ n12 * n24 * n33 +
85
+ n13 * n22 * n34 -
86
+ n12 * n23 * n34;
87
+ const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
88
+ if (det === 0)
89
+ return null;
90
+ const idet = 1 / det;
91
+ return [
92
+ t11 * idet,
93
+ (n24 * n33 * n41 -
94
+ n23 * n34 * n41 -
95
+ n24 * n31 * n43 +
96
+ n21 * n34 * n43 +
97
+ n23 * n31 * n44 -
98
+ n21 * n33 * n44) *
99
+ idet,
100
+ (n22 * n34 * n41 -
101
+ n24 * n32 * n41 +
102
+ n24 * n31 * n42 -
103
+ n21 * n34 * n42 -
104
+ n22 * n31 * n44 +
105
+ n21 * n32 * n44) *
106
+ idet,
107
+ (n23 * n32 * n41 -
108
+ n22 * n33 * n41 -
109
+ n23 * n31 * n42 +
110
+ n21 * n33 * n42 +
111
+ n22 * n31 * n43 -
112
+ n21 * n32 * n43) *
113
+ idet,
114
+ t12 * idet,
115
+ (n13 * n34 * n41 -
116
+ n14 * n33 * n41 +
117
+ n14 * n31 * n43 -
118
+ n11 * n34 * n43 -
119
+ n13 * n31 * n44 +
120
+ n11 * n33 * n44) *
121
+ idet,
122
+ (n14 * n32 * n41 -
123
+ n12 * n34 * n41 -
124
+ n14 * n31 * n42 +
125
+ n11 * n34 * n42 +
126
+ n12 * n31 * n44 -
127
+ n11 * n32 * n44) *
128
+ idet,
129
+ (n12 * n33 * n41 -
130
+ n13 * n32 * n41 +
131
+ n13 * n31 * n42 -
132
+ n11 * n33 * n42 -
133
+ n12 * n31 * n43 +
134
+ n11 * n32 * n43) *
135
+ idet,
136
+ t13 * idet,
137
+ (n14 * n23 * n41 -
138
+ n13 * n24 * n41 -
139
+ n14 * n21 * n43 +
140
+ n11 * n24 * n43 +
141
+ n13 * n21 * n44 -
142
+ n11 * n23 * n44) *
143
+ idet,
144
+ (n12 * n24 * n41 -
145
+ n14 * n22 * n41 +
146
+ n14 * n21 * n42 -
147
+ n11 * n24 * n42 -
148
+ n12 * n21 * n44 +
149
+ n11 * n22 * n44) *
150
+ idet,
151
+ (n13 * n22 * n41 -
152
+ n12 * n23 * n41 -
153
+ n13 * n21 * n42 +
154
+ n11 * n23 * n42 +
155
+ n12 * n21 * n43 -
156
+ n11 * n22 * n43) *
157
+ idet,
158
+ t14 * idet,
159
+ (n13 * n24 * n31 -
160
+ n14 * n23 * n31 +
161
+ n14 * n21 * n33 -
162
+ n11 * n24 * n33 -
163
+ n13 * n21 * n34 +
164
+ n11 * n23 * n34) *
165
+ idet,
166
+ (n14 * n22 * n31 -
167
+ n12 * n24 * n31 -
168
+ n14 * n21 * n32 +
169
+ n11 * n24 * n32 +
170
+ n12 * n21 * n34 -
171
+ n11 * n22 * n34) *
172
+ idet,
173
+ (n12 * n23 * n31 -
174
+ n13 * n22 * n31 +
175
+ n13 * n21 * n32 -
176
+ n11 * n23 * n32 -
177
+ n12 * n21 * n33 +
178
+ n11 * n22 * n33) *
179
+ idet,
180
+ ];
181
+ }
182
+ /** Decompose a column-major 4×4 into position / rotation quaternion / scale. */
183
+ function decompose(e) {
184
+ const position = [e[12], e[13], e[14]];
185
+ let sx = Math.hypot(e[0], e[1], e[2]);
186
+ const sy = Math.hypot(e[4], e[5], e[6]);
187
+ const sz = Math.hypot(e[8], e[9], e[10]);
188
+ const det = e[0] * (e[5] * e[10] - e[6] * e[9]) -
189
+ e[4] * (e[1] * e[10] - e[2] * e[9]) +
190
+ e[8] * (e[1] * e[6] - e[2] * e[5]);
191
+ if (det < 0)
192
+ sx = -sx;
193
+ const ix = sx !== 0 ? 1 / sx : 0;
194
+ const iy = sy !== 0 ? 1 / sy : 0;
195
+ const iz = sz !== 0 ? 1 / sz : 0;
196
+ const m11 = e[0] * ix, m21 = e[1] * ix, m31 = e[2] * ix;
197
+ const m12 = e[4] * iy, m22 = e[5] * iy, m32 = e[6] * iy;
198
+ const m13 = e[8] * iz, m23 = e[9] * iz, m33 = e[10] * iz;
199
+ const trace = m11 + m22 + m33;
200
+ let x, y, z, w;
201
+ if (trace > 0) {
202
+ const s = 0.5 / Math.sqrt(trace + 1);
203
+ w = 0.25 / s;
204
+ x = (m32 - m23) * s;
205
+ y = (m13 - m31) * s;
206
+ z = (m21 - m12) * s;
207
+ }
208
+ else if (m11 > m22 && m11 > m33) {
209
+ const s = 2 * Math.sqrt(1 + m11 - m22 - m33);
210
+ w = (m32 - m23) / s;
211
+ x = 0.25 * s;
212
+ y = (m12 + m21) / s;
213
+ z = (m13 + m31) / s;
214
+ }
215
+ else if (m22 > m33) {
216
+ const s = 2 * Math.sqrt(1 + m22 - m11 - m33);
217
+ w = (m13 - m31) / s;
218
+ x = (m12 + m21) / s;
219
+ y = 0.25 * s;
220
+ z = (m23 + m32) / s;
221
+ }
222
+ else {
223
+ const s = 2 * Math.sqrt(1 + m33 - m11 - m22);
224
+ w = (m21 - m12) / s;
225
+ x = (m13 + m31) / s;
226
+ y = (m23 + m32) / s;
227
+ z = 0.25 * s;
228
+ }
229
+ return { position, rotation: [x, y, z, w], scale: [sx, sy, sz] };
230
+ }
231
+ function transformMat4(t) {
232
+ return compose(t.position, t.rotation, t.scale ?? [1, 1, 1]);
233
+ }
234
+ /**
235
+ * Reconstruct the world transforms of an actor's rigid sub-assembly at time `t`
236
+ * from a single recorded root transform and the scene proxy's scan-time snapshot.
237
+ * Returns one entry per descendant proxy mesh that carries `path` + `world`;
238
+ * meshes without those fields, and the root itself, are skipped. Returns `[]` when
239
+ * the proxy has no usable scan-time root transform.
240
+ *
241
+ * Callers MUST prefer a captured `childPath` sample over these reconstructed
242
+ * transforms (ADR 0033 §3): use this only for descendants with no captured stream.
243
+ */
244
+ export function reconstructRigidSubtree(options) {
245
+ const { proxy, rootPath, rootWorld, rootWorldAtScan } = options;
246
+ const prefix = `${rootPath}/`;
247
+ const scanRoot = rootWorldAtScan ?? proxy.meshes.find((m) => m.path === rootPath && m.world)?.world;
248
+ if (!scanRoot)
249
+ return [];
250
+ const scanRootInv = invert(transformMat4(scanRoot));
251
+ if (!scanRootInv)
252
+ return [];
253
+ // M = rootWorld(t) · rootWorld(t0)⁻¹ — the rigid delta applied to every child.
254
+ const delta = multiply(transformMat4(rootWorld), scanRootInv);
255
+ const out = [];
256
+ for (const mesh of proxy.meshes) {
257
+ if (!mesh.path || !mesh.world)
258
+ continue;
259
+ if (!mesh.path.startsWith(prefix))
260
+ continue; // strict descendants only
261
+ const childWorld = multiply(delta, transformMat4(mesh.world));
262
+ out.push({ name: mesh.name, path: mesh.path, world: decompose(childWorld) });
263
+ }
264
+ return out;
265
+ }
266
+ //# sourceMappingURL=reconstruct.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconstruct.js","sourceRoot":"","sources":["../src/reconstruct.ts"],"names":[],"mappings":"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AAE,CAAC;IACf,OAAO;QACL,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;QAC7C,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GA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QACN,GAAG,GAAG,IAAI;QACV,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,GAAG,GAAG,IAAI;QACV,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,GAAG,GAAG,IAAI;QACV,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;QACN,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG;YACd,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG;YACf,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;YAChB,IAAI;KACP,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,CAAO;IACxB,MAAM,QAAQ,GAAS,CAAC,CAAC,CAAC,EAAE,CAAE,EAAE,CAAC,CAAC,EAAE,CAAE,EAAE,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;IAChD,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;IAC5C,MAAM,GAAG,GACP,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,EAAE,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACxC,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,EAAE,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACxC,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IAC1C,IAAI,GAAG,GAAG,CAAC;QAAE,EAAE,GAAG,CAAC,EAAE,CAAC;IACtB,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,EACpB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,EAChB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,EACpB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,EAChB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,EACpB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,EAChB,GAAG,GAAG,CAAC,CAAC,EAAE,CAAE,GAAG,EAAE,CAAC;IACpB,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC9B,IAAI,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,CAAC;IAC/C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QACb,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;SAAM,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;QAC7C,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QACb,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;SAAM,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;QAC7C,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QACb,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;QAC7C,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;IACf,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,SAAS,aAAa,CAAC,CAAmD;IACxE,OAAO,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAqBD;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAuC;IAEvC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;IAChE,MAAM,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC;IAE9B,MAAM,QAAQ,GACZ,eAAe,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACrF,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEzB,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,+EAA+E;IAC/E,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,CAAC;IAE9D,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,SAAS;QACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,0BAA0B;QACvE,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}