@jdultra/threedtiles 14.0.20 → 14.0.22

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.
@@ -0,0 +1,37 @@
1
+ function u(n, e = null, t = []) {
2
+ n != null && postMessage({ replyTo: n, result: e }, t);
3
+ }
4
+ function a(n, e) {
5
+ n != null && postMessage({ replyTo: n, error: e && (e.message || String(e)) || String(e) });
6
+ }
7
+ function f(n, e) {
8
+ if (!(n instanceof Float32Array))
9
+ throw new Error("positions must be a Float32Array");
10
+ const t = n.length;
11
+ if (t % 3 !== 0)
12
+ throw new Error("positions length must be a multiple of 3");
13
+ const s = e && +e[0] || 1, r = e && +e[1] || 1, o = e && +e[2] || 1;
14
+ if (s !== 1 || r !== 1 || o !== 1)
15
+ for (let l = 0; l < t; l += 3)
16
+ n[l + 0] *= s, n[l + 1] *= r, n[l + 2] *= o;
17
+ return { hullVertices: n, hullIndices: null };
18
+ }
19
+ self.addEventListener("message", (n) => {
20
+ const e = n.data || {}, t = typeof e._envId < "u" ? e._envId : typeof e.replyTo < "u" ? e.replyTo : e.id;
21
+ try {
22
+ switch (e.type) {
23
+ case "computeConvexHull": {
24
+ const s = e.positions instanceof Float32Array ? e.positions : new Float32Array(e.positions?.buffer || e.positions), r = e.localScale || e.scale || e.local?.s || [1, 1, 1], { hullVertices: o, hullIndices: i } = f(s, r), c = [];
25
+ o?.buffer && c.push(o.buffer), i?.buffer, u(t, { vertices: o, indices: i }, c);
26
+ break;
27
+ }
28
+ default: {
29
+ u(t, { ok: !1, reason: "unknown message type" });
30
+ break;
31
+ }
32
+ }
33
+ } catch (s) {
34
+ a(t, s);
35
+ }
36
+ });
37
+ //# sourceMappingURL=physicsHelper.worker-Cr8S3sZk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"physicsHelper.worker-Cr8S3sZk.js","sources":["../src/simulation/physicsHelper.worker.js"],"sourcesContent":["// physicsHelper.worker.js\r\n// Helper worker that computes a convex hull from mesh geometry using three.js's ConvexHull.\r\n// - Receives Float32Array positions (and optional Uint32Array indices - not required for hull).\r\n// - Applies optional non-uniform localScale [sx,sy,sz] to vertex positions in-place.\r\n// - Computes convex hull and returns hull vertices (Float32Array) and indices (Uint32Array) to the main thread.\r\n// - Buffer ownership is transferred back to main to minimize memory usage.\r\n\r\n/* No external imports required */\r\n\r\n// Simple reply helpers for request/reply correlation with _envId\r\nfunction ack(id, result = null, transfer = []) {\r\n if (id == null) return;\r\n // Always include replyTo to match main thread envelope handling\r\n postMessage({ replyTo: id, result }, transfer);\r\n}\r\nfunction nack(id, error) {\r\n if (id == null) return;\r\n postMessage({ replyTo: id, error: (error && (error.message || String(error))) || String(error) });\r\n}\r\n\r\n// Compute convex hull input for Rapier from points (Float32Array positions).\r\n// Rapier's ColliderDesc.convexHull computes the hull internally from an arbitrary point cloud,\r\n// so we only need to return a scaled vertex array. No triangle faces are required.\r\nfunction computeHullFromPositions(positions, scale) {\r\n if (!(positions instanceof Float32Array)) {\r\n throw new Error('positions must be a Float32Array');\r\n }\r\n const n = positions.length;\r\n if (n % 3 !== 0) {\r\n throw new Error('positions length must be a multiple of 3');\r\n }\r\n\r\n // Apply in-place scaling to avoid additional copies (positions buffer is owned by this worker).\r\n const sx = (scale && +scale[0]) || 1.0;\r\n const sy = (scale && +scale[1]) || 1.0;\r\n const sz = (scale && +scale[2]) || 1.0;\r\n if (sx !== 1 || sy !== 1 || sz !== 1) {\r\n for (let i = 0; i < n; i += 3) {\r\n positions[i + 0] *= sx;\r\n positions[i + 1] *= sy;\r\n positions[i + 2] *= sz;\r\n }\r\n }\r\n\r\n // Return the scaled point cloud directly; indices are unnecessary for Rapier's convexHull.\r\n const hullVertices = positions;\r\n const hullIndices = null;\r\n return { hullVertices, hullIndices };\r\n}\r\n\r\nself.addEventListener('message', (e) => {\r\n const msg = e.data || {};\r\n const replyId = (typeof msg._envId !== 'undefined') ? msg._envId : (typeof msg.replyTo !== 'undefined' ? msg.replyTo : msg.id);\r\n try {\r\n switch (msg.type) {\r\n case 'computeConvexHull': {\r\n const positions = msg.positions instanceof Float32Array ? msg.positions : new Float32Array(msg.positions?.buffer || msg.positions);\r\n // indices are not strictly needed for hull generation with ConvexHull; accept but ignore for computation.\r\n // If provided and transferred, they will be garbage collected afterward.\r\n const scale = msg.localScale || msg.scale || msg.local?.s || [1, 1, 1];\r\n\r\n const { hullVertices, hullIndices } = computeHullFromPositions(positions, scale);\r\n\r\n // Transfer results back, release incoming buffers by letting them go out of scope.\r\n const transfer = [];\r\n if (hullVertices?.buffer) transfer.push(hullVertices.buffer);\r\n if (hullIndices?.buffer) transfer.push(hullIndices.buffer);\r\n\r\n ack(replyId, { vertices: hullVertices, indices: hullIndices }, transfer);\r\n break;\r\n }\r\n\r\n default: {\r\n ack(replyId, { ok: false, reason: 'unknown message type' });\r\n break;\r\n }\r\n }\r\n } catch (err) {\r\n nack(replyId, err);\r\n }\r\n});"],"names":["ack","id","result","transfer","nack","error","computeHullFromPositions","positions","scale","n","sx","sy","sz","i","e","msg","replyId","hullVertices","hullIndices","err"],"mappings":"AAUA,SAASA,EAAIC,GAAIC,IAAS,MAAMC,IAAW,CAAA,GAAI;AAC7C,EAAIF,KAAM,QAEV,YAAY,EAAE,SAASA,GAAI,QAAAC,EAAM,GAAIC,CAAQ;AAC/C;AACA,SAASC,EAAKH,GAAII,GAAO;AACvB,EAAIJ,KAAM,QACV,YAAY,EAAE,SAASA,GAAI,OAAQI,MAAUA,EAAM,WAAW,OAAOA,CAAK,MAAO,OAAOA,CAAK,EAAC,CAAE;AAClG;AAKA,SAASC,EAAyBC,GAAWC,GAAO;AAClD,MAAI,EAAED,aAAqB;AACzB,UAAM,IAAI,MAAM,kCAAkC;AAEpD,QAAME,IAAIF,EAAU;AACpB,MAAIE,IAAI,MAAM;AACZ,UAAM,IAAI,MAAM,0CAA0C;AAI5D,QAAMC,IAAMF,KAAS,CAACA,EAAM,CAAC,KAAM,GAC7BG,IAAMH,KAAS,CAACA,EAAM,CAAC,KAAM,GAC7BI,IAAMJ,KAAS,CAACA,EAAM,CAAC,KAAM;AACnC,MAAIE,MAAO,KAAKC,MAAO,KAAKC,MAAO;AACjC,aAASC,IAAI,GAAGA,IAAIJ,GAAGI,KAAK;AAC1B,MAAAN,EAAUM,IAAI,CAAC,KAAKH,GACpBH,EAAUM,IAAI,CAAC,KAAKF,GACpBJ,EAAUM,IAAI,CAAC,KAAKD;AAOxB,SAAO,EAAE,cAFYL,GAEE,aADH;AAEtB;AAEA,KAAK,iBAAiB,WAAW,CAACO,MAAM;AACtC,QAAMC,IAAMD,EAAE,QAAQ,IAChBE,IAAW,OAAOD,EAAI,SAAW,MAAeA,EAAI,SAAU,OAAOA,EAAI,UAAY,MAAcA,EAAI,UAAUA,EAAI;AAC3H,MAAI;AACF,YAAQA,EAAI,MAAI;AAAA,MACd,KAAK,qBAAqB;AACxB,cAAMR,IAAYQ,EAAI,qBAAqB,eAAeA,EAAI,YAAY,IAAI,aAAaA,EAAI,WAAW,UAAUA,EAAI,SAAS,GAG3HP,IAAQO,EAAI,cAAcA,EAAI,SAASA,EAAI,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,GAE/D,EAAE,cAAAE,GAAc,aAAAC,EAAW,IAAKZ,EAAyBC,GAAWC,CAAK,GAGzEL,IAAW,CAAA;AACjB,QAAIc,GAAc,UAAQd,EAAS,KAAKc,EAAa,MAAM,GACvDC,GAAa,QAEjBlB,EAAIgB,GAAS,EAAE,UAAUC,GAAc,SAASC,EAAW,GAAIf,CAAQ;AACvE;AAAA,MACF;AAAA,MAEA,SAAS;AACP,QAAAH,EAAIgB,GAAS,EAAE,IAAI,IAAO,QAAQ,uBAAsB,CAAE;AAC1D;AAAA,MACF;AAAA,IACN;AAAA,EACE,SAASG,GAAK;AACZ,IAAAf,EAAKY,GAASG,CAAG;AAAA,EACnB;AACF,CAAC;"}
@@ -0,0 +1,393 @@
1
+ let l = null, p = null, A = null;
2
+ const x = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map(), C = /* @__PURE__ */ new Map(), M = /* @__PURE__ */ new Map();
3
+ let I = "vector", D = { x: 0, y: -9.81, z: 0 }, W = { x: 0, y: 0, z: 0 }, q = 9.81, E = 0, R = 1 / 60;
4
+ function F(t, e = null) {
5
+ t != null && postMessage({ replyTo: t, result: e });
6
+ }
7
+ function U(t, e) {
8
+ t != null && postMessage({ replyTo: t, error: e && (e.message || e) || "error" });
9
+ }
10
+ function L(t, e, o) {
11
+ return Math.max(e, Math.min(o, t));
12
+ }
13
+ function w(t) {
14
+ return { x: +t[0], y: +t[1], z: +t[2] };
15
+ }
16
+ function z(t) {
17
+ return { x: +t[0], y: +t[1], z: +t[2], w: +t[3] };
18
+ }
19
+ function P(t, e) {
20
+ return { x: t.x - e.x, y: t.y - e.y, z: t.z - e.z };
21
+ }
22
+ function j(t, e) {
23
+ return { x: t.x * e, y: t.y * e, z: t.z * e };
24
+ }
25
+ function O(t) {
26
+ return Math.hypot(t.x, t.y, t.z);
27
+ }
28
+ function $(t) {
29
+ const e = O(t) || 1;
30
+ return { x: t.x / e, y: t.y / e, z: t.z / e };
31
+ }
32
+ async function v() {
33
+ if (A) {
34
+ await A;
35
+ return;
36
+ }
37
+ A = (async () => {
38
+ if (!l) {
39
+ postMessage({ type: "debug", msg: "importing rapier module" });
40
+ const t = await import("./rapier-CaKmQPsS.js"), o = { locateFile: (r) => {
41
+ try {
42
+ return new URL(r, import.meta.url).href;
43
+ } catch {
44
+ return r;
45
+ }
46
+ } }, n = t?.default ?? t;
47
+ postMessage({
48
+ type: "debug",
49
+ msg: "rapier module import result",
50
+ hasDefault: !!t?.default,
51
+ hasInitFunction: typeof n?.init == "function",
52
+ isFactoryFunction: typeof n == "function"
53
+ });
54
+ try {
55
+ if (typeof n == "function") {
56
+ postMessage({ type: "debug", msg: "rapier: calling module factory function" });
57
+ const r = n(o);
58
+ l = r && typeof r.then == "function" ? await r : r || n, postMessage({ type: "debug", msg: "rapier factory resolved", hasWorld: !!l?.World });
59
+ } else if (typeof n?.init == "function")
60
+ postMessage({ type: "debug", msg: "rapier: calling init()" }), await n.init(o), l = n, postMessage({ type: "debug", msg: "rapier.init completed", hasWorld: !!l?.World });
61
+ else if (n)
62
+ l = n, postMessage({ type: "debug", msg: "rapier: using imported module as-is", hasWorld: !!l?.World });
63
+ else
64
+ throw new Error("Imported Rapier module is empty/invalid");
65
+ } catch (r) {
66
+ throw postMessage({ type: "error", msg: "rapier init failed", error: r && (r.message || String(r)) || String(r) }), r;
67
+ }
68
+ if (!l) throw new Error("Failed to import Rapier module");
69
+ }
70
+ if (!p) {
71
+ const t = I === "vector" ? D : { x: 0, y: 0, z: 0 };
72
+ try {
73
+ typeof l.World == "function" ? p = new l.World(t) : typeof l.World?.new == "function" ? p = l.World.new(t) : typeof l?.World == "object" && typeof l.World.create == "function" ? p = l.World.create(t) : typeof l == "function" ? p = l(t) : p = l.World ? l.World(t) : null, postMessage({ type: "debug", msg: "rapier world created" });
74
+ } catch (e) {
75
+ throw postMessage({ type: "error", msg: "failed to construct rapier World", error: e && (e.message || String(e)) || String(e) }), new Error("Failed to construct Rapier World: " + (e && e.message ? e.message : String(e)));
76
+ }
77
+ }
78
+ })();
79
+ try {
80
+ await A;
81
+ } finally {
82
+ }
83
+ }
84
+ function S(t) {
85
+ I = "vector", D = { x: +t[0], y: +t[1], z: +t[2] }, p && (p.gravity = D);
86
+ }
87
+ function T(t, e) {
88
+ I = "geocentric", W = { x: +t[0], y: +t[1], z: +t[2] }, q = +e, p && (p.gravity = { x: 0, y: 0, z: 0 });
89
+ }
90
+ function H(t) {
91
+ const e = $(P(W, t));
92
+ return j(e, q);
93
+ }
94
+ function V(t, e, o) {
95
+ try {
96
+ if (typeof p.createRigidBody != "function")
97
+ throw postMessage({ type: "error", msg: "world.createRigidBody is not a function", value: typeof p.createRigidBody }), new Error("world.createRigidBody is not a function");
98
+ postMessage({ type: "debug", msg: "createBody: about to call world.createRigidBody", id: e, descType: typeof t, descCtor: t && t.constructor ? t.constructor.name : null });
99
+ const n = p.createRigidBody(t);
100
+ return o?.v && typeof n.setLinvel == "function" && n.setLinvel(w(o.v), !1), o?.w && typeof n.setAngvel == "function" && n.setAngvel(w(o.w), !1), x.set(e, n), B.set(e, { type: o.type, mass: o.mass }), n;
101
+ } catch (n) {
102
+ throw postMessage({ type: "error", msg: "createBody failed", error: n && (n.message || String(n)) || String(n), id: e, descType: typeof t }), n;
103
+ }
104
+ }
105
+ function G(t) {
106
+ const e = x.get(t);
107
+ if (e) {
108
+ for (const [o, n] of Array.from(M.entries()))
109
+ if (n === t) {
110
+ const r = C.get(o);
111
+ r && p.removeCollider(r, !0), C.delete(o), M.delete(o);
112
+ }
113
+ p.removeRigidBody(e);
114
+ }
115
+ x.delete(t), B.delete(t);
116
+ }
117
+ function N({ id: t, positions: e, indices: o, bodyId: n, local: r }) {
118
+ if (!(e instanceof Float32Array))
119
+ throw new Error("attachCollider: positions must be Float32Array");
120
+ if (e.length % 3 !== 0)
121
+ throw new Error("attachCollider: positions length must be a multiple of 3");
122
+ const d = new Float32Array(e), h = r && r.s && +r.s[0] || 1, m = r && r.s && +r.s[1] || 1, k = r && r.s && +r.s[2] || 1;
123
+ for (let i = 0, c = d.length; i < c; i += 3)
124
+ d[i + 0] *= h, d[i + 1] *= m, d[i + 2] *= k;
125
+ let s = null;
126
+ if (o) {
127
+ const i = o instanceof Uint32Array ? o : new Uint32Array(o.buffer || o);
128
+ s = new Uint32Array(i);
129
+ const c = d.length / 3;
130
+ for (let u = 0; u < s.length; ++u) {
131
+ const b = s[u];
132
+ if (!Number.isFinite(b) || b < 0 || b >= c)
133
+ throw new Error(`attachCollider: index out of range or invalid at ${u}: ${b} (vertCount=${c})`);
134
+ }
135
+ }
136
+ for (let i = 0; i < d.length; ++i) {
137
+ const c = d[i];
138
+ if (!Number.isFinite(c)) throw new Error(`attachCollider: invalid position value at ${i}: ${c}`);
139
+ }
140
+ const a = l.ColliderDesc.trimesh(d, s);
141
+ r?.p && a.setTranslation(+r.p[0], +r.p[1], +r.p[2]), r?.q && a.setRotation(z(r.q));
142
+ const y = x.get(n);
143
+ if (!y) throw new Error(`attachCollider: body not found: ${n}`);
144
+ const f = p.createCollider(a, y);
145
+ C.set(t, f), M.set(t, n);
146
+ }
147
+ function _(t) {
148
+ const e = C.get(t);
149
+ e && p.removeCollider(e, !0), C.delete(t), M.delete(t);
150
+ }
151
+ function K(t) {
152
+ if (!t || typeof t != "object") throw new Error("attachShapeCollider: missing shape");
153
+ const e = String(t.kind || "").toLowerCase(), o = t.params || {};
154
+ switch (e) {
155
+ case "ball": {
156
+ const n = +o.radius;
157
+ return l.ColliderDesc.ball(n);
158
+ }
159
+ case "cuboid":
160
+ case "box": {
161
+ const n = +o.hx, r = +o.hy, d = +o.hz;
162
+ return l.ColliderDesc.cuboid(n, r, d);
163
+ }
164
+ case "roundcuboid":
165
+ case "round_cuboid":
166
+ case "round-cuboid": {
167
+ const n = +o.hx, r = +o.hy, d = +o.hz, h = +o.radius || 0;
168
+ return l.ColliderDesc.roundCuboid(n, r, d, h);
169
+ }
170
+ case "capsule": {
171
+ const n = +o.halfHeight, r = +o.radius;
172
+ return l.ColliderDesc.capsule(n, r);
173
+ }
174
+ case "cone": {
175
+ const n = +o.halfHeight, r = +o.radius;
176
+ return l.ColliderDesc.cone(n, r);
177
+ }
178
+ case "cylinder": {
179
+ const n = +o.halfHeight, r = +o.radius;
180
+ return l.ColliderDesc.cylinder(n, r);
181
+ }
182
+ case "segment": {
183
+ const n = o.a || o.p1, r = o.b || o.p2;
184
+ if (!n || !r) throw new Error("segment requires a and b (or p1,p2)");
185
+ return l.ColliderDesc.segment(w(n), w(r));
186
+ }
187
+ case "triangle": {
188
+ const n = o.a, r = o.b, d = o.c;
189
+ if (!n || !r || !d) throw new Error("triangle requires a, b, c");
190
+ return l.ColliderDesc.triangle(w(n), w(r), w(d));
191
+ }
192
+ case "polyline": {
193
+ const n = o.vertices instanceof Float32Array ? o.vertices : new Float32Array(o.vertices);
194
+ let r = null;
195
+ return o.indices && (r = o.indices instanceof Uint32Array ? o.indices : new Uint32Array(o.indices)), l.ColliderDesc.polyline(n, r);
196
+ }
197
+ case "convexhull":
198
+ case "convex_hull":
199
+ case "convex-hull": {
200
+ const n = o.vertices instanceof Float32Array ? o.vertices : new Float32Array(o.vertices), r = l.ColliderDesc.convexHull(n);
201
+ if (!r) throw new Error("convexHull: invalid or insufficient points");
202
+ return r;
203
+ }
204
+ case "heightfield": {
205
+ const n = +o.rows, r = +o.cols, d = o.heights instanceof Float32Array ? o.heights : new Float32Array(o.heights), h = o.scale || { x: 1, y: 1, z: 1 };
206
+ return l.ColliderDesc.heightfield(n, r, d, h);
207
+ }
208
+ default:
209
+ throw new Error(`Unknown primitive collider kind: ${t.kind}`);
210
+ }
211
+ }
212
+ function J(t) {
213
+ if (I === "geocentric")
214
+ for (const [e, o] of x.entries()) {
215
+ if (!o || o.isFixed()) continue;
216
+ const n = Math.max(1e-6, B.get(e)?.mass ?? 1), r = o.translation(), d = H(r), h = { x: d.x * n, y: d.y * n, z: d.z * n };
217
+ o.applyForce(h, !0);
218
+ }
219
+ }
220
+ function Q(t) {
221
+ p.timestep = t, J(), p.step(), E += t * 1e3;
222
+ const e = {};
223
+ for (const [o, n] of x.entries()) {
224
+ const r = n.translation(), d = n.rotation();
225
+ e[o] = { p: [r.x, r.y, r.z], q: [d.x, d.y, d.z, d.w] };
226
+ }
227
+ postMessage({ type: "state", state: { timeMs: E, bodies: e } });
228
+ }
229
+ function X(t, e, o = 1e6) {
230
+ const n = w(t), r = w(e), d = new l.Ray(n, r), h = p.castRay(d, o, !0);
231
+ if (!h) return { hits: [] };
232
+ const m = h.toi, k = d.pointAt(m), s = h.normal;
233
+ let a = null;
234
+ for (const [i, c] of C.entries())
235
+ if (c.handle === h.collider.handle) {
236
+ a = i;
237
+ break;
238
+ }
239
+ let y = null;
240
+ const f = h.collider.parent()?.handle;
241
+ if (f != null) {
242
+ for (const [i, c] of x.entries())
243
+ if (c.handle === f) {
244
+ y = i;
245
+ break;
246
+ }
247
+ }
248
+ return {
249
+ hits: [{
250
+ toi: m,
251
+ point: [k.x, k.y, k.z],
252
+ normal: [s.x, s.y, s.z],
253
+ colliderId: a,
254
+ bodyId: y
255
+ }]
256
+ };
257
+ }
258
+ async function Y(t) {
259
+ const e = t.data || {}, { id: o, type: n, _envId: r, replyTo: d } = e, h = typeof r < "u" ? r : typeof d < "u" ? d : o, m = (s) => F(h, s), k = (s) => U(h, s);
260
+ try {
261
+ switch (n) {
262
+ case "init": {
263
+ R = typeof e.fixedDt == "number" ? e.fixedDt : R;
264
+ const s = e.gravity || {};
265
+ (s.mode || "vector").toLowerCase() === "geocentric" ? T(s.planetCenter || [0, 0, 0], typeof s.intensity == "number" ? s.intensity : 9.81) : S(s.vector || [0, -9.81, 0]), await v(), m({ ok: !0 });
266
+ break;
267
+ }
268
+ case "addObject": {
269
+ let u = function(g) {
270
+ return typeof g == "number" && isFinite(g);
271
+ };
272
+ await v();
273
+ const s = e.id, a = e.body || {}, y = (a.type || "dynamic").toLowerCase(), f = typeof a.mass == "number" ? a.mass : 1, i = w(a.p || [0, 0, 0]), c = z(a.q || [0, 0, 0, 1]);
274
+ if ((!u(i.x) || !u(i.y) || !u(i.z)) && (postMessage({ type: "debug", msg: "addObject: invalid translation detected, resetting to 0", bodyId: s, p: i }), i.x = u(i.x) ? i.x : 0, i.y = u(i.y) ? i.y : 0, i.z = u(i.z) ? i.z : 0), ![c.x, c.y, c.z, c.w].every(u))
275
+ postMessage({ type: "debug", msg: "addObject: invalid rotation detected, using identity quat", bodyId: s, q: c }), c.x = 0, c.y = 0, c.z = 0, c.w = 1;
276
+ else {
277
+ const g = Math.hypot(c.x, c.y, c.z, c.w) || 1;
278
+ c.x /= g, c.y /= g, c.z /= g, c.w /= g;
279
+ }
280
+ let b;
281
+ y === "fixed" ? b = l.RigidBodyDesc.fixed() : y === "kinematic" ? b = l.RigidBodyDesc.kinematicPositionBased() : b = l.RigidBodyDesc.dynamic().setAdditionalMass(f);
282
+ try {
283
+ b.setTranslation(i.x, i.y, i.z);
284
+ } catch (g) {
285
+ throw postMessage({ type: "error", msg: "desc.setTranslation failed", error: g && (g.message || String(g)) || String(g), bodyId: s, p: i }), g;
286
+ }
287
+ try {
288
+ b.setRotation(c);
289
+ } catch (g) {
290
+ throw postMessage({ type: "error", msg: "desc.setRotation failed", error: g && (g.message || String(g)) || String(g), bodyId: s, q: c }), g;
291
+ }
292
+ postMessage({ type: "debug", msg: "addObject: creating body", bodyId: s, typeStr: y, mass: f, p: i, q: c }), V(b, s, { type: y, mass: f, v: a.v, w: a.w }), m({ ok: !0 });
293
+ break;
294
+ }
295
+ case "removeObject": {
296
+ await v(), G(e.id), m({ ok: !0 });
297
+ break;
298
+ }
299
+ // addCollider removed: colliders are created during attachCollider
300
+ // disposeCollider removed
301
+ case "attachCollider":
302
+ case "attachTrimeshCollider": {
303
+ await v();
304
+ const s = e.bodyId, a = e.id || e.colliderId, y = e.positions, f = e.indices || null, i = e.local || {};
305
+ if (!y) {
306
+ F(o, { ok: !1, reason: "missing positions" });
307
+ break;
308
+ }
309
+ const c = y instanceof Float32Array ? y : new Float32Array(y.buffer || y);
310
+ let u = f;
311
+ u && !(u instanceof Uint32Array) && (u = new Uint32Array(u.buffer || u)), N({
312
+ id: a,
313
+ positions: c,
314
+ indices: u || null,
315
+ bodyId: s,
316
+ local: i
317
+ }), m({ ok: !0, colliderId: a });
318
+ break;
319
+ }
320
+ case "attachShapeCollider": {
321
+ await v();
322
+ const s = e.bodyId, a = e.id || e.colliderId, y = e.shape, f = e.local || {}, i = K(y);
323
+ f?.p && i.setTranslation(+f.p[0], +f.p[1], +f.p[2]), f?.q && i.setRotation(z(f.q));
324
+ const c = x.get(s);
325
+ if (!c) {
326
+ F(o, { ok: !1, reason: "unknown body" });
327
+ break;
328
+ }
329
+ const u = p.createCollider(i, c);
330
+ C.set(a, u), M.set(a, s), m({ ok: !0, colliderId: a });
331
+ break;
332
+ }
333
+ case "detachCollider": {
334
+ await v();
335
+ const s = e.colliderId || e.id;
336
+ _(s), m({ ok: !0 });
337
+ break;
338
+ }
339
+ case "applyForce": {
340
+ await v();
341
+ const s = e.id, a = x.get(s);
342
+ if (!a) {
343
+ F(o, { ok: !1, reason: "unknown body" });
344
+ break;
345
+ }
346
+ const y = !!e.impulse, f = w(e.force || [0, 0, 0]), i = e.wake !== !1;
347
+ y ? e.point && typeof a.applyImpulseAtPoint == "function" ? a.applyImpulseAtPoint(f, w(e.point), i) : a.applyImpulse(f, i) : e.point && typeof a.applyForceAtPoint == "function" ? a.applyForceAtPoint(f, w(e.point), i) : a.applyForce(f, i), m({ ok: !0 });
348
+ break;
349
+ }
350
+ case "setPose": {
351
+ await v();
352
+ const s = e.id, a = x.get(s);
353
+ if (!a) {
354
+ m({ ok: !1, reason: "unknown body" });
355
+ break;
356
+ }
357
+ const y = e.p, f = e.q, i = e.wake !== !1;
358
+ try {
359
+ typeof a.isKinematic == "function" && a.isKinematic() ? (y && a.setNextKinematicTranslation(w(y)), f && a.setNextKinematicRotation(z(f))) : (y && typeof a.setTranslation == "function" && a.setTranslation(w(y), !0), f && typeof a.setRotation == "function" && a.setRotation(z(f), !0)), i && typeof a.wakeUp == "function" && a.wakeUp(), m({ ok: !0 });
360
+ } catch (c) {
361
+ k(c);
362
+ }
363
+ break;
364
+ }
365
+ case "setGravity": {
366
+ await v();
367
+ const s = e.gravity || {};
368
+ (s.mode || "vector").toLowerCase() === "geocentric" ? T(s.planetCenter || [0, 0, 0], typeof s.intensity == "number" ? s.intensity : 9.81) : S(s.vector || [0, -9.81, 0]), m({ ok: !0 });
369
+ break;
370
+ }
371
+ case "step": {
372
+ await v();
373
+ const s = typeof e.dt == "number" ? L(e.dt, 1 / 600, 1 / 10) : R;
374
+ Q(s), m({ ok: !0, dtUsed: s });
375
+ break;
376
+ }
377
+ case "raycast": {
378
+ await v();
379
+ const s = X(e.origin || [0, 0, 0], e.direction || [0, -1, 0], typeof e.maxToi == "number" ? e.maxToi : 1e6);
380
+ m(s);
381
+ break;
382
+ }
383
+ default: {
384
+ m({ ok: !1, reason: "unknown message type" });
385
+ break;
386
+ }
387
+ }
388
+ } catch (s) {
389
+ k(s);
390
+ }
391
+ }
392
+ self.addEventListener("message", Y);
393
+ //# sourceMappingURL=physicsRapier.worker-jgQ9dgLt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"physicsRapier.worker-jgQ9dgLt.js","sources":["../src/simulation/physicsRapier.worker.js"],"sourcesContent":["// physicsRapier.worker.js\r\n// Fully implemented physics worker using @dimforge/rapier3d-compat.\r\n// Handles rigid bodies, primitive and trimesh colliders, gravity (vector/geocentric), forces, stepping, and raycasts.\r\n// Message contract mirrors the placeholder worker but executes with Rapier under the hood.\r\n\r\nlet RAPIER = null;\r\nlet world = null;\r\n// Single-flight init to avoid concurrent wasm initialization races\r\nlet initPromise = null;\r\n\r\n// State maps\r\nconst bodies = new Map(); // id -> RigidBody\r\nconst bodyInfo = new Map(); // id -> { type, mass }\r\nconst colliders = new Map(); // id -> Collider\r\nconst colliderOwners = new Map(); // id -> bodyId\r\n\r\n// Gravity configuration\r\nlet gravityMode = 'vector'; // 'vector' | 'geocentric'\r\nlet gravityVec = { x: 0, y: -9.81, z: 0 };\r\nlet planetCenter = { x: 0, y: 0, z: 0 };\r\nlet gravityIntensity = 9.81;\r\n\r\n// Timing\r\nlet simTimeMs = 0;\r\nlet fixedDt = 1 / 60;\r\n\r\n// Utilities\r\nfunction ack(id, result = null) {\r\n if (id == null) return;\r\n postMessage({ replyTo: id, result });\r\n}\r\nfunction nack(id, error) {\r\n if (id == null) return;\r\n postMessage({ replyTo: id, error: (error && (error.message || error)) || 'error' });\r\n}\r\nfunction clamp(v, a, b) { return Math.max(a, Math.min(b, v)); }\r\nfunction v3(a) { return { x: +a[0], y: +a[1], z: +a[2] }; }\r\nfunction q4(a) { return { x: +a[0], y: +a[1], z: +a[2], w: +a[3] }; }\r\nfunction toArrV3(v) { return [v.x, v.y, v.z]; }\r\nfunction toArrQ4(q) { return [q.x, q.y, q.z, q.w]; }\r\nfunction addV(a, b) { return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z }; }\r\nfunction subV(a, b) { return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }; }\r\nfunction scaleV(a, s) { return { x: a.x * s, y: a.y * s, z: a.z * s }; }\r\nfunction lenV(a) { return Math.hypot(a.x, a.y, a.z); }\r\nfunction normV(a) { const L = lenV(a) || 1; return { x: a.x / L, y: a.y / L, z: a.z / L }; }\r\n\r\nasync function ensureRapier() {\r\n // De-duplicate concurrent initialization to avoid WASM re-entrancy (\"unreachable\"/OOB) races.\r\n if (initPromise) {\r\n await initPromise;\r\n return;\r\n }\r\n initPromise = (async () => {\r\n if (!RAPIER) {\r\n postMessage({ type: 'debug', msg: 'importing rapier module' });\r\n // Import may provide the module as the default export or as the module namespace.\r\n const mod = await import('@dimforge/rapier3d-compat');\r\n\r\n // Provide locateFile so the worker can resolve the .wasm file relative to this worker module.\r\n const locateFile = (file) => {\r\n try {\r\n return new URL(file, import.meta.url).href;\r\n } catch (e) {\r\n // Fallback: return filename (bundlers may replace with emitted asset paths)\r\n return file;\r\n }\r\n };\r\n const initOptions = { locateFile };\r\n\r\n // Normalize common export patterns:\r\n // - Factory function: default or module export is a function that initializes/returns the module.\r\n // - Object with init(options) function: call init and then use the object.\r\n // - Already-initialized object/module returned directly.\r\n const maybe = mod?.default ?? mod;\r\n postMessage({\r\n type: 'debug',\r\n msg: 'rapier module import result',\r\n hasDefault: !!mod?.default,\r\n hasInitFunction: typeof (maybe?.init) === 'function',\r\n isFactoryFunction: typeof maybe === 'function'\r\n });\r\n\r\n try {\r\n if (typeof maybe === 'function') {\r\n // Factory function case: call it with initOptions. It may return a Promise or the module synchronously.\r\n postMessage({ type: 'debug', msg: 'rapier: calling module factory function' });\r\n const res = maybe(initOptions);\r\n RAPIER = (res && typeof res.then === 'function') ? await res : (res || maybe);\r\n postMessage({ type: 'debug', msg: 'rapier factory resolved', hasWorld: !!RAPIER?.World });\r\n } else if (typeof maybe?.init === 'function') {\r\n // Object with init() API\r\n postMessage({ type: 'debug', msg: 'rapier: calling init()' });\r\n await maybe.init(initOptions);\r\n RAPIER = maybe;\r\n postMessage({ type: 'debug', msg: 'rapier.init completed', hasWorld: !!RAPIER?.World });\r\n } else if (maybe) {\r\n // Already-initialized module/object\r\n RAPIER = maybe;\r\n postMessage({ type: 'debug', msg: 'rapier: using imported module as-is', hasWorld: !!RAPIER?.World });\r\n } else {\r\n throw new Error('Imported Rapier module is empty/invalid');\r\n }\r\n } catch (err) {\r\n // Emit a helpful debug/error message back to the main thread so the app can surface it.\r\n postMessage({ type: 'error', msg: 'rapier init failed', error: (err && (err.message || String(err))) || String(err) });\r\n throw err;\r\n }\r\n\r\n if (!RAPIER) throw new Error('Failed to import Rapier module');\r\n }\r\n\r\n if (!world) {\r\n // Initialize world with vector gravity; if geocentric, we keep world gravity = 0 and apply per-body forces each step\r\n const g = (gravityMode === 'vector') ? gravityVec : { x: 0, y: 0, z: 0 };\r\n\r\n // Different Rapier builds expose constructors differently; try common variants.\r\n try {\r\n if (typeof RAPIER.World === 'function') {\r\n world = new RAPIER.World(g);\r\n } else if (typeof RAPIER.World?.new === 'function') {\r\n world = RAPIER.World.new(g);\r\n } else if (typeof RAPIER?.World === 'object' && typeof RAPIER.World.create === 'function') {\r\n world = RAPIER.World.create(g);\r\n } else if (typeof RAPIER === 'function') {\r\n // In case RAPIER itself is callable and returns a World\r\n world = RAPIER(g);\r\n } else {\r\n // Last resort: attempt to call World as a function if present\r\n world = RAPIER.World ? RAPIER.World(g) : null;\r\n }\r\n postMessage({ type: 'debug', msg: 'rapier world created' });\r\n } catch (err) {\r\n // Surface a clearer error for debugging\r\n postMessage({ type: 'error', msg: 'failed to construct rapier World', error: (err && (err.message || String(err))) || String(err) });\r\n throw new Error('Failed to construct Rapier World: ' + (err && err.message ? err.message : String(err)));\r\n }\r\n }\r\n })();\r\n\r\n try {\r\n await initPromise;\r\n } finally {\r\n // Keep the resolved promise for future awaiters; do not clear to prevent re-init.\r\n }\r\n}\r\n\r\nfunction setVectorGravity(vec3) {\r\n gravityMode = 'vector';\r\n gravityVec = { x: +vec3[0], y: +vec3[1], z: +vec3[2] };\r\n if (world) world.gravity = gravityVec;\r\n}\r\n\r\nfunction setGeocentricGravity(center, intensity) {\r\n gravityMode = 'geocentric';\r\n planetCenter = { x: +center[0], y: +center[1], z: +center[2] };\r\n gravityIntensity = +intensity;\r\n if (world) world.gravity = { x: 0, y: 0, z: 0 };\r\n}\r\n\r\nfunction computeGeocentricAt(p) {\r\n const dir = normV(subV(planetCenter, p));\r\n return scaleV(dir, gravityIntensity);\r\n}\r\n\r\n// Bodies\r\nfunction createBody(desc, id, init) {\r\n try {\r\n if (typeof world.createRigidBody !== 'function') {\r\n postMessage({ type: 'error', msg: 'world.createRigidBody is not a function', value: typeof world.createRigidBody });\r\n throw new Error('world.createRigidBody is not a function');\r\n }\r\n postMessage({ type: 'debug', msg: 'createBody: about to call world.createRigidBody', id, descType: typeof desc, descCtor: (desc && desc.constructor) ? desc.constructor.name : null });\r\n const rb = world.createRigidBody(desc);\r\n if (init?.v && typeof rb.setLinvel === 'function') rb.setLinvel(v3(init.v), false);\r\n if (init?.w && typeof rb.setAngvel === 'function') rb.setAngvel(v3(init.w), false);\r\n bodies.set(id, rb);\r\n bodyInfo.set(id, { type: init.type, mass: init.mass });\r\n return rb;\r\n } catch (err) {\r\n postMessage({ type: 'error', msg: 'createBody failed', error: (err && (err.message || String(err))) || String(err), id, descType: typeof desc });\r\n throw err;\r\n }\r\n}\r\n\r\nfunction removeBodyById(id) {\r\n const rb = bodies.get(id);\r\n if (rb) {\r\n // Remove attached colliders\r\n for (const [cid, owner] of Array.from(colliderOwners.entries())) {\r\n if (owner === id) {\r\n const col = colliders.get(cid);\r\n if (col) world.removeCollider(col, true);\r\n colliders.delete(cid);\r\n colliderOwners.delete(cid);\r\n }\r\n }\r\n world.removeRigidBody(rb);\r\n }\r\n bodies.delete(id);\r\n bodyInfo.delete(id);\r\n}\r\n\r\n// Colliders - create from trimesh with baked scale\r\nfunction createTrimeshColliderScaled({ id, positions, indices, bodyId, local }) {\r\n // Validate incoming positions buffer\r\n if (!(positions instanceof Float32Array)) {\r\n throw new Error('attachCollider: positions must be Float32Array');\r\n }\r\n if (positions.length % 3 !== 0) {\r\n throw new Error('attachCollider: positions length must be a multiple of 3');\r\n }\r\n\r\n // Copy positions to avoid unsafe aliasing with other views that may share the same ArrayBuffer.\r\n // This also protects Rapier's wasm from receiving JS-owned buffers that might be reused elsewhere.\r\n const posCopy = new Float32Array(positions);\r\n\r\n // Bake non-uniform scale into the copied vertex positions\r\n const sx = (local && local.s && +local.s[0]) || 1;\r\n const sy = (local && local.s && +local.s[1]) || 1;\r\n const sz = (local && local.s && +local.s[2]) || 1;\r\n for (let i = 0, n = posCopy.length; i < n; i += 3) {\r\n posCopy[i + 0] *= sx;\r\n posCopy[i + 1] *= sy;\r\n posCopy[i + 2] *= sz;\r\n }\r\n\r\n // Prepare a safe copy of indices (if provided) and validate index ranges\r\n let idxCopy = null;\r\n if (indices) {\r\n const srcIdx = indices instanceof Uint32Array ? indices : new Uint32Array(indices.buffer || indices);\r\n idxCopy = new Uint32Array(srcIdx); // make a copy to avoid aliasing\r\n const vertCount = posCopy.length / 3;\r\n for (let i = 0; i < idxCopy.length; ++i) {\r\n const v = idxCopy[i];\r\n if (!Number.isFinite(v) || v < 0 || v >= vertCount) {\r\n throw new Error(`attachCollider: index out of range or invalid at ${i}: ${v} (vertCount=${vertCount})`);\r\n }\r\n }\r\n }\r\n\r\n // Validate numeric contents to prevent wasm OOB or NaN propagation\r\n for (let i = 0; i < posCopy.length; ++i) {\r\n const v = posCopy[i];\r\n if (!Number.isFinite(v)) throw new Error(`attachCollider: invalid position value at ${i}: ${v}`);\r\n }\r\n\r\n // Construct the Rapier collider descriptor with the copied, validated buffers\r\n const desc = RAPIER.ColliderDesc.trimesh(posCopy, idxCopy);\r\n if (local?.p) desc.setTranslation(+local.p[0], +local.p[1], +local.p[2]);\r\n if (local?.q) desc.setRotation(q4(local.q));\r\n\r\n const rb = bodies.get(bodyId);\r\n if (!rb) throw new Error(`attachCollider: body not found: ${bodyId}`);\r\n const col = world.createCollider(desc, rb);\r\n\r\n colliders.set(id, col);\r\n colliderOwners.set(id, bodyId);\r\n}\r\n\r\nfunction removeColliderById(id) {\r\n const col = colliders.get(id);\r\n if (col) world.removeCollider(col, true);\r\n colliders.delete(id);\r\n colliderOwners.delete(id);\r\n}\r\n\r\n// Engine-agnostic primitive shape adapter\r\nfunction colliderDescFromShape(shape) {\r\n if (!shape || typeof shape !== 'object') throw new Error('attachShapeCollider: missing shape');\r\n const kind = String(shape.kind || '').toLowerCase();\r\n const p = shape.params || {};\r\n switch (kind) {\r\n case 'ball': {\r\n const r = +p.radius;\r\n return RAPIER.ColliderDesc.ball(r);\r\n }\r\n case 'cuboid':\r\n case 'box': {\r\n const hx = +p.hx, hy = +p.hy, hz = +p.hz;\r\n return RAPIER.ColliderDesc.cuboid(hx, hy, hz);\r\n }\r\n case 'roundcuboid':\r\n case 'round_cuboid':\r\n case 'round-cuboid': {\r\n const hx = +p.hx, hy = +p.hy, hz = +p.hz, radius = +p.radius || 0;\r\n return RAPIER.ColliderDesc.roundCuboid(hx, hy, hz, radius);\r\n }\r\n case 'capsule': {\r\n const hh = +p.halfHeight;\r\n const r = +p.radius;\r\n return RAPIER.ColliderDesc.capsule(hh, r);\r\n }\r\n case 'cone': {\r\n const hh = +p.halfHeight;\r\n const r = +p.radius;\r\n return RAPIER.ColliderDesc.cone(hh, r);\r\n }\r\n case 'cylinder': {\r\n const hh = +p.halfHeight;\r\n const r = +p.radius;\r\n return RAPIER.ColliderDesc.cylinder(hh, r);\r\n }\r\n case 'segment': {\r\n const a = p.a || p.p1;\r\n const b = p.b || p.p2;\r\n if (!a || !b) throw new Error('segment requires a and b (or p1,p2)');\r\n return RAPIER.ColliderDesc.segment(v3(a), v3(b));\r\n }\r\n case 'triangle': {\r\n const a = p.a, b = p.b, c = p.c;\r\n if (!a || !b || !c) throw new Error('triangle requires a, b, c');\r\n return RAPIER.ColliderDesc.triangle(v3(a), v3(b), v3(c));\r\n }\r\n case 'polyline': {\r\n const verts = p.vertices instanceof Float32Array ? p.vertices : new Float32Array(p.vertices);\r\n let idx = null;\r\n if (p.indices) idx = p.indices instanceof Uint32Array ? p.indices : new Uint32Array(p.indices);\r\n return RAPIER.ColliderDesc.polyline(verts, idx);\r\n }\r\n case 'convexhull':\r\n case 'convex_hull':\r\n case 'convex-hull': {\r\n const verts = p.vertices instanceof Float32Array ? p.vertices : new Float32Array(p.vertices);\r\n const desc = RAPIER.ColliderDesc.convexHull(verts);\r\n if (!desc) throw new Error('convexHull: invalid or insufficient points');\r\n return desc;\r\n }\r\n case 'heightfield': {\r\n const rows = +p.rows, cols = +p.cols;\r\n const heights = p.heights instanceof Float32Array ? p.heights : new Float32Array(p.heights);\r\n const scale = p.scale || { x: 1, y: 1, z: 1 };\r\n return RAPIER.ColliderDesc.heightfield(rows, cols, heights, scale);\r\n }\r\n default:\r\n throw new Error(`Unknown primitive collider kind: ${shape.kind}`);\r\n }\r\n}\r\n\r\n// Step and state\r\nfunction applyExternalForces(dt) {\r\n if (gravityMode !== 'geocentric') return;\r\n for (const [id, rb] of bodies.entries()) {\r\n if (!rb || rb.isFixed()) continue;\r\n const mass = Math.max(1e-6, bodyInfo.get(id)?.mass ?? 1);\r\n const p = rb.translation();\r\n const g = computeGeocentricAt(p);\r\n const f = { x: g.x * mass, y: g.y * mass, z: g.z * mass };\r\n rb.applyForce(f, true);\r\n }\r\n}\r\n\r\nfunction step(dt) {\r\n world.timestep = dt;\r\n applyExternalForces(dt);\r\n world.step();\r\n simTimeMs += dt * 1000.0;\r\n\r\n const stateBodies = {};\r\n for (const [id, rb] of bodies.entries()) {\r\n const t = rb.translation();\r\n const r = rb.rotation();\r\n stateBodies[id] = { p: [t.x, t.y, t.z], q: [r.x, r.y, r.z, r.w] };\r\n }\r\n postMessage({ type: 'state', state: { timeMs: simTimeMs, bodies: stateBodies } });\r\n}\r\n\r\n// Raycast (first hit)\r\nfunction raycast(origin, dir, maxToi = 1e6) {\r\n const o = v3(origin);\r\n const d = v3(dir);\r\n const ray = new RAPIER.Ray(o, d);\r\n // solid=true returns time-of-impact including if ray starts inside collider\r\n const hit = world.castRay(ray, maxToi, true);\r\n if (!hit) return { hits: [] };\r\n\r\n const toi = hit.toi;\r\n const point = ray.pointAt(toi);\r\n const normal = hit.normal;\r\n // Find collider id\r\n let colliderId = null;\r\n for (const [cid, col] of colliders.entries()) {\r\n if (col.handle === hit.collider.handle) {\r\n colliderId = cid;\r\n break;\r\n }\r\n }\r\n let bodyId = null;\r\n const rbHandle = hit.collider.parent()?.handle;\r\n if (rbHandle != null) {\r\n for (const [bid, rb] of bodies.entries()) {\r\n if (rb.handle === rbHandle) { bodyId = bid; break; }\r\n }\r\n }\r\n return {\r\n hits: [{\r\n toi,\r\n point: [point.x, point.y, point.z],\r\n normal: [normal.x, normal.y, normal.z],\r\n colliderId,\r\n bodyId\r\n }]\r\n };\r\n}\r\n\r\n// Message handling\r\nasync function onMessage(e) {\r\n const msg = e.data || {};\r\n const { id, type, _envId, replyTo } = msg;\r\n const replyId = (typeof _envId !== 'undefined') ? _envId : (typeof replyTo !== 'undefined' ? replyTo : id);\r\n const _ack = (res) => ack(replyId, res);\r\n const _nack = (err) => nack(replyId, err);\r\n try {\r\n switch (type) {\r\n case 'init': {\r\n fixedDt = typeof msg.fixedDt === 'number' ? msg.fixedDt : fixedDt;\r\n const g = msg.gravity || {};\r\n const mode = (g.mode || 'vector').toLowerCase();\r\n if (mode === 'geocentric') {\r\n setGeocentricGravity(g.planetCenter || [0, 0, 0], typeof g.intensity === 'number' ? g.intensity : 9.81);\r\n } else {\r\n setVectorGravity(g.vector || [0, -9.81, 0]);\r\n }\r\n await ensureRapier();\r\n _ack({ ok: true });\r\n break;\r\n }\r\n\r\n case 'addObject': {\r\n await ensureRapier();\r\n const bodyId = msg.id;\r\n const b = msg.body || {};\r\n const typeStr = (b.type || 'dynamic').toLowerCase();\r\n const mass = typeof b.mass === 'number' ? b.mass : 1.0;\r\n const p = v3(b.p || [0, 0, 0]);\r\n const q = q4(b.q || [0, 0, 0, 1]);\r\n \r\n // Validate numeric values to avoid creating a RigidBodyDesc with NaN/Infinity\r\n function isNum(n) { return typeof n === 'number' && isFinite(n); }\r\n if (!isNum(p.x) || !isNum(p.y) || !isNum(p.z)) {\r\n postMessage({ type: 'debug', msg: 'addObject: invalid translation detected, resetting to 0', bodyId, p });\r\n p.x = isNum(p.x) ? p.x : 0;\r\n p.y = isNum(p.y) ? p.y : 0;\r\n p.z = isNum(p.z) ? p.z : 0;\r\n }\r\n if (![q.x, q.y, q.z, q.w].every(isNum)) {\r\n postMessage({ type: 'debug', msg: 'addObject: invalid rotation detected, using identity quat', bodyId, q });\r\n q.x = 0; q.y = 0; q.z = 0; q.w = 1;\r\n } else {\r\n // Normalize quaternion to be safe\r\n const L = Math.hypot(q.x, q.y, q.z, q.w) || 1;\r\n q.x /= L; q.y /= L; q.z /= L; q.w /= L;\r\n }\r\n \r\n let desc;\r\n if (typeStr === 'fixed') desc = RAPIER.RigidBodyDesc.fixed();\r\n else if (typeStr === 'kinematic') desc = RAPIER.RigidBodyDesc.kinematicPositionBased();\r\n else desc = RAPIER.RigidBodyDesc.dynamic().setAdditionalMass(mass);\r\n \r\n // Defensive setters to capture errors before calling into wasm\r\n try {\r\n desc.setTranslation(p.x, p.y, p.z);\r\n } catch (err) {\r\n postMessage({ type: 'error', msg: 'desc.setTranslation failed', error: (err && (err.message || String(err))) || String(err), bodyId, p });\r\n throw err;\r\n }\r\n try {\r\n desc.setRotation(q);\r\n } catch (err) {\r\n postMessage({ type: 'error', msg: 'desc.setRotation failed', error: (err && (err.message || String(err))) || String(err), bodyId, q });\r\n throw err;\r\n }\r\n \r\n postMessage({ type: 'debug', msg: 'addObject: creating body', bodyId, typeStr, mass, p, q });\r\n createBody(desc, bodyId, { type: typeStr, mass, v: b.v, w: b.w });\r\n _ack({ ok: true });\r\n break;\r\n }\r\n\r\n case 'removeObject': {\r\n await ensureRapier();\r\n removeBodyById(msg.id);\r\n _ack({ ok: true });\r\n break;\r\n }\r\n\r\n // addCollider removed: colliders are created during attachCollider\r\n\r\n // disposeCollider removed\r\n\r\n case 'attachCollider':\r\n case 'attachTrimeshCollider': {\r\n await ensureRapier();\r\n const bodyId = msg.bodyId;\r\n const colId = msg.id || msg.colliderId;\r\n const positions = msg.positions;\r\n const indices = msg.indices || null;\r\n const local = msg.local || {};\r\n if (!positions) { ack(id, { ok: false, reason: 'missing positions' }); break; }\r\n const verts = positions instanceof Float32Array ? positions : new Float32Array(positions.buffer || positions);\r\n let idx = indices;\r\n if (idx && !(idx instanceof Uint32Array)) idx = new Uint32Array(idx.buffer || idx);\r\n createTrimeshColliderScaled({\r\n id: colId,\r\n positions: verts,\r\n indices: idx || null,\r\n bodyId,\r\n local\r\n });\r\n _ack({ ok: true, colliderId: colId });\r\n break;\r\n }\r\n \r\n case 'attachShapeCollider': {\r\n await ensureRapier();\r\n const bodyId = msg.bodyId;\r\n const colId = msg.id || msg.colliderId;\r\n const shape = msg.shape;\r\n const local = msg.local || {};\r\n const desc = colliderDescFromShape(shape);\r\n if (local?.p) desc.setTranslation(+local.p[0], +local.p[1], +local.p[2]);\r\n if (local?.q) desc.setRotation(q4(local.q));\r\n const rb = bodies.get(bodyId);\r\n if (!rb) { ack(id, { ok: false, reason: 'unknown body' }); break; }\r\n const col = world.createCollider(desc, rb);\r\n colliders.set(colId, col);\r\n colliderOwners.set(colId, bodyId);\r\n _ack({ ok: true, colliderId: colId });\r\n break;\r\n }\r\n \r\n case 'detachCollider': {\r\n await ensureRapier();\r\n const colId = msg.colliderId || msg.id;\r\n removeColliderById(colId);\r\n _ack({ ok: true });\r\n break;\r\n }\r\n\r\n case 'applyForce': {\r\n await ensureRapier();\r\n const bodyId = msg.id;\r\n const rb = bodies.get(bodyId);\r\n if (!rb) { ack(id, { ok: false, reason: 'unknown body' }); break; }\r\n\r\n const impulse = !!msg.impulse;\r\n const force = v3(msg.force || [0, 0, 0]);\r\n const wake = msg.wake !== false;\r\n\r\n if (impulse) {\r\n if (msg.point && typeof rb.applyImpulseAtPoint === 'function') {\r\n rb.applyImpulseAtPoint(force, v3(msg.point), wake);\r\n } else {\r\n rb.applyImpulse(force, wake);\r\n }\r\n } else {\r\n if (msg.point && typeof rb.applyForceAtPoint === 'function') {\r\n rb.applyForceAtPoint(force, v3(msg.point), wake);\r\n } else {\r\n rb.applyForce(force, wake);\r\n }\r\n }\r\n _ack({ ok: true });\r\n break;\r\n }\r\n\r\n case 'setPose': {\r\n await ensureRapier();\r\n const bodyId = msg.id;\r\n const rb = bodies.get(bodyId);\r\n if (!rb) { _ack({ ok: false, reason: 'unknown body' }); break; }\r\n\r\n const p = msg.p; // [x,y,z] or null\r\n const q = msg.q; // [x,y,z,w] or null\r\n const wake = msg.wake !== false;\r\n\r\n try {\r\n if (typeof rb.isKinematic === 'function' && rb.isKinematic()) {\r\n // Kinematic bodies use \"next\" pose setters\r\n if (p) rb.setNextKinematicTranslation(v3(p));\r\n if (q) rb.setNextKinematicRotation(q4(q));\r\n } else {\r\n // Dynamic/fixed bodies: set pose directly\r\n if (p && typeof rb.setTranslation === 'function') rb.setTranslation(v3(p), true);\r\n if (q && typeof rb.setRotation === 'function') rb.setRotation(q4(q), true);\r\n }\r\n if (wake && typeof rb.wakeUp === 'function') rb.wakeUp();\r\n _ack({ ok: true });\r\n } catch (err) {\r\n _nack(err);\r\n }\r\n break;\r\n }\r\n\r\n case 'setGravity': {\r\n await ensureRapier();\r\n const g = msg.gravity || {};\r\n const mode = (g.mode || 'vector').toLowerCase();\r\n if (mode === 'geocentric') {\r\n setGeocentricGravity(g.planetCenter || [0, 0, 0], typeof g.intensity === 'number' ? g.intensity : 9.81);\r\n } else {\r\n setVectorGravity(g.vector || [0, -9.81, 0]);\r\n }\r\n _ack({ ok: true });\r\n break;\r\n }\r\n\r\n case 'step': {\r\n await ensureRapier();\r\n const dt = typeof msg.dt === 'number' ? clamp(msg.dt, 1 / 600, 1 / 10) : fixedDt;\r\n step(dt);\r\n _ack({ ok: true, dtUsed: dt });\r\n break;\r\n }\r\n\r\n case 'raycast': {\r\n await ensureRapier();\r\n const result = raycast(msg.origin || [0, 0, 0], msg.direction || [0, -1, 0], typeof msg.maxToi === 'number' ? msg.maxToi : 1e6);\r\n _ack(result);\r\n break;\r\n }\r\n\r\n default: {\r\n _ack({ ok: false, reason: 'unknown message type' });\r\n break;\r\n }\r\n }\r\n } catch (err) {\r\n _nack(err);\r\n }\r\n}\r\n\r\nself.addEventListener('message', onMessage);"],"names":["RAPIER","world","initPromise","bodies","bodyInfo","colliders","colliderOwners","gravityMode","gravityVec","planetCenter","gravityIntensity","simTimeMs","fixedDt","ack","id","result","nack","error","clamp","v","a","b","v3","q4","subV","scaleV","s","lenV","normV","L","ensureRapier","mod","initOptions","file","maybe","res","err","g","setVectorGravity","vec3","setGeocentricGravity","center","intensity","computeGeocentricAt","p","dir","createBody","desc","init","rb","removeBodyById","cid","owner","col","createTrimeshColliderScaled","positions","indices","bodyId","local","posCopy","sx","sy","sz","n","idxCopy","srcIdx","vertCount","i","removeColliderById","colliderDescFromShape","shape","kind","r","hx","hy","hz","radius","hh","c","verts","idx","rows","cols","heights","scale","applyExternalForces","dt","mass","f","step","stateBodies","t","raycast","origin","maxToi","o","d","ray","hit","toi","point","normal","colliderId","rbHandle","bid","onMessage","e","msg","type","_envId","replyTo","replyId","_ack","_nack","isNum","typeStr","q","colId","impulse","force","wake"],"mappings":"AAKA,IAAIA,IAAS,MACTC,IAAQ,MAERC,IAAc;AAGlB,MAAMC,IAAS,oBAAI,OACbC,IAAW,oBAAI,OACfC,IAAY,oBAAI,OAChBC,IAAiB,oBAAI;AAG3B,IAAIC,IAAc,UACdC,IAAa,EAAE,GAAG,GAAG,GAAG,OAAO,GAAG,KAClCC,IAAe,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,KAChCC,IAAmB,MAGnBC,IAAY,GACZC,IAAU,IAAI;AAGlB,SAASC,EAAIC,GAAIC,IAAS,MAAM;AAC9B,EAAID,KAAM,QACV,YAAY,EAAE,SAASA,GAAI,QAAAC,EAAM,CAAE;AACrC;AACA,SAASC,EAAKF,GAAIG,GAAO;AACvB,EAAIH,KAAM,QACV,YAAY,EAAE,SAASA,GAAI,OAAQG,MAAUA,EAAM,WAAWA,MAAW,QAAO,CAAE;AACpF;AACA,SAASC,EAAMC,GAAGC,GAAGC,GAAG;AAAE,SAAO,KAAK,IAAID,GAAG,KAAK,IAAIC,GAAGF,CAAC,CAAC;AAAG;AAC9D,SAASG,EAAGF,GAAG;AAAE,SAAO,EAAE,GAAG,CAACA,EAAE,CAAC,GAAG,GAAG,CAACA,EAAE,CAAC,GAAG,GAAG,CAACA,EAAE,CAAC,EAAC;AAAI;AAC1D,SAASG,EAAGH,GAAG;AAAE,SAAO,EAAE,GAAG,CAACA,EAAE,CAAC,GAAG,GAAG,CAACA,EAAE,CAAC,GAAG,GAAG,CAACA,EAAE,CAAC,GAAG,GAAG,CAACA,EAAE,CAAC,EAAC;AAAI;AAIpE,SAASI,EAAKJ,GAAGC,GAAG;AAAE,SAAO,EAAE,GAAGD,EAAE,IAAIC,EAAE,GAAG,GAAGD,EAAE,IAAIC,EAAE,GAAG,GAAGD,EAAE,IAAIC,EAAE,EAAC;AAAI;AAC3E,SAASI,EAAOL,GAAGM,GAAG;AAAE,SAAO,EAAE,GAAGN,EAAE,IAAIM,GAAG,GAAGN,EAAE,IAAIM,GAAG,GAAGN,EAAE,IAAIM,EAAC;AAAI;AACvE,SAASC,EAAKP,GAAG;AAAE,SAAO,KAAK,MAAMA,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC;AAAG;AACrD,SAASQ,EAAMR,GAAG;AAAE,QAAMS,IAAIF,EAAKP,CAAC,KAAK;AAAG,SAAO,EAAE,GAAGA,EAAE,IAAIS,GAAG,GAAGT,EAAE,IAAIS,GAAG,GAAGT,EAAE,IAAIS,EAAC;AAAI;AAE3F,eAAeC,IAAe;AAE5B,MAAI5B,GAAa;AACf,UAAMA;AACN;AAAA,EACF;AACA,EAAAA,KAAe,YAAY;AACzB,QAAI,CAACF,GAAQ;AACX,kBAAY,EAAE,MAAM,SAAS,KAAK,0BAAyB,CAAE;AAE7D,YAAM+B,IAAM,MAAM,OAAO,sBAA2B,GAW9CC,IAAc,EAAE,YARH,CAACC,MAAS;AAC3B,YAAI;AACF,iBAAO,IAAI,IAAIA,GAAM,YAAY,GAAG,EAAE;AAAA,QACxC,QAAY;AAEV,iBAAOA;AAAA,QACT;AAAA,MACF,KAOMC,IAAQH,GAAK,WAAWA;AAC9B,kBAAY;AAAA,QACV,MAAM;AAAA,QACN,KAAK;AAAA,QACL,YAAY,CAAC,CAACA,GAAK;AAAA,QACnB,iBAAiB,OAAQG,GAAO,QAAU;AAAA,QAC1C,mBAAmB,OAAOA,KAAU;AAAA,MAC5C,CAAO;AAED,UAAI;AACF,YAAI,OAAOA,KAAU,YAAY;AAE/B,sBAAY,EAAE,MAAM,SAAS,KAAK,0CAAyC,CAAE;AAC7E,gBAAMC,IAAMD,EAAMF,CAAW;AAC7B,UAAAhC,IAAUmC,KAAO,OAAOA,EAAI,QAAS,aAAc,MAAMA,IAAOA,KAAOD,GACvE,YAAY,EAAE,MAAM,SAAS,KAAK,2BAA2B,UAAU,CAAC,CAAClC,GAAQ,MAAK,CAAE;AAAA,QAC1F,WAAW,OAAOkC,GAAO,QAAS;AAEhC,sBAAY,EAAE,MAAM,SAAS,KAAK,yBAAwB,CAAE,GAC5D,MAAMA,EAAM,KAAKF,CAAW,GAC5BhC,IAASkC,GACT,YAAY,EAAE,MAAM,SAAS,KAAK,yBAAyB,UAAU,CAAC,CAAClC,GAAQ,MAAK,CAAE;AAAA,iBAC7EkC;AAET,UAAAlC,IAASkC,GACT,YAAY,EAAE,MAAM,SAAS,KAAK,uCAAuC,UAAU,CAAC,CAAClC,GAAQ,MAAK,CAAE;AAAA;AAEpG,gBAAM,IAAI,MAAM,yCAAyC;AAAA,MAE7D,SAASoC,GAAK;AAEZ,0BAAY,EAAE,MAAM,SAAS,KAAK,sBAAsB,OAAQA,MAAQA,EAAI,WAAW,OAAOA,CAAG,MAAO,OAAOA,CAAG,EAAC,CAAE,GAC/GA;AAAA,MACR;AAEA,UAAI,CAACpC,EAAQ,OAAM,IAAI,MAAM,gCAAgC;AAAA,IAC/D;AAEA,QAAI,CAACC,GAAO;AAEV,YAAMoC,IAAK9B,MAAgB,WAAYC,IAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAGtE,UAAI;AACF,QAAI,OAAOR,EAAO,SAAU,aAC1BC,IAAQ,IAAID,EAAO,MAAMqC,CAAC,IACjB,OAAOrC,EAAO,OAAO,OAAQ,aACtCC,IAAQD,EAAO,MAAM,IAAIqC,CAAC,IACjB,OAAOrC,GAAQ,SAAU,YAAY,OAAOA,EAAO,MAAM,UAAW,aAC7EC,IAAQD,EAAO,MAAM,OAAOqC,CAAC,IACpB,OAAOrC,KAAW,aAE3BC,IAAQD,EAAOqC,CAAC,IAGhBpC,IAAQD,EAAO,QAAQA,EAAO,MAAMqC,CAAC,IAAI,MAE3C,YAAY,EAAE,MAAM,SAAS,KAAK,uBAAsB,CAAE;AAAA,MAC5D,SAASD,GAAK;AAEZ,0BAAY,EAAE,MAAM,SAAS,KAAK,oCAAoC,OAAQA,MAAQA,EAAI,WAAW,OAAOA,CAAG,MAAO,OAAOA,CAAG,EAAC,CAAE,GAC7H,IAAI,MAAM,wCAAwCA,KAAOA,EAAI,UAAUA,EAAI,UAAU,OAAOA,CAAG,EAAE;AAAA,MACzG;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAMlC;AAAA,EACR,UAAC;AAAA,EAED;AACF;AAEA,SAASoC,EAAiBC,GAAM;AAC9B,EAAAhC,IAAc,UACdC,IAAa,EAAE,GAAG,CAAC+B,EAAK,CAAC,GAAG,GAAG,CAACA,EAAK,CAAC,GAAG,GAAG,CAACA,EAAK,CAAC,EAAC,GAChDtC,MAAOA,EAAM,UAAUO;AAC7B;AAEA,SAASgC,EAAqBC,GAAQC,GAAW;AAC/C,EAAAnC,IAAc,cACdE,IAAe,EAAE,GAAG,CAACgC,EAAO,CAAC,GAAG,GAAG,CAACA,EAAO,CAAC,GAAG,GAAG,CAACA,EAAO,CAAC,EAAC,GAC5D/B,IAAmB,CAACgC,GAChBzC,MAAOA,EAAM,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG;AAC9C;AAEA,SAAS0C,EAAoBC,GAAG;AAC9B,QAAMC,IAAMjB,EAAMJ,EAAKf,GAAcmC,CAAC,CAAC;AACvC,SAAOnB,EAAOoB,GAAKnC,CAAgB;AACrC;AAGA,SAASoC,EAAWC,GAAMjC,GAAIkC,GAAM;AAClC,MAAI;AACF,QAAI,OAAO/C,EAAM,mBAAoB;AACnC,wBAAY,EAAE,MAAM,SAAS,KAAK,2CAA2C,OAAO,OAAOA,EAAM,gBAAe,CAAE,GAC5G,IAAI,MAAM,yCAAyC;AAE3D,gBAAY,EAAE,MAAM,SAAS,KAAK,mDAAmD,IAAAa,GAAI,UAAU,OAAOiC,GAAM,UAAWA,KAAQA,EAAK,cAAeA,EAAK,YAAY,OAAO,KAAI,CAAE;AACrL,UAAME,IAAKhD,EAAM,gBAAgB8C,CAAI;AACrC,WAAIC,GAAM,KAAK,OAAOC,EAAG,aAAc,cAAYA,EAAG,UAAU3B,EAAG0B,EAAK,CAAC,GAAG,EAAK,GAC7EA,GAAM,KAAK,OAAOC,EAAG,aAAc,cAAYA,EAAG,UAAU3B,EAAG0B,EAAK,CAAC,GAAG,EAAK,GACjF7C,EAAO,IAAIW,GAAImC,CAAE,GACjB7C,EAAS,IAAIU,GAAI,EAAE,MAAMkC,EAAK,MAAM,MAAMA,EAAK,KAAI,CAAE,GAC9CC;AAAA,EACT,SAASb,GAAK;AACZ,sBAAY,EAAE,MAAM,SAAS,KAAK,qBAAqB,OAAQA,MAAQA,EAAI,WAAW,OAAOA,CAAG,MAAO,OAAOA,CAAG,GAAG,IAAAtB,GAAI,UAAU,OAAOiC,EAAI,CAAE,GACzIX;AAAA,EACR;AACF;AAEA,SAASc,EAAepC,GAAI;AAC1B,QAAMmC,IAAK9C,EAAO,IAAIW,CAAE;AACxB,MAAImC,GAAI;AAEN,eAAW,CAACE,GAAKC,CAAK,KAAK,MAAM,KAAK9C,EAAe,QAAO,CAAE;AAC5D,UAAI8C,MAAUtC,GAAI;AAChB,cAAMuC,IAAMhD,EAAU,IAAI8C,CAAG;AAC7B,QAAIE,KAAKpD,EAAM,eAAeoD,GAAK,EAAI,GACvChD,EAAU,OAAO8C,CAAG,GACpB7C,EAAe,OAAO6C,CAAG;AAAA,MAC3B;AAEF,IAAAlD,EAAM,gBAAgBgD,CAAE;AAAA,EAC1B;AACA,EAAA9C,EAAO,OAAOW,CAAE,GAChBV,EAAS,OAAOU,CAAE;AACpB;AAGA,SAASwC,EAA4B,EAAE,IAAAxC,GAAI,WAAAyC,GAAW,SAAAC,GAAS,QAAAC,GAAQ,OAAAC,KAAS;AAE9E,MAAI,EAAEH,aAAqB;AACzB,UAAM,IAAI,MAAM,gDAAgD;AAElE,MAAIA,EAAU,SAAS,MAAM;AAC3B,UAAM,IAAI,MAAM,0DAA0D;AAK5E,QAAMI,IAAU,IAAI,aAAaJ,CAAS,GAGpCK,IAAMF,KAASA,EAAM,KAAK,CAACA,EAAM,EAAE,CAAC,KAAM,GAC1CG,IAAMH,KAASA,EAAM,KAAK,CAACA,EAAM,EAAE,CAAC,KAAM,GAC1CI,IAAMJ,KAASA,EAAM,KAAK,CAACA,EAAM,EAAE,CAAC,KAAM;AAChD,WAAS,IAAI,GAAGK,IAAIJ,EAAQ,QAAQ,IAAII,GAAG,KAAK;AAC9C,IAAAJ,EAAQ,IAAI,CAAC,KAAKC,GAClBD,EAAQ,IAAI,CAAC,KAAKE,GAClBF,EAAQ,IAAI,CAAC,KAAKG;AAIpB,MAAIE,IAAU;AACd,MAAIR,GAAS;AACX,UAAMS,IAAST,aAAmB,cAAcA,IAAU,IAAI,YAAYA,EAAQ,UAAUA,CAAO;AACnG,IAAAQ,IAAU,IAAI,YAAYC,CAAM;AAChC,UAAMC,IAAYP,EAAQ,SAAS;AACnC,aAASQ,IAAI,GAAGA,IAAIH,EAAQ,QAAQ,EAAEG,GAAG;AACvC,YAAMhD,IAAI6C,EAAQG,CAAC;AACnB,UAAI,CAAC,OAAO,SAAShD,CAAC,KAAKA,IAAI,KAAKA,KAAK+C;AACvC,cAAM,IAAI,MAAM,oDAAoDC,CAAC,KAAKhD,CAAC,eAAe+C,CAAS,GAAG;AAAA,IAE1G;AAAA,EACF;AAGA,WAAS,IAAI,GAAG,IAAIP,EAAQ,QAAQ,EAAE,GAAG;AACvC,UAAMxC,IAAIwC,EAAQ,CAAC;AACnB,QAAI,CAAC,OAAO,SAASxC,CAAC,EAAG,OAAM,IAAI,MAAM,6CAA6C,CAAC,KAAKA,CAAC,EAAE;AAAA,EACjG;AAGA,QAAM4B,IAAO/C,EAAO,aAAa,QAAQ2D,GAASK,CAAO;AACzD,EAAIN,GAAO,KAAGX,EAAK,eAAe,CAACW,EAAM,EAAE,CAAC,GAAG,CAACA,EAAM,EAAE,CAAC,GAAG,CAACA,EAAM,EAAE,CAAC,CAAC,GACnEA,GAAO,KAAGX,EAAK,YAAYxB,EAAGmC,EAAM,CAAC,CAAC;AAE1C,QAAMT,IAAK9C,EAAO,IAAIsD,CAAM;AAC5B,MAAI,CAACR,EAAI,OAAM,IAAI,MAAM,mCAAmCQ,CAAM,EAAE;AACpE,QAAMJ,IAAMpD,EAAM,eAAe8C,GAAME,CAAE;AAEzC,EAAA5C,EAAU,IAAIS,GAAIuC,CAAG,GACrB/C,EAAe,IAAIQ,GAAI2C,CAAM;AAC/B;AAEA,SAASW,EAAmBtD,GAAI;AAC9B,QAAMuC,IAAMhD,EAAU,IAAIS,CAAE;AAC5B,EAAIuC,KAAKpD,EAAM,eAAeoD,GAAK,EAAI,GACvChD,EAAU,OAAOS,CAAE,GACnBR,EAAe,OAAOQ,CAAE;AAC1B;AAGA,SAASuD,EAAsBC,GAAO;AACpC,MAAI,CAACA,KAAS,OAAOA,KAAU,SAAU,OAAM,IAAI,MAAM,oCAAoC;AAC7F,QAAMC,IAAO,OAAOD,EAAM,QAAQ,EAAE,EAAE,eAChC1B,IAAI0B,EAAM,UAAU;AAC1B,UAAQC,GAAI;AAAA,IACV,KAAK,QAAQ;AACX,YAAMC,IAAI,CAAC5B,EAAE;AACb,aAAO5C,EAAO,aAAa,KAAKwE,CAAC;AAAA,IACnC;AAAA,IACA,KAAK;AAAA,IACL,KAAK,OAAO;AACV,YAAMC,IAAK,CAAC7B,EAAE,IAAI8B,IAAK,CAAC9B,EAAE,IAAI+B,IAAK,CAAC/B,EAAE;AACtC,aAAO5C,EAAO,aAAa,OAAOyE,GAAIC,GAAIC,CAAE;AAAA,IAC9C;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,gBAAgB;AACnB,YAAMF,IAAK,CAAC7B,EAAE,IAAI8B,IAAK,CAAC9B,EAAE,IAAI+B,IAAK,CAAC/B,EAAE,IAAIgC,IAAS,CAAChC,EAAE,UAAU;AAChE,aAAO5C,EAAO,aAAa,YAAYyE,GAAIC,GAAIC,GAAIC,CAAM;AAAA,IAC3D;AAAA,IACA,KAAK,WAAW;AACd,YAAMC,IAAK,CAACjC,EAAE,YACR,IAAI,CAACA,EAAE;AACb,aAAO5C,EAAO,aAAa,QAAQ6E,GAAI,CAAC;AAAA,IAC1C;AAAA,IACA,KAAK,QAAQ;AACX,YAAMA,IAAK,CAACjC,EAAE,YACR,IAAI,CAACA,EAAE;AACb,aAAO5C,EAAO,aAAa,KAAK6E,GAAI,CAAC;AAAA,IACvC;AAAA,IACA,KAAK,YAAY;AACf,YAAMA,IAAK,CAACjC,EAAE,YACR,IAAI,CAACA,EAAE;AACb,aAAO5C,EAAO,aAAa,SAAS6E,GAAI,CAAC;AAAA,IAC3C;AAAA,IACA,KAAK,WAAW;AACd,YAAMzD,IAAIwB,EAAE,KAAKA,EAAE,IACbvB,IAAIuB,EAAE,KAAKA,EAAE;AACnB,UAAI,CAACxB,KAAK,CAACC,EAAG,OAAM,IAAI,MAAM,qCAAqC;AACnE,aAAOrB,EAAO,aAAa,QAAQsB,EAAGF,CAAC,GAAGE,EAAGD,CAAC,CAAC;AAAA,IACjD;AAAA,IACA,KAAK,YAAY;AACf,YAAMD,IAAIwB,EAAE,GAAGvB,IAAIuB,EAAE,GAAGkC,IAAIlC,EAAE;AAC9B,UAAI,CAACxB,KAAK,CAACC,KAAK,CAACyD,EAAG,OAAM,IAAI,MAAM,2BAA2B;AAC/D,aAAO9E,EAAO,aAAa,SAASsB,EAAGF,CAAC,GAAGE,EAAGD,CAAC,GAAGC,EAAGwD,CAAC,CAAC;AAAA,IACzD;AAAA,IACA,KAAK,YAAY;AACf,YAAMC,IAAQnC,EAAE,oBAAoB,eAAeA,EAAE,WAAW,IAAI,aAAaA,EAAE,QAAQ;AAC3F,UAAIoC,IAAM;AACV,aAAIpC,EAAE,YAASoC,IAAMpC,EAAE,mBAAmB,cAAcA,EAAE,UAAU,IAAI,YAAYA,EAAE,OAAO,IACtF5C,EAAO,aAAa,SAAS+E,GAAOC,CAAG;AAAA,IAChD;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,eAAe;AAClB,YAAMD,IAAQnC,EAAE,oBAAoB,eAAeA,EAAE,WAAW,IAAI,aAAaA,EAAE,QAAQ,GACrFG,IAAO/C,EAAO,aAAa,WAAW+E,CAAK;AACjD,UAAI,CAAChC,EAAM,OAAM,IAAI,MAAM,4CAA4C;AACvE,aAAOA;AAAA,IACT;AAAA,IACA,KAAK,eAAe;AAClB,YAAMkC,IAAO,CAACrC,EAAE,MAAMsC,IAAO,CAACtC,EAAE,MAC1BuC,IAAUvC,EAAE,mBAAmB,eAAeA,EAAE,UAAU,IAAI,aAAaA,EAAE,OAAO,GACpFwC,IAAQxC,EAAE,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG;AAC1C,aAAO5C,EAAO,aAAa,YAAYiF,GAAMC,GAAMC,GAASC,CAAK;AAAA,IACnE;AAAA,IACA;AACE,YAAM,IAAI,MAAM,oCAAoCd,EAAM,IAAI,EAAE;AAAA,EACtE;AACA;AAGA,SAASe,EAAoBC,GAAI;AAC/B,MAAI/E,MAAgB;AACpB,eAAW,CAACO,GAAImC,CAAE,KAAK9C,EAAO,QAAO,GAAI;AACvC,UAAI,CAAC8C,KAAMA,EAAG,QAAO,EAAI;AACzB,YAAMsC,IAAO,KAAK,IAAI,MAAMnF,EAAS,IAAIU,CAAE,GAAG,QAAQ,CAAC,GACjD8B,IAAIK,EAAG,eACPZ,IAAIM,EAAoBC,CAAC,GACzB4C,IAAI,EAAE,GAAGnD,EAAE,IAAIkD,GAAM,GAAGlD,EAAE,IAAIkD,GAAM,GAAGlD,EAAE,IAAIkD,EAAI;AACvD,MAAAtC,EAAG,WAAWuC,GAAG,EAAI;AAAA,IACvB;AACF;AAEA,SAASC,EAAKH,GAAI;AAChB,EAAArF,EAAM,WAAWqF,GACjBD,EAAsB,GACtBpF,EAAM,KAAI,GACVU,KAAa2E,IAAK;AAElB,QAAMI,IAAc,CAAA;AACpB,aAAW,CAAC5E,GAAImC,CAAE,KAAK9C,EAAO,QAAO,GAAI;AACvC,UAAMwF,IAAI1C,EAAG,eACPuB,IAAIvB,EAAG;AACb,IAAAyC,EAAY5E,CAAE,IAAI,EAAE,GAAG,CAAC6E,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC,GAAG,GAAG,CAACnB,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC;EAChE;AACA,cAAY,EAAE,MAAM,SAAS,OAAO,EAAE,QAAQ7D,GAAW,QAAQ+E,EAAW,EAAE,CAAE;AAClF;AAGA,SAASE,EAAQC,GAAQhD,GAAKiD,IAAS,KAAK;AAC1C,QAAMC,IAAIzE,EAAGuE,CAAM,GACbG,IAAI1E,EAAGuB,CAAG,GACVoD,IAAM,IAAIjG,EAAO,IAAI+F,GAAGC,CAAC,GAEzBE,IAAMjG,EAAM,QAAQgG,GAAKH,GAAQ,EAAI;AAC3C,MAAI,CAACI,EAAK,QAAO,EAAE,MAAM,CAAA,EAAE;AAE3B,QAAMC,IAAMD,EAAI,KACVE,IAAQH,EAAI,QAAQE,CAAG,GACvBE,IAASH,EAAI;AAEnB,MAAII,IAAa;AACjB,aAAW,CAACnD,GAAKE,CAAG,KAAKhD,EAAU,QAAO;AACxC,QAAIgD,EAAI,WAAW6C,EAAI,SAAS,QAAQ;AACtC,MAAAI,IAAanD;AACb;AAAA,IACF;AAEF,MAAIM,IAAS;AACb,QAAM8C,IAAWL,EAAI,SAAS,OAAM,GAAI;AACxC,MAAIK,KAAY;AACd,eAAW,CAACC,GAAKvD,CAAE,KAAK9C,EAAO,QAAO;AACpC,UAAI8C,EAAG,WAAWsD,GAAU;AAAE,QAAA9C,IAAS+C;AAAK;AAAA,MAAO;AAAA;AAGvD,SAAO;AAAA,IACL,MAAM,CAAC;AAAA,MACL,KAAAL;AAAA,MACA,OAAO,CAACC,EAAM,GAAGA,EAAM,GAAGA,EAAM,CAAC;AAAA,MACjC,QAAQ,CAACC,EAAO,GAAGA,EAAO,GAAGA,EAAO,CAAC;AAAA,MACrC,YAAAC;AAAA,MACA,QAAA7C;AAAA,IACN,CAAK;AAAA,EACL;AACA;AAGA,eAAegD,EAAUC,GAAG;AAC1B,QAAMC,IAAMD,EAAE,QAAQ,IAChB,EAAE,IAAA5F,GAAI,MAAA8F,GAAM,QAAAC,GAAQ,SAAAC,EAAO,IAAKH,GAChCI,IAAW,OAAOF,IAAW,MAAeA,IAAU,OAAOC,IAAY,MAAcA,IAAUhG,GACjGkG,IAAO,CAAC7E,MAAQtB,EAAIkG,GAAS5E,CAAG,GAChC8E,IAAQ,CAAC7E,MAAQpB,EAAK+F,GAAS3E,CAAG;AACxC,MAAI;AACF,YAAQwE,GAAI;AAAA,MACV,KAAK,QAAQ;AACX,QAAAhG,IAAU,OAAO+F,EAAI,WAAY,WAAWA,EAAI,UAAU/F;AAC1D,cAAMyB,IAAIsE,EAAI,WAAW;AAEzB,SADctE,EAAE,QAAQ,UAAU,YAAW,MAChC,eACXG,EAAqBH,EAAE,gBAAgB,CAAC,GAAG,GAAG,CAAC,GAAG,OAAOA,EAAE,aAAc,WAAWA,EAAE,YAAY,IAAI,IAEtGC,EAAiBD,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,GAE5C,MAAMP,EAAY,GAClBkF,EAAK,EAAE,IAAI,GAAI,CAAE;AACjB;AAAA,MACF;AAAA,MAEA,KAAK,aAAa;AAUhB,YAASE,IAAT,SAAenD,GAAG;AAAE,iBAAO,OAAOA,KAAM,YAAY,SAASA,CAAC;AAAA,QAAG;AATjE,cAAMjC,EAAY;AAClB,cAAM2B,IAASkD,EAAI,IACbtF,IAAIsF,EAAI,QAAQ,IAChBQ,KAAW9F,EAAE,QAAQ,WAAW,YAAW,GAC3CkE,IAAO,OAAOlE,EAAE,QAAS,WAAWA,EAAE,OAAO,GAC7CuB,IAAItB,EAAGD,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GACvB+F,IAAI7F,EAAGF,EAAE,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AAUhC,aANI,CAAC6F,EAAMtE,EAAE,CAAC,KAAK,CAACsE,EAAMtE,EAAE,CAAC,KAAK,CAACsE,EAAMtE,EAAE,CAAC,OAC1C,YAAY,EAAE,MAAM,SAAS,KAAK,2DAA2D,QAAAa,GAAQ,GAAAb,EAAC,CAAE,GACxGA,EAAE,IAAIsE,EAAMtE,EAAE,CAAC,IAAIA,EAAE,IAAI,GACzBA,EAAE,IAAIsE,EAAMtE,EAAE,CAAC,IAAIA,EAAE,IAAI,GACzBA,EAAE,IAAIsE,EAAMtE,EAAE,CAAC,IAAIA,EAAE,IAAI,IAEvB,CAAC,CAACwE,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC,EAAE,MAAMF,CAAK;AACnC,sBAAY,EAAE,MAAM,SAAS,KAAK,6DAA6D,QAAAzD,GAAQ,GAAA2D,EAAC,CAAE,GAC1GA,EAAE,IAAI,GAAGA,EAAE,IAAI,GAAGA,EAAE,IAAI,GAAGA,EAAE,IAAI;AAAA,aAC5B;AAEL,gBAAMvF,IAAI,KAAK,MAAMuF,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC,KAAK;AAC5C,UAAAA,EAAE,KAAKvF,GAAGuF,EAAE,KAAKvF,GAAGuF,EAAE,KAAKvF,GAAGuF,EAAE,KAAKvF;AAAA,QACvC;AAEA,YAAIkB;AACJ,QAAIoE,MAAY,UAASpE,IAAO/C,EAAO,cAAc,UAC5CmH,MAAY,cAAapE,IAAO/C,EAAO,cAAc,2BACzD+C,IAAO/C,EAAO,cAAc,QAAO,EAAG,kBAAkBuF,CAAI;AAGjE,YAAI;AACF,UAAAxC,EAAK,eAAeH,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC;AAAA,QACnC,SAASR,GAAK;AACZ,4BAAY,EAAE,MAAM,SAAS,KAAK,8BAA8B,OAAQA,MAAQA,EAAI,WAAW,OAAOA,CAAG,MAAO,OAAOA,CAAG,GAAG,QAAAqB,GAAQ,GAAAb,EAAC,CAAE,GAClIR;AAAA,QACR;AACA,YAAI;AACF,UAAAW,EAAK,YAAYqE,CAAC;AAAA,QACpB,SAAShF,GAAK;AACZ,4BAAY,EAAE,MAAM,SAAS,KAAK,2BAA2B,OAAQA,MAAQA,EAAI,WAAW,OAAOA,CAAG,MAAO,OAAOA,CAAG,GAAG,QAAAqB,GAAQ,GAAA2D,EAAC,CAAE,GAC/HhF;AAAA,QACR;AAEA,oBAAY,EAAE,MAAM,SAAS,KAAK,4BAA4B,QAAAqB,GAAQ,SAAA0D,GAAS,MAAA5B,GAAM,GAAA3C,GAAG,GAAAwE,EAAC,CAAE,GAC3FtE,EAAWC,GAAMU,GAAQ,EAAE,MAAM0D,GAAS,MAAA5B,GAAM,GAAGlE,EAAE,GAAG,GAAGA,EAAE,EAAC,CAAE,GAChE2F,EAAK,EAAE,IAAI,GAAI,CAAE;AACjB;AAAA,MACF;AAAA,MAEA,KAAK,gBAAgB;AACnB,cAAMlF,EAAY,GAClBoB,EAAeyD,EAAI,EAAE,GACrBK,EAAK,EAAE,IAAI,GAAI,CAAE;AACjB;AAAA,MACF;AAAA;AAAA;AAAA,MAMA,KAAK;AAAA,MACL,KAAK,yBAAyB;AAC5B,cAAMlF,EAAY;AAClB,cAAM2B,IAASkD,EAAI,QACbU,IAAQV,EAAI,MAAMA,EAAI,YACtBpD,IAAYoD,EAAI,WAChBnD,IAAUmD,EAAI,WAAW,MACzBjD,IAAQiD,EAAI,SAAS;AAC3B,YAAI,CAACpD,GAAW;AAAE,UAAA1C,EAAIC,GAAI,EAAE,IAAI,IAAO,QAAQ,oBAAmB,CAAE;AAAG;AAAA,QAAO;AAC9E,cAAMiE,IAAQxB,aAAqB,eAAeA,IAAY,IAAI,aAAaA,EAAU,UAAUA,CAAS;AAC5G,YAAIyB,IAAMxB;AACV,QAAIwB,KAAO,EAAEA,aAAe,iBAAcA,IAAM,IAAI,YAAYA,EAAI,UAAUA,CAAG,IACjF1B,EAA4B;AAAA,UAC1B,IAAI+D;AAAA,UACJ,WAAWtC;AAAA,UACX,SAASC,KAAO;AAAA,UAChB,QAAAvB;AAAA,UACA,OAAAC;AAAA,QACV,CAAS,GACDsD,EAAK,EAAE,IAAI,IAAM,YAAYK,EAAK,CAAE;AACpC;AAAA,MACF;AAAA,MAEA,KAAK,uBAAuB;AAC1B,cAAMvF,EAAY;AAClB,cAAM2B,IAASkD,EAAI,QACbU,IAAQV,EAAI,MAAMA,EAAI,YACtBrC,IAAQqC,EAAI,OACZjD,IAAQiD,EAAI,SAAS,IACrB5D,IAAOsB,EAAsBC,CAAK;AACxC,QAAIZ,GAAO,KAAGX,EAAK,eAAe,CAACW,EAAM,EAAE,CAAC,GAAG,CAACA,EAAM,EAAE,CAAC,GAAG,CAACA,EAAM,EAAE,CAAC,CAAC,GACnEA,GAAO,KAAGX,EAAK,YAAYxB,EAAGmC,EAAM,CAAC,CAAC;AAC1C,cAAMT,IAAK9C,EAAO,IAAIsD,CAAM;AAC5B,YAAI,CAACR,GAAI;AAAE,UAAApC,EAAIC,GAAI,EAAE,IAAI,IAAO,QAAQ,eAAc,CAAE;AAAG;AAAA,QAAO;AAClE,cAAMuC,IAAMpD,EAAM,eAAe8C,GAAME,CAAE;AACzC,QAAA5C,EAAU,IAAIgH,GAAOhE,CAAG,GACxB/C,EAAe,IAAI+G,GAAO5D,CAAM,GAChCuD,EAAK,EAAE,IAAI,IAAM,YAAYK,EAAK,CAAE;AACpC;AAAA,MACF;AAAA,MAEC,KAAK,kBAAkB;AACtB,cAAMvF,EAAY;AAClB,cAAMuF,IAAQV,EAAI,cAAcA,EAAI;AACpC,QAAAvC,EAAmBiD,CAAK,GACxBL,EAAK,EAAE,IAAI,GAAI,CAAE;AACjB;AAAA,MACF;AAAA,MAEA,KAAK,cAAc;AACjB,cAAMlF,EAAY;AAClB,cAAM2B,IAASkD,EAAI,IACb1D,IAAK9C,EAAO,IAAIsD,CAAM;AAC5B,YAAI,CAACR,GAAI;AAAE,UAAApC,EAAIC,GAAI,EAAE,IAAI,IAAO,QAAQ,eAAc,CAAE;AAAG;AAAA,QAAO;AAElE,cAAMwG,IAAU,CAAC,CAACX,EAAI,SAChBY,IAAQjG,EAAGqF,EAAI,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,GACjCa,IAAOb,EAAI,SAAS;AAE1B,QAAIW,IACEX,EAAI,SAAS,OAAO1D,EAAG,uBAAwB,aACjDA,EAAG,oBAAoBsE,GAAOjG,EAAGqF,EAAI,KAAK,GAAGa,CAAI,IAEjDvE,EAAG,aAAasE,GAAOC,CAAI,IAGzBb,EAAI,SAAS,OAAO1D,EAAG,qBAAsB,aAC/CA,EAAG,kBAAkBsE,GAAOjG,EAAGqF,EAAI,KAAK,GAAGa,CAAI,IAE/CvE,EAAG,WAAWsE,GAAOC,CAAI,GAG7BR,EAAK,EAAE,IAAI,GAAI,CAAE;AACjB;AAAA,MACF;AAAA,MAEA,KAAK,WAAW;AACd,cAAMlF,EAAY;AAClB,cAAM2B,IAASkD,EAAI,IACb1D,IAAK9C,EAAO,IAAIsD,CAAM;AAC5B,YAAI,CAACR,GAAI;AAAE,UAAA+D,EAAK,EAAE,IAAI,IAAO,QAAQ,eAAc,CAAE;AAAG;AAAA,QAAO;AAE/D,cAAMpE,IAAI+D,EAAI,GACRS,IAAIT,EAAI,GACRa,IAAOb,EAAI,SAAS;AAE1B,YAAI;AACF,UAAI,OAAO1D,EAAG,eAAgB,cAAcA,EAAG,YAAW,KAEpDL,KAAGK,EAAG,4BAA4B3B,EAAGsB,CAAC,CAAC,GACvCwE,KAAGnE,EAAG,yBAAyB1B,EAAG6F,CAAC,CAAC,MAGpCxE,KAAK,OAAOK,EAAG,kBAAmB,cAAYA,EAAG,eAAe3B,EAAGsB,CAAC,GAAG,EAAI,GAC3EwE,KAAK,OAAOnE,EAAG,eAAgB,cAAYA,EAAG,YAAY1B,EAAG6F,CAAC,GAAG,EAAI,IAEvEI,KAAQ,OAAOvE,EAAG,UAAW,cAAYA,EAAG,UAChD+D,EAAK,EAAE,IAAI,GAAI,CAAE;AAAA,QACnB,SAAS5E,GAAK;AACZ,UAAA6E,EAAM7E,CAAG;AAAA,QACX;AACA;AAAA,MACF;AAAA,MAEA,KAAK,cAAc;AACjB,cAAMN,EAAY;AAClB,cAAMO,IAAIsE,EAAI,WAAW;AAEzB,SADctE,EAAE,QAAQ,UAAU,YAAW,MAChC,eACXG,EAAqBH,EAAE,gBAAgB,CAAC,GAAG,GAAG,CAAC,GAAG,OAAOA,EAAE,aAAc,WAAWA,EAAE,YAAY,IAAI,IAEtGC,EAAiBD,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,GAE5C2E,EAAK,EAAE,IAAI,GAAI,CAAE;AACjB;AAAA,MACF;AAAA,MAEA,KAAK,QAAQ;AACX,cAAMlF,EAAY;AAClB,cAAMwD,IAAK,OAAOqB,EAAI,MAAO,WAAWzF,EAAMyF,EAAI,IAAI,IAAI,KAAK,IAAI,EAAE,IAAI/F;AACzE,QAAA6E,EAAKH,CAAE,GACP0B,EAAK,EAAE,IAAI,IAAM,QAAQ1B,EAAE,CAAE;AAC7B;AAAA,MACF;AAAA,MAEA,KAAK,WAAW;AACd,cAAMxD,EAAY;AAClB,cAAMf,IAAS6E,EAAQe,EAAI,UAAU,CAAC,GAAG,GAAG,CAAC,GAAGA,EAAI,aAAa,CAAC,GAAG,IAAI,CAAC,GAAG,OAAOA,EAAI,UAAW,WAAWA,EAAI,SAAS,GAAG;AAC9H,QAAAK,EAAKjG,CAAM;AACX;AAAA,MACF;AAAA,MAEA,SAAS;AACP,QAAAiG,EAAK,EAAE,IAAI,IAAO,QAAQ,uBAAsB,CAAE;AAClD;AAAA,MACF;AAAA,IACN;AAAA,EACE,SAAS5E,GAAK;AACZ,IAAA6E,EAAM7E,CAAG;AAAA,EACX;AACF;AAEA,KAAK,iBAAiB,WAAWqE,CAAS;"}