@solid-labs/fab-one-widget 0.1.11 → 1.0.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.
@@ -0,0 +1,4975 @@
1
+ import { jsxs as k, jsx as i, Fragment as Oe } from "react/jsx-runtime";
2
+ import { createContext as no, Component as oo, useCallback as te, useMemo as H, useState as W, memo as ro, useEffect as U, useRef as le, forwardRef as io, createElement as nn } from "react";
3
+ import { useFrame as fn, useThree as un, Canvas as so } from "@react-three/fiber";
4
+ import { Html as Xe, Line as fe, OrbitControls as pn } from "@react-three/drei";
5
+ import * as O from "three";
6
+ import { Plane as ht, Vector3 as C, Box3 as hn, Line3 as gn, Raycaster as lo } from "three";
7
+ import { create as ao } from "zustand";
8
+ import { OBJLoader as mn } from "three/examples/jsm/loaders/OBJLoader.js";
9
+ import { STLLoader as co } from "three/examples/jsm/loaders/STLLoader.js";
10
+ import { MeshBVH as gt } from "three-mesh-bvh";
11
+ let kr, ft, gr, An;
12
+ let __tla = (async () => {
13
+ const fo = {
14
+ showDragDrop: true,
15
+ showStartOver: true,
16
+ showDebug: true,
17
+ showSpacingToggle: true,
18
+ showAmputationModal: true,
19
+ showNavigation: true,
20
+ showToolbar: false,
21
+ showSaveButton: true
22
+ }, uo = {
23
+ showDragDrop: false,
24
+ showStartOver: false,
25
+ showDebug: false,
26
+ showSpacingToggle: false,
27
+ showAmputationModal: false,
28
+ showNavigation: false,
29
+ showToolbar: false,
30
+ showSaveButton: false
31
+ }, po = no(fo), Et = ao((e, r) => ({
32
+ landmarkPoints: [],
33
+ isAligned: false,
34
+ isCut: false,
35
+ addLandmarkPoint: (t) => e((o) => o.landmarkPoints.length >= 3 ? o : {
36
+ landmarkPoints: [
37
+ ...o.landmarkPoints,
38
+ t
39
+ ]
40
+ }),
41
+ removeLandmarkPoint: (t) => e((o) => ({
42
+ landmarkPoints: o.landmarkPoints.filter((l, s) => s !== t)
43
+ })),
44
+ clearLandmarkPoints: () => e({
45
+ landmarkPoints: [],
46
+ isAligned: false,
47
+ isCut: false
48
+ }),
49
+ updateLandmarkPositions: (t) => e((o) => ({
50
+ landmarkPoints: o.landmarkPoints.map((l, s) => ({
51
+ ...l,
52
+ position: t[s] ?? l.position
53
+ }))
54
+ })),
55
+ setAligned: (t) => e({
56
+ isAligned: t
57
+ }),
58
+ setCut: (t) => e({
59
+ isCut: t
60
+ }),
61
+ isSelectionComplete: () => r().landmarkPoints.length === 3,
62
+ reset: () => e({
63
+ landmarkPoints: [],
64
+ isAligned: false,
65
+ isCut: false
66
+ })
67
+ })), ho = 0.45, mt = 3, Bt = 1e-3, ut = 25.4, go = [
68
+ 0.25,
69
+ -0.25,
70
+ 0.5,
71
+ -0.5
72
+ ];
73
+ function mo(e) {
74
+ var _a;
75
+ const r = e.match(/^v\s+\S+\s+\S+\s+\S+(.*)$/m);
76
+ if (!r || !((_a = r[1]) == null ? void 0 : _a.trim().includes(" "))) return null;
77
+ const t = e.split(`
78
+ `), o = [], l = [];
79
+ let s = false;
80
+ for (const c of t) if (c.startsWith("v ")) {
81
+ const a = c.trim().split(/\s+/);
82
+ if (a.length >= 7) {
83
+ o.push(parseFloat(a[1]), parseFloat(a[2]), parseFloat(a[3]));
84
+ let n = parseFloat(a[4]), m = parseFloat(a[5]), d = parseFloat(a[6]);
85
+ (n > 1 || m > 1 || d > 1) && (n /= 255, m /= 255, d /= 255), l.push(n, m, d), s = true;
86
+ } else a.length >= 4 && (o.push(parseFloat(a[1]), parseFloat(a[2]), parseFloat(a[3])), l.push(0, 0, 0));
87
+ }
88
+ return s ? {
89
+ positions: new Float32Array(o),
90
+ colors: new Float32Array(l)
91
+ } : null;
92
+ }
93
+ function xo(e, r, t, o) {
94
+ const l = e.getAttribute("position"), s = l.count, c = new Float32Array(s * 3), a = r.length / 3;
95
+ let n = 1 / 0, m = 1 / 0, d = 1 / 0, f = -1 / 0, u = -1 / 0, x = -1 / 0;
96
+ for (let _ = 0; _ < a; _++) {
97
+ const E = r[_ * 3] * o, V = r[_ * 3 + 1] * o, N = r[_ * 3 + 2] * o;
98
+ E < n && (n = E), E > f && (f = E), V < m && (m = V), V > u && (u = V), N < d && (d = N), N > x && (x = N);
99
+ }
100
+ const S = (n + f) * 0.5, p = (m + u) * 0.5, g = (d + x) * 0.5, b = f - n + 1e-6, A = u - m + 1e-6, L = x - d + 1e-6, z = b * 0.5, P = A * 0.5, y = L * 0.5, M = Math.min(128, Math.max(16, Math.round(Math.cbrt(a)))), h = b / M, v = A / M, F = L / M, I = /* @__PURE__ */ new Map();
101
+ for (let _ = 0; _ < a; _++) {
102
+ const E = r[_ * 3] * o - S, V = r[_ * 3 + 1] * o - p, N = r[_ * 3 + 2] * o - g, J = Math.min(M - 1, Math.max(0, Math.floor((E + z) / h))), ye = Math.min(M - 1, Math.max(0, Math.floor((V + P) / v))), ae = Math.min(M - 1, Math.max(0, Math.floor((N + y) / F))), ue = J * M * M + ye * M + ae;
103
+ let ie = I.get(ue);
104
+ ie || (ie = [], I.set(ue, ie)), ie.push(_);
105
+ }
106
+ for (let _ = 0; _ < s; _++) {
107
+ const E = l.getX(_), V = l.getY(_), N = l.getZ(_), J = Math.min(M - 1, Math.max(0, Math.floor((E + z) / h))), ye = Math.min(M - 1, Math.max(0, Math.floor((V + P) / v))), ae = Math.min(M - 1, Math.max(0, Math.floor((N + y) / F)));
108
+ let ue = 1 / 0, ie = 0;
109
+ for (let Q = 0; Q <= M && ue > 0; Q++) {
110
+ for (let Y = -Q; Y <= Q; Y++) for (let he = -Q; he <= Q; he++) for (let Z = -Q; Z <= Q; Z++) {
111
+ if (Q > 0 && Math.abs(Y) < Q && Math.abs(he) < Q && Math.abs(Z) < Q) continue;
112
+ const ge = J + Y, me = ye + he, pe = ae + Z;
113
+ if (ge < 0 || ge >= M || me < 0 || me >= M || pe < 0 || pe >= M) continue;
114
+ const $ = I.get(ge * M * M + me * M + pe);
115
+ if ($) for (const ne of $) {
116
+ const xe = r[ne * 3] * o - S, Me = r[ne * 3 + 1] * o - p, we = r[ne * 3 + 2] * o - g, re = (E - xe) ** 2 + (V - Me) ** 2 + (N - we) ** 2;
117
+ re < ue && (ue = re, ie = ne);
118
+ }
119
+ }
120
+ if (ue < 1 / 0) break;
121
+ }
122
+ c[_ * 3] = t[ie * 3], c[_ * 3 + 1] = t[ie * 3 + 1], c[_ * 3 + 2] = t[ie * 3 + 2];
123
+ }
124
+ e.setAttribute("color", new O.Float32BufferAttribute(c, 3));
125
+ }
126
+ const on = {
127
+ debug: 0,
128
+ info: 1,
129
+ warn: 2,
130
+ error: 3
131
+ };
132
+ let xn = "warn", bn = null;
133
+ const de = {
134
+ setLevel(e) {
135
+ xn = e;
136
+ },
137
+ setHandler(e) {
138
+ bn = e;
139
+ },
140
+ debug(e, r, t) {
141
+ ct("debug", e, r, t);
142
+ },
143
+ info(e, r, t) {
144
+ ct("info", e, r, t);
145
+ },
146
+ warn(e, r, t) {
147
+ ct("warn", e, r, t);
148
+ },
149
+ error(e, r, t) {
150
+ ct("error", e, r, t);
151
+ }
152
+ };
153
+ function ct(e, r, t, o) {
154
+ if (on[e] < on[xn]) return;
155
+ const l = `[${r}]`, s = o !== void 0 ? [
156
+ l,
157
+ t,
158
+ o
159
+ ] : [
160
+ l,
161
+ t
162
+ ];
163
+ switch (e) {
164
+ case "debug":
165
+ console.debug(...s);
166
+ break;
167
+ case "info":
168
+ console.log(...s);
169
+ break;
170
+ case "warn":
171
+ console.warn(...s);
172
+ break;
173
+ case "error":
174
+ console.error(...s);
175
+ break;
176
+ }
177
+ bn == null ? void 0 : bn(e, r, t, o);
178
+ }
179
+ function pt(e) {
180
+ const r = e.getAttribute("position"), t = new Float32Array(r.array), o = e.getIndex();
181
+ if (o) return {
182
+ positions: t,
183
+ indices: new Uint32Array(o.array)
184
+ };
185
+ const l = t.length / 3, s = new Uint32Array(l);
186
+ for (let c = 0; c < l; c++) s[c] = c;
187
+ return {
188
+ positions: t,
189
+ indices: s
190
+ };
191
+ }
192
+ function yn(e, r) {
193
+ const t = new O.BufferGeometry();
194
+ return t.setAttribute("position", new O.Float32BufferAttribute(e, 3)), t.setIndex(new O.BufferAttribute(r, 1)), t.computeVertexNormals(), t;
195
+ }
196
+ async function bo(e, r, t) {
197
+ try {
198
+ const o = mo(e);
199
+ t == null ? void 0 : t("Parsing mesh...");
200
+ const s = new mn().parse(e);
201
+ let c = null;
202
+ if (s.traverse((b) => {
203
+ b.isMesh && !c && (c = b.geometry);
204
+ }), !c) return null;
205
+ const { positions: a, indices: n } = pt(c);
206
+ if (a.length < 9 || n.length < 3) return de.warn("wasm", `Mesh too small: positions=${a.length} indices=${n.length}`), null;
207
+ for (let b = 0; b < Math.min(a.length, 300); b++) if (!isFinite(a[b])) return de.error("wasm", `Invalid position data: NaN/Infinity at index ${b}`), null;
208
+ const m = a.length / 3;
209
+ for (let b = 0; b < Math.min(n.length, 300); b++) if (n[b] >= m) return de.error("wasm", `Out-of-bounds index: ${n[b]} >= ${m}`), null;
210
+ t == null ? void 0 : t("Processing mesh (WASM)...");
211
+ const d = r.preprocess_mesh(a, n, 10, 1e-4, 500), f = d.positions(), u = d.indices(), x = d.unit_converted(), S = d.detected_unit(), p = d.log();
212
+ if (de.debug("wasm", "preprocess result", p), f.length === 0) return null;
213
+ t == null ? void 0 : t("Building geometry...");
214
+ const g = yn(f, u);
215
+ if (o) {
216
+ const b = x ? 1e3 : 1;
217
+ xo(g, o.positions, o.colors, b);
218
+ }
219
+ return {
220
+ geometry: g,
221
+ wasScaled: x,
222
+ unitConverted: x,
223
+ detectedUnit: S
224
+ };
225
+ } catch (o) {
226
+ return de.error("wasm", "Processing failed", o), null;
227
+ }
228
+ }
229
+ function yo(e) {
230
+ const t = new mn().parse(e);
231
+ let o = null;
232
+ return t.traverse((l) => {
233
+ l.isMesh && !o && (o = l.geometry);
234
+ }), o;
235
+ }
236
+ async function Rt(e) {
237
+ const r = await e.arrayBuffer(), l = new co().parse(r).getAttribute("position");
238
+ if (!l || l.count === 0) throw new Error("Empty STL geometry");
239
+ const s = [];
240
+ for (let c = 0; c < l.count; c++) s.push(`v ${l.getX(c)} ${l.getY(c)} ${l.getZ(c)}`);
241
+ for (let c = 0; c < l.count; c += 3) s.push(`f ${c + 1} ${c + 2} ${c + 3}`);
242
+ return s.join(`
243
+ `);
244
+ }
245
+ function wo(e, r) {
246
+ const t = 1 / r;
247
+ return `${Math.round(e.x * t)}_${Math.round(e.y * t)}_${Math.round(e.z * t)}`;
248
+ }
249
+ function So(e, r) {
250
+ if (!e.length) return [];
251
+ const t = [];
252
+ for (const o of e) (t.length === 0 || t[t.length - 1].distanceTo(o) > r) && t.push(o.clone());
253
+ return t.length > 2 && t[0].distanceTo(t[t.length - 1]) > r && t.push(t[0].clone()), t;
254
+ }
255
+ function Ke(e) {
256
+ let r = 0;
257
+ for (let t = 0; t < e.length - 1; t++) r += e[t].distanceTo(e[t + 1]);
258
+ return r;
259
+ }
260
+ function wn(e, r = 1e-3, t = false) {
261
+ if (!e.length) return [];
262
+ const o = /* @__PURE__ */ new Map(), l = (f) => {
263
+ const u = wo(f, r);
264
+ let x = o.get(u);
265
+ return x || (x = f.clone(), o.set(u, x)), x;
266
+ }, s = e.map((f) => ({
267
+ a: l(f.a),
268
+ b: l(f.b)
269
+ })), c = [];
270
+ for (; s.length; ) {
271
+ const f = s.pop(), u = [
272
+ f.a,
273
+ f.b
274
+ ];
275
+ let x = true;
276
+ for (; x; ) {
277
+ x = false;
278
+ for (let p = s.length - 1; p >= 0; p--) {
279
+ const { a: g, b } = s[p];
280
+ if (g.equals(u[u.length - 1])) u.push(b);
281
+ else if (b.equals(u[u.length - 1])) u.push(g);
282
+ else if (g.equals(u[0])) u.unshift(b);
283
+ else if (b.equals(u[0])) u.unshift(g);
284
+ else continue;
285
+ s.splice(p, 1), x = true;
286
+ }
287
+ }
288
+ const S = So(u, r);
289
+ S.length > 1 && c.push(S);
290
+ }
291
+ if (!c.length) return [];
292
+ if (t) {
293
+ c.sort((x, S) => Ke(S) - Ke(x));
294
+ const f = Ke(c[0]), u = c.filter((x) => Ke(x) >= f * 0.3);
295
+ return u[u.length - 1] ?? c[0];
296
+ }
297
+ const a = c.filter((f) => f.length >= 3 && f[0].distanceTo(f[f.length - 1]) < r * 10), n = a.length > 0 ? a : c;
298
+ if (n.length === 1) return n[0];
299
+ let m = n[0], d = 1 / 0;
300
+ for (const f of n) {
301
+ let u = 0, x = 0;
302
+ for (const p of f) u += p.x, x += p.z;
303
+ u /= f.length, x /= f.length;
304
+ const S = Math.sqrt(u * u + x * x);
305
+ S < d && (d = S, m = f);
306
+ }
307
+ return m;
308
+ }
309
+ function rn(e, r, t, o = false) {
310
+ const l = new ht(new C(0, 1, 0), -t), s = [], c = new hn();
311
+ c.setFromBufferAttribute(r.getAttribute("position"));
312
+ const a = {
313
+ linePoints: [],
314
+ lineLength: 0,
315
+ rightmostPoint: new C(0, t, 0)
316
+ };
317
+ if (!l.intersectsBox(c)) return a;
318
+ const n = new gn(), m = new C();
319
+ e.shapecast({
320
+ intersectsBounds: (p) => l.intersectsBox(p),
321
+ intersectsTriangle: (p) => {
322
+ const g = [];
323
+ n.set(p.a, p.b), l.intersectLine(n, m) && g.push(m.clone()), n.set(p.b, p.c), l.intersectLine(n, m) && g.push(m.clone()), n.set(p.c, p.a), l.intersectLine(n, m) && g.push(m.clone()), g.length === 2 && s.push({
324
+ a: g[0],
325
+ b: g[1]
326
+ });
327
+ }
328
+ });
329
+ const d = wn(s, Bt, o);
330
+ if (d.length < 2) return a;
331
+ const f = Ke(d);
332
+ let u = -1 / 0, x = new C(0, t, 0);
333
+ for (const p of d) p.x > u && (u = p.x, x = p.clone());
334
+ const S = d.length > 2 && d[0].distanceTo(d[d.length - 1]) < Bt * 10;
335
+ return {
336
+ linePoints: d,
337
+ lineLength: f,
338
+ rightmostPoint: x,
339
+ isClosed: S
340
+ };
341
+ }
342
+ function Ye(e, r, t, o = false) {
343
+ const l = rn(e, r, t, o);
344
+ if (l.isClosed && l.linePoints.length >= 3) return l;
345
+ de.debug("slice", `y=${t.toFixed(2)} failed (pts=${l.linePoints.length}, closed=${l.isClosed}), retrying...`);
346
+ let s = l;
347
+ for (const c of go) {
348
+ const a = rn(e, r, t + c, o);
349
+ if (a.isClosed && a.linePoints.length >= 3) return de.debug("slice", `y=${t.toFixed(2)} recovered with offset ${c > 0 ? "+" : ""}${c}mm (pts=${a.linePoints.length}, len=${a.lineLength.toFixed(1)}mm)`), a;
350
+ a.linePoints.length > s.linePoints.length && (s = a);
351
+ }
352
+ return de.warn("slice", `y=${t.toFixed(2)} all retries exhausted (pts=${s.linePoints.length}, closed=${s.isClosed})`), s;
353
+ }
354
+ function vo(e, r, t, o) {
355
+ const l = new ht().setFromNormalAndCoplanarPoint(o.clone().normalize(), t), s = new hn();
356
+ if (s.setFromBufferAttribute(r.getAttribute("position")), !l.intersectsBox(s)) return 0;
357
+ const c = [], a = new gn(), n = new C();
358
+ e.shapecast({
359
+ intersectsBounds: (d) => l.intersectsBox(d),
360
+ intersectsTriangle: (d) => {
361
+ const f = [];
362
+ a.set(d.a, d.b), l.intersectLine(a, n) && f.push(n.clone()), a.set(d.b, d.c), l.intersectLine(a, n) && f.push(n.clone()), a.set(d.c, d.a), l.intersectLine(a, n) && f.push(n.clone()), f.length === 2 && c.push({
363
+ a: f[0],
364
+ b: f[1]
365
+ });
366
+ }
367
+ });
368
+ const m = wn(c, Bt);
369
+ return Ke(m);
370
+ }
371
+ function Sn(e) {
372
+ return new gt(e, {
373
+ maxLeafTris: mt
374
+ });
375
+ }
376
+ function Co(e, r, t, o) {
377
+ const l = e.getIndex(), s = l ? l.count / 3 : 0;
378
+ if (s < 10) return {
379
+ valid: false,
380
+ reason: `Geometry is empty or degenerate (${s} faces)`
381
+ };
382
+ const c = r - t;
383
+ if (c < 4) return {
384
+ valid: false,
385
+ reason: `Height too small (${c.toFixed(1)}mm < 4mm)`
386
+ };
387
+ if (c > 1e3) return {
388
+ valid: false,
389
+ reason: `Height too large (${c.toFixed(1)}mm > 1000mm)`
390
+ };
391
+ const a = new gt(e, {
392
+ maxLeafTris: mt
393
+ }), n = Ye(a, e, r);
394
+ if (n.lineLength === 0) return {
395
+ valid: false,
396
+ reason: "No circumference at green point \u2014 mesh may be empty at that height"
397
+ };
398
+ const m = r - o;
399
+ if (m <= t) return {
400
+ valid: true,
401
+ reason: ""
402
+ };
403
+ const d = Ye(a, e, m);
404
+ if (n.lineLength > 0 && d.lineLength > 0) {
405
+ const u = n.lineLength / d.lineLength;
406
+ if (u < 0.5) return {
407
+ valid: false,
408
+ reason: `First circumference is too small relative to second (ratio ${u.toFixed(2)} < 0.5) \u2014 possible trimmed angle`
409
+ };
410
+ }
411
+ const f = r - o * 2;
412
+ if (f > t) {
413
+ const u = Ye(a, e, f);
414
+ if (d.lineLength > 0 && u.lineLength > 0) {
415
+ const x = d.lineLength / u.lineLength;
416
+ if (x < 0.5) return {
417
+ valid: false,
418
+ reason: `Second circumference is too small relative to third (ratio ${x.toFixed(2)} < 0.5) \u2014 possible trimmed angle`
419
+ };
420
+ }
421
+ }
422
+ return {
423
+ valid: true,
424
+ reason: ""
425
+ };
426
+ }
427
+ const Pe = "pipeline";
428
+ function Mo(e, r, t, o) {
429
+ var _a, _b, _c, _d;
430
+ const l = e.geometry.clone(), s = r.map((a) => ({
431
+ ...a
432
+ })), c = o.wasmModule;
433
+ try {
434
+ let a = e.geometry, n = s.map(($) => new C($.position.x, $.position.y, $.position.z));
435
+ const m = n[0], d = n[1];
436
+ if (!c) {
437
+ o.onStatus("Aligning mesh (JS fallback)..."), de.warn(Pe, "WASM not available, using JS fallback alignment");
438
+ const $ = new C(0, 1, 0), ne = new C().subVectors(d, m).normalize(), xe = ne.dot($), Me = new C().crossVectors(ne, $);
439
+ if (Me.length() > 1e-4) {
440
+ Me.normalize();
441
+ const X = new O.Quaternion().setFromAxisAngle(Me, Math.acos(Math.min(1, Math.max(-1, xe))));
442
+ a.applyMatrix4(new O.Matrix4().makeRotationFromQuaternion(X)), n = n.map((Le) => Le.clone().applyQuaternion(X));
443
+ }
444
+ if (n[0].y > n[1].y) {
445
+ const X = new O.Quaternion().setFromAxisAngle(new C(1, 0, 0), Math.PI);
446
+ a.applyMatrix4(new O.Matrix4().makeRotationFromQuaternion(X)), n = n.map((Le) => Le.clone().applyQuaternion(X));
447
+ }
448
+ const we = n[0].clone();
449
+ a.translate(-we.x, -we.y, -we.z), n = n.map((X) => new C(X.x - we.x, X.y - we.y, X.z - we.z)), a.computeVertexNormals(), a.computeBoundingBox();
450
+ const re = new C(n[0].x, n[0].y, n[0].z);
451
+ n.push(re), o.addLandmarkPoint({
452
+ faceIndex: -1,
453
+ vertexIndices: [
454
+ 0,
455
+ 1,
456
+ 2
457
+ ],
458
+ position: {
459
+ x: re.x,
460
+ y: re.y,
461
+ z: re.z
462
+ },
463
+ barycentricCoords: {
464
+ u: 0.33,
465
+ v: 0.33,
466
+ w: 0.34
467
+ }
468
+ }), o.updateLandmarkPositions(n.map((X) => ({
469
+ x: X.x,
470
+ y: X.y,
471
+ z: X.z
472
+ }))), o.setAligned(true), o.setCut(true), o.setAdjustedStartY(null), o.setAdjustedEndY(null), o.setOriginalEndY(n[1].y + 2 * ut);
473
+ const j = new C();
474
+ a.computeBoundingBox(), a.boundingBox.getSize(j), o.setModelSize(Math.max(j.x, j.y, j.z)), l.dispose();
475
+ return;
476
+ }
477
+ const { positions: f, indices: u } = pt(a), x = new Float32Array([
478
+ m.x,
479
+ m.y,
480
+ m.z
481
+ ]), S = new Float32Array([
482
+ d.x,
483
+ d.y,
484
+ d.z
485
+ ]);
486
+ o.onStatus("Detecting shell type...");
487
+ const p = c.detect_shell(f, u, S, 40), g = p.is_double_shell(), b = p.surface_normal();
488
+ de.info(Pe, `Shell: ${g ? "DOUBLE" : "SINGLE"}`, p.details()), (_a = o.setDoubleShell) == null ? void 0 : _a.call(o, g), o.onStatus("Finding cross-section plane...");
489
+ const A = new Float32Array([
490
+ b[0],
491
+ b[1],
492
+ b[2]
493
+ ]), L = c.find_min_cross_section(f, u, S, A, 10), z = L.plane_normal();
494
+ de.info(Pe, "Cross-section found", L.details()), o.onStatus("Aligning mesh...");
495
+ const P = new Float32Array([
496
+ z[0],
497
+ z[1],
498
+ z[2]
499
+ ]), y = c.align_to_origin(f, x, S, P);
500
+ let M = y.positions(), h = y.mpt(), v = y.origin();
501
+ const F = y.transform();
502
+ de.info(Pe, "Alignment complete", y.details());
503
+ const I = [
504
+ F[3],
505
+ F[4],
506
+ F[5],
507
+ F[6],
508
+ F[7],
509
+ F[8],
510
+ F[9],
511
+ F[10],
512
+ F[11]
513
+ ], _ = new Float32Array([
514
+ I[0] * z[0] + I[1] * z[1] + I[2] * z[2],
515
+ I[3] * z[0] + I[4] * z[1] + I[5] * z[2],
516
+ I[6] * z[0] + I[7] * z[1] + I[8] * z[2]
517
+ ]);
518
+ o.onStatus("Generating measurement points...");
519
+ const E = c.subdivide_origin_to_plane(new Float32Array(v), new Float32Array(h), _);
520
+ de.debug(Pe, `Subdivide: ${E.count()} pts, spacing=${E.spacing().toFixed(1)}mm`);
521
+ const V = E.points(), N = E.count(), J = 2, ye = 1, ae = [];
522
+ for (let $ = J; $ < N - ye; $++) ae.push(V[$ * 3 + 1]);
523
+ o.onStatus("Computing cross-sections...");
524
+ let ue = [];
525
+ if (ae.length >= 2) {
526
+ const ne = (g ? c.batch_cross_sections_y_inner.bind(c) : c.batch_cross_sections_y.bind(c))(M, u, new Float32Array(ae), 10);
527
+ de.debug(Pe, "Batch (subdivision)", ne.details());
528
+ const xe = ne.all_loop_points(), Me = ne.offsets(), we = ne.circumferences();
529
+ for (let re = 0; re < Me.length - 1; re++) {
530
+ const j = Me[re], X = Me[re + 1];
531
+ if (X <= j || we[re] <= 0) continue;
532
+ const Le = (X - j) / 3;
533
+ if (Le < 3) continue;
534
+ let Ie = 0, Ge = 0, se = 0;
535
+ for (let Ae = j; Ae < X; Ae += 3) Ie += xe[Ae], Ge += xe[Ae + 1], se += xe[Ae + 2];
536
+ ue.push(Ie / Le, Ge / Le, se / Le);
537
+ }
538
+ }
539
+ if (ue.length >= 6) {
540
+ o.onStatus("Refining alignment...");
541
+ const $ = c.refine_alignment(new Float32Array(ue), M, new Float32Array(v), new Float32Array(h));
542
+ de.info(Pe, "Refinement complete", $.details()), M = $.positions(), h = $.mpt(), v = $.origin();
543
+ }
544
+ const ie = a.getAttribute("color"), Q = yn(M, u);
545
+ ie && Q.setAttribute("color", ie), a.dispose(), a = Q, e.geometry = a, a.computeVertexNormals(), a.computeBoundingBox(), n[0] = new C(v[0], v[1], v[2]), n[1] = new C(h[0], h[1], h[2]), o.onStatus("Setting blue point...");
546
+ const Y = new C(n[0].x, n[0].y, n[0].z);
547
+ n.push(Y), o.addLandmarkPoint({
548
+ faceIndex: -1,
549
+ vertexIndices: [
550
+ 0,
551
+ 1,
552
+ 2
553
+ ],
554
+ position: {
555
+ x: Y.x,
556
+ y: Y.y,
557
+ z: Y.z
558
+ },
559
+ barycentricCoords: {
560
+ u: 0.33,
561
+ v: 0.33,
562
+ w: 0.34
563
+ }
564
+ }), o.updateLandmarkPositions(n.map(($) => ({
565
+ x: $.x,
566
+ y: $.y,
567
+ z: $.z
568
+ }))), o.setAligned(true);
569
+ const he = a.boundingBox, Z = new C();
570
+ he.getSize(Z), o.setModelSize(Math.max(Z.x, Z.y, Z.z)), o.setCut(true), o.setAdjustedStartY(null), o.setAdjustedEndY(null), o.setOriginalEndY(n[1].y + 2 * ut), o.onStatus("Computing final measurements...");
571
+ {
572
+ const $ = pt(a), ne = n[1].y, xe = n[0].y;
573
+ let Me = 1 / 0, we = -1 / 0;
574
+ const re = $.positions;
575
+ for (let se = 1; se < re.length; se += 3) re[se] < Me && (Me = re[se]), re[se] > we && (we = re[se]);
576
+ const j = 25.4, X = [];
577
+ X.push(ne);
578
+ for (let se = 1; se <= 2; se++) {
579
+ const Ae = ne + se * j;
580
+ Ae < we - 1 && X.push(Ae);
581
+ }
582
+ for (let se = ne - j; se > xe; se -= j) X.push(se);
583
+ X.sort((se, Ae) => se - Ae), de.info(Pe, `Horizontal slices: ${X.length} Y planes, range ${(_b = X[0]) == null ? void 0 : _b.toFixed(1)} \u2192 ${(_c = X[X.length - 1]) == null ? void 0 : _c.toFixed(1)} mm`);
584
+ const Ie = (g ? c.batch_cross_sections_y_inner.bind(c) : c.batch_cross_sections_y.bind(c))($.positions, $.indices, new Float32Array(X), 10);
585
+ de.info(Pe, `Horizontal slices (${g ? "inner" : "outer"}): ${Ie.count()}/${X.length} valid`), de.debug(Pe, "Slice details", Ie.details());
586
+ const Ge = {
587
+ yValues: X,
588
+ circumferences: Array.from(Ie.circumferences()),
589
+ allLoopPoints: new Float32Array(Ie.all_loop_points()),
590
+ offsets: new Uint32Array(Ie.offsets()),
591
+ mptY: ne,
592
+ originY: xe
593
+ };
594
+ (_d = o.setWasmSlices) == null ? void 0 : _d.call(o, Ge);
595
+ }
596
+ o.onStatus("Validating results...");
597
+ const ge = n[1].y, me = n[0].y, pe = Co(a, ge, me, t);
598
+ pe.valid || de.warn(Pe, `Validation: ${pe.reason}`), o.setClippedReferenceGeometry ? (l.computeVertexNormals(), o.setClippedReferenceGeometry(l)) : l.dispose();
599
+ } catch (a) {
600
+ de.error(Pe, "Processing failed", a), o.setError(a instanceof Error ? a.message : "Failed to process mesh."), l.dispose();
601
+ }
602
+ }
603
+ class zo extends oo {
604
+ constructor() {
605
+ super(...arguments), this.state = {
606
+ error: null
607
+ }, this.reset = () => {
608
+ this.setState({
609
+ error: null
610
+ });
611
+ };
612
+ }
613
+ static getDerivedStateFromError(r) {
614
+ return {
615
+ error: r
616
+ };
617
+ }
618
+ componentDidCatch(r, t) {
619
+ console.error("[ErrorBoundary] Caught error:", r, t.componentStack);
620
+ }
621
+ render() {
622
+ return this.state.error ? this.props.fallback ? this.props.fallback(this.state.error, this.reset) : k("div", {
623
+ style: {
624
+ display: "flex",
625
+ flexDirection: "column",
626
+ alignItems: "center",
627
+ justifyContent: "center",
628
+ height: "100%",
629
+ padding: 32,
630
+ textAlign: "center",
631
+ fontFamily: "system-ui, sans-serif"
632
+ },
633
+ children: [
634
+ i("div", {
635
+ style: {
636
+ fontSize: 16,
637
+ fontWeight: 600,
638
+ color: "#dc3545",
639
+ marginBottom: 8
640
+ },
641
+ children: "Something went wrong"
642
+ }),
643
+ i("div", {
644
+ style: {
645
+ fontSize: 13,
646
+ color: "#666",
647
+ maxWidth: 400,
648
+ marginBottom: 16
649
+ },
650
+ children: this.state.error.message
651
+ }),
652
+ i("button", {
653
+ onClick: this.reset,
654
+ style: {
655
+ padding: "8px 20px",
656
+ borderRadius: 4,
657
+ fontSize: 13,
658
+ fontWeight: 500,
659
+ backgroundColor: "rgb(12, 67, 173)",
660
+ border: "none",
661
+ color: "#fff",
662
+ cursor: "pointer"
663
+ },
664
+ children: "Try Again"
665
+ })
666
+ ]
667
+ }) : this.props.children;
668
+ }
669
+ }
670
+ const ko = ({ message: e, onDismiss: r }) => k("div", {
671
+ style: {
672
+ position: "absolute",
673
+ top: 16,
674
+ right: 16,
675
+ padding: "12px 16px",
676
+ backgroundColor: "rgba(220, 53, 69, 0.95)",
677
+ borderRadius: 8,
678
+ color: "#fff",
679
+ fontSize: 14,
680
+ maxWidth: 300,
681
+ zIndex: 100,
682
+ display: "flex",
683
+ alignItems: "flex-start",
684
+ gap: 12
685
+ },
686
+ children: [
687
+ k("div", {
688
+ style: {
689
+ flex: 1
690
+ },
691
+ children: [
692
+ i("div", {
693
+ style: {
694
+ fontWeight: "bold",
695
+ marginBottom: 4
696
+ },
697
+ children: "Error"
698
+ }),
699
+ i("div", {
700
+ style: {
701
+ fontSize: 12,
702
+ opacity: 0.9
703
+ },
704
+ children: e
705
+ })
706
+ ]
707
+ }),
708
+ i("button", {
709
+ onClick: r,
710
+ style: {
711
+ background: "none",
712
+ border: "none",
713
+ color: "#fff",
714
+ cursor: "pointer",
715
+ fontSize: 18,
716
+ padding: 0,
717
+ lineHeight: 1,
718
+ opacity: 0.7
719
+ },
720
+ children: "x"
721
+ })
722
+ ]
723
+ }), sn = ({ message: e }) => k("div", {
724
+ style: {
725
+ position: "absolute",
726
+ top: 0,
727
+ left: 0,
728
+ right: 0,
729
+ bottom: 0,
730
+ backgroundColor: "rgba(0, 0, 0, 0.7)",
731
+ display: "flex",
732
+ flexDirection: "column",
733
+ alignItems: "center",
734
+ justifyContent: "center",
735
+ zIndex: 100
736
+ },
737
+ children: [
738
+ i("div", {
739
+ style: {
740
+ width: 48,
741
+ height: 48,
742
+ border: "4px solid rgba(255, 255, 255, 0.2)",
743
+ borderTopColor: "#4a90d9",
744
+ borderRadius: "50%",
745
+ animation: "spin 1s linear infinite"
746
+ }
747
+ }),
748
+ e && i("div", {
749
+ style: {
750
+ marginTop: 16,
751
+ color: "#fff",
752
+ fontSize: 14
753
+ },
754
+ children: e
755
+ }),
756
+ i("style", {
757
+ children: "@keyframes spin { to { transform: rotate(360deg); } }"
758
+ })
759
+ ]
760
+ });
761
+ function Ao(e, r, t, o) {
762
+ const l = new C().subVectors(t, r), s = new C().subVectors(o, r), c = new C().subVectors(e, r), a = l.dot(l), n = l.dot(s), m = l.dot(c), d = s.dot(s), f = s.dot(c), u = 1 / (a * d - n * n), x = (d * m - n * f) * u, S = (a * f - n * m) * u;
763
+ return {
764
+ u: 1 - x - S,
765
+ v: x,
766
+ w: S
767
+ };
768
+ }
769
+ const Fo = ({ mesh: e, maxPoints: r = 2, meshColor: t = "#c8c8c8", meshOpacity: o = 1, frontFaceOnly: l = false, doubleShellTransparency: s = false }) => {
770
+ const { addLandmarkPoint: c, landmarkPoints: a } = Et(), n = te((x) => {
771
+ if (a.length >= r) return;
772
+ x.stopPropagation();
773
+ const S = x.intersections[0], p = S == null ? void 0 : S.faceIndex;
774
+ if (!S || p == null) return;
775
+ const g = e.geometry, b = g.index;
776
+ let A;
777
+ b ? A = [
778
+ b.getX(p * 3),
779
+ b.getX(p * 3 + 1),
780
+ b.getX(p * 3 + 2)
781
+ ] : A = [
782
+ p * 3,
783
+ p * 3 + 1,
784
+ p * 3 + 2
785
+ ];
786
+ const L = g.getAttribute("position"), z = new C().fromBufferAttribute(L, A[0]), P = new C().fromBufferAttribute(L, A[1]), y = new C().fromBufferAttribute(L, A[2]);
787
+ z.applyMatrix4(e.matrixWorld), P.applyMatrix4(e.matrixWorld), y.applyMatrix4(e.matrixWorld);
788
+ const M = S.point, h = Ao(M, z, P, y), v = {
789
+ faceIndex: p,
790
+ vertexIndices: A,
791
+ position: {
792
+ x: M.x,
793
+ y: M.y,
794
+ z: M.z
795
+ },
796
+ barycentricCoords: h
797
+ };
798
+ c(v);
799
+ }, [
800
+ e,
801
+ c,
802
+ a.length,
803
+ r
804
+ ]), m = H(() => !!e.geometry.getAttribute("color"), [
805
+ e
806
+ ]), d = s ? Math.min(o, 0.65) : o, f = d < 1, u = H(() => new O.MeshStandardMaterial({
807
+ color: m ? "#ffffff" : t,
808
+ side: l ? O.FrontSide : O.DoubleSide,
809
+ roughness: 0.6,
810
+ metalness: 0.1,
811
+ transparent: f,
812
+ opacity: d,
813
+ depthWrite: !s,
814
+ vertexColors: m
815
+ }), [
816
+ t,
817
+ d,
818
+ f,
819
+ m,
820
+ l,
821
+ s
822
+ ]);
823
+ return i("primitive", {
824
+ object: e,
825
+ onClick: n,
826
+ material: u,
827
+ renderOrder: s ? 0 : void 0
828
+ });
829
+ }, Po = ({ point: e, index: r, markerSize: t, color: o, label: l }) => {
830
+ const [s, c] = W(false);
831
+ return k("mesh", {
832
+ position: [
833
+ e.position.x,
834
+ e.position.y,
835
+ e.position.z
836
+ ],
837
+ onPointerOver: () => c(true),
838
+ onPointerOut: () => c(false),
839
+ children: [
840
+ i("sphereGeometry", {
841
+ args: [
842
+ t,
843
+ 16,
844
+ 16
845
+ ]
846
+ }),
847
+ i("meshBasicMaterial", {
848
+ color: o
849
+ }),
850
+ s && i(Xe, {
851
+ center: true,
852
+ style: {
853
+ pointerEvents: "none"
854
+ },
855
+ children: i("div", {
856
+ style: {
857
+ padding: "3px 8px",
858
+ backgroundColor: "rgba(0, 0, 0, 0.75)",
859
+ borderRadius: 4,
860
+ color: "#fff",
861
+ fontSize: 12,
862
+ fontFamily: "system-ui, sans-serif",
863
+ whiteSpace: "nowrap",
864
+ transform: "translateY(-24px)"
865
+ },
866
+ children: l
867
+ })
868
+ })
869
+ ]
870
+ }, r);
871
+ }, Lo = ({ modelSize: e, labels: r }) => {
872
+ const { landmarkPoints: t } = Et(), o = e * 0.02, l = [
873
+ "#44ff44",
874
+ "#ff4444",
875
+ "#4444ff"
876
+ ], c = r ?? [
877
+ "MPT",
878
+ "Origin",
879
+ "Cut Plane"
880
+ ];
881
+ return i(Oe, {
882
+ children: t.map((a, n) => i(Po, {
883
+ point: a,
884
+ index: n,
885
+ markerSize: o,
886
+ color: l[n],
887
+ label: c[n]
888
+ }, n))
889
+ });
890
+ };
891
+ function vn(e) {
892
+ return H(() => e ? new gt(e, {
893
+ maxLeafTris: mt
894
+ }) : null, [
895
+ e
896
+ ]);
897
+ }
898
+ const ln = (e, r) => {
899
+ const t = Math.abs(e - r);
900
+ return t <= 7 ? "#8BC34A" : t <= 20 ? "#FFC107" : "#FF5722";
901
+ }, an = new O.Color("#8BC34A"), cn = new O.Color("#FFC107"), Io = new O.Color("#FF5722"), Do = (e) => {
902
+ if (e <= 7) return an.clone();
903
+ if (e <= 20) {
904
+ const t = (e - 7) / 13;
905
+ return an.clone().lerp(cn, t);
906
+ }
907
+ const r = Math.min((e - 20) / 20, 1);
908
+ return cn.clone().lerp(Io, r);
909
+ }, _o = (e, r) => {
910
+ const t = e.length, o = new Float32Array(t * 2 * 3), l = new Float32Array(t * 2 * 3), s = [];
911
+ for (let n = 0; n < t; n++) {
912
+ const m = e[n], d = r[n], f = m.distanceTo(d), u = Do(f);
913
+ if (o[n * 6] = m.x, o[n * 6 + 1] = m.y, o[n * 6 + 2] = m.z, l[n * 6] = u.r, l[n * 6 + 1] = u.g, l[n * 6 + 2] = u.b, o[n * 6 + 3] = d.x, o[n * 6 + 4] = d.y, o[n * 6 + 5] = d.z, l[n * 6 + 3] = u.r, l[n * 6 + 4] = u.g, l[n * 6 + 5] = u.b, n < t - 1) {
914
+ const x = n * 2, S = x + 1, p = (n + 1) * 2, g = p + 1;
915
+ s.push(x, S, p, S, g, p);
916
+ }
917
+ }
918
+ const c = new O.BufferGeometry();
919
+ c.setAttribute("position", new O.Float32BufferAttribute(o, 3)), c.setAttribute("color", new O.Float32BufferAttribute(l, 3)), c.setIndex(s);
920
+ const a = new O.MeshBasicMaterial({
921
+ vertexColors: true,
922
+ transparent: true,
923
+ opacity: 0.25,
924
+ side: O.DoubleSide,
925
+ depthTest: false,
926
+ depthWrite: false
927
+ });
928
+ return new O.Mesh(c, a);
929
+ }, Ro = ({ bvh: e, geometry: r, yPosition: t, color: o = "#00ff00", labelX: l, onDataChange: s, displayUnit: c = "mm", useInnerSurface: a = false, formValue: n, lineWidth: m = 1.5, wasmLoopPoints: d, wasmCircumference: f }) => {
930
+ const u = H(() => d && f != null ? null : Ye(e, r, t, a), [
931
+ e,
932
+ r,
933
+ t,
934
+ a,
935
+ d,
936
+ f
937
+ ]), x = d ?? (u == null ? void 0 : u.linePoints) ?? [], S = f ?? (u == null ? void 0 : u.lineLength) ?? 0, p = H(() => {
938
+ if (n == null || n === 0 || S <= 0 || x.length < 2) return null;
939
+ const L = n / S, z = x.reduce((y, M) => y + M.x, 0) / x.length, P = x.reduce((y, M) => y + M.z, 0) / x.length;
940
+ return x.map((y) => new C(z + (y.x - z) * L, y.y, P + (y.z - P) * L));
941
+ }, [
942
+ x,
943
+ S,
944
+ n
945
+ ]), g = H(() => !p || x.length < 2 ? null : _o(x, p), [
946
+ x,
947
+ p
948
+ ]);
949
+ U(() => () => {
950
+ g && (g.geometry.dispose(), g.material.dispose());
951
+ }, [
952
+ g
953
+ ]);
954
+ const b = le(null), A = H(() => {
955
+ const L = new O.BufferGeometry();
956
+ L.setAttribute("position", new O.Float32BufferAttribute(new Float32Array(6), 3));
957
+ const z = new O.LineBasicMaterial({
958
+ color: 6710886,
959
+ depthTest: false,
960
+ depthWrite: false,
961
+ transparent: true
962
+ });
963
+ return new O.Line(L, z);
964
+ }, []);
965
+ return U(() => () => {
966
+ A.geometry.dispose(), A.material.dispose();
967
+ }, [
968
+ A
969
+ ]), U(() => {
970
+ S > 0 && (s == null ? void 0 : s({
971
+ yPosition: t,
972
+ originalValue: S,
973
+ modifiedValue: null
974
+ }));
975
+ }, [
976
+ S,
977
+ t,
978
+ s
979
+ ]), fn(({ camera: L }) => {
980
+ if (!b.current || x.length < 2) return;
981
+ const z = new C();
982
+ L.getWorldDirection(z);
983
+ const P = new C(z.x, 0, z.z);
984
+ if (P.lengthSq() < 1e-8) return;
985
+ P.normalize();
986
+ const y = new C().crossVectors(P, new C(0, 1, 0)).normalize();
987
+ let M = -1 / 0, h = x[0];
988
+ for (const _ of x) {
989
+ const E = y.x * _.x + y.z * _.z;
990
+ E > M && (M = E, h = _);
991
+ }
992
+ const v = l * 0.35, F = new C(h.x + y.x * v, t, h.z + y.z * v);
993
+ b.current.position.copy(F);
994
+ const I = A.geometry.getAttribute("position");
995
+ I.setXYZ(0, h.x, h.y, h.z), I.setXYZ(1, F.x, F.y, F.z), I.needsUpdate = true;
996
+ }), x.length < 2 ? null : k("group", {
997
+ renderOrder: 10,
998
+ children: [
999
+ i(fe, {
1000
+ points: x,
1001
+ color: o,
1002
+ lineWidth: m,
1003
+ depthTest: false,
1004
+ depthWrite: false,
1005
+ transparent: true,
1006
+ renderOrder: 10
1007
+ }),
1008
+ g && i("primitive", {
1009
+ object: g,
1010
+ renderOrder: 10
1011
+ }),
1012
+ p && n != null && n !== 0 && i(fe, {
1013
+ points: p,
1014
+ color: ln(S, n),
1015
+ lineWidth: 2.5,
1016
+ dashed: true,
1017
+ dashSize: 2,
1018
+ gapSize: 1.5,
1019
+ depthTest: false,
1020
+ depthWrite: false,
1021
+ transparent: true,
1022
+ opacity: 0.8,
1023
+ renderOrder: 10
1024
+ }),
1025
+ i("primitive", {
1026
+ object: A,
1027
+ renderOrder: 10
1028
+ }),
1029
+ i("group", {
1030
+ ref: b,
1031
+ children: i(Xe, {
1032
+ zIndexRange: [
1033
+ 100,
1034
+ 0
1035
+ ],
1036
+ style: {
1037
+ pointerEvents: "none",
1038
+ transform: "translateY(-50%)"
1039
+ },
1040
+ children: k("div", {
1041
+ style: {
1042
+ display: "flex",
1043
+ alignItems: "stretch",
1044
+ gap: 0,
1045
+ marginLeft: 10,
1046
+ pointerEvents: "none",
1047
+ whiteSpace: "nowrap"
1048
+ },
1049
+ children: [
1050
+ k("div", {
1051
+ style: {
1052
+ display: "flex",
1053
+ alignItems: "center",
1054
+ gap: 4,
1055
+ padding: "5px 10px",
1056
+ backgroundColor: "rgba(0, 0, 0, 0.75)",
1057
+ borderRadius: n != null && n !== 0 ? "4px 0 0 4px" : 4
1058
+ },
1059
+ children: [
1060
+ i("span", {
1061
+ style: {
1062
+ fontSize: 14,
1063
+ color: "#fff",
1064
+ fontFamily: "monospace",
1065
+ minWidth: 52,
1066
+ textAlign: "right"
1067
+ },
1068
+ children: c === "inch" ? (S / 25.4).toFixed(2) : S.toFixed(1)
1069
+ }),
1070
+ i("span", {
1071
+ style: {
1072
+ fontSize: 11,
1073
+ color: "rgba(255,255,255,0.6)",
1074
+ fontFamily: "monospace"
1075
+ },
1076
+ children: c === "inch" ? "in" : "mm"
1077
+ })
1078
+ ]
1079
+ }),
1080
+ n != null && n !== 0 && S > 0 && (() => {
1081
+ const L = S - n, z = L > 0.5 ? "\u25B2" : L < -0.5 ? "\u25BC" : "", P = ln(S, n);
1082
+ return k("div", {
1083
+ style: {
1084
+ display: "flex",
1085
+ alignItems: "center",
1086
+ gap: 5,
1087
+ padding: "5px 10px",
1088
+ backgroundColor: "rgba(0, 0, 0, 0.55)",
1089
+ borderRadius: "0 4px 4px 0",
1090
+ borderLeft: "1px solid rgba(255,255,255,0.12)"
1091
+ },
1092
+ children: [
1093
+ z && i("span", {
1094
+ style: {
1095
+ fontSize: 10,
1096
+ color: P,
1097
+ lineHeight: 1
1098
+ },
1099
+ children: z
1100
+ }),
1101
+ k("span", {
1102
+ style: {
1103
+ fontSize: 13,
1104
+ color: P,
1105
+ fontFamily: "monospace",
1106
+ fontWeight: 600
1107
+ },
1108
+ children: [
1109
+ L > 0 ? "+" : "",
1110
+ c === "inch" ? (L / 25.4).toFixed(2) : L.toFixed(1)
1111
+ ]
1112
+ }),
1113
+ k("span", {
1114
+ style: {
1115
+ fontSize: 11,
1116
+ color: "rgba(255,255,255,0.4)",
1117
+ fontFamily: "monospace"
1118
+ },
1119
+ children: [
1120
+ "from ",
1121
+ c === "inch" ? (n / 25.4).toFixed(2) : n.toFixed(0)
1122
+ ]
1123
+ })
1124
+ ]
1125
+ });
1126
+ })()
1127
+ ]
1128
+ })
1129
+ })
1130
+ })
1131
+ ]
1132
+ });
1133
+ }, Wo = ro(Ro), Bo = ({ mesh: e, startY: r, endY: t, spacing: o, modelSize: l, onMeasurementsChange: s, reverseOrder: c = false, displayUnit: a = "mm", useInnerSurface: n = false, formMeasurements: m, originY: d, wasmSlices: f }) => {
1134
+ const u = le(/* @__PURE__ */ new Map()), x = e.geometry, S = vn(x), p = H(() => {
1135
+ if (f) {
1136
+ let M = [
1137
+ ...f.yValues
1138
+ ];
1139
+ if (o > 25.4 + 0.1) {
1140
+ const h = f.mptY;
1141
+ M = M.filter((v) => {
1142
+ const F = Math.abs(v - h);
1143
+ return F < 0.5 || Math.abs(Math.round(F / o) * o - F) < 0.5;
1144
+ });
1145
+ }
1146
+ return c ? M.sort((h, v) => v - h) : M.sort((h, v) => h - v), M;
1147
+ }
1148
+ const P = [];
1149
+ if (c) for (let y = t; y >= r; y -= o) P.push(y);
1150
+ else for (let y = r; y <= t; y += o) P.push(y);
1151
+ return P;
1152
+ }, [
1153
+ r,
1154
+ t,
1155
+ o,
1156
+ c,
1157
+ f
1158
+ ]), g = H(() => {
1159
+ if (!f) return null;
1160
+ const P = /* @__PURE__ */ new Map(), { allLoopPoints: y, offsets: M, yValues: h } = f;
1161
+ for (let v = 0; v < M.length - 1; v++) {
1162
+ const F = M[v], I = M[v + 1];
1163
+ if (I <= F) continue;
1164
+ const _ = [];
1165
+ for (let E = F; E < I; E += 3) _.push(new C(y[E], y[E + 1], y[E + 2]));
1166
+ _.length >= 3 && P.set(h[v], _);
1167
+ }
1168
+ return P;
1169
+ }, [
1170
+ f
1171
+ ]), b = H(() => {
1172
+ if (!f) return null;
1173
+ const P = /* @__PURE__ */ new Map();
1174
+ for (let y = 0; y < f.yValues.length; y++) P.set(f.yValues[y], f.circumferences[y]);
1175
+ return P;
1176
+ }, [
1177
+ f
1178
+ ]);
1179
+ U(() => {
1180
+ u.current.clear();
1181
+ }, [
1182
+ p
1183
+ ]), U(() => {
1184
+ if (!b || !s) return;
1185
+ const P = p.filter((y) => (b.get(y) ?? 0) > 0).map((y) => ({
1186
+ yPosition: y,
1187
+ originalValue: b.get(y) ?? 0,
1188
+ modifiedValue: null
1189
+ }));
1190
+ s(P);
1191
+ }, [
1192
+ b,
1193
+ p,
1194
+ s
1195
+ ]);
1196
+ const A = [
1197
+ "#5B9BD5"
1198
+ ], L = l * ho, z = te((P) => {
1199
+ if (b) return;
1200
+ u.current.set(P.yPosition, P);
1201
+ const y = Array.from(u.current.values()).sort((M, h) => c ? h.yPosition - M.yPosition : M.yPosition - h.yPosition);
1202
+ s == null ? void 0 : s(y);
1203
+ }, [
1204
+ s,
1205
+ c,
1206
+ b
1207
+ ]);
1208
+ return S ? i(Oe, {
1209
+ children: p.map((P, y) => i(Wo, {
1210
+ bvh: S,
1211
+ geometry: x,
1212
+ yPosition: P,
1213
+ color: d != null && Math.abs(P - d) < o * 0.5 ? "#44ff44" : A[y % A.length],
1214
+ labelX: L,
1215
+ onDataChange: z,
1216
+ displayUnit: a,
1217
+ useInnerSurface: n,
1218
+ formValue: m == null ? void 0 : m[y],
1219
+ lineWidth: d != null && Math.abs(P - d) < o * 0.5 ? 4 : 1.5,
1220
+ wasmLoopPoints: g == null ? void 0 : g.get(P),
1221
+ wasmCircumference: b == null ? void 0 : b.get(P)
1222
+ }, P))
1223
+ }) : null;
1224
+ }, Eo = (e, r) => {
1225
+ const t = Math.abs(e - r);
1226
+ return t <= 7 ? "#4caf50" : t <= 15 ? "#ff9800" : "#f44336";
1227
+ }, To = ({ mesh: e, greenY: r, modelSize: t, displayUnit: o = "mm", bottomY: l, formHeight: s }) => {
1228
+ var _a;
1229
+ const c = e.geometry;
1230
+ c.computeBoundingBox();
1231
+ const a = l ?? ((_a = c.boundingBox) == null ? void 0 : _a.min.y) ?? 0, n = r - a, m = t * 0.4, d = t * 0.03, f = le(null);
1232
+ fn(({ camera: y }) => {
1233
+ if (!f.current) return;
1234
+ const M = new C();
1235
+ y.getWorldDirection(M);
1236
+ const h = new C(M.x, 0, M.z);
1237
+ if (h.lengthSq() < 1e-8) return;
1238
+ h.normalize();
1239
+ const v = new C().crossVectors(new C(0, 1, 0), h).normalize();
1240
+ f.current.position.set(v.x * m, 0, v.z * m);
1241
+ const F = y.position.x - f.current.position.x, I = y.position.z - f.current.position.z;
1242
+ f.current.rotation.y = Math.atan2(F, I);
1243
+ });
1244
+ const u = new C(0, r, 0), x = new C(0, a, 0), S = new C(0, (r + a) / 2, 0), p = new C(-d, r, 0), g = new C(d, r, 0), b = new C(-d, a, 0), A = new C(d, a, 0), L = s != null && s > 0, z = L ? n - s : 0, P = L ? Eo(n, s) : "#fff";
1245
+ return k("group", {
1246
+ ref: f,
1247
+ children: [
1248
+ i(fe, {
1249
+ points: [
1250
+ u,
1251
+ x
1252
+ ],
1253
+ color: "#888888",
1254
+ lineWidth: 1.5
1255
+ }),
1256
+ i(fe, {
1257
+ points: [
1258
+ p,
1259
+ g
1260
+ ],
1261
+ color: "#888888",
1262
+ lineWidth: 1.5
1263
+ }),
1264
+ i(fe, {
1265
+ points: [
1266
+ b,
1267
+ A
1268
+ ],
1269
+ color: "#888888",
1270
+ lineWidth: 1.5
1271
+ }),
1272
+ i("mesh", {
1273
+ position: S,
1274
+ children: i(Xe, {
1275
+ center: true,
1276
+ style: {
1277
+ pointerEvents: "none"
1278
+ },
1279
+ zIndexRange: [
1280
+ 0,
1281
+ 0
1282
+ ],
1283
+ children: k("div", {
1284
+ style: {
1285
+ display: "flex",
1286
+ flexDirection: "column",
1287
+ alignItems: "center",
1288
+ gap: 0,
1289
+ transform: "rotate(-90deg)",
1290
+ transformOrigin: "center center",
1291
+ pointerEvents: "none"
1292
+ },
1293
+ children: [
1294
+ k("div", {
1295
+ style: {
1296
+ padding: "4px 8px",
1297
+ backgroundColor: "rgba(0, 0, 0, 0.75)",
1298
+ borderRadius: L ? "4px 4px 0 0" : 4,
1299
+ color: "#fff",
1300
+ fontSize: 16,
1301
+ fontFamily: "monospace",
1302
+ whiteSpace: "nowrap",
1303
+ pointerEvents: "none"
1304
+ },
1305
+ children: [
1306
+ o === "inch" ? (n / 25.4).toFixed(2) : n.toFixed(1),
1307
+ " ",
1308
+ o === "inch" ? "in" : "mm"
1309
+ ]
1310
+ }),
1311
+ L && k("div", {
1312
+ style: {
1313
+ display: "flex",
1314
+ alignItems: "center",
1315
+ gap: 5,
1316
+ padding: "3px 8px",
1317
+ backgroundColor: "rgba(0, 0, 0, 0.55)",
1318
+ borderRadius: "0 0 4px 4px",
1319
+ borderTop: "1px solid rgba(255,255,255,0.12)",
1320
+ whiteSpace: "nowrap",
1321
+ pointerEvents: "none"
1322
+ },
1323
+ children: [
1324
+ Math.abs(z) > 0.5 && i("span", {
1325
+ style: {
1326
+ fontSize: 10,
1327
+ color: P,
1328
+ lineHeight: 1
1329
+ },
1330
+ children: z > 0.5 ? "\u25B2" : "\u25BC"
1331
+ }),
1332
+ k("span", {
1333
+ style: {
1334
+ fontSize: 13,
1335
+ color: P,
1336
+ fontFamily: "monospace",
1337
+ fontWeight: 600
1338
+ },
1339
+ children: [
1340
+ z > 0 ? "+" : "",
1341
+ o === "inch" ? (z / 25.4).toFixed(2) : z.toFixed(1)
1342
+ ]
1343
+ }),
1344
+ k("span", {
1345
+ style: {
1346
+ fontSize: 11,
1347
+ color: "rgba(255,255,255,0.4)",
1348
+ fontFamily: "monospace"
1349
+ },
1350
+ children: [
1351
+ "from ",
1352
+ o === "inch" ? (s / 25.4).toFixed(2) : s.toFixed(0)
1353
+ ]
1354
+ })
1355
+ ]
1356
+ })
1357
+ ]
1358
+ })
1359
+ })
1360
+ })
1361
+ ]
1362
+ });
1363
+ }, Oo = ({ modelSize: e, isAligned: r, isCut: t, mesh: o, viewMode: l, sliceY: s, landmarkCount: c = 0, measurementGeometry: a, resetCameraToFrontRef: n }) => {
1364
+ const { set: m, size: d, camera: f, invalidate: u } = un(), x = le(false), S = le(l), p = le(new C()), g = le(null), b = le(c), A = le(r), L = le(t), z = le(a), P = le(0), y = te(() => {
1365
+ if (!o || e <= 0) return null;
1366
+ const h = a ?? o.geometry;
1367
+ h.computeBoundingBox();
1368
+ const v = h.boundingBox, F = new C();
1369
+ v.getCenter(F);
1370
+ const I = new C();
1371
+ v.getSize(I), p.current.copy(I);
1372
+ const _ = d.width / d.height, E = Math.max(I.y, I.x / _) * 1.6, V = E * _, N = F.y - I.y * 0.05;
1373
+ P.current = N;
1374
+ const J = new O.OrthographicCamera(-V / 2, V / 2, E / 2, -E / 2, 0.1, e * 10);
1375
+ return J.position.set(0, N, e * 2), J.lookAt(0, N, 0), J;
1376
+ }, [
1377
+ o,
1378
+ e,
1379
+ d,
1380
+ a
1381
+ ]);
1382
+ U(() => {
1383
+ if (n) return n.current = () => {
1384
+ const h = y();
1385
+ h && (m({
1386
+ camera: h
1387
+ }), u());
1388
+ }, () => {
1389
+ n && (n.current = null);
1390
+ };
1391
+ }, [
1392
+ n,
1393
+ y,
1394
+ m,
1395
+ u
1396
+ ]);
1397
+ const M = te((h) => {
1398
+ const v = h.position.clone(), F = v.length(), I = Math.atan2(v.x, v.z), _ = Math.acos(v.y / F), V = I + 0.02;
1399
+ h.position.set(F * Math.sin(_) * Math.sin(V), F * Math.cos(_), F * Math.sin(_) * Math.cos(V)), h.lookAt(0, 0, 0), h.updateMatrixWorld(true), u();
1400
+ }, [
1401
+ u
1402
+ ]);
1403
+ return U(() => {
1404
+ if (e > 0 && !x.current && !r) {
1405
+ x.current = true;
1406
+ const h = new O.PerspectiveCamera(50, d.width / d.height, 0.1, e * 10);
1407
+ h.position.set(e * 0.3, e * 0.2, e * 1.5), h.lookAt(0, 0, 0), m({
1408
+ camera: h
1409
+ }), requestAnimationFrame(() => M(h));
1410
+ }
1411
+ }, [
1412
+ e,
1413
+ d,
1414
+ m,
1415
+ r,
1416
+ M
1417
+ ]), U(() => {
1418
+ const h = b.current;
1419
+ b.current = c, h === 0 && c === 1 && !r && requestAnimationFrame(() => M(f));
1420
+ }, [
1421
+ c,
1422
+ r,
1423
+ f,
1424
+ M
1425
+ ]), U(() => {
1426
+ const h = A.current !== r, v = L.current !== t, F = !z.current && !!a;
1427
+ if (A.current = r, L.current = t, z.current = a, !h && !v && !F || !r || l !== "3D") return;
1428
+ const I = y();
1429
+ I && m({
1430
+ camera: I
1431
+ });
1432
+ }, [
1433
+ r,
1434
+ t,
1435
+ l,
1436
+ a,
1437
+ y,
1438
+ m
1439
+ ]), U(() => {
1440
+ if (S.current === l) return;
1441
+ const h = S.current;
1442
+ if (S.current = l, !(!r || !o || e <= 0)) {
1443
+ if (l === "2D" && s != null) {
1444
+ g.current = f;
1445
+ const v = o.geometry, F = v.getAttribute("position"), I = F.array, _ = e * 0.15;
1446
+ let E = 1 / 0, V = -1 / 0, N = 1 / 0, J = -1 / 0, ye = false;
1447
+ for (let pe = 0; pe < F.count; pe++) if (Math.abs(I[pe * 3 + 1] - s) < _) {
1448
+ const $ = I[pe * 3], ne = I[pe * 3 + 2];
1449
+ $ < E && (E = $), $ > V && (V = $), ne < N && (N = ne), ne > J && (J = ne), ye = true;
1450
+ }
1451
+ if (!ye) {
1452
+ v.computeBoundingBox();
1453
+ const pe = v.boundingBox;
1454
+ E = pe.min.x, V = pe.max.x, N = pe.min.z, J = pe.max.z;
1455
+ }
1456
+ const ae = (E + V) / 2, ue = (N + J) / 2, ie = d.width / d.height, Q = 1.4, Y = (V - E) * Q, he = (J - N) * Q;
1457
+ let Z, ge;
1458
+ Y / he > ie ? (Z = Y, ge = Y / ie) : (ge = he, Z = he * ie);
1459
+ const me = new O.OrthographicCamera(-Z / 2, Z / 2, ge / 2, -ge / 2, 0.1, e * 10);
1460
+ me.position.set(ae, s + e * 2, ue), me.up.set(0, 0, -1), me.lookAt(ae, s, ue), m({
1461
+ camera: me
1462
+ });
1463
+ } else if (h === "2D") if (g.current) m({
1464
+ camera: g.current
1465
+ }), g.current = null;
1466
+ else {
1467
+ const v = y();
1468
+ v && m({
1469
+ camera: v
1470
+ });
1471
+ }
1472
+ }
1473
+ }, [
1474
+ l,
1475
+ s,
1476
+ r,
1477
+ o,
1478
+ e,
1479
+ d,
1480
+ m,
1481
+ f,
1482
+ y
1483
+ ]), U(() => {
1484
+ if (!r || !f || !f.isOrthographicCamera) return;
1485
+ const h = f;
1486
+ if (l === "2D") {
1487
+ if (!o || s == null) return;
1488
+ const v = o.geometry, F = v.getAttribute("position"), I = F.array, _ = e * 0.15;
1489
+ let E = 1 / 0, V = -1 / 0, N = 1 / 0, J = -1 / 0, ye = false;
1490
+ for (let Z = 0; Z < F.count; Z++) if (Math.abs(I[Z * 3 + 1] - s) < _) {
1491
+ const ge = I[Z * 3], me = I[Z * 3 + 2];
1492
+ ge < E && (E = ge), ge > V && (V = ge), me < N && (N = me), me > J && (J = me), ye = true;
1493
+ }
1494
+ if (!ye) {
1495
+ v.computeBoundingBox();
1496
+ const Z = v.boundingBox;
1497
+ E = Z.min.x, V = Z.max.x, N = Z.min.z, J = Z.max.z;
1498
+ }
1499
+ const ae = d.width / d.height, ue = 1.4, ie = (V - E) * ue, Q = (J - N) * ue;
1500
+ let Y, he;
1501
+ ie / Q > ae ? (Y = ie, he = ie / ae) : (he = Q, Y = Q * ae), h.left = -Y / 2, h.right = Y / 2, h.top = he / 2, h.bottom = -he / 2;
1502
+ } else {
1503
+ const v = p.current, F = d.width / d.height, I = Math.max(v.y, v.x / F) * 1.6, _ = I * F;
1504
+ h.left = -_ / 2, h.right = _ / 2, h.top = I / 2, h.bottom = -I / 2;
1505
+ }
1506
+ h.updateProjectionMatrix();
1507
+ }, [
1508
+ d.width,
1509
+ d.height,
1510
+ r,
1511
+ f,
1512
+ l,
1513
+ o
1514
+ ]), null;
1515
+ }, $o = ({ mesh: e, isDragging: r }) => {
1516
+ var _a;
1517
+ const t = e.geometry;
1518
+ t.computeBoundingBox();
1519
+ const o = new C();
1520
+ return (_a = t.boundingBox) == null ? void 0 : _a.getCenter(o), i(pn, {
1521
+ enableDamping: false,
1522
+ enablePan: false,
1523
+ minPolarAngle: Math.PI * 0.15,
1524
+ maxPolarAngle: Math.PI * 0.85,
1525
+ minZoom: 0.5,
1526
+ maxZoom: 3,
1527
+ enabled: !r,
1528
+ target: [
1529
+ o.x,
1530
+ o.y,
1531
+ o.z
1532
+ ]
1533
+ });
1534
+ }, Ho = ({ wasAutoScaled: e, onDismiss: r }) => k("div", {
1535
+ style: {
1536
+ position: "absolute",
1537
+ bottom: 16,
1538
+ left: 16,
1539
+ zIndex: 10,
1540
+ display: "flex",
1541
+ alignItems: "flex-start",
1542
+ gap: 10,
1543
+ padding: "10px 14px",
1544
+ maxWidth: 320,
1545
+ backgroundColor: e ? "rgba(30, 70, 160, 0.92)" : "rgba(40, 40, 40, 0.88)",
1546
+ borderRadius: 8,
1547
+ boxShadow: "0 2px 12px rgba(0,0,0,0.15)",
1548
+ fontFamily: "system-ui, sans-serif"
1549
+ },
1550
+ children: [
1551
+ i("span", {
1552
+ style: {
1553
+ fontSize: 13,
1554
+ color: "#fff",
1555
+ lineHeight: "20px"
1556
+ },
1557
+ children: e ? "Units detected as meters - converted to mm" : "Units detected as mm"
1558
+ }),
1559
+ i("button", {
1560
+ onClick: r,
1561
+ style: {
1562
+ background: "none",
1563
+ border: "none",
1564
+ color: "rgba(255,255,255,0.7)",
1565
+ cursor: "pointer",
1566
+ fontSize: 16,
1567
+ lineHeight: "20px",
1568
+ padding: 0,
1569
+ marginLeft: "auto",
1570
+ flexShrink: 0
1571
+ },
1572
+ children: "X"
1573
+ })
1574
+ ]
1575
+ }), Vo = ({ isDoubleShell: e, onDismiss: r }) => k("div", {
1576
+ style: {
1577
+ position: "absolute",
1578
+ bottom: 68,
1579
+ left: 16,
1580
+ zIndex: 10,
1581
+ display: "flex",
1582
+ alignItems: "flex-start",
1583
+ gap: 10,
1584
+ padding: "10px 14px",
1585
+ maxWidth: 320,
1586
+ backgroundColor: e ? "rgba(130, 80, 20, 0.92)" : "rgba(40, 40, 40, 0.88)",
1587
+ borderRadius: 8,
1588
+ boxShadow: "0 2px 12px rgba(0,0,0,0.15)",
1589
+ fontFamily: "system-ui, sans-serif"
1590
+ },
1591
+ children: [
1592
+ i("span", {
1593
+ style: {
1594
+ fontSize: 13,
1595
+ color: "#fff",
1596
+ lineHeight: "20px"
1597
+ },
1598
+ children: e ? "Double shell scan detected" : "Single shell scan detected"
1599
+ }),
1600
+ i("button", {
1601
+ onClick: r,
1602
+ style: {
1603
+ background: "none",
1604
+ border: "none",
1605
+ color: "rgba(255,255,255,0.7)",
1606
+ cursor: "pointer",
1607
+ fontSize: 16,
1608
+ lineHeight: "20px",
1609
+ padding: 0,
1610
+ marginLeft: "auto",
1611
+ flexShrink: 0
1612
+ },
1613
+ children: "X"
1614
+ })
1615
+ ]
1616
+ }), jo = ({ steps: e, currentStep: r, accentColor: t = "rgb(12, 67, 173)" }) => i("div", {
1617
+ style: {
1618
+ backgroundColor: "#fff",
1619
+ borderBottom: "1px solid #e0e0e0",
1620
+ display: "flex",
1621
+ alignItems: "center",
1622
+ padding: "24px 24px",
1623
+ flexShrink: 0
1624
+ },
1625
+ children: e.map((o, l) => {
1626
+ const s = o.number < r, c = o.number === r;
1627
+ return k("div", {
1628
+ style: {
1629
+ display: "contents"
1630
+ },
1631
+ children: [
1632
+ k("div", {
1633
+ style: {
1634
+ display: "flex",
1635
+ alignItems: "center",
1636
+ gap: 8,
1637
+ padding: "0 8px",
1638
+ flexShrink: 0,
1639
+ cursor: "default"
1640
+ },
1641
+ children: [
1642
+ i("div", {
1643
+ style: {
1644
+ width: 24,
1645
+ height: 24,
1646
+ borderRadius: "50%",
1647
+ backgroundColor: s || c ? t : "rgba(0, 0, 0, 0.38)",
1648
+ color: "#fff",
1649
+ display: "flex",
1650
+ alignItems: "center",
1651
+ justifyContent: "center",
1652
+ fontSize: 12,
1653
+ fontFamily: "system-ui, sans-serif",
1654
+ flexShrink: 0
1655
+ },
1656
+ children: s ? "\u2713" : o.number
1657
+ }),
1658
+ i("div", {
1659
+ style: {
1660
+ fontSize: 14,
1661
+ fontWeight: c ? 600 : 400,
1662
+ color: c ? "rgba(0, 0, 0, 0.87)" : "rgba(0, 0, 0, 0.54)",
1663
+ fontFamily: "system-ui, sans-serif",
1664
+ whiteSpace: "nowrap"
1665
+ },
1666
+ children: o.label
1667
+ })
1668
+ ]
1669
+ }),
1670
+ l < e.length - 1 && i("div", {
1671
+ style: {
1672
+ flex: "auto",
1673
+ borderTop: "1px solid #bdbdbd",
1674
+ margin: "0 8px"
1675
+ }
1676
+ })
1677
+ ]
1678
+ }, o.number);
1679
+ })
1680
+ }), No = ({ mesh: e, upperY: r, originY: t, modelSize: o, meshColor: l = "#c8c8c8", displayUnit: s = "mm" }) => {
1681
+ const c = e.geometry, a = H(() => new gt(c, {
1682
+ maxLeafTris: mt
1683
+ }), [
1684
+ c
1685
+ ]), n = H(() => Ye(a, c, t), [
1686
+ a,
1687
+ c,
1688
+ t
1689
+ ]), m = H(() => new ht(new C(0, -1, 0), r), [
1690
+ r
1691
+ ]), { mlLine: d, apLine: f, mlWidth: u, apWidth: x } = H(() => {
1692
+ let g = null, b = null, A = 0, L = 0;
1693
+ if (n.linePoints.length >= 2) {
1694
+ let z = n.linePoints[0], P = n.linePoints[0], y = n.linePoints[0], M = n.linePoints[0];
1695
+ for (const h of n.linePoints) h.x < z.x && (z = h), h.x > P.x && (P = h), h.z < y.z && (y = h), h.z > M.z && (M = h);
1696
+ g = [
1697
+ new C(z.x, t, z.z),
1698
+ new C(P.x, t, P.z)
1699
+ ], b = [
1700
+ new C(y.x, t, y.z),
1701
+ new C(M.x, t, M.z)
1702
+ ], A = g[0].distanceTo(g[1]), L = b[0].distanceTo(b[1]);
1703
+ }
1704
+ return {
1705
+ mlLine: g,
1706
+ apLine: b,
1707
+ mlWidth: A,
1708
+ apWidth: L
1709
+ };
1710
+ }, [
1711
+ n,
1712
+ t
1713
+ ]), S = (g) => s === "inch" ? (g / 25.4).toFixed(2) : g.toFixed(1), p = s === "inch" ? "in" : "mm";
1714
+ return k(Oe, {
1715
+ children: [
1716
+ i("mesh", {
1717
+ geometry: e.geometry,
1718
+ children: i("meshStandardMaterial", {
1719
+ color: l,
1720
+ side: O.DoubleSide,
1721
+ transparent: true,
1722
+ opacity: 0.15,
1723
+ depthWrite: false,
1724
+ clippingPlanes: [
1725
+ m
1726
+ ]
1727
+ })
1728
+ }),
1729
+ n.linePoints.length >= 2 && i(fe, {
1730
+ points: n.linePoints,
1731
+ color: "#00ff00",
1732
+ lineWidth: 3,
1733
+ depthTest: false,
1734
+ depthWrite: false,
1735
+ transparent: true
1736
+ }),
1737
+ d && k(Oe, {
1738
+ children: [
1739
+ i(fe, {
1740
+ points: d,
1741
+ color: "#ff8800",
1742
+ lineWidth: 2,
1743
+ depthTest: false,
1744
+ depthWrite: false,
1745
+ transparent: true
1746
+ }),
1747
+ i(Xe, {
1748
+ position: [
1749
+ d[0].x,
1750
+ t,
1751
+ d[0].z - o * 0.02
1752
+ ],
1753
+ center: true,
1754
+ style: {
1755
+ pointerEvents: "none"
1756
+ },
1757
+ children: i("div", {
1758
+ style: {
1759
+ whiteSpace: "nowrap",
1760
+ padding: "2px 6px",
1761
+ backgroundColor: "rgba(0,0,0,0.75)",
1762
+ borderRadius: 3
1763
+ },
1764
+ children: k("span", {
1765
+ style: {
1766
+ fontSize: 12,
1767
+ color: "#ff8800",
1768
+ fontFamily: "monospace"
1769
+ },
1770
+ children: [
1771
+ "ML ",
1772
+ S(u),
1773
+ " ",
1774
+ p
1775
+ ]
1776
+ })
1777
+ })
1778
+ })
1779
+ ]
1780
+ }),
1781
+ f && k(Oe, {
1782
+ children: [
1783
+ i(fe, {
1784
+ points: f,
1785
+ color: "#ff00ff",
1786
+ lineWidth: 2,
1787
+ depthTest: false,
1788
+ depthWrite: false,
1789
+ transparent: true
1790
+ }),
1791
+ i(Xe, {
1792
+ position: [
1793
+ Math.max(f[0].x, f[1].x) + o * 0.02,
1794
+ t,
1795
+ f[0].z > f[1].z ? f[0].z : f[1].z
1796
+ ],
1797
+ center: true,
1798
+ style: {
1799
+ pointerEvents: "none"
1800
+ },
1801
+ children: i("div", {
1802
+ style: {
1803
+ whiteSpace: "nowrap",
1804
+ padding: "2px 6px",
1805
+ backgroundColor: "rgba(0,0,0,0.75)",
1806
+ borderRadius: 3
1807
+ },
1808
+ children: k("span", {
1809
+ style: {
1810
+ fontSize: 12,
1811
+ color: "#ff00ff",
1812
+ fontFamily: "monospace"
1813
+ },
1814
+ children: [
1815
+ "AP ",
1816
+ S(x),
1817
+ " ",
1818
+ p
1819
+ ]
1820
+ })
1821
+ })
1822
+ })
1823
+ ]
1824
+ })
1825
+ ]
1826
+ });
1827
+ }, Yo = ({ mesh: e, yPosition: r, onYChange: t, minY: o, maxY: l, modelSize: s, color: c, hoverColor: a, dragColor: n, label: m, onDragStart: d, onDragEnd: f }) => {
1828
+ const [u, x] = W(false), [S, p] = W(false), { camera: g, gl: b } = un(), A = le(0), L = e.geometry, z = vn(L), P = H(() => z ? Ye(z, L, r) : {
1829
+ linePoints: [],
1830
+ lineLength: 0,
1831
+ rightmostPoint: new C()
1832
+ }, [
1833
+ z,
1834
+ L,
1835
+ r
1836
+ ]), y = te((I, _) => {
1837
+ const E = b.domElement.getBoundingClientRect(), V = (I - E.left) / E.width * 2 - 1, N = -((_ - E.top) / E.height) * 2 + 1, J = new lo();
1838
+ J.setFromCamera(new O.Vector2(V, N), g);
1839
+ const ye = new ht(new C(0, 0, 1), 0), ae = new C();
1840
+ return J.ray.intersectPlane(ye, ae), ae ? ae.y : r;
1841
+ }, [
1842
+ g,
1843
+ b,
1844
+ r
1845
+ ]), M = te((I) => {
1846
+ I.stopPropagation(), x(true), b.domElement.style.cursor = "ns-resize", A.current = r - y(I.clientX, I.clientY), I.target.setPointerCapture(I.pointerId), d == null ? void 0 : d();
1847
+ }, [
1848
+ r,
1849
+ b,
1850
+ y,
1851
+ d
1852
+ ]), h = te((I) => {
1853
+ if (!u) return;
1854
+ let _ = y(I.clientX, I.clientY) + A.current;
1855
+ _ = Math.max(o, Math.min(l, _)), t(_);
1856
+ }, [
1857
+ u,
1858
+ y,
1859
+ t,
1860
+ o,
1861
+ l
1862
+ ]), v = te((I) => {
1863
+ x(false), b.domElement.style.cursor = "auto", I.target.releasePointerCapture(I.pointerId), f == null ? void 0 : f();
1864
+ }, [
1865
+ b,
1866
+ f
1867
+ ]);
1868
+ if (P.linePoints.length < 2) return null;
1869
+ const F = u ? n : S ? a : c;
1870
+ return k("group", {
1871
+ renderOrder: 10,
1872
+ children: [
1873
+ i(fe, {
1874
+ points: P.linePoints,
1875
+ color: F,
1876
+ lineWidth: u ? 6 : S ? 5 : 4,
1877
+ depthTest: false,
1878
+ depthWrite: false,
1879
+ transparent: true,
1880
+ renderOrder: 10,
1881
+ onPointerDown: M,
1882
+ onPointerMove: h,
1883
+ onPointerUp: v,
1884
+ onPointerEnter: () => {
1885
+ p(true), b.domElement.style.cursor = "ns-resize";
1886
+ },
1887
+ onPointerLeave: () => {
1888
+ u || (p(false), b.domElement.style.cursor = "auto");
1889
+ }
1890
+ }),
1891
+ (S || u) && i("mesh", {
1892
+ position: [
1893
+ P.rightmostPoint.x + s * 0.15,
1894
+ r,
1895
+ 0
1896
+ ],
1897
+ children: i(Xe, {
1898
+ center: true,
1899
+ children: i("div", {
1900
+ style: {
1901
+ padding: "4px 8px",
1902
+ backgroundColor: "rgba(0, 0, 0, 0.8)",
1903
+ borderRadius: 4,
1904
+ color: F,
1905
+ fontSize: 11,
1906
+ whiteSpace: "nowrap",
1907
+ pointerEvents: "none"
1908
+ },
1909
+ children: u ? "Dragging..." : m
1910
+ })
1911
+ })
1912
+ })
1913
+ ]
1914
+ });
1915
+ };
1916
+ function Xo(e, r) {
1917
+ if (e == null) return {};
1918
+ var t = {}, o = Object.keys(e), l, s;
1919
+ for (s = 0; s < o.length; s++) l = o[s], !(r.indexOf(l) >= 0) && (t[l] = e[l]);
1920
+ return t;
1921
+ }
1922
+ var Go = [
1923
+ "color"
1924
+ ], Zo = io(function(e, r) {
1925
+ var t = e.color, o = t === void 0 ? "currentColor" : t, l = Xo(e, Go);
1926
+ return nn("svg", Object.assign({
1927
+ width: "15",
1928
+ height: "15",
1929
+ viewBox: "0 0 15 15",
1930
+ fill: "none",
1931
+ xmlns: "http://www.w3.org/2000/svg"
1932
+ }, l, {
1933
+ ref: r
1934
+ }), nn("path", {
1935
+ d: "M7.5 2C7.77614 2 8 2.22386 8 2.5L8 11.2929L11.1464 8.14645C11.3417 7.95118 11.6583 7.95118 11.8536 8.14645C12.0488 8.34171 12.0488 8.65829 11.8536 8.85355L7.85355 12.8536C7.75979 12.9473 7.63261 13 7.5 13C7.36739 13 7.24021 12.9473 7.14645 12.8536L3.14645 8.85355C2.95118 8.65829 2.95118 8.34171 3.14645 8.14645C3.34171 7.95118 3.65829 7.95118 3.85355 8.14645L7 11.2929L7 2.5C7 2.22386 7.22386 2 7.5 2Z",
1936
+ fill: o,
1937
+ fillRule: "evenodd",
1938
+ clipRule: "evenodd"
1939
+ }));
1940
+ });
1941
+ const Ko = [
1942
+ "Scan doesn't load properly",
1943
+ "Takes too long",
1944
+ "I don't want to",
1945
+ "I want a second opinion",
1946
+ "I measured from IT"
1947
+ ], dt = {
1948
+ padding: "8px 20px",
1949
+ borderRadius: 4,
1950
+ fontSize: 14,
1951
+ fontWeight: 500,
1952
+ cursor: "pointer",
1953
+ fontFamily: "system-ui, sans-serif",
1954
+ letterSpacing: "0.4px",
1955
+ lineHeight: "36px"
1956
+ }, Uo = {
1957
+ width: "100%",
1958
+ padding: "10px 12px",
1959
+ fontSize: 15,
1960
+ border: "2px solid #ccc",
1961
+ borderRadius: 4,
1962
+ outline: "none",
1963
+ boxSizing: "border-box",
1964
+ fontFamily: "system-ui, sans-serif"
1965
+ }, Cn = ({ onSkip: e, onCancel: r }) => {
1966
+ const [t, o] = W("confirm"), [l, s] = W(null), [c, a] = W(""), n = te(() => {
1967
+ o("reasons");
1968
+ }, []), m = te(() => {
1969
+ t === "reasons" ? (o("confirm"), s(null), a("")) : r();
1970
+ }, [
1971
+ t,
1972
+ r
1973
+ ]), d = l != null && (l !== "Other" || c.trim() !== ""), f = te(() => {
1974
+ !d || !l || e(l === "Other" ? `Other: ${c.trim()}` : l);
1975
+ }, [
1976
+ d,
1977
+ l,
1978
+ c,
1979
+ e
1980
+ ]);
1981
+ return t === "reasons" ? i("div", {
1982
+ style: {
1983
+ position: "fixed",
1984
+ inset: 0,
1985
+ backgroundColor: "rgba(0,0,0,0.5)",
1986
+ backdropFilter: "blur(6px)",
1987
+ WebkitBackdropFilter: "blur(6px)",
1988
+ display: "flex",
1989
+ alignItems: "center",
1990
+ justifyContent: "center",
1991
+ zIndex: 9999,
1992
+ fontFamily: "system-ui, sans-serif"
1993
+ },
1994
+ children: k("div", {
1995
+ style: {
1996
+ backgroundColor: "#fff",
1997
+ borderRadius: 12,
1998
+ width: 440,
1999
+ boxShadow: "0 24px 38px 3px rgba(0,0,0,0.14)"
2000
+ },
2001
+ children: [
2002
+ k("div", {
2003
+ style: {
2004
+ padding: "24px 24px 0"
2005
+ },
2006
+ children: [
2007
+ i("div", {
2008
+ style: {
2009
+ fontSize: 18,
2010
+ fontWeight: 600,
2011
+ color: "rgba(0,0,0,0.87)",
2012
+ marginBottom: 4
2013
+ },
2014
+ children: "Why are you skipping?"
2015
+ }),
2016
+ i("div", {
2017
+ style: {
2018
+ fontSize: 13,
2019
+ color: "rgba(0,0,0,0.5)"
2020
+ },
2021
+ children: "Select a reason to help us improve."
2022
+ })
2023
+ ]
2024
+ }),
2025
+ k("div", {
2026
+ style: {
2027
+ padding: "20px 24px",
2028
+ display: "flex",
2029
+ flexDirection: "column",
2030
+ gap: 2
2031
+ },
2032
+ children: [
2033
+ [
2034
+ ...Ko,
2035
+ "Other"
2036
+ ].map((u) => k("label", {
2037
+ style: {
2038
+ display: "flex",
2039
+ alignItems: "center",
2040
+ gap: 12,
2041
+ padding: "10px 12px",
2042
+ borderRadius: 6,
2043
+ cursor: "pointer",
2044
+ backgroundColor: l === u ? "rgba(12, 67, 173, 0.06)" : "transparent"
2045
+ },
2046
+ children: [
2047
+ i("input", {
2048
+ type: "radio",
2049
+ name: "skip-reason",
2050
+ checked: l === u,
2051
+ onChange: () => {
2052
+ s(u), u !== "Other" && a("");
2053
+ },
2054
+ style: {
2055
+ accentColor: "rgb(12, 67, 173)",
2056
+ width: 16,
2057
+ height: 16,
2058
+ margin: 0,
2059
+ flexShrink: 0
2060
+ }
2061
+ }),
2062
+ i("span", {
2063
+ style: {
2064
+ fontSize: 14,
2065
+ color: "#333"
2066
+ },
2067
+ children: u
2068
+ })
2069
+ ]
2070
+ }, u)),
2071
+ l === "Other" && i("input", {
2072
+ autoFocus: true,
2073
+ type: "text",
2074
+ placeholder: "Please describe...",
2075
+ value: c,
2076
+ onChange: (u) => a(u.target.value),
2077
+ onKeyDown: (u) => {
2078
+ u.key === "Enter" && f();
2079
+ },
2080
+ style: {
2081
+ ...Uo,
2082
+ marginTop: 8,
2083
+ marginLeft: 40,
2084
+ width: "calc(100% - 40px)",
2085
+ border: "1px solid #ddd"
2086
+ }
2087
+ })
2088
+ ]
2089
+ }),
2090
+ k("div", {
2091
+ style: {
2092
+ display: "flex",
2093
+ justifyContent: "flex-end",
2094
+ gap: 8,
2095
+ padding: "16px 24px",
2096
+ borderTop: "1px solid #eee"
2097
+ },
2098
+ children: [
2099
+ i("button", {
2100
+ onClick: m,
2101
+ style: {
2102
+ ...dt,
2103
+ backgroundColor: "#fff",
2104
+ border: "1px solid #ddd",
2105
+ color: "#666"
2106
+ },
2107
+ children: "Cancel"
2108
+ }),
2109
+ i("button", {
2110
+ onClick: f,
2111
+ disabled: !d,
2112
+ style: {
2113
+ ...dt,
2114
+ backgroundColor: d ? "rgb(12, 67, 173)" : "#e0e0e0",
2115
+ border: "none",
2116
+ color: d ? "#fff" : "#9e9e9e",
2117
+ cursor: d ? "pointer" : "not-allowed"
2118
+ },
2119
+ children: "Submit"
2120
+ })
2121
+ ]
2122
+ })
2123
+ ]
2124
+ })
2125
+ }) : i("div", {
2126
+ style: {
2127
+ position: "fixed",
2128
+ inset: 0,
2129
+ backgroundColor: "rgba(0,0,0,0.5)",
2130
+ backdropFilter: "blur(6px)",
2131
+ WebkitBackdropFilter: "blur(6px)",
2132
+ display: "flex",
2133
+ alignItems: "center",
2134
+ justifyContent: "center",
2135
+ zIndex: 9999,
2136
+ fontFamily: "system-ui, sans-serif"
2137
+ },
2138
+ children: k("div", {
2139
+ style: {
2140
+ backgroundColor: "#fff",
2141
+ borderRadius: 8,
2142
+ width: 440,
2143
+ padding: 32,
2144
+ boxShadow: "0 24px 38px 3px rgba(0,0,0,0.14)"
2145
+ },
2146
+ children: [
2147
+ i("div", {
2148
+ style: {
2149
+ fontSize: 20,
2150
+ fontWeight: 600,
2151
+ color: "rgba(0,0,0,0.87)",
2152
+ marginBottom: 8
2153
+ },
2154
+ children: "Skip Scan Comparison?"
2155
+ }),
2156
+ i("div", {
2157
+ style: {
2158
+ fontSize: 14,
2159
+ color: "rgba(0,0,0,0.54)",
2160
+ marginBottom: 24
2161
+ },
2162
+ children: "Your measurements will be submitted without comparing to the scan. Are you sure?"
2163
+ }),
2164
+ k("div", {
2165
+ style: {
2166
+ display: "flex",
2167
+ justifyContent: "flex-end",
2168
+ gap: 8
2169
+ },
2170
+ children: [
2171
+ i("button", {
2172
+ onClick: r,
2173
+ style: {
2174
+ ...dt,
2175
+ backgroundColor: "#fff",
2176
+ border: "1px solid #bdbdbd",
2177
+ color: "#333"
2178
+ },
2179
+ children: "Cancel"
2180
+ }),
2181
+ i("button", {
2182
+ onClick: n,
2183
+ style: {
2184
+ ...dt,
2185
+ backgroundColor: "rgb(12, 67, 173)",
2186
+ border: "none",
2187
+ color: "#fff"
2188
+ },
2189
+ children: "Confirm"
2190
+ })
2191
+ ]
2192
+ })
2193
+ ]
2194
+ })
2195
+ });
2196
+ }, Wt = {
2197
+ padding: "8px 20px",
2198
+ borderRadius: 4,
2199
+ fontSize: 14,
2200
+ fontWeight: 500,
2201
+ cursor: "pointer",
2202
+ fontFamily: "system-ui, sans-serif",
2203
+ letterSpacing: "0.4px",
2204
+ lineHeight: "36px"
2205
+ }, dn = {
2206
+ width: "100%",
2207
+ padding: "10px 12px",
2208
+ fontSize: 15,
2209
+ border: "2px solid #ccc",
2210
+ borderRadius: 4,
2211
+ outline: "none",
2212
+ boxSizing: "border-box",
2213
+ fontFamily: "system-ui, sans-serif"
2214
+ }, Jo = ({ amputationType: e, spacingInches: r, scanMeasurements: t, scanFrontalHeight: o, onSave: l, onSkip: s, onFormChange: c, onHeightChange: a, initialValues: n, initialFrontalHeight: m }) => {
2215
+ const d = e === "AK" ? "IT" : "MPT", f = r, u = e === "AK" ? 18 : 9, x = H(() => {
2216
+ const h = [];
2217
+ for (let v = 2; v >= 1; v -= f) h.push(`${v}\u2033 above ${d}`);
2218
+ h.push(`At ${d}`);
2219
+ for (let v = f; v <= u; v += f) h.push(`${v}\u2033 below ${d}`);
2220
+ return h;
2221
+ }, [
2222
+ f,
2223
+ d,
2224
+ u
2225
+ ]), [S, p] = W(() => {
2226
+ if (!n) return {};
2227
+ const h = {};
2228
+ return x.forEach((v, F) => {
2229
+ n[F] != null && n[F] !== 0 && (h[v] = n[F].toFixed(1));
2230
+ }), h;
2231
+ }), [g, b] = W(m && m > 0 ? m.toFixed(1) : ""), [A, L] = W(false), z = H(() => x.map((h) => {
2232
+ const v = S[h];
2233
+ return v != null && v !== "" && !isNaN(parseFloat(v)) ? parseFloat(v) : 0;
2234
+ }), [
2235
+ x,
2236
+ S
2237
+ ]);
2238
+ U(() => {
2239
+ c == null ? void 0 : c(z);
2240
+ }, [
2241
+ z,
2242
+ c
2243
+ ]), U(() => {
2244
+ const h = g !== "" && !isNaN(parseFloat(g)) ? parseFloat(g) : void 0;
2245
+ a == null ? void 0 : a(h);
2246
+ }, [
2247
+ g,
2248
+ a
2249
+ ]);
2250
+ const P = H(() => {
2251
+ const h = g !== "" && !isNaN(parseFloat(g)), v = z.some((F) => F !== 0);
2252
+ return h || v;
2253
+ }, [
2254
+ z,
2255
+ g
2256
+ ]), y = te(() => {
2257
+ if (!P) return;
2258
+ const h = g !== "" && !isNaN(parseFloat(g)) ? parseFloat(g) : 0;
2259
+ l({
2260
+ circumferences: z,
2261
+ frontalHeight: h
2262
+ });
2263
+ }, [
2264
+ P,
2265
+ z,
2266
+ g,
2267
+ l
2268
+ ]), M = te(() => {
2269
+ const h = {};
2270
+ x.forEach((v, F) => {
2271
+ const I = t[F];
2272
+ if (I) {
2273
+ const _ = I.modifiedValue ?? I.originalValue;
2274
+ h[v] = _.toFixed(1);
2275
+ }
2276
+ }), p(h), o > 0 && b(o.toFixed(1));
2277
+ }, [
2278
+ x,
2279
+ t,
2280
+ o
2281
+ ]);
2282
+ return k("div", {
2283
+ style: {
2284
+ display: "flex",
2285
+ flexDirection: "column",
2286
+ height: "100%",
2287
+ backgroundColor: "#f5f5f5",
2288
+ fontFamily: "system-ui, sans-serif"
2289
+ },
2290
+ children: [
2291
+ A && i(Cn, {
2292
+ onSkip: s,
2293
+ onCancel: () => L(false)
2294
+ }),
2295
+ k("div", {
2296
+ style: {
2297
+ padding: "16px 20px 12px",
2298
+ backgroundColor: "#fff",
2299
+ borderBottom: "1px solid #e0e0e0",
2300
+ flexShrink: 0
2301
+ },
2302
+ children: [
2303
+ k("div", {
2304
+ style: {
2305
+ fontSize: 18,
2306
+ fontWeight: 600,
2307
+ color: "rgba(0,0,0,0.87)"
2308
+ },
2309
+ children: [
2310
+ e,
2311
+ " Measurements"
2312
+ ]
2313
+ }),
2314
+ k("div", {
2315
+ style: {
2316
+ fontSize: 12,
2317
+ color: "rgba(0,0,0,0.54)",
2318
+ marginTop: 2
2319
+ },
2320
+ children: [
2321
+ "Enter measurements (mm). ",
2322
+ f,
2323
+ "\u2033",
2324
+ " spacing."
2325
+ ]
2326
+ }),
2327
+ i("button", {
2328
+ onClick: M,
2329
+ style: {
2330
+ ...Wt,
2331
+ backgroundColor: "#fff",
2332
+ border: "2px solid rgb(12, 67, 173)",
2333
+ color: "rgb(12, 67, 173)",
2334
+ fontWeight: 600,
2335
+ padding: "4px 12px",
2336
+ fontSize: 12,
2337
+ marginTop: 8,
2338
+ width: "100%"
2339
+ },
2340
+ children: k("span", {
2341
+ style: {
2342
+ display: "flex",
2343
+ alignItems: "center",
2344
+ justifyContent: "center",
2345
+ gap: 4
2346
+ },
2347
+ children: [
2348
+ i(Zo, {
2349
+ style: {
2350
+ width: 14,
2351
+ height: 14
2352
+ }
2353
+ }),
2354
+ "Pull from Scan"
2355
+ ]
2356
+ })
2357
+ })
2358
+ ]
2359
+ }),
2360
+ k("div", {
2361
+ style: {
2362
+ flex: 1,
2363
+ minHeight: 0,
2364
+ overflow: "auto",
2365
+ padding: "16px 20px",
2366
+ WebkitOverflowScrolling: "touch"
2367
+ },
2368
+ children: [
2369
+ i("div", {
2370
+ style: {
2371
+ fontSize: 13,
2372
+ fontWeight: 600,
2373
+ color: "rgba(0,0,0,0.87)",
2374
+ marginBottom: 8
2375
+ },
2376
+ children: "Circumferences"
2377
+ }),
2378
+ i("div", {
2379
+ style: {
2380
+ display: "flex",
2381
+ flexDirection: "column",
2382
+ gap: 8,
2383
+ marginBottom: 20
2384
+ },
2385
+ children: x.map((h, v) => k("div", {
2386
+ style: {
2387
+ display: "flex",
2388
+ alignItems: "center",
2389
+ gap: 8
2390
+ },
2391
+ children: [
2392
+ i("label", {
2393
+ style: {
2394
+ fontSize: 11,
2395
+ fontWeight: 500,
2396
+ color: "rgb(12, 67, 173)",
2397
+ minWidth: 100,
2398
+ flexShrink: 0
2399
+ },
2400
+ children: h
2401
+ }),
2402
+ i("input", {
2403
+ type: "number",
2404
+ step: "0.1",
2405
+ value: S[h] ?? "",
2406
+ onChange: (F) => p((I) => ({
2407
+ ...I,
2408
+ [h]: F.target.value
2409
+ })),
2410
+ style: {
2411
+ ...dn,
2412
+ padding: "6px 8px",
2413
+ fontSize: 13,
2414
+ borderColor: S[h] ? "rgb(12, 67, 173)" : "#ccc",
2415
+ borderWidth: 1
2416
+ },
2417
+ placeholder: "0.0"
2418
+ })
2419
+ ]
2420
+ }, v))
2421
+ }),
2422
+ i("div", {
2423
+ style: {
2424
+ fontSize: 13,
2425
+ fontWeight: 600,
2426
+ color: "rgba(0,0,0,0.87)",
2427
+ marginBottom: 8
2428
+ },
2429
+ children: "Lengths"
2430
+ }),
2431
+ k("div", {
2432
+ style: {
2433
+ display: "flex",
2434
+ alignItems: "center",
2435
+ gap: 8
2436
+ },
2437
+ children: [
2438
+ i("label", {
2439
+ style: {
2440
+ fontSize: 11,
2441
+ fontWeight: 500,
2442
+ color: "rgb(12, 67, 173)",
2443
+ minWidth: 100,
2444
+ flexShrink: 0
2445
+ },
2446
+ children: "Starting Pt Height"
2447
+ }),
2448
+ i("input", {
2449
+ type: "number",
2450
+ step: "0.1",
2451
+ value: g,
2452
+ onChange: (h) => b(h.target.value),
2453
+ style: {
2454
+ ...dn,
2455
+ padding: "6px 8px",
2456
+ fontSize: 13,
2457
+ borderColor: g ? "rgb(12, 67, 173)" : "#ccc",
2458
+ borderWidth: 1
2459
+ },
2460
+ placeholder: "0.0"
2461
+ })
2462
+ ]
2463
+ })
2464
+ ]
2465
+ }),
2466
+ k("div", {
2467
+ style: {
2468
+ padding: "12px 20px",
2469
+ backgroundColor: "#fff",
2470
+ borderTop: "1px solid #e0e0e0",
2471
+ display: "flex",
2472
+ flexDirection: "column",
2473
+ gap: 8,
2474
+ flexShrink: 0
2475
+ },
2476
+ children: [
2477
+ i("button", {
2478
+ onClick: y,
2479
+ disabled: !P,
2480
+ style: {
2481
+ ...Wt,
2482
+ backgroundColor: P ? "rgb(12, 67, 173)" : "#e0e0e0",
2483
+ border: "none",
2484
+ color: P ? "#fff" : "#9e9e9e",
2485
+ cursor: P ? "pointer" : "not-allowed",
2486
+ padding: "6px 16px",
2487
+ fontSize: 13,
2488
+ width: "100%"
2489
+ },
2490
+ children: "Save Measurements"
2491
+ }),
2492
+ i("button", {
2493
+ onClick: () => L(true),
2494
+ style: {
2495
+ ...Wt,
2496
+ backgroundColor: "#fff",
2497
+ border: "1px solid #bdbdbd",
2498
+ color: "#666",
2499
+ padding: "6px 16px",
2500
+ fontSize: 12,
2501
+ width: "100%"
2502
+ },
2503
+ children: "Have Galileo Check My Measurements"
2504
+ })
2505
+ ]
2506
+ })
2507
+ ]
2508
+ });
2509
+ };
2510
+ function Mn(e, r, t) {
2511
+ const o = e.getAttribute("position"), l = t - r;
2512
+ if (l < 1) return null;
2513
+ const s = 30, c = l / s, a = [];
2514
+ for (let g = 0; g < s; g++) {
2515
+ const b = r + g * c, A = r + (g + 1) * c;
2516
+ let L = 0, z = 0, P = 0, y = 0;
2517
+ for (let M = 0; M < o.count; M++) {
2518
+ const h = o.getY(M);
2519
+ h >= b && h < A && (L += o.getX(M), z += h, P += o.getZ(M), y++);
2520
+ }
2521
+ y > 20 && a.push(new C(L / y, z / y, P / y));
2522
+ }
2523
+ if (a.length < 5) return null;
2524
+ const n = new C();
2525
+ for (const g of a) n.add(g);
2526
+ n.divideScalar(a.length);
2527
+ let m = 0, d = 0, f = 0, u = 0, x = 0, S = 0;
2528
+ for (const g of a) {
2529
+ const b = g.x - n.x, A = g.y - n.y, L = g.z - n.z;
2530
+ m += b * b, d += b * A, f += b * L, u += A * A, x += A * L, S += L * L;
2531
+ }
2532
+ let p = new C(0.01, 1, 0.01).normalize();
2533
+ for (let g = 0; g < 30; g++) {
2534
+ const b = m * p.x + d * p.y + f * p.z, A = d * p.x + u * p.y + x * p.z, L = f * p.x + x * p.y + S * p.z, z = new C(b, A, L), P = z.length();
2535
+ if (P < 1e-10 || (z.divideScalar(P), p.distanceTo(z) < 1e-8)) break;
2536
+ p = z;
2537
+ }
2538
+ return p.y < 0 && p.negate(), p;
2539
+ }
2540
+ const Qo = {
2541
+ pcaAxes: true,
2542
+ obb: true,
2543
+ obbAxis: true,
2544
+ shellComponents: true,
2545
+ ambientOcclusion: true,
2546
+ circumferenceScan: false,
2547
+ landmarkAxis: true,
2548
+ iterativePCA: false,
2549
+ fullRegionPCA: true
2550
+ }, qo = [
2551
+ "#ff4444",
2552
+ "#44cc44",
2553
+ "#4488ff"
2554
+ ];
2555
+ function zn(e) {
2556
+ const r = e.getAttribute("position"), t = r.count, o = new C();
2557
+ for (let p = 0; p < t; p++) o.x += r.getX(p), o.y += r.getY(p), o.z += r.getZ(p);
2558
+ o.divideScalar(t);
2559
+ let l = 0, s = 0, c = 0, a = 0, n = 0, m = 0;
2560
+ for (let p = 0; p < t; p++) {
2561
+ const g = r.getX(p) - o.x, b = r.getY(p) - o.y, A = r.getZ(p) - o.z;
2562
+ l += g * g, s += g * b, c += g * A, a += b * b, n += b * A, m += A * A;
2563
+ }
2564
+ l /= t, s /= t, c /= t, a /= t, n /= t, m /= t;
2565
+ const d = [], f = [], u = [
2566
+ [
2567
+ l,
2568
+ s,
2569
+ c
2570
+ ],
2571
+ [
2572
+ s,
2573
+ a,
2574
+ n
2575
+ ],
2576
+ [
2577
+ c,
2578
+ n,
2579
+ m
2580
+ ]
2581
+ ];
2582
+ for (let p = 0; p < 3; p++) {
2583
+ let g = new C(1 + p * 0.1, 1 - p * 0.1, 0.5 + p * 0.3).normalize(), b = 0;
2584
+ for (let A = 0; A < 100; A++) {
2585
+ const L = u[0][0] * g.x + u[0][1] * g.y + u[0][2] * g.z, z = u[1][0] * g.x + u[1][1] * g.y + u[1][2] * g.z, P = u[2][0] * g.x + u[2][1] * g.y + u[2][2] * g.z, y = new C(L, z, P);
2586
+ if (b = y.length(), b < 1e-12) break;
2587
+ if (y.divideScalar(b), g.distanceTo(y) < 1e-10) {
2588
+ g = y;
2589
+ break;
2590
+ }
2591
+ g = y;
2592
+ }
2593
+ d.push(g.clone()), f.push(b);
2594
+ for (let A = 0; A < 3; A++) for (let L = 0; L < 3; L++) {
2595
+ const z = [
2596
+ g.x,
2597
+ g.y,
2598
+ g.z
2599
+ ][A], P = [
2600
+ g.x,
2601
+ g.y,
2602
+ g.z
2603
+ ][L];
2604
+ u[A][L] -= b * z * P;
2605
+ }
2606
+ }
2607
+ const x = new C();
2608
+ for (let p = 0; p < t; p++) x.x += r.getX(p), x.y += r.getY(p), x.z += r.getZ(p);
2609
+ x.divideScalar(t);
2610
+ const S = [
2611
+ 0,
2612
+ 0,
2613
+ 0
2614
+ ];
2615
+ for (let p = 0; p < 3; p++) {
2616
+ let g = 1 / 0, b = -1 / 0;
2617
+ const A = d[p];
2618
+ for (let L = 0; L < t; L++) {
2619
+ const z = r.getX(L) - x.x, P = r.getY(L) - x.y, y = r.getZ(L) - x.z, M = z * A.x + P * A.y + y * A.z;
2620
+ M < g && (g = M), M > b && (b = M);
2621
+ }
2622
+ S[p] = (b - g) / 2;
2623
+ }
2624
+ return {
2625
+ axes: d,
2626
+ eigenvalues: f,
2627
+ center: x,
2628
+ halfExtents: S
2629
+ };
2630
+ }
2631
+ function er({ pca: e }) {
2632
+ return i("group", {
2633
+ children: e.axes.map((r, t) => {
2634
+ const o = e.center.clone().addScaledVector(r, e.halfExtents[t]), l = e.center.clone().addScaledVector(r, -e.halfExtents[t]);
2635
+ return i(fe, {
2636
+ points: [
2637
+ l,
2638
+ o
2639
+ ],
2640
+ color: qo[t],
2641
+ lineWidth: 2
2642
+ }, t);
2643
+ })
2644
+ });
2645
+ }
2646
+ function tr({ pca: e }) {
2647
+ const r = H(() => {
2648
+ const { center: t, axes: o, halfExtents: l } = e, s = [];
2649
+ for (let a = -1; a <= 1; a += 2) for (let n = -1; n <= 1; n += 2) for (let m = -1; m <= 1; m += 2) s.push(t.clone().addScaledVector(o[0], a * l[0]).addScaledVector(o[1], n * l[1]).addScaledVector(o[2], m * l[2]));
2650
+ return [
2651
+ [
2652
+ 0,
2653
+ 1
2654
+ ],
2655
+ [
2656
+ 2,
2657
+ 3
2658
+ ],
2659
+ [
2660
+ 4,
2661
+ 5
2662
+ ],
2663
+ [
2664
+ 6,
2665
+ 7
2666
+ ],
2667
+ [
2668
+ 0,
2669
+ 2
2670
+ ],
2671
+ [
2672
+ 1,
2673
+ 3
2674
+ ],
2675
+ [
2676
+ 4,
2677
+ 6
2678
+ ],
2679
+ [
2680
+ 5,
2681
+ 7
2682
+ ],
2683
+ [
2684
+ 0,
2685
+ 4
2686
+ ],
2687
+ [
2688
+ 1,
2689
+ 5
2690
+ ],
2691
+ [
2692
+ 2,
2693
+ 6
2694
+ ],
2695
+ [
2696
+ 3,
2697
+ 7
2698
+ ]
2699
+ ].map(([a, n]) => [
2700
+ s[a],
2701
+ s[n]
2702
+ ]);
2703
+ }, [
2704
+ e
2705
+ ]);
2706
+ return i("group", {
2707
+ children: r.map((t, o) => i(fe, {
2708
+ points: t,
2709
+ color: "#ffaa00",
2710
+ lineWidth: 1,
2711
+ transparent: true,
2712
+ opacity: 0.5
2713
+ }, o))
2714
+ });
2715
+ }
2716
+ function nr({ redPoint: e, greenPoint: r }) {
2717
+ const t = H(() => new C().subVectors(r, e).normalize(), [
2718
+ e,
2719
+ r
2720
+ ]), o = H(() => {
2721
+ const s = t.dot(new C(0, 1, 0));
2722
+ return Math.acos(Math.min(1, Math.abs(s))) * 180 / Math.PI;
2723
+ }, [
2724
+ t
2725
+ ]), l = o < 1 ? "#44ff44" : o < 5 ? "#ffcc00" : "#ff4444";
2726
+ return k("group", {
2727
+ children: [
2728
+ i(fe, {
2729
+ points: [
2730
+ e,
2731
+ r
2732
+ ],
2733
+ color: l,
2734
+ lineWidth: 3
2735
+ }),
2736
+ k("mesh", {
2737
+ position: e,
2738
+ children: [
2739
+ i("sphereGeometry", {
2740
+ args: [
2741
+ 1.5,
2742
+ 8,
2743
+ 8
2744
+ ]
2745
+ }),
2746
+ i("meshBasicMaterial", {
2747
+ color: "#ff4444"
2748
+ })
2749
+ ]
2750
+ }),
2751
+ k("mesh", {
2752
+ position: r,
2753
+ children: [
2754
+ i("sphereGeometry", {
2755
+ args: [
2756
+ 1.5,
2757
+ 8,
2758
+ 8
2759
+ ]
2760
+ }),
2761
+ i("meshBasicMaterial", {
2762
+ color: "#44ff44"
2763
+ })
2764
+ ]
2765
+ })
2766
+ ]
2767
+ });
2768
+ }
2769
+ function or({ geometry: e, redY: r, greenY: t, modelSize: o }) {
2770
+ const s = o * 0.15, c = H(() => {
2771
+ const a = [];
2772
+ let n = t - 10;
2773
+ const m = new C(0, 1, 0);
2774
+ for (; n > r; ) {
2775
+ const d = Math.min(n, t), f = Math.max(n, t), u = Mn(e, d, f);
2776
+ if (u) {
2777
+ const x = u.dot(m), S = Math.acos(Math.min(1, Math.abs(x))) * 180 / Math.PI;
2778
+ a.push({
2779
+ axis: u,
2780
+ regionMin: d,
2781
+ regionMax: f,
2782
+ angleDeg: S
2783
+ });
2784
+ }
2785
+ n -= 10;
2786
+ }
2787
+ return a;
2788
+ }, [
2789
+ e,
2790
+ r,
2791
+ t
2792
+ ]);
2793
+ return i("group", {
2794
+ children: c.map((a, n) => {
2795
+ const m = (a.regionMin + a.regionMax) / 2, d = new C(0, m, 0), f = d.clone().addScaledVector(a.axis, s), u = d.clone().addScaledVector(a.axis, -s), x = n / Math.max(1, c.length - 1), S = a.angleDeg < 0.5 ? `hsl(${120 - x * 120}, 80%, 60%)` : `hsl(${40 - a.angleDeg * 2}, 90%, 55%)`;
2796
+ return k("group", {
2797
+ children: [
2798
+ i(fe, {
2799
+ points: [
2800
+ u,
2801
+ f
2802
+ ],
2803
+ color: S,
2804
+ lineWidth: 1.5,
2805
+ transparent: true,
2806
+ opacity: 0.7
2807
+ }),
2808
+ i(fe, {
2809
+ points: [
2810
+ new C(-s * 0.3, a.regionMin, 0),
2811
+ new C(s * 0.3, a.regionMin, 0)
2812
+ ],
2813
+ color: S,
2814
+ lineWidth: 0.5,
2815
+ transparent: true,
2816
+ opacity: 0.3
2817
+ })
2818
+ ]
2819
+ }, n);
2820
+ })
2821
+ });
2822
+ }
2823
+ function rr({ geometry: e, redY: r, greenY: t, modelSize: o }) {
2824
+ const l = H(() => {
2825
+ const f = Mn(e, r, t);
2826
+ if (!f) return null;
2827
+ const u = f.dot(new C(0, 1, 0)), x = Math.acos(Math.min(1, Math.abs(u))) * 180 / Math.PI;
2828
+ return {
2829
+ axis: f,
2830
+ angleDeg: x
2831
+ };
2832
+ }, [
2833
+ e,
2834
+ r,
2835
+ t
2836
+ ]);
2837
+ if (!l) return null;
2838
+ const s = (r + t) / 2, c = new C(0, s, 0), a = o * 0.4, n = c.clone().addScaledVector(l.axis, a), m = c.clone().addScaledVector(l.axis, -a), d = l.angleDeg < 0.5 ? "#00ffff" : l.angleDeg < 2 ? "#ffcc00" : "#ff6600";
2839
+ return i("group", {
2840
+ children: i(fe, {
2841
+ points: [
2842
+ m,
2843
+ n
2844
+ ],
2845
+ color: d,
2846
+ lineWidth: 3,
2847
+ dashed: true,
2848
+ dashSize: 3,
2849
+ gapSize: 2
2850
+ })
2851
+ });
2852
+ }
2853
+ function ir({ pca: e, modelSize: r }) {
2854
+ const t = e.axes[0], o = r * 0.6, l = e.center.clone().addScaledVector(t, o), s = e.center.clone().addScaledVector(t, -o);
2855
+ return i(fe, {
2856
+ points: [
2857
+ s,
2858
+ l
2859
+ ],
2860
+ color: "#ff8800",
2861
+ lineWidth: 2,
2862
+ dashed: true,
2863
+ dashSize: 3,
2864
+ gapSize: 2
2865
+ });
2866
+ }
2867
+ function sr({ geometry: e, redY: r, greenY: t, modelSize: o, measurementGeometry: l }) {
2868
+ const s = H(() => {
2869
+ const d = l ?? e, f = Sn(d), u = new C(0, 1, 0), x = 5, p = t + 3 * 25.4, g = [];
2870
+ for (let h = r + x; h < p; h += x) {
2871
+ const v = vo(f, d, new C(0, h, 0), u);
2872
+ v > 0 && g.push({
2873
+ y: h,
2874
+ circ: v
2875
+ });
2876
+ }
2877
+ if (g.length < 5) return null;
2878
+ const b = t - r, A = r + b * 0.3, L = r + b * 0.7, z = g.filter((h) => h.y >= A && h.y <= L);
2879
+ if (z.length < 3) return null;
2880
+ const P = z.map((h) => h.circ).sort((h, v) => h - v), y = P[Math.floor(P.length / 2)], M = Math.max(...g.map((h) => h.circ));
2881
+ return {
2882
+ circumferences: g,
2883
+ baseline: y,
2884
+ maxCirc: M
2885
+ };
2886
+ }, [
2887
+ e,
2888
+ r,
2889
+ t
2890
+ ]);
2891
+ if (!s) return null;
2892
+ const { circumferences: c, baseline: a, maxCirc: n } = s, m = o * 0.3 / n;
2893
+ return k("group", {
2894
+ children: [
2895
+ c.map(({ y: d, circ: f }, u) => {
2896
+ const x = f / a, S = x > 1.6 ? "#ff4444" : x > 1.3 ? "#ffcc00" : "#22cc66", p = f * m;
2897
+ return i(fe, {
2898
+ points: [
2899
+ new C(-p, d, 0),
2900
+ new C(p, d, 0)
2901
+ ],
2902
+ color: S,
2903
+ lineWidth: 1.5,
2904
+ transparent: true,
2905
+ opacity: 0.6
2906
+ }, u);
2907
+ }),
2908
+ (() => {
2909
+ const d = a * 1.6 * m, f = c[0].y, u = c[c.length - 1].y;
2910
+ return k(Oe, {
2911
+ children: [
2912
+ i(fe, {
2913
+ points: [
2914
+ new C(-d, f, 0),
2915
+ new C(-d, u, 0)
2916
+ ],
2917
+ color: "#ff4444",
2918
+ lineWidth: 1,
2919
+ dashed: true,
2920
+ dashSize: 3,
2921
+ gapSize: 2,
2922
+ transparent: true,
2923
+ opacity: 0.4
2924
+ }),
2925
+ i(fe, {
2926
+ points: [
2927
+ new C(d, f, 0),
2928
+ new C(d, u, 0)
2929
+ ],
2930
+ color: "#ff4444",
2931
+ lineWidth: 1,
2932
+ dashed: true,
2933
+ dashSize: 3,
2934
+ gapSize: 2,
2935
+ transparent: true,
2936
+ opacity: 0.4
2937
+ })
2938
+ ]
2939
+ });
2940
+ })()
2941
+ ]
2942
+ });
2943
+ }
2944
+ function lr({ componentDebug: e }) {
2945
+ return i("group", {
2946
+ children: e.geometries.map((r, t) => {
2947
+ const o = e.colors[t] ?? "#888888", l = t === e.innerIdx;
2948
+ r.computeBoundingBox();
2949
+ const s = new C();
2950
+ return r.boundingBox.getCenter(s), k("group", {
2951
+ children: [
2952
+ i("mesh", {
2953
+ geometry: r,
2954
+ renderOrder: l ? 2 : 1,
2955
+ children: i("meshStandardMaterial", {
2956
+ color: o,
2957
+ transparent: true,
2958
+ opacity: l ? 0.5 : 0.2,
2959
+ side: O.DoubleSide,
2960
+ depthWrite: false,
2961
+ polygonOffset: true,
2962
+ polygonOffsetFactor: 1,
2963
+ polygonOffsetUnits: 1
2964
+ })
2965
+ }),
2966
+ i("mesh", {
2967
+ geometry: r,
2968
+ renderOrder: l ? 2 : 1,
2969
+ children: i("meshBasicMaterial", {
2970
+ color: o,
2971
+ wireframe: true,
2972
+ transparent: true,
2973
+ opacity: l ? 0.4 : 0.15
2974
+ })
2975
+ }),
2976
+ i("group", {
2977
+ position: s,
2978
+ children: i(Xe, {
2979
+ center: true,
2980
+ style: {
2981
+ pointerEvents: "none"
2982
+ },
2983
+ children: i("div", {
2984
+ style: {
2985
+ padding: "2px 8px",
2986
+ backgroundColor: "rgba(0,0,0,0.8)",
2987
+ borderRadius: 4,
2988
+ border: `1px solid ${o}`,
2989
+ whiteSpace: "nowrap"
2990
+ },
2991
+ children: i("span", {
2992
+ style: {
2993
+ fontSize: 11,
2994
+ color: o,
2995
+ fontFamily: "monospace",
2996
+ fontWeight: l ? 700 : 400
2997
+ },
2998
+ children: e.labels[t]
2999
+ })
3000
+ })
3001
+ })
3002
+ })
3003
+ ]
3004
+ }, t);
3005
+ })
3006
+ });
3007
+ }
3008
+ function ar({ geometry: e, aoData: r }) {
3009
+ const t = H(() => {
3010
+ const o = e.toNonIndexed(), l = o.getAttribute("position"), s = r.length, c = l.count, a = new Float32Array(c * 3);
3011
+ for (let n = 0; n < s && n * 3 + 2 < c; n++) {
3012
+ const m = r[n], d = m, f = m < 0.5 ? 0.8 - m * 1.2 : 0.2 * (1 - m), u = 1 - m;
3013
+ for (let x = 0; x < 3; x++) {
3014
+ const S = (n * 3 + x) * 3;
3015
+ a[S] = d, a[S + 1] = f, a[S + 2] = u;
3016
+ }
3017
+ }
3018
+ return o.setAttribute("color", new O.Float32BufferAttribute(a, 3)), o;
3019
+ }, [
3020
+ e,
3021
+ r
3022
+ ]);
3023
+ return H(() => () => t.dispose(), [
3024
+ t
3025
+ ]), i("mesh", {
3026
+ geometry: t,
3027
+ renderOrder: 3,
3028
+ children: i("meshBasicMaterial", {
3029
+ vertexColors: true,
3030
+ transparent: true,
3031
+ opacity: 0.85,
3032
+ side: O.DoubleSide,
3033
+ depthWrite: false
3034
+ })
3035
+ });
3036
+ }
3037
+ function cr({ mesh: e, layers: r, landmarkPoints: t, componentDebug: o, aoData: l, aoGeometry: s, measurementGeometry: c }) {
3038
+ const a = e.geometry, n = H(() => a.getAttribute("position") ? zn(a) : null, [
3039
+ a
3040
+ ]), m = H(() => !t || t.length < 2 ? null : {
3041
+ red: new C(t[1].position.x, t[1].position.y, t[1].position.z),
3042
+ green: new C(t[0].position.x, t[0].position.y, t[0].position.z)
3043
+ }, [
3044
+ t
3045
+ ]);
3046
+ return k("group", {
3047
+ children: [
3048
+ r.pcaAxes && n && i(er, {
3049
+ pca: n
3050
+ }),
3051
+ r.obb && n && i(tr, {
3052
+ pca: n
3053
+ }),
3054
+ r.obbAxis && n && i(ir, {
3055
+ pca: n,
3056
+ modelSize: n.halfExtents[0] ? Math.max(...n.halfExtents) * 2 : 100
3057
+ }),
3058
+ r.shellComponents && o && i(lr, {
3059
+ componentDebug: o
3060
+ }),
3061
+ r.ambientOcclusion && l && l.length > 0 && i(ar, {
3062
+ geometry: s ?? a,
3063
+ aoData: l
3064
+ }),
3065
+ r.circumferenceScan && m && i(sr, {
3066
+ geometry: a,
3067
+ redY: m.red.y,
3068
+ greenY: m.green.y,
3069
+ modelSize: (n == null ? void 0 : n.halfExtents[0]) ? Math.max(...n.halfExtents) * 2 : 100,
3070
+ measurementGeometry: c
3071
+ }),
3072
+ c && i("mesh", {
3073
+ geometry: c,
3074
+ renderOrder: 5,
3075
+ children: i("meshBasicMaterial", {
3076
+ color: "#00ccff",
3077
+ wireframe: true,
3078
+ transparent: true,
3079
+ opacity: 0.15,
3080
+ depthWrite: false
3081
+ })
3082
+ }),
3083
+ r.landmarkAxis && m && i(nr, {
3084
+ redPoint: m.red,
3085
+ greenPoint: m.green
3086
+ }),
3087
+ r.iterativePCA && m && i(or, {
3088
+ geometry: a,
3089
+ redY: m.red.y,
3090
+ greenY: m.green.y,
3091
+ modelSize: (n == null ? void 0 : n.halfExtents[0]) ? Math.max(...n.halfExtents) * 2 : 100
3092
+ }),
3093
+ r.fullRegionPCA && m && i(rr, {
3094
+ geometry: a,
3095
+ redY: m.red.y,
3096
+ greenY: m.green.y,
3097
+ modelSize: (n == null ? void 0 : n.halfExtents[0]) ? Math.max(...n.halfExtents) * 2 : 100
3098
+ })
3099
+ ]
3100
+ });
3101
+ }
3102
+ function dr({ mesh: e }) {
3103
+ const r = e.geometry, t = H(() => {
3104
+ if (!r.getAttribute("position")) return null;
3105
+ const s = zn(r), c = s.axes[0], a = s.halfExtents[0] * 1.3;
3106
+ return {
3107
+ axis: c,
3108
+ center: s.center,
3109
+ halfLen: a
3110
+ };
3111
+ }, [
3112
+ r
3113
+ ]);
3114
+ if (!t) return null;
3115
+ const o = t.center.clone().addScaledVector(t.axis, t.halfLen), l = t.center.clone().addScaledVector(t.axis, -t.halfLen);
3116
+ return i(fe, {
3117
+ points: [
3118
+ l,
3119
+ o
3120
+ ],
3121
+ color: "#666",
3122
+ lineWidth: 1,
3123
+ dashed: true,
3124
+ dashSize: 4,
3125
+ gapSize: 3,
3126
+ transparent: true,
3127
+ opacity: 0.4,
3128
+ depthTest: false,
3129
+ renderOrder: 999
3130
+ });
3131
+ }
3132
+ const kn = [
3133
+ {
3134
+ key: "pcaAxes",
3135
+ label: "PCA Axes (full mesh)",
3136
+ color: "#ff4444",
3137
+ group: "Geometry"
3138
+ },
3139
+ {
3140
+ key: "obb",
3141
+ label: "OBB Wireframe",
3142
+ color: "#ffaa00",
3143
+ group: "Geometry"
3144
+ },
3145
+ {
3146
+ key: "obbAxis",
3147
+ label: "OBB Primary Axis",
3148
+ color: "#ff8800",
3149
+ group: "Geometry"
3150
+ },
3151
+ {
3152
+ key: "shellComponents",
3153
+ label: "Shell Components",
3154
+ color: "#4488ff",
3155
+ group: "Shell Detection"
3156
+ },
3157
+ {
3158
+ key: "ambientOcclusion",
3159
+ label: "Ambient Occlusion (inner faces)",
3160
+ color: "#ff6644",
3161
+ group: "Shell Detection"
3162
+ },
3163
+ {
3164
+ key: "circumferenceScan",
3165
+ label: "Circumference Scan (step 4.5)",
3166
+ color: "#22cc66",
3167
+ group: "Isolation",
3168
+ hideWhenDoubleShell: true
3169
+ },
3170
+ {
3171
+ key: "landmarkAxis",
3172
+ label: "Landmark Axis (rough align)",
3173
+ color: "#44ff44",
3174
+ group: "Alignment"
3175
+ },
3176
+ {
3177
+ key: "iterativePCA",
3178
+ label: "Iterative PCA (step 5)",
3179
+ color: "#cc66ff",
3180
+ group: "Alignment"
3181
+ },
3182
+ {
3183
+ key: "fullRegionPCA",
3184
+ label: "Full Region PCA (step 7)",
3185
+ color: "#00ffff",
3186
+ group: "Alignment"
3187
+ }
3188
+ ], fr = [
3189
+ ...new Set(kn.map((e) => e.group))
3190
+ ];
3191
+ function ur({ layers: e, onToggleLayer: r, isDoubleShell: t }) {
3192
+ return k("div", {
3193
+ style: {
3194
+ position: "absolute",
3195
+ top: 16,
3196
+ left: 16,
3197
+ zIndex: 20,
3198
+ backgroundColor: "rgba(7, 6, 17, 0.9)",
3199
+ border: "1px solid rgba(255,255,255,0.1)",
3200
+ borderRadius: 6,
3201
+ padding: "10px 12px",
3202
+ fontFamily: "system-ui, sans-serif",
3203
+ fontSize: 12,
3204
+ color: "#ccc",
3205
+ minWidth: 180,
3206
+ backdropFilter: "blur(8px)"
3207
+ },
3208
+ children: [
3209
+ i("div", {
3210
+ style: {
3211
+ fontSize: 10,
3212
+ fontWeight: 600,
3213
+ textTransform: "uppercase",
3214
+ letterSpacing: "0.5px",
3215
+ color: "#888",
3216
+ marginBottom: 8
3217
+ },
3218
+ children: "Debug Layers"
3219
+ }),
3220
+ fr.map((o) => {
3221
+ const l = kn.filter((s) => s.group === o && !(s.hideWhenDoubleShell && t));
3222
+ return l.length === 0 ? null : k("div", {
3223
+ children: [
3224
+ i("div", {
3225
+ style: {
3226
+ fontSize: 9,
3227
+ fontWeight: 600,
3228
+ textTransform: "uppercase",
3229
+ letterSpacing: "0.5px",
3230
+ color: "#555",
3231
+ marginTop: 6,
3232
+ marginBottom: 4
3233
+ },
3234
+ children: o
3235
+ }),
3236
+ l.map(({ key: s, label: c, color: a }) => k("label", {
3237
+ style: {
3238
+ display: "flex",
3239
+ alignItems: "center",
3240
+ gap: 8,
3241
+ padding: "3px 0",
3242
+ cursor: "pointer",
3243
+ userSelect: "none"
3244
+ },
3245
+ children: [
3246
+ i("input", {
3247
+ type: "checkbox",
3248
+ checked: e[s],
3249
+ onChange: () => r(s),
3250
+ style: {
3251
+ accentColor: a,
3252
+ width: 14,
3253
+ height: 14,
3254
+ cursor: "pointer"
3255
+ }
3256
+ }),
3257
+ i("span", {
3258
+ style: {
3259
+ width: 8,
3260
+ height: 8,
3261
+ borderRadius: "50%",
3262
+ backgroundColor: a,
3263
+ opacity: e[s] ? 1 : 0.3,
3264
+ flexShrink: 0
3265
+ }
3266
+ }),
3267
+ i("span", {
3268
+ style: {
3269
+ opacity: e[s] ? 1 : 0.5
3270
+ },
3271
+ children: c
3272
+ })
3273
+ ]
3274
+ }, s))
3275
+ ]
3276
+ }, o);
3277
+ })
3278
+ ]
3279
+ });
3280
+ }
3281
+ const pr = ({ config: e, spacingType: r, scanUrl: t, formMeasurements: o, onComplete: l, isDebugUser: s = false, onAnalyticsEvent: c, wasmModule: a }) => {
3282
+ const [n, m] = W(null), [d, f] = W(0), [u, x] = W(false), [S, p] = W(false), [g, b] = W(""), [A, L] = W("3D"), [z, P] = W(r === "AK" ? 2 : 1), [y, M] = W(false), [h, v] = W(null), [F, I] = W(r ?? null), [_, E] = W("mm"), [V, N] = W(false), [J, ye] = W(""), [ae, ue] = W(false), [ie, Q] = W(false), [Y, he] = W(false), [Z, ge] = W(false), [me, pe] = W(null), [$, ne] = W(null), [xe, Me] = W(null), [we, re] = W(false), [j, X] = W([]), [Le, Ie] = W(null), [Ge, se] = W(null), [Ae, Tt] = W(null), [xt, Fn] = W(null), [Pn, Ot] = W(false), [bt, Ln] = W(null), [yt, De] = W(null), [We, In] = W(false), [$t, Dn] = W(Qo), [$e, Ht] = W("obj"), [Se, wt] = W(o), [Ue, Vt] = W(true), [He, St] = W(false), [vt, _n] = W(false), [ze, rt] = W(false), [Rn, Ct] = W(false), [Je, Wn] = W(null), [Bn, En] = W(void 0), [Tn, On] = W(void 0), [jt] = W("#c8c8c8"), [$n] = W(1), [Ze, Hn] = W(false), [Mt, Nt] = W([]), it = le(null), Ve = le(null), zt = le(false), Vn = le(null), kt = le(null), At = le(null), Qe = te(async () => {
3283
+ if (At.current) try {
3284
+ const w = (await import("./html2canvas.esm-Dmi1NfiH.js")).default, D = At.current, B = 2, R = async (K = false) => {
3285
+ const oe = await w(D, {
3286
+ backgroundColor: null,
3287
+ useCORS: true,
3288
+ scale: B,
3289
+ ignoreElements: (nt) => {
3290
+ var _a, _b;
3291
+ return ((_a = nt.style) == null ? void 0 : _a.zIndex) === "10" || ((_b = nt.hasAttribute) == null ? void 0 : _b.call(nt, "data-finalizing-overlay"));
3292
+ }
3293
+ }), ee = D.getBoundingClientRect(), Fe = ee.width, Be = ee.height;
3294
+ let Ce, ke, be, Te;
3295
+ if (K) {
3296
+ const _e = oe.getContext("2d").getImageData(0, 0, oe.width, oe.height).data;
3297
+ let Re = oe.width, Ee = oe.height, ot = 0, at = 0;
3298
+ for (let je = 0; je < oe.height; je++) for (let Ne = 0; Ne < oe.width; Ne++) {
3299
+ const to = (je * oe.width + Ne) * 4;
3300
+ _e[to + 3] > 20 && (Ne < Re && (Re = Ne), Ne > ot && (ot = Ne), je < Ee && (Ee = je), je > at && (at = je));
3301
+ }
3302
+ ot <= Re && (Re = 0, Ee = 0, ot = oe.width, at = oe.height), Ce = Re / B, ke = Ee / B, be = ot / B, Te = at / B;
3303
+ } else {
3304
+ const nt = D.querySelectorAll("[style*='pointer-events: none']");
3305
+ Ce = 1 / 0, ke = 1 / 0, be = -1 / 0, Te = -1 / 0, nt.forEach((_t) => {
3306
+ const _e = _t.getBoundingClientRect();
3307
+ if (_e.width === 0 || _e.height === 0) return;
3308
+ const Re = _e.left - ee.left, Ee = _e.top - ee.top;
3309
+ Re < Ce && (Ce = Re), Ee < ke && (ke = Ee), Re + _e.width > be && (be = Re + _e.width), Ee + _e.height > Te && (Te = Ee + _e.height);
3310
+ }), Ce === 1 / 0 && (Ce = 0, ke = 0, be = Fe, Te = Be);
3311
+ }
3312
+ const en = Math.max(Fe, Be) * 0.03, tn = Math.max(Fe, Be) * 0.06;
3313
+ Ce = Math.max(0, Ce - en), ke = Math.max(0, ke - tn), be = Math.min(Fe, be + en), Te = Math.min(Be, Te + tn);
3314
+ const It = (be - Ce) * B, Dt = (Te - ke) * B, qn = Math.max(0, Ce * B), eo = Math.max(0, ke * B), lt = document.createElement("canvas");
3315
+ return lt.width = Math.round(It), lt.height = Math.round(Dt), lt.getContext("2d").drawImage(oe, Math.round(qn), Math.round(eo), Math.round(It), Math.round(Dt), 0, 0, Math.round(It), Math.round(Dt)), lt.toDataURL("image/png");
3316
+ };
3317
+ kt.current && kt.current(), await new Promise((K) => setTimeout(K, 100)), await new Promise((K) => requestAnimationFrame(() => requestAnimationFrame(K)));
3318
+ const ce = await R();
3319
+ L("2D"), await new Promise((K) => setTimeout(K, 200)), await new Promise((K) => requestAnimationFrame(() => requestAnimationFrame(K)));
3320
+ const G = await R(true);
3321
+ return L("3D"), {
3322
+ frontal_view_png: ce,
3323
+ side_view_png: G
3324
+ };
3325
+ } catch {
3326
+ return;
3327
+ }
3328
+ }, []), ve = te((w) => {
3329
+ const D = /* @__PURE__ */ new Date(), B = `${String(D.getHours()).padStart(2, "0")}:${String(D.getMinutes()).padStart(2, "0")}:${String(D.getSeconds()).padStart(2, "0")}.${String(D.getMilliseconds()).padStart(3, "0")}`;
3330
+ Nt((R) => [
3331
+ ...R.slice(-200),
3332
+ `[${B}] ${w}`
3333
+ ]);
3334
+ }, []), { landmarkPoints: T, clearLandmarkPoints: jn, addLandmarkPoint: Yt, removeLandmarkPoint: Xt, updateLandmarkPositions: Gt, setAligned: Zt, isAligned: q, setCut: Kt, isCut: Ft, reset: Ut } = Et();
3335
+ U(() => {
3336
+ Ut();
3337
+ }, [
3338
+ Ut
3339
+ ]);
3340
+ const st = z * ut;
3341
+ U(() => {
3342
+ if (!s || T.length === 0) return;
3343
+ const w = T[T.length - 1];
3344
+ ve(`LANDMARK[${T.length - 1}]: placed at (${w.position.x.toFixed(1)}, ${w.position.y.toFixed(1)}, ${w.position.z.toFixed(1)}) face=${w.faceIndex}`);
3345
+ }, [
3346
+ T.length,
3347
+ s,
3348
+ ve
3349
+ ]), U(() => {
3350
+ s && q && ve("STATE: mesh aligned");
3351
+ }, [
3352
+ q,
3353
+ s,
3354
+ ve
3355
+ ]), U(() => {
3356
+ s && Ft && ve("STATE: mesh cut");
3357
+ }, [
3358
+ Ft,
3359
+ s,
3360
+ ve
3361
+ ]), U(() => {
3362
+ it.current && (it.current.scrollTop = it.current.scrollHeight);
3363
+ }, [
3364
+ Mt
3365
+ ]);
3366
+ const Jt = H(() => xe ? new O.Mesh(xe) : null, [
3367
+ xe
3368
+ ]);
3369
+ U(() => {
3370
+ o && wt(o);
3371
+ }, [
3372
+ o
3373
+ ]), U(() => {
3374
+ o || wt(void 0);
3375
+ }, [
3376
+ z
3377
+ ]);
3378
+ const Pt = le(false);
3379
+ U(() => {
3380
+ if (!q || j.length === 0 || Pt.current || !c) return;
3381
+ Pt.current = true;
3382
+ const w = T.length >= 3 ? Math.abs(T[2].position.y - T[0].position.y) : null;
3383
+ c("dimensions_calculated", {
3384
+ spacing_type: F,
3385
+ source_unit: "mm",
3386
+ file_format: $e,
3387
+ measurement_source: "scan_derived",
3388
+ is_double_wall: Y,
3389
+ is_unit_converted: false,
3390
+ form_measurements: (Se == null ? void 0 : Se.filter((D) => D != null)) ?? null,
3391
+ scan_measurements: j.map((D) => +(D.modifiedValue ?? D.originalValue).toFixed(1)),
3392
+ measurement_variance: Se ? j.map((D, B) => {
3393
+ const R = Se[B];
3394
+ return R == null ? null : +((D.modifiedValue ?? D.originalValue) - R).toFixed(1);
3395
+ }) : null,
3396
+ frontal_height: w !== null ? +w.toFixed(1) : null
3397
+ });
3398
+ }, [
3399
+ q,
3400
+ j
3401
+ ]), U(() => {
3402
+ a !== void 0 && (Ve.current = a), Hn(true);
3403
+ }, [
3404
+ a
3405
+ ]);
3406
+ const qe = te((w, D) => {
3407
+ w.computeBoundingBox();
3408
+ const B = w.boundingBox, R = new C();
3409
+ B.getCenter(R), w.translate(-R.x, -R.y, -R.z), w.computeBoundingBox();
3410
+ const ce = w.boundingBox, G = new C();
3411
+ ce.getSize(G), f(Math.max(G.x, G.y, G.z));
3412
+ const K = new O.Mesh(w, new O.MeshStandardMaterial({
3413
+ color: 8947848,
3414
+ side: O.DoubleSide
3415
+ }));
3416
+ m(K), ue(D), Q(true), ge(false), zt.current = false;
3417
+ }, []), et = te(async (w, D) => {
3418
+ De(null);
3419
+ const B = D.toLowerCase(), R = B.endsWith(".stl");
3420
+ if (!B.endsWith(".obj") && !R) {
3421
+ De("Unsupported file format. Please use OBJ or STL.");
3422
+ return;
3423
+ }
3424
+ Ht(R ? "stl" : "obj"), p(true), b("Processing file..."), ve(`FILE_LOAD: ${D} (${R ? "STL" : "OBJ"})`);
3425
+ try {
3426
+ let G;
3427
+ if (R) if (b("Converting STL..."), w instanceof ArrayBuffer) {
3428
+ const ee = new Blob([
3429
+ w
3430
+ ]), Fe = new File([
3431
+ ee
3432
+ ], D);
3433
+ G = await Rt(Fe);
3434
+ } else {
3435
+ const ee = new Blob([
3436
+ w
3437
+ ]), Fe = new File([
3438
+ ee
3439
+ ], D);
3440
+ G = await Rt(Fe);
3441
+ }
3442
+ else G = typeof w == "string" ? w : new TextDecoder().decode(w);
3443
+ const K = performance.now(), oe = Ve.current ? await bo(G, Ve.current, (ee) => {
3444
+ b(ee), ve(`PREPROCESS: ${ee}`);
3445
+ }) : null;
3446
+ if (oe) ve(`PREPROCESS: done in ${(performance.now() - K).toFixed(0)}ms \u2014 unit=${oe.detectedUnit}, scaled=${oe.wasScaled}`), e.showAmputationModal && !r ? (v(oe), M(true)) : qe(oe.geometry, oe.wasScaled);
3447
+ else {
3448
+ b("Using fallback loader...");
3449
+ const ee = yo(G);
3450
+ ee ? e.showAmputationModal && !r ? (v({
3451
+ geometry: ee,
3452
+ wasScaled: false
3453
+ }), M(true)) : qe(ee, false) : De("Failed to parse the mesh.");
3454
+ }
3455
+ } catch (G) {
3456
+ De(G instanceof Error ? G.message : "Failed to process the mesh file.");
3457
+ } finally {
3458
+ p(false), b("");
3459
+ }
3460
+ }, [
3461
+ Ze,
3462
+ e.showAmputationModal,
3463
+ r,
3464
+ qe
3465
+ ]);
3466
+ U(() => {
3467
+ if (!t || !Ze) return;
3468
+ (async () => {
3469
+ p(true), b("Loading scan...");
3470
+ try {
3471
+ const D = await fetch(t);
3472
+ if (!D.ok) throw new Error(`Failed to download scan: ${D.status}`);
3473
+ const R = new URL(t).pathname.split("/").pop() || "scan.obj";
3474
+ if (R.toLowerCase().endsWith(".stl")) {
3475
+ const G = await D.arrayBuffer();
3476
+ await et(G, R);
3477
+ } else {
3478
+ const G = await D.text();
3479
+ await et(G, R);
3480
+ }
3481
+ } catch (D) {
3482
+ De(D instanceof Error ? D.message : "Failed to load scan from URL."), p(false), b("");
3483
+ }
3484
+ })();
3485
+ }, [
3486
+ t,
3487
+ Ze
3488
+ ]);
3489
+ const Nn = te((w) => {
3490
+ w.preventDefault(), x(true);
3491
+ }, []), Yn = te((w) => {
3492
+ w.preventDefault(), x(false);
3493
+ }, []), Xn = te(async (w) => {
3494
+ if (w.preventDefault(), x(false), !Ze) {
3495
+ De("WASM module is still loading. Please wait.");
3496
+ return;
3497
+ }
3498
+ const D = w.dataTransfer.files[0];
3499
+ if (!D) return;
3500
+ const B = D.name.toLowerCase();
3501
+ if (!B.endsWith(".obj") && !B.endsWith(".stl")) {
3502
+ De("Please drop an OBJ or STL file.");
3503
+ return;
3504
+ }
3505
+ if (B.endsWith(".stl")) {
3506
+ Ht("stl"), p(true), b("Converting STL...");
3507
+ try {
3508
+ const R = await Rt(D);
3509
+ await et(R, D.name.replace(/\.stl$/i, ".obj"));
3510
+ } catch (R) {
3511
+ De(R instanceof Error ? R.message : "Failed to process STL file."), p(false), b("");
3512
+ }
3513
+ } else {
3514
+ const R = await D.text();
3515
+ await et(R, D.name);
3516
+ }
3517
+ }, [
3518
+ Ze,
3519
+ et
3520
+ ]), Gn = te((w) => {
3521
+ I(w), P(w === "AK" ? 2 : 1), M(false), h && (qe(h.geometry, h.wasScaled), v(null)), c == null ? void 0 : c("file_loaded", {
3522
+ spacing_type: w,
3523
+ file_format: $e,
3524
+ is_double_wall: false
3525
+ });
3526
+ }, [
3527
+ h,
3528
+ qe,
3529
+ c,
3530
+ $e
3531
+ ]);
3532
+ U(() => {
3533
+ if (!n || T.length !== 1 || !Ve.current || zt.current) return;
3534
+ zt.current = true;
3535
+ const w = T[0], D = Ve.current, B = n.geometry, { positions: R, indices: ce } = pt(B), G = new Float32Array([
3536
+ w.position.x,
3537
+ w.position.y,
3538
+ w.position.z
3539
+ ]), K = D.detect_shell(R, ce, G, 40), oe = K.details(), ee = K.is_double_shell();
3540
+ ve(`SHELL_DETECT: ${ee ? "DOUBLE" : "SINGLE"} \u2014 ${oe}`), ee && (he(true), re(true), ve(`SHELL_DETECT: double shell, thickness=${K.thickness().toFixed(1)}mm`));
3541
+ }, [
3542
+ n,
3543
+ T,
3544
+ ve
3545
+ ]);
3546
+ const Zn = te(() => {
3547
+ if (!n || T.length < 2) return;
3548
+ N(true), ye("Please wait..."), ve("PIPELINE: starting processing pipeline...");
3549
+ const w = performance.now();
3550
+ setTimeout(() => {
3551
+ const D = [
3552
+ T[1],
3553
+ T[0],
3554
+ ...T.slice(2)
3555
+ ];
3556
+ Mo(n, D, ut, {
3557
+ onStatus: (B) => {
3558
+ ye(B), ve(`PIPELINE: ${B}`);
3559
+ },
3560
+ addLandmarkPoint: Yt,
3561
+ removeLandmarkPoint: Xt,
3562
+ updateLandmarkPositions: (B) => {
3563
+ const R = [
3564
+ B[1],
3565
+ B[0],
3566
+ ...B.slice(2)
3567
+ ];
3568
+ Gt(R);
3569
+ },
3570
+ setAligned: Zt,
3571
+ setCut: Kt,
3572
+ setModelSize: f,
3573
+ setOriginalEndY: Fn,
3574
+ setAdjustedStartY: se,
3575
+ setAdjustedEndY: Tt,
3576
+ setError: De,
3577
+ setDoubleShell: (B) => {
3578
+ he(B), re(true);
3579
+ },
3580
+ setAoData: (B, R) => {
3581
+ pe(B), ne(R ?? null);
3582
+ },
3583
+ setInnerShellExtracted: ge,
3584
+ setMeasurementGeometry: Me,
3585
+ setWasmSlices: Ie,
3586
+ wasmModule: Ve.current ?? void 0
3587
+ }), ve(`PIPELINE: completed in ${(performance.now() - w).toFixed(0)}ms`), Pt.current = false, N(false);
3588
+ }, 50);
3589
+ }, [
3590
+ n,
3591
+ T,
3592
+ Gt,
3593
+ Zt,
3594
+ Yt,
3595
+ Xt,
3596
+ Kt,
3597
+ Z
3598
+ ]), Qt = le(false);
3599
+ U(() => {
3600
+ q && j.length > 0 && !Qt.current && (Qt.current = true, St(true));
3601
+ }, [
3602
+ q,
3603
+ j.length
3604
+ ]);
3605
+ const tt = H(() => {
3606
+ var _a;
3607
+ if (!n || T.length < 3) return 0;
3608
+ if (Y) return Math.abs(T[0].position.y - T[2].position.y);
3609
+ const w = n.geometry;
3610
+ w.computeBoundingBox();
3611
+ const D = ((_a = w.boundingBox) == null ? void 0 : _a.min.y) ?? 0;
3612
+ return Math.abs(T[0].position.y - D);
3613
+ }, [
3614
+ n,
3615
+ T,
3616
+ Y
3617
+ ]), Kn = te((w) => {
3618
+ Wn(w), wt(w.circumferences), Vt(true), _n(true);
3619
+ }, []), qt = te(async (w) => {
3620
+ if (l) {
3621
+ St(false), Ct(false), rt(true);
3622
+ try {
3623
+ const D = n ? await Promise.race([
3624
+ Qe(),
3625
+ new Promise((B) => setTimeout(() => B(void 0), 8e3))
3626
+ ]) : void 0;
3627
+ l({
3628
+ spacingType: F ?? "BK",
3629
+ sourceUnit: "mm",
3630
+ fileFormat: $e,
3631
+ measurementSource: "form_provided",
3632
+ isDoubleWall: Y,
3633
+ isUnitConverted: false,
3634
+ formMeasurements: Se,
3635
+ scanMeasurements: j,
3636
+ frontalHeight: tt,
3637
+ transverseML: 0,
3638
+ transverseAP: 0,
3639
+ scanUrl: t,
3640
+ decision: "skip",
3641
+ skipReason: w,
3642
+ screenshots: D
3643
+ });
3644
+ } finally {
3645
+ rt(false);
3646
+ }
3647
+ }
3648
+ }, [
3649
+ l,
3650
+ n,
3651
+ F,
3652
+ $e,
3653
+ Y,
3654
+ Se,
3655
+ j,
3656
+ tt,
3657
+ t,
3658
+ Qe
3659
+ ]), Lt = te(async (w) => {
3660
+ if (!(!l || !n || j.length === 0 || !F)) {
3661
+ rt(true);
3662
+ try {
3663
+ let D = 0, B = 0;
3664
+ if (T.length >= 2) {
3665
+ const ce = n.geometry, K = T[0].position.y;
3666
+ try {
3667
+ const oe = Sn(ce), ee = Ye(oe, ce, K);
3668
+ if (ee.linePoints.length >= 2) {
3669
+ let Fe = ee.linePoints[0], Be = ee.linePoints[0], Ce = ee.linePoints[0], ke = ee.linePoints[0];
3670
+ for (const be of ee.linePoints) be.x < Fe.x && (Fe = be), be.x > Be.x && (Be = be), be.z < Ce.z && (Ce = be), be.z > ke.z && (ke = be);
3671
+ D = new C(Fe.x, K, Fe.z).distanceTo(new C(Be.x, K, Be.z)), B = new C(Ce.x, K, Ce.z).distanceTo(new C(ke.x, K, ke.z));
3672
+ }
3673
+ } catch {
3674
+ }
3675
+ }
3676
+ const R = await Promise.race([
3677
+ Qe(),
3678
+ new Promise((ce) => setTimeout(() => ce(void 0), 8e3))
3679
+ ]);
3680
+ l({
3681
+ spacingType: F,
3682
+ sourceUnit: "mm",
3683
+ fileFormat: $e,
3684
+ measurementSource: w === "use_form_measurements" ? "form_provided" : "scan_derived",
3685
+ isDoubleWall: Y,
3686
+ isUnitConverted: false,
3687
+ formMeasurements: Se,
3688
+ scanMeasurements: j,
3689
+ frontalHeight: (Je == null ? void 0 : Je.frontalHeight) ?? tt,
3690
+ transverseML: D,
3691
+ transverseAP: B,
3692
+ scanUrl: t,
3693
+ decision: w,
3694
+ userEnteredMeasurements: Je ?? void 0,
3695
+ screenshots: R
3696
+ });
3697
+ } finally {
3698
+ rt(false);
3699
+ }
3700
+ }
3701
+ }, [
3702
+ l,
3703
+ n,
3704
+ j,
3705
+ F,
3706
+ T,
3707
+ $e,
3708
+ Y,
3709
+ Se,
3710
+ t,
3711
+ Je,
3712
+ tt,
3713
+ Qe
3714
+ ]), Un = H(() => {
3715
+ if (!Se || j.length === 0) return false;
3716
+ const w = Math.min(Se.length, j.length);
3717
+ if (w === 0) return false;
3718
+ for (let D = 0; D < w; D++) {
3719
+ const B = Se[D], R = j[D];
3720
+ if (!R || B == null || B === 0) continue;
3721
+ const ce = R.modifiedValue ?? R.originalValue;
3722
+ if (Math.abs(ce - B) > 7) return false;
3723
+ }
3724
+ return true;
3725
+ }, [
3726
+ Se,
3727
+ j
3728
+ ]), Jn = vt ? 5 : q && He || q ? 4 : n ? T.length === 0 ? 2 : 3 : 1, Qn = [
3729
+ {
3730
+ label: "Load File",
3731
+ number: 1
3732
+ },
3733
+ {
3734
+ label: F === "AK" ? "Set IT" : "Set MPT",
3735
+ number: 2
3736
+ },
3737
+ {
3738
+ label: "Set Origin",
3739
+ number: 3
3740
+ },
3741
+ {
3742
+ label: "Measurements",
3743
+ number: 4
3744
+ },
3745
+ {
3746
+ label: "Review",
3747
+ number: 5
3748
+ }
3749
+ ];
3750
+ return k(po.Provider, {
3751
+ value: e,
3752
+ children: [
3753
+ k("div", {
3754
+ style: {
3755
+ flex: 1,
3756
+ display: "flex",
3757
+ flexDirection: "column",
3758
+ backgroundColor: "#F9F9FA",
3759
+ minWidth: 0,
3760
+ position: "relative",
3761
+ height: "100%"
3762
+ },
3763
+ children: [
3764
+ e.showToolbar && i("div", {
3765
+ style: {
3766
+ height: 83,
3767
+ backgroundColor: "#9e9e9e",
3768
+ flexShrink: 0,
3769
+ position: "relative",
3770
+ overflow: "hidden"
3771
+ },
3772
+ children: i("div", {
3773
+ style: {
3774
+ position: "absolute",
3775
+ inset: 0,
3776
+ opacity: 0.1,
3777
+ backgroundImage: "repeating-linear-gradient(45deg, transparent, transparent 10px, #fff 10px, #fff 12px)",
3778
+ pointerEvents: "none"
3779
+ }
3780
+ })
3781
+ }),
3782
+ i(jo, {
3783
+ steps: Qn,
3784
+ currentStep: Jn
3785
+ }),
3786
+ k("div", {
3787
+ style: {
3788
+ flex: 1,
3789
+ display: "flex",
3790
+ flexDirection: "column",
3791
+ minHeight: 0
3792
+ },
3793
+ children: [
3794
+ k("div", {
3795
+ style: {
3796
+ flex: 1,
3797
+ display: "flex",
3798
+ flexDirection: "row",
3799
+ minHeight: 0
3800
+ },
3801
+ children: [
3802
+ q && He && F && i("div", {
3803
+ style: {
3804
+ width: 340,
3805
+ flexShrink: 0,
3806
+ borderRight: "1px solid #e0e0e0",
3807
+ overflow: "hidden"
3808
+ },
3809
+ children: i(Jo, {
3810
+ amputationType: F,
3811
+ spacingInches: z,
3812
+ scanMeasurements: j,
3813
+ scanFrontalHeight: tt,
3814
+ onSave: Kn,
3815
+ onSkip: qt,
3816
+ onFormChange: En,
3817
+ onHeightChange: On,
3818
+ initialValues: Se,
3819
+ initialFrontalHeight: Je == null ? void 0 : Je.frontalHeight
3820
+ })
3821
+ }),
3822
+ k("div", {
3823
+ ref: At,
3824
+ style: {
3825
+ flex: 1,
3826
+ position: "relative",
3827
+ minHeight: 0,
3828
+ overflow: "hidden"
3829
+ },
3830
+ onDragOver: e.showDragDrop ? Nn : void 0,
3831
+ onDragLeave: e.showDragDrop ? Yn : void 0,
3832
+ onDrop: e.showDragDrop ? Xn : void 0,
3833
+ children: [
3834
+ e.showDragDrop && !n && !S && i("div", {
3835
+ style: {
3836
+ position: "absolute",
3837
+ inset: 16,
3838
+ border: "3px dashed #ccc",
3839
+ borderRadius: 4,
3840
+ display: "flex",
3841
+ alignItems: "center",
3842
+ justifyContent: "center",
3843
+ pointerEvents: "none"
3844
+ },
3845
+ children: Ze ? i("div", {
3846
+ style: {
3847
+ fontSize: 18,
3848
+ color: "#aaa",
3849
+ fontWeight: 400,
3850
+ fontFamily: "system-ui, sans-serif"
3851
+ },
3852
+ children: "Drag & Drop Files Here"
3853
+ }) : k("div", {
3854
+ style: {
3855
+ textAlign: "center"
3856
+ },
3857
+ children: [
3858
+ i("div", {
3859
+ style: {
3860
+ width: 32,
3861
+ height: 32,
3862
+ border: "3px solid rgba(0,0,0,0.1)",
3863
+ borderTopColor: "#4a90d9",
3864
+ borderRadius: "50%",
3865
+ animation: "spin 1s linear infinite",
3866
+ margin: "0 auto 12px"
3867
+ }
3868
+ }),
3869
+ i("div", {
3870
+ style: {
3871
+ fontSize: 16,
3872
+ color: "#999",
3873
+ fontFamily: "system-ui, sans-serif"
3874
+ },
3875
+ children: "Loading WASM module..."
3876
+ }),
3877
+ i("style", {
3878
+ children: "@keyframes spin { to { transform: rotate(360deg); } }"
3879
+ })
3880
+ ]
3881
+ })
3882
+ }),
3883
+ !e.showDragDrop && !n && !S && !yt && i("div", {
3884
+ style: {
3885
+ position: "absolute",
3886
+ inset: 0,
3887
+ display: "flex",
3888
+ alignItems: "center",
3889
+ justifyContent: "center"
3890
+ },
3891
+ children: k("div", {
3892
+ style: {
3893
+ textAlign: "center"
3894
+ },
3895
+ children: [
3896
+ i("div", {
3897
+ style: {
3898
+ width: 32,
3899
+ height: 32,
3900
+ border: "3px solid rgba(0,0,0,0.1)",
3901
+ borderTopColor: "#4a90d9",
3902
+ borderRadius: "50%",
3903
+ animation: "spin 1s linear infinite",
3904
+ margin: "0 auto 12px"
3905
+ }
3906
+ }),
3907
+ i("div", {
3908
+ style: {
3909
+ fontSize: 16,
3910
+ color: "#999",
3911
+ fontFamily: "system-ui, sans-serif"
3912
+ },
3913
+ children: "Loading scan..."
3914
+ }),
3915
+ i("style", {
3916
+ children: "@keyframes spin { to { transform: rotate(360deg); } }"
3917
+ })
3918
+ ]
3919
+ })
3920
+ }),
3921
+ n && !q && T.length === 0 && k("div", {
3922
+ style: {
3923
+ position: "absolute",
3924
+ top: 16,
3925
+ left: "50%",
3926
+ transform: "translateX(-50%)",
3927
+ display: "flex",
3928
+ alignItems: "center",
3929
+ gap: 8,
3930
+ padding: "8px 16px",
3931
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
3932
+ borderRadius: 8,
3933
+ color: "#fff",
3934
+ fontSize: 13,
3935
+ pointerEvents: "none",
3936
+ zIndex: 5,
3937
+ fontFamily: "system-ui, sans-serif"
3938
+ },
3939
+ children: [
3940
+ i("div", {
3941
+ style: {
3942
+ width: 10,
3943
+ height: 10,
3944
+ borderRadius: "50%",
3945
+ backgroundColor: "#44ff44",
3946
+ flexShrink: 0
3947
+ }
3948
+ }),
3949
+ "Click mesh to set ",
3950
+ F === "AK" ? "IT" : "MPT"
3951
+ ]
3952
+ }),
3953
+ n && !q && T.length === 1 && k("div", {
3954
+ style: {
3955
+ position: "absolute",
3956
+ top: 16,
3957
+ left: "50%",
3958
+ transform: "translateX(-50%)",
3959
+ display: "flex",
3960
+ alignItems: "center",
3961
+ gap: 8,
3962
+ padding: "8px 16px",
3963
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
3964
+ borderRadius: 8,
3965
+ color: "#fff",
3966
+ fontSize: 13,
3967
+ pointerEvents: "none",
3968
+ zIndex: 5,
3969
+ fontFamily: "system-ui, sans-serif"
3970
+ },
3971
+ children: [
3972
+ i("div", {
3973
+ style: {
3974
+ width: 10,
3975
+ height: 10,
3976
+ borderRadius: "50%",
3977
+ backgroundColor: "#ff4444",
3978
+ flexShrink: 0
3979
+ }
3980
+ }),
3981
+ "Click mesh to set Origin"
3982
+ ]
3983
+ }),
3984
+ S && i(sn, {
3985
+ message: g || "Processing mesh..."
3986
+ }),
3987
+ V && i(sn, {
3988
+ message: J
3989
+ }),
3990
+ yt && i(ko, {
3991
+ message: yt,
3992
+ onDismiss: () => De(null)
3993
+ }),
3994
+ e.showAmputationModal && y && i("div", {
3995
+ style: {
3996
+ position: "absolute",
3997
+ inset: 0,
3998
+ backgroundColor: "rgba(0,0,0,0.32)",
3999
+ backdropFilter: "blur(6px)",
4000
+ WebkitBackdropFilter: "blur(6px)",
4001
+ display: "flex",
4002
+ alignItems: "center",
4003
+ justifyContent: "center",
4004
+ zIndex: 20
4005
+ },
4006
+ children: k("div", {
4007
+ style: {
4008
+ backgroundColor: "#fff",
4009
+ borderRadius: 4,
4010
+ width: 560,
4011
+ boxShadow: "0 11px 15px -7px rgba(0,0,0,0.2), 0 24px 38px 3px rgba(0,0,0,0.14), 0 9px 46px 8px rgba(0,0,0,0.12)",
4012
+ fontFamily: "system-ui, sans-serif"
4013
+ },
4014
+ children: [
4015
+ k("div", {
4016
+ style: {
4017
+ padding: "24px 24px 20px"
4018
+ },
4019
+ children: [
4020
+ i("div", {
4021
+ style: {
4022
+ fontSize: 20,
4023
+ fontWeight: 500,
4024
+ color: "rgba(0,0,0,0.87)",
4025
+ marginBottom: 8
4026
+ },
4027
+ children: "Select Spacing Type"
4028
+ }),
4029
+ i("div", {
4030
+ style: {
4031
+ fontSize: 14,
4032
+ color: "rgba(0,0,0,0.54)",
4033
+ marginBottom: 24
4034
+ },
4035
+ children: "Choose the measurement spacing for this scan"
4036
+ }),
4037
+ i("div", {
4038
+ style: {
4039
+ display: "flex",
4040
+ gap: 16
4041
+ },
4042
+ children: [
4043
+ "AK",
4044
+ "BK"
4045
+ ].map((w) => k("label", {
4046
+ onClick: () => I(w),
4047
+ style: {
4048
+ flex: 1,
4049
+ display: "flex",
4050
+ flexDirection: "column",
4051
+ padding: "20px 24px",
4052
+ border: "2px solid",
4053
+ borderRadius: 4,
4054
+ cursor: "pointer",
4055
+ borderColor: F === w ? "rgb(12, 67, 173)" : "#e0e0e0",
4056
+ backgroundColor: F === w ? "rgba(12, 67, 173, 0.04)" : "#fff",
4057
+ transition: "border-color 0.15s, background-color 0.15s"
4058
+ },
4059
+ children: [
4060
+ i("input", {
4061
+ type: "radio",
4062
+ name: "ampType",
4063
+ checked: F === w,
4064
+ onChange: () => I(w),
4065
+ style: {
4066
+ accentColor: "rgb(12, 67, 173)",
4067
+ marginBottom: 12,
4068
+ width: 18,
4069
+ height: 18
4070
+ }
4071
+ }),
4072
+ i("span", {
4073
+ style: {
4074
+ fontSize: 18,
4075
+ fontWeight: 600,
4076
+ color: "rgba(0,0,0,0.87)",
4077
+ marginBottom: 4
4078
+ },
4079
+ children: w
4080
+ }),
4081
+ k("span", {
4082
+ style: {
4083
+ fontSize: 13,
4084
+ color: "rgba(0,0,0,0.54)"
4085
+ },
4086
+ children: [
4087
+ w === "AK" ? "2" : "1",
4088
+ "-inch measurement spacing"
4089
+ ]
4090
+ })
4091
+ ]
4092
+ }, w))
4093
+ })
4094
+ ]
4095
+ }),
4096
+ k("div", {
4097
+ style: {
4098
+ display: "flex",
4099
+ justifyContent: "flex-end",
4100
+ gap: 8,
4101
+ padding: "12px 24px 20px",
4102
+ borderTop: "1px solid #e0e0e0"
4103
+ },
4104
+ children: [
4105
+ i("button", {
4106
+ onClick: () => {
4107
+ M(false), v(null);
4108
+ },
4109
+ style: {
4110
+ padding: "6px 16px",
4111
+ borderRadius: 4,
4112
+ fontSize: 14,
4113
+ fontWeight: 500,
4114
+ backgroundColor: "#fff",
4115
+ border: "1px solid #bdbdbd",
4116
+ color: "rgba(0,0,0,0.87)",
4117
+ cursor: "pointer",
4118
+ fontFamily: "system-ui, sans-serif",
4119
+ lineHeight: "36px",
4120
+ letterSpacing: "0.4px"
4121
+ },
4122
+ children: "Cancel"
4123
+ }),
4124
+ i("button", {
4125
+ onClick: () => F && Gn(F),
4126
+ disabled: !F,
4127
+ style: {
4128
+ padding: "6px 16px",
4129
+ borderRadius: 4,
4130
+ fontSize: 14,
4131
+ fontWeight: 500,
4132
+ backgroundColor: F ? "rgb(12, 67, 173)" : "#e0e0e0",
4133
+ border: "none",
4134
+ color: F ? "#fff" : "#9e9e9e",
4135
+ cursor: F ? "pointer" : "not-allowed",
4136
+ fontFamily: "system-ui, sans-serif",
4137
+ lineHeight: "36px",
4138
+ letterSpacing: "0.4px"
4139
+ },
4140
+ children: "Next \xBB"
4141
+ })
4142
+ ]
4143
+ })
4144
+ ]
4145
+ })
4146
+ }),
4147
+ e.showDragDrop && u && i("div", {
4148
+ style: {
4149
+ position: "absolute",
4150
+ inset: 0,
4151
+ backgroundColor: "rgba(12, 67, 173, 0.1)",
4152
+ border: "2px dashed rgb(12, 67, 173)",
4153
+ pointerEvents: "none",
4154
+ zIndex: 10
4155
+ }
4156
+ }),
4157
+ i(zo, {
4158
+ children: k(so, {
4159
+ camera: {
4160
+ position: [
4161
+ 0,
4162
+ 0,
4163
+ 5
4164
+ ]
4165
+ },
4166
+ style: {
4167
+ display: n ? "block" : "none",
4168
+ backgroundColor: We ? "#070611" : void 0
4169
+ },
4170
+ gl: {
4171
+ localClippingEnabled: true,
4172
+ preserveDrawingBuffer: true
4173
+ },
4174
+ scene: {
4175
+ background: We ? new O.Color("#070611") : null
4176
+ },
4177
+ children: [
4178
+ i("ambientLight", {
4179
+ intensity: 0.4
4180
+ }),
4181
+ i("directionalLight", {
4182
+ position: [
4183
+ 10,
4184
+ 10,
4185
+ 5
4186
+ ],
4187
+ intensity: 1.2
4188
+ }),
4189
+ i("directionalLight", {
4190
+ position: [
4191
+ -5,
4192
+ 5,
4193
+ -5
4194
+ ],
4195
+ intensity: 0.4
4196
+ }),
4197
+ i("directionalLight", {
4198
+ position: [
4199
+ 0,
4200
+ -10,
4201
+ 0
4202
+ ],
4203
+ intensity: 0.2
4204
+ }),
4205
+ n && A === "3D" && i(Fo, {
4206
+ mesh: n,
4207
+ maxPoints: 2,
4208
+ meshColor: jt,
4209
+ meshOpacity: We ? 0.3 : $n,
4210
+ frontFaceOnly: Z,
4211
+ doubleShellTransparency: Y && q
4212
+ }),
4213
+ n && A === "3D" && i(Lo, {
4214
+ modelSize: d,
4215
+ labels: [
4216
+ F === "AK" ? "IT" : "MPT",
4217
+ "Origin",
4218
+ "Cut Plane"
4219
+ ]
4220
+ }),
4221
+ i(Oo, {
4222
+ modelSize: d,
4223
+ isAligned: q,
4224
+ isCut: Ft,
4225
+ mesh: n,
4226
+ viewMode: A,
4227
+ sliceY: q && T.length >= 2 ? Ae ?? xt ?? T[0].position.y : void 0,
4228
+ landmarkCount: T.length,
4229
+ measurementGeometry: xe,
4230
+ resetCameraToFrontRef: kt
4231
+ }),
4232
+ !q && i(pn, {
4233
+ enableDamping: false
4234
+ }),
4235
+ q && j.length > 0 && n && A === "3D" && i($o, {
4236
+ mesh: n,
4237
+ isDragging: Pn
4238
+ }),
4239
+ n && q && T.length >= 3 && (() => {
4240
+ const D = n.geometry.getIndex();
4241
+ if (!D || D.count < 30) return null;
4242
+ const B = T[2], R = T[0], ce = Ge ?? B.position.y, G = Ae ?? xt ?? R.position.y;
4243
+ return A === "2D" ? i(No, {
4244
+ mesh: Jt ?? n,
4245
+ upperY: G,
4246
+ originY: R.position.y,
4247
+ modelSize: d,
4248
+ meshColor: jt,
4249
+ displayUnit: _
4250
+ }) : k(Oe, {
4251
+ children: [
4252
+ i(Bo, {
4253
+ mesh: Jt ?? n,
4254
+ startY: ce,
4255
+ endY: G,
4256
+ spacing: st,
4257
+ modelSize: d,
4258
+ onMeasurementsChange: X,
4259
+ reverseOrder: true,
4260
+ displayUnit: _,
4261
+ useInnerSurface: Y && !Z,
4262
+ formMeasurements: He ? Bn ?? Se : Ue ? Se : void 0,
4263
+ originY: bt ?? R.position.y,
4264
+ wasmSlices: Le
4265
+ }),
4266
+ i(To, {
4267
+ mesh: n,
4268
+ greenY: bt ?? R.position.y,
4269
+ modelSize: d,
4270
+ displayUnit: _,
4271
+ bottomY: Y ? B.position.y : void 0,
4272
+ formHeight: He ? Tn : Ue ? Je == null ? void 0 : Je.frontalHeight : void 0
4273
+ }),
4274
+ i(Yo, {
4275
+ mesh: n,
4276
+ yPosition: bt ?? R.position.y,
4277
+ onYChange: (K) => {
4278
+ Ln(K), Ie(null);
4279
+ const oe = K - R.position.y;
4280
+ Tt((xt ?? R.position.y + st * 2) + oe);
4281
+ },
4282
+ minY: R.position.y - st,
4283
+ maxY: R.position.y + st,
4284
+ modelSize: d,
4285
+ color: "#44ff44",
4286
+ hoverColor: "#88ff88",
4287
+ dragColor: "#ffffff",
4288
+ label: F === "AK" ? "IT" : "MPT",
4289
+ onDragStart: () => Ot(true),
4290
+ onDragEnd: () => Ot(false)
4291
+ })
4292
+ ]
4293
+ });
4294
+ })(),
4295
+ n && q && A === "3D" && We && i(dr, {
4296
+ mesh: n
4297
+ }),
4298
+ n && e.showDebug && We && A === "3D" && i(cr, {
4299
+ mesh: n,
4300
+ modelSize: d,
4301
+ layers: $t,
4302
+ landmarkPoints: T,
4303
+ componentDebug: null,
4304
+ aoData: me,
4305
+ aoGeometry: $,
4306
+ measurementGeometry: xe
4307
+ }),
4308
+ i(hr, {
4309
+ screenshotFnRef: Vn,
4310
+ mesh: n,
4311
+ modelSize: d,
4312
+ measurementGeometry: xe
4313
+ })
4314
+ ]
4315
+ })
4316
+ }),
4317
+ n && k("div", {
4318
+ style: {
4319
+ position: "absolute",
4320
+ top: 16,
4321
+ left: 16,
4322
+ zIndex: 10,
4323
+ display: "flex",
4324
+ gap: 8
4325
+ },
4326
+ children: [
4327
+ e.showStartOver && i("button", {
4328
+ onClick: () => window.location.reload(),
4329
+ style: {
4330
+ padding: "6px 16px",
4331
+ borderRadius: 4,
4332
+ fontSize: 13,
4333
+ fontWeight: 500,
4334
+ backgroundColor: "#fff",
4335
+ border: "1px solid #bdbdbd",
4336
+ color: "#333",
4337
+ cursor: "pointer",
4338
+ fontFamily: "system-ui, sans-serif",
4339
+ letterSpacing: "0.4px",
4340
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4341
+ },
4342
+ children: "Start Over"
4343
+ }),
4344
+ !q && T.length >= 1 && i("button", {
4345
+ onClick: jn,
4346
+ style: {
4347
+ padding: "6px 16px",
4348
+ borderRadius: 4,
4349
+ fontSize: 13,
4350
+ fontWeight: 500,
4351
+ backgroundColor: "#fff",
4352
+ border: "1px solid #bdbdbd",
4353
+ color: "#333",
4354
+ cursor: "pointer",
4355
+ fontFamily: "system-ui, sans-serif",
4356
+ letterSpacing: "0.4px",
4357
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4358
+ },
4359
+ children: "Reset Points"
4360
+ })
4361
+ ]
4362
+ }),
4363
+ e.showDebug && We && n && A === "3D" && i(ur, {
4364
+ layers: $t,
4365
+ onToggleLayer: (w) => Dn((D) => ({
4366
+ ...D,
4367
+ [w]: !D[w]
4368
+ })),
4369
+ isDoubleShell: Y
4370
+ }),
4371
+ q && j.length > 0 && k("div", {
4372
+ style: {
4373
+ position: "absolute",
4374
+ top: 16,
4375
+ right: 16,
4376
+ display: "flex",
4377
+ gap: 8,
4378
+ zIndex: 10
4379
+ },
4380
+ children: [
4381
+ k("div", {
4382
+ style: {
4383
+ display: "flex",
4384
+ borderRadius: 6,
4385
+ overflow: "hidden",
4386
+ border: "1px solid #ccc",
4387
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4388
+ },
4389
+ children: [
4390
+ i("button", {
4391
+ onClick: () => L("3D"),
4392
+ style: {
4393
+ padding: "6px 14px",
4394
+ fontSize: 13,
4395
+ fontWeight: A === "3D" ? 600 : 400,
4396
+ backgroundColor: A === "3D" ? "rgb(12, 67, 173)" : "#fff",
4397
+ color: A === "3D" ? "#fff" : "#666",
4398
+ border: "none",
4399
+ cursor: "pointer",
4400
+ fontFamily: "system-ui, sans-serif"
4401
+ },
4402
+ children: "Orbital"
4403
+ }),
4404
+ i("button", {
4405
+ onClick: () => L("2D"),
4406
+ style: {
4407
+ padding: "6px 14px",
4408
+ fontSize: 13,
4409
+ fontWeight: A === "2D" ? 600 : 400,
4410
+ backgroundColor: A === "2D" ? "rgb(12, 67, 173)" : "#fff",
4411
+ color: A === "2D" ? "#fff" : "#666",
4412
+ border: "none",
4413
+ borderLeft: "1px solid #ccc",
4414
+ cursor: "pointer",
4415
+ fontFamily: "system-ui, sans-serif"
4416
+ },
4417
+ children: "Transverse"
4418
+ })
4419
+ ]
4420
+ }),
4421
+ k("div", {
4422
+ style: {
4423
+ display: "flex",
4424
+ borderRadius: 6,
4425
+ overflow: "hidden",
4426
+ border: "1px solid #ccc",
4427
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4428
+ },
4429
+ children: [
4430
+ i("button", {
4431
+ onClick: () => E("mm"),
4432
+ style: {
4433
+ padding: "6px 14px",
4434
+ fontSize: 13,
4435
+ fontWeight: _ === "mm" ? 600 : 400,
4436
+ backgroundColor: _ === "mm" ? "rgb(12, 67, 173)" : "#fff",
4437
+ color: _ === "mm" ? "#fff" : "#666",
4438
+ border: "none",
4439
+ cursor: "pointer",
4440
+ fontFamily: "system-ui, sans-serif"
4441
+ },
4442
+ children: "mm"
4443
+ }),
4444
+ i("button", {
4445
+ onClick: () => E("inch"),
4446
+ style: {
4447
+ padding: "6px 14px",
4448
+ fontSize: 13,
4449
+ fontWeight: _ === "inch" ? 600 : 400,
4450
+ backgroundColor: _ === "inch" ? "rgb(12, 67, 173)" : "#fff",
4451
+ color: _ === "inch" ? "#fff" : "#666",
4452
+ border: "none",
4453
+ borderLeft: "1px solid #ccc",
4454
+ cursor: "pointer",
4455
+ fontFamily: "system-ui, sans-serif"
4456
+ },
4457
+ children: "in"
4458
+ })
4459
+ ]
4460
+ }),
4461
+ e.showSpacingToggle && A === "3D" && k("div", {
4462
+ style: {
4463
+ display: "flex",
4464
+ borderRadius: 6,
4465
+ overflow: "hidden",
4466
+ border: "1px solid #ccc",
4467
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4468
+ },
4469
+ children: [
4470
+ i("button", {
4471
+ onClick: () => P(1),
4472
+ style: {
4473
+ padding: "6px 14px",
4474
+ fontSize: 13,
4475
+ fontWeight: z === 1 ? 600 : 400,
4476
+ backgroundColor: z === 1 ? "rgb(12, 67, 173)" : "#fff",
4477
+ color: z === 1 ? "#fff" : "#666",
4478
+ border: "none",
4479
+ cursor: "pointer",
4480
+ fontFamily: "system-ui, sans-serif"
4481
+ },
4482
+ children: '1"'
4483
+ }),
4484
+ i("button", {
4485
+ onClick: () => P(2),
4486
+ style: {
4487
+ padding: "6px 14px",
4488
+ fontSize: 13,
4489
+ fontWeight: z === 2 ? 600 : 400,
4490
+ backgroundColor: z === 2 ? "rgb(12, 67, 173)" : "#fff",
4491
+ color: z === 2 ? "#fff" : "#666",
4492
+ border: "none",
4493
+ borderLeft: "1px solid #ccc",
4494
+ cursor: "pointer",
4495
+ fontFamily: "system-ui, sans-serif"
4496
+ },
4497
+ children: '2"'
4498
+ })
4499
+ ]
4500
+ }),
4501
+ A === "3D" && Se && i("div", {
4502
+ style: {
4503
+ display: "flex",
4504
+ borderRadius: 6,
4505
+ overflow: "hidden",
4506
+ border: "1px solid #ccc",
4507
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4508
+ },
4509
+ children: i("button", {
4510
+ onClick: () => Vt((w) => !w),
4511
+ style: {
4512
+ padding: "6px 14px",
4513
+ fontSize: 13,
4514
+ fontWeight: Ue ? 600 : 400,
4515
+ backgroundColor: Ue ? "rgb(12, 67, 173)" : "#fff",
4516
+ color: Ue ? "#fff" : "#666",
4517
+ border: "none",
4518
+ cursor: "pointer",
4519
+ fontFamily: "system-ui, sans-serif"
4520
+ },
4521
+ children: "Measurement Overlay"
4522
+ })
4523
+ }),
4524
+ e.showSaveButton && i("div", {
4525
+ style: {
4526
+ display: "flex",
4527
+ borderRadius: 6,
4528
+ overflow: "hidden",
4529
+ border: "1px solid #ccc",
4530
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4531
+ },
4532
+ children: i("button", {
4533
+ onClick: async () => {
4534
+ const w = await Qe();
4535
+ if (!w) return;
4536
+ const D = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10), B = (R, ce) => {
4537
+ const G = document.createElement("a");
4538
+ G.href = R, G.download = ce, G.click();
4539
+ };
4540
+ B(w.frontal_view_png, `measurements_front_${D}.png`), await new Promise((R) => setTimeout(R, 300)), B(w.side_view_png, `measurements_transverse_${D}.png`);
4541
+ },
4542
+ style: {
4543
+ padding: "6px 14px",
4544
+ fontSize: 13,
4545
+ fontWeight: 400,
4546
+ backgroundColor: "#fff",
4547
+ color: "#666",
4548
+ border: "none",
4549
+ cursor: "pointer",
4550
+ fontFamily: "system-ui, sans-serif"
4551
+ },
4552
+ children: "Save"
4553
+ })
4554
+ }),
4555
+ e.showDebug && s && i("div", {
4556
+ style: {
4557
+ display: "flex",
4558
+ borderRadius: 6,
4559
+ overflow: "hidden",
4560
+ border: "1px solid #ccc",
4561
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
4562
+ },
4563
+ children: i("button", {
4564
+ onClick: () => In((w) => !w),
4565
+ style: {
4566
+ padding: "6px 14px",
4567
+ fontSize: 13,
4568
+ fontWeight: We ? 600 : 400,
4569
+ backgroundColor: We ? "#e65100" : "#fff",
4570
+ color: We ? "#fff" : "#666",
4571
+ border: "none",
4572
+ cursor: "pointer",
4573
+ fontFamily: "system-ui, sans-serif"
4574
+ },
4575
+ children: "Debug"
4576
+ })
4577
+ })
4578
+ ]
4579
+ }),
4580
+ n && ie && i(Ho, {
4581
+ wasAutoScaled: ae,
4582
+ onDismiss: () => Q(false)
4583
+ }),
4584
+ n && we && q && i(Vo, {
4585
+ isDoubleShell: Y,
4586
+ onDismiss: () => re(false)
4587
+ })
4588
+ ]
4589
+ })
4590
+ ]
4591
+ }),
4592
+ ze && k("div", {
4593
+ "data-finalizing-overlay": true,
4594
+ style: {
4595
+ position: "absolute",
4596
+ inset: 0,
4597
+ backgroundColor: "#fff",
4598
+ display: "flex",
4599
+ flexDirection: "column",
4600
+ alignItems: "center",
4601
+ justifyContent: "center",
4602
+ zIndex: 50
4603
+ },
4604
+ children: [
4605
+ i("div", {
4606
+ style: {
4607
+ width: 32,
4608
+ height: 32,
4609
+ border: "3px solid #e0e0e0",
4610
+ borderTopColor: "rgb(12, 67, 173)",
4611
+ borderRadius: "50%",
4612
+ animation: "gm-spin 0.8s linear infinite"
4613
+ }
4614
+ }),
4615
+ i("p", {
4616
+ style: {
4617
+ marginTop: 12,
4618
+ fontSize: 14,
4619
+ color: "#555",
4620
+ fontFamily: "system-ui, sans-serif"
4621
+ },
4622
+ children: "Generating screenshots and preparing data\u2026"
4623
+ }),
4624
+ i("style", {
4625
+ children: "@keyframes gm-spin { to { transform: rotate(360deg) } }"
4626
+ })
4627
+ ]
4628
+ }),
4629
+ k("div", {
4630
+ style: {
4631
+ padding: "12px 24px",
4632
+ backgroundColor: "#fff",
4633
+ borderTop: "1px solid #e0e0e0",
4634
+ display: "flex",
4635
+ alignItems: "center",
4636
+ justifyContent: "space-between",
4637
+ gap: 8,
4638
+ flexShrink: 0
4639
+ },
4640
+ children: [
4641
+ !He && l && i("button", {
4642
+ disabled: ze,
4643
+ onClick: () => Ct(true),
4644
+ style: {
4645
+ padding: "6px 16px",
4646
+ borderRadius: 4,
4647
+ fontSize: 13,
4648
+ fontWeight: 500,
4649
+ backgroundColor: "#fff",
4650
+ border: "1px solid #bdbdbd",
4651
+ color: ze ? "#999" : "#666",
4652
+ cursor: ze ? "not-allowed" : "pointer",
4653
+ fontFamily: "system-ui, sans-serif",
4654
+ letterSpacing: "0.4px",
4655
+ lineHeight: "36px"
4656
+ },
4657
+ children: "Have Galileo Check My Measurements"
4658
+ }),
4659
+ He && i("div", {}),
4660
+ k("div", {
4661
+ style: {
4662
+ display: "flex",
4663
+ gap: 8
4664
+ },
4665
+ children: [
4666
+ n && !q && T.length >= 2 && i("button", {
4667
+ onClick: Zn,
4668
+ style: {
4669
+ padding: "6px 16px",
4670
+ borderRadius: 4,
4671
+ fontSize: 14,
4672
+ fontWeight: 500,
4673
+ backgroundColor: "rgb(12, 67, 173)",
4674
+ border: "none",
4675
+ color: "#fff",
4676
+ cursor: "pointer",
4677
+ fontFamily: "system-ui, sans-serif",
4678
+ letterSpacing: "0.4px",
4679
+ lineHeight: "36px"
4680
+ },
4681
+ children: "Next \xBB"
4682
+ }),
4683
+ q && vt && !He && i("button", {
4684
+ onClick: () => St(true),
4685
+ style: {
4686
+ padding: "6px 16px",
4687
+ borderRadius: 4,
4688
+ fontSize: 14,
4689
+ fontWeight: 500,
4690
+ backgroundColor: "#fff",
4691
+ border: "1px solid #bdbdbd",
4692
+ color: "#333",
4693
+ cursor: "pointer",
4694
+ fontFamily: "system-ui, sans-serif",
4695
+ letterSpacing: "0.4px",
4696
+ lineHeight: "36px"
4697
+ },
4698
+ children: "Edit Measurements"
4699
+ }),
4700
+ q && vt && (Un ? i("button", {
4701
+ disabled: ze,
4702
+ onClick: () => Lt("continue"),
4703
+ style: {
4704
+ padding: "6px 16px",
4705
+ borderRadius: 4,
4706
+ fontSize: 14,
4707
+ fontWeight: 500,
4708
+ backgroundColor: ze ? "#9e9e9e" : "rgb(12, 67, 173)",
4709
+ border: "none",
4710
+ color: "#fff",
4711
+ cursor: ze ? "not-allowed" : "pointer",
4712
+ fontFamily: "system-ui, sans-serif",
4713
+ letterSpacing: "0.4px",
4714
+ lineHeight: "36px"
4715
+ },
4716
+ children: "Continue"
4717
+ }) : k(Oe, {
4718
+ children: [
4719
+ i("button", {
4720
+ disabled: ze,
4721
+ onClick: () => Lt("use_form_measurements"),
4722
+ style: {
4723
+ padding: "6px 16px",
4724
+ borderRadius: 4,
4725
+ fontSize: 14,
4726
+ fontWeight: 500,
4727
+ backgroundColor: ze ? "#9e9e9e" : "rgb(12, 67, 173)",
4728
+ border: "none",
4729
+ color: "#fff",
4730
+ cursor: ze ? "not-allowed" : "pointer",
4731
+ fontFamily: "system-ui, sans-serif",
4732
+ letterSpacing: "0.4px",
4733
+ lineHeight: "36px"
4734
+ },
4735
+ children: "Set to Measurements"
4736
+ }),
4737
+ i("button", {
4738
+ disabled: ze,
4739
+ onClick: () => Lt("use_scan"),
4740
+ style: {
4741
+ padding: "6px 16px",
4742
+ borderRadius: 4,
4743
+ fontSize: 14,
4744
+ fontWeight: 500,
4745
+ backgroundColor: ze ? "#e0e0e0" : "#fff",
4746
+ border: "1px solid #bdbdbd",
4747
+ color: ze ? "#999" : "#333",
4748
+ cursor: ze ? "not-allowed" : "pointer",
4749
+ fontFamily: "system-ui, sans-serif",
4750
+ letterSpacing: "0.4px",
4751
+ lineHeight: "36px"
4752
+ },
4753
+ children: "Go With Scan"
4754
+ })
4755
+ ]
4756
+ }))
4757
+ ]
4758
+ })
4759
+ ]
4760
+ })
4761
+ ]
4762
+ }),
4763
+ s && Mt.length > 0 && k("div", {
4764
+ style: {
4765
+ height: 120,
4766
+ flexShrink: 0,
4767
+ background: "#0d1117",
4768
+ borderTop: "1px solid #30363d",
4769
+ fontFamily: "'SF Mono', 'Cascadia Code', 'Fira Code', Consolas, monospace",
4770
+ fontSize: 11,
4771
+ color: "#c9d1d9",
4772
+ display: "flex",
4773
+ flexDirection: "column"
4774
+ },
4775
+ children: [
4776
+ k("div", {
4777
+ style: {
4778
+ display: "flex",
4779
+ alignItems: "center",
4780
+ justifyContent: "space-between",
4781
+ padding: "3px 10px",
4782
+ background: "#161b22",
4783
+ borderBottom: "1px solid #21262d",
4784
+ flexShrink: 0
4785
+ },
4786
+ children: [
4787
+ i("span", {
4788
+ style: {
4789
+ color: "#58a6ff",
4790
+ fontSize: 10,
4791
+ fontWeight: 600,
4792
+ letterSpacing: 0.5
4793
+ },
4794
+ children: "GALILEO DEBUG"
4795
+ }),
4796
+ k("div", {
4797
+ style: {
4798
+ display: "flex",
4799
+ gap: 8,
4800
+ alignItems: "center"
4801
+ },
4802
+ children: [
4803
+ k("span", {
4804
+ style: {
4805
+ color: "#484f58",
4806
+ fontSize: 9
4807
+ },
4808
+ children: [
4809
+ "WASM ",
4810
+ Ve.current ? "v2" : "N/A",
4811
+ " | ",
4812
+ T.length,
4813
+ " pts | ",
4814
+ q ? "aligned" : "unaligned",
4815
+ " | ",
4816
+ j.length,
4817
+ " slices"
4818
+ ]
4819
+ }),
4820
+ i("button", {
4821
+ onClick: () => Nt([]),
4822
+ style: {
4823
+ background: "none",
4824
+ border: "1px solid #30363d",
4825
+ borderRadius: 3,
4826
+ color: "#484f58",
4827
+ fontSize: 9,
4828
+ cursor: "pointer",
4829
+ padding: "1px 6px"
4830
+ },
4831
+ children: "clear"
4832
+ })
4833
+ ]
4834
+ })
4835
+ ]
4836
+ }),
4837
+ i("div", {
4838
+ ref: it,
4839
+ style: {
4840
+ flex: 1,
4841
+ overflowY: "auto",
4842
+ padding: "4px 10px",
4843
+ lineHeight: 1.6
4844
+ },
4845
+ children: Mt.map((w, D) => {
4846
+ const B = w.includes("ERROR") || w.includes("failed"), R = w.includes("warning") || w.includes("WARN"), ce = w.includes("PIPELINE:"), G = w.includes("STATE:");
4847
+ return i("div", {
4848
+ style: {
4849
+ color: B ? "#f85149" : R ? "#d29922" : ce ? "#58a6ff" : G ? "#3fb950" : "#8b949e",
4850
+ whiteSpace: "pre"
4851
+ },
4852
+ children: w
4853
+ }, D);
4854
+ })
4855
+ })
4856
+ ]
4857
+ })
4858
+ ]
4859
+ }),
4860
+ Rn && i(Cn, {
4861
+ onSkip: qt,
4862
+ onCancel: () => Ct(false)
4863
+ })
4864
+ ]
4865
+ });
4866
+ };
4867
+ function hr({ screenshotFnRef: e }) {
4868
+ return U(() => {
4869
+ e.current = null;
4870
+ }, [
4871
+ e
4872
+ ]), null;
4873
+ }
4874
+ An = function(e) {
4875
+ const r = e === "AK" ? 2 : 1, t = [];
4876
+ for (let o = 2; o >= 1; o -= r) t.push(`${o}_above`);
4877
+ t.push("at_ref");
4878
+ for (let o = r; o <= 9; o += r) t.push(`${o}_below`);
4879
+ if (e === "BK") for (const o of [
4880
+ 10,
4881
+ 11,
4882
+ 12
4883
+ ]) t.push(`${o}_below`);
4884
+ else for (const o of [
4885
+ 10,
4886
+ 12,
4887
+ 14,
4888
+ 16,
4889
+ 18
4890
+ ]) t.push(`${o}_below`);
4891
+ return t;
4892
+ };
4893
+ ft = function(e, r) {
4894
+ const t = An(r), o = {};
4895
+ for (let l = 0; l < Math.min(e.length, t.length); l++) {
4896
+ const s = e[l];
4897
+ s != null && !isNaN(s) && (o[t[l]] = s);
4898
+ }
4899
+ return o;
4900
+ };
4901
+ gr = function(e, r) {
4902
+ if (!e) return;
4903
+ const o = An(r).map((l) => {
4904
+ const s = e[l];
4905
+ return s ?? void 0;
4906
+ });
4907
+ if (!o.every((l) => l == null)) return o;
4908
+ };
4909
+ kr = ({ request: e, onComplete: r, wasmModule: t }) => {
4910
+ const o = H(() => gr(e.form_measurements, e.spacing_type), [
4911
+ e.form_measurements,
4912
+ e.spacing_type
4913
+ ]), l = (s) => {
4914
+ var _a, _b;
4915
+ const c = s.scanMeasurements.map((p) => +(p.modifiedValue ?? p.originalValue).toFixed(1)), a = ft(c, e.spacing_type);
4916
+ let n, m;
4917
+ if (s.formMeasurements) {
4918
+ n = ft(s.formMeasurements, e.spacing_type);
4919
+ const p = s.scanMeasurements.map((g, b) => {
4920
+ var _a2;
4921
+ const A = (_a2 = s.formMeasurements) == null ? void 0 : _a2[b];
4922
+ return A == null || isNaN(A) ? null : +((g.modifiedValue ?? g.originalValue) - A).toFixed(1);
4923
+ });
4924
+ m = ft(p, e.spacing_type);
4925
+ }
4926
+ const d = s.userEnteredMeasurements ? ft(s.userEnteredMeasurements.circumferences, e.spacing_type) : void 0, f = s.decision === "use_scan" || s.decision === "continue", u = f ? a : d ?? n ?? a, x = f ? +s.frontalHeight.toFixed(1) : +(((_a = s.userEnteredMeasurements) == null ? void 0 : _a.frontalHeight) ?? s.frontalHeight).toFixed(1), S = {
4927
+ spacing_type: e.spacing_type,
4928
+ source_unit: "mm",
4929
+ file_format: s.fileFormat,
4930
+ measurement_source: s.formMeasurements ? "form_provided" : "scan_derived",
4931
+ is_double_wall: s.isDoubleWall,
4932
+ is_unit_converted: false,
4933
+ form_measurements: n,
4934
+ scan_measurements: a,
4935
+ measurement_variance: m,
4936
+ scan_url: e.scan_url,
4937
+ frontal_height: +s.frontalHeight.toFixed(1),
4938
+ transverse_ml: +s.transverseML.toFixed(1),
4939
+ transverse_ap: +s.transverseAP.toFixed(1),
4940
+ decision: s.decision,
4941
+ skip_reason: s.skipReason,
4942
+ user_measurements: d,
4943
+ user_frontal_height: (_b = s.userEnteredMeasurements) == null ? void 0 : _b.frontalHeight,
4944
+ final_measurements: u,
4945
+ final_frontal_height: x,
4946
+ final_transverse_ml: +s.transverseML.toFixed(1),
4947
+ final_transverse_ap: +s.transverseAP.toFixed(1),
4948
+ screenshots: s.screenshots
4949
+ };
4950
+ r == null ? void 0 : r(S);
4951
+ };
4952
+ return i("div", {
4953
+ style: {
4954
+ width: "100%",
4955
+ height: "100%",
4956
+ display: "flex"
4957
+ },
4958
+ children: i(pr, {
4959
+ config: uo,
4960
+ spacingType: e.spacing_type,
4961
+ scanUrl: e.scan_url,
4962
+ formMeasurements: o,
4963
+ onComplete: l,
4964
+ wasmModule: t
4965
+ })
4966
+ });
4967
+ };
4968
+ })();
4969
+ export {
4970
+ kr as G,
4971
+ __tla,
4972
+ ft as a,
4973
+ gr as c,
4974
+ An as g
4975
+ };